#! /usr/bin/env python import archive import carchive import sys, string, tempfile, os try: import zlib except ImportError: zlib = archive.DummyZlib() import pprint stack = [] cleanup = [] def main(): global stack name = sys.argv[1] arch = getArchive(name) stack.append((name, arch)) show(name, arch) while 1: toks = string.split(raw_input('? '), ' ', 1) if not toks: usage() continue if len(toks) == 1: cmd = toks[0] arg = '' else: cmd, arg = toks cmd = string.upper(cmd) if cmd == 'U': if len(stack) > 1: arch = stack[-1][1] arch.lib.close() del stack[-1] nm, arch = stack[-1] show(nm, arch) elif cmd == 'O': if not arg: arg = raw_input('open name? ') arg = string.strip(arg) arch = getArchive(arg) if arch is None: print arg, "not found" continue stack.append((arg, arch)) show(arg, arch) elif cmd == 'X': if not arg: arg = raw_input('extract name? ') arg = string.strip(arg) data = getData(arg, arch) if data is None: print "Not found" continue fnm = raw_input('to filename? ') if not fnm: print `data` else: open(fnm, 'wb').write(data) elif cmd == 'Q': break else: usage() for (nm, arch) in stack: arch.lib.close() stack = [] for fnm in cleanup: try: os.remove(fnm) except Exception, e: print "couldn't delete", fnm, e.args def usage(): print "U: go Up one level" print "O : open embedded archive nm" print "X : extract nm" print "Q: quit" def getArchive(nm): if not stack: if string.lower(nm[-4:]) == '.pyz': return ZlibArchive(nm) return carchive.CArchive(nm) parent = stack[-1][1] try: return parent.openEmbedded(nm) except KeyError, e: return None except (ValueError, RuntimeError): ndx = parent.toc.find(nm) dpos, dlen, ulen, flag, typcd, nm = parent.toc[ndx] x, data = parent.extract(ndx) tfnm = tempfile.mktemp() cleanup.append(tfnm) open(tfnm, 'wb').write(data) if typcd == 'z': return ZlibArchive(tfnm) else: return carchive.CArchive(tfnm) def getData(nm, arch): if type(arch.toc) is type({}): (ispkg, pos, lngth) = arch.toc.get(nm, (0, None, 0)) if pos is None: return None arch.lib.seek(arch.start + pos) return zlib.decompress(arch.lib.read(lngth)) ndx = arch.toc.find(nm) dpos, dlen, ulen, flag, typcd, nm = arch.toc[ndx] x, data = arch.extract(ndx) if flag == 1: return zlib.decompress(data) return data def show(nm, arch): if type(arch.toc) == type({}): print " Name: (ispkg, pos, len)" toc = arch.toc else: print " pos, length, uncompressed, iscompressed, type, name" toc = arch.toc.data pprint.pprint(toc) class ZlibArchive(archive.ZlibArchive): def checkmagic(self): """ Overridable. Check to see if the file object self.lib actually has a file we understand. """ self.lib.seek(self.start) #default - magic is at start of file if self.lib.read(len(self.MAGIC)) != self.MAGIC: raise RuntimeError, "%s is not a valid %s archive file" \ % (self.path, self.__class__.__name__) if self.lib.read(len(self.pymagic)) != self.pymagic: print "Warning: pyz is from a different Python version" self.lib.read(4) if __name__ == '__main__': main()