#!/usr/bin/python # Copyright (C) 2012, Jeff Epler # See license information at bottom import mmap import optparse import os import struct MODE_UNKNOWN, MODE_PACK, MODE_UNPACK = range(3) mode = MODE_UNKNOWN parser = optparse.OptionParser() parser.add_option('-p', '--pack', action="store_const", const=MODE_PACK) parser.add_option('-u', '--unpack', action="store_const", const=MODE_UNPACK) opts, args = parser.parse_args() if len(args) == 1 or len(args) == 2: if mode == MODE_UNKNOWN: if os.path.isdir(args[0]): indir = args[0] if len(args) == 1: outfile = args[0] + '.dat' else: outfile = args[1] mode = MODE_PACK else: infile = args[0] if len(args) == 1: outdir = os.path.basename(os.path.splitext(args[0])[0]) else: outdir = args[1] mode = MODE_UNPACK elif mode == MODE_PACK: indir = args[0] if len(args) == 1: outfile = args[0] + '.dat' else: outfile = args[1] else: infile = args[0] if len(args) == 1: outfile = os.path.basename(args[0]) else: outfile = args[1] else: raise SystemExit, """\ Usage: %(p)s [--pack] data # pack files in data/ to data.dat %(p)s [--unpack] data.dat # unpack data.dat to data/""" % { 'p': os.path.basename(sys.argv[0])} def splitall(p): h, t = os.path.split(p) if h: return splitall(h) + (t,) else: return t, def dropfirst(path): return os.path.join(*splitall(path)[1:]) # Remove first compo. def gather(dir): for dirpath, dirnames, filenames in os.walk(dir): for f in filenames: j = os.path.join(dirpath, f) yield (j, dropfirst(j), os.stat(j).st_size) made = set() def makedirs(d): if d in made: return made.add(d) try: os.makedirs(d) except os.error: pass def parse_ftl_dat(buf, st): data_size, name_size = struct.unpack("", repr(outfile) files = list(gather(indir)) out = open(outfile, "wb") out.write(struct.pack("", repr(outdir) inf = open(infile, "rb") buf = mmap.mmap(inf.fileno(), 0, access=mmap.PROT_READ) st = 4 st, = struct.unpack("