1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
#!/usr/bin/python
#############################################################
# tdbutil
#
# Purpose:
# Contains functions that are used to pack and unpack data
# from Samba's tdb databases. Samba sometimes represents complex
# data structures as a single value in a database. These functions
# allow other python scripts to package data types into a single python
# string and unpackage them.
#
#
# XXXXX: This code is no longer used; it's just here for testing
# compatibility with the new (much faster) C implementation.
#
##############################################################
import string
def pack(format,list):
retstring = ''
listind = 0
# Cycle through format entries
for type in format:
# Null Terminated String
if (type == 'f' or type == 'P'):
retstring = retstring + list[listind] + "\000"
# 4 Byte Number
if (type == 'd'):
retstring = retstring + PackNum(list[listind],4)
# 2 Byte Number
if (type == 'w'):
retstring = retstring + PackNum(list[listind],2)
# Pointer Value
if (type == 'p'):
if (list[listind]):
retstring = retstring + PackNum(1,4)
else:
retstring = retstring + PackNum(0,4)
# Buffer and Length
if (type == 'B'):
# length
length = list[listind]
retstring = retstring + PackNum(length,4)
length = int(length)
listind = listind + 1
# buffer
retstring = retstring + list[listind][:length]
listind = listind + 1
return retstring
def unpack(format,buffer):
retlist = []
bufind = 0
lasttype = ""
for type in format:
# Pointer Value
if (type == 'p'):
newvalue = UnpackNum(buffer[bufind:bufind+4])
bufind = bufind + 4
if (newvalue):
newvalue = 1L
else:
newvalue = 0L
retlist.append(newvalue)
# Previous character till end of data
elif (type == '$'):
if (lasttype == 'f'):
while (bufind < len(buffer)):
newstring = ''
while (buffer[bufind] != '\000'):
newstring = newstring + buffer[bufind]
bufind = bufind + 1
bufind = bufind + 1
retlist.append(newstring)
# Null Terminated String
elif (type == 'f' or type == 'P'):
newstring = ''
while (buffer[bufind] != '\000'):
newstring = newstring + buffer[bufind]
bufind = bufind + 1
bufind = bufind + 1
retlist.append(newstring)
# 4 Byte Number
elif (type == 'd'):
newvalue = UnpackNum(buffer[bufind:bufind+4])
bufind = bufind + 4
retlist.append(newvalue)
# 2 Byte Number
elif (type == 'w'):
newvalue = UnpackNum(buffer[bufind:bufind+2])
bufind = bufind + 2
retlist.append(newvalue)
# Length and Buffer
elif (type == 'B'):
# Length
length = UnpackNum(buffer[bufind:bufind+4])
bufind = bufind + 4
retlist.append(length)
length = int(length)
# Buffer
retlist.append(buffer[bufind:bufind+length])
bufind = bufind + length
lasttype = type
return ((retlist,buffer[bufind:]))
def PackNum(myint,size):
retstring = ''
size = size * 2
hint = hex(myint)[2:]
# Check for long notation
if (hint[-1:] == 'L'):
hint = hint[:-1]
addon = size - len(hint)
for i in range(0,addon):
hint = '0' + hint
while (size > 0):
val = string.atoi(hint[size-2:size],16)
retstring = retstring + chr(val)
size = size - 2
return retstring
def UnpackNum(buffer):
size = len(buffer)
mystring = ''
for i in range(size-1,-1,-1):
val = hex(ord(buffer[i]))[2:]
if (len(val) == 1):
val = '0' + val
mystring = mystring + val
if (len(mystring) > 4):
return string.atol(mystring,16)
else:
return string.atoi(mystring,16)
|