rendered paste bodyimport zlib, struct, bz2, os, sys
from xml.dom.minidom import parseString
def getByte(f):
return struct.unpack("<B",f.read(1))[0];
def getWord(f):
return struct.unpack(">H",f.read(2))[0];
def getSWord(f):
return struct.unpack(">h",f.read(2))[0];
def getDWord(f):
return struct.unpack(">I",f.read(4))[0];
def getSDWord(f):
return struct.unpack(">i",f.read(4))[0];
def getQWord(f):
return struct.unpack(">Q",f.read(8))[0];
def getDouble(f):
return struct.unpack(">d",f.read(8))[0];
"""
struct xar_header {
uint32_t magic;
uint16_t size;
uint16_t version;
uint64_t toc_length_compressed;
uint64_t toc_length_uncompressed;
uint32_t cksum_alg;
};
"""
def getChildNodes(node, tagname):
return [c for c in node.childNodes if ((c.nodeType==c.ELEMENT_NODE) and (c.tagName==tagname))]
def getChildNode(node, tagname):
return getChildNodes(node, tagname)[0]
def domtext(node, subnode):
n1 = getChildNode(node, subnode)
for n2 in n1.childNodes:
if n2.nodeType == n2.TEXT_NODE:
return n2.data
def domint(node, subnode):
return int(domtext(node, subnode))
def getattr(node, subnode, attrname):
subn = node.getElementsByTagName(subnode)[0]
attr = subn.getAttribute(attrname)
return attr
class XarFile:
def handleFile(self, fil, dirname):
name = domtext(fil, "name")
type = domtext(fil, "type")
print "Name: %s"%name
print "Type: %s"%type
if type == "file":
dtn = getChildNode(fil, "data")
offset = domint(dtn, "offset")
length = domint(dtn, "length")
enc = getattr(dtn, "encoding", "style")
self._file.seek(self.start_offset+offset)
data = self._file.read(length)
if enc=="application/x-bzip2":
try:
data = bz2.decompress(data)
except:
print "Error decompressing %s! Writing as-is"%name
elif enc!="application/octet-stream":
raise Exception("Unknown encoding: %s!"%enc)
file(dirname+'/'+name, "wb").write(data)
elif type == "directory":
newdir = dirname+'/'+name
try:
os.makedirs(newdir)
except:
pass
files = getChildNodes(fil, "file")
for fil2 in files:
#print fil
self.handleFile(fil2, newdir)
def walk_toc(self, toc_, dirname):
dom = parseString(toc_)
toc = dom.getElementsByTagName("toc")[0]
files = getChildNodes(toc, "file")
for fil in files:
#print fil
self.handleFile(fil, dirname)
def doXar(self, fname, dirname):
f = file(fname,"rb")
if f.read(4)!='xar!':
print "bad header!"
return
size = getWord(f)
ver = getWord(f)
tocu = getQWord(f)
tocc = getQWord(f)
f.seek(size)
toc = zlib.decompress(f.read(tocc))
#f.seek(size+tocu)
self.start_offset = size+tocu
#print toc
self._file = f
try:
os.makedirs(dirname)
except:
pass
self.walk_toc(toc, dirname)
#return toc, (size+tocu)
xar = XarFile()
xar.doXar(sys.argv[1],sys.argv[2])