diff options
Diffstat (limited to 'BeOS/ar-1.1/docs/dumpar.py')
-rw-r--r-- | BeOS/ar-1.1/docs/dumpar.py | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/BeOS/ar-1.1/docs/dumpar.py b/BeOS/ar-1.1/docs/dumpar.py new file mode 100644 index 0000000..93e2283 --- /dev/null +++ b/BeOS/ar-1.1/docs/dumpar.py @@ -0,0 +1,271 @@ +#! /bin/env python +""" Dump data about a Metrowerks archive file. + +$Id$ + +Based on reverse-engineering the library file format. + +Copyright (C) 1997 Chris Herborth (chrish@qnx.com) +""" + +# ---------------------------------------------------------------------- +# Standard modules +import sys +import getopt +import string +import time + +# ---------------------------------------------------------------------- +def usage(): + """ Display a usage message and exit. + """ + print "dumpar [-v] library1 [library2 ... libraryn]" + print + print "Attempt to display some useful information about the contents" + print "of the given Metrowerks library file(s)." + print + print "-v Be verbose (displays offsets along with the data)" + raise SystemExit + +# ---------------------------------------------------------------------- +def mk_long( str ): + """ convert a 4-byte string into a number + + Assumes big-endian! + """ + if len( str ) < 4: + raise ValueError, "str must be 4 bytes long" + + num = ord( str[3] ) + num = num + ord( str[2] ) * 0x100 + num = num + ord( str[1] ) * 0x10000 + num = num + ord( str[0] ) * 0x1000000 + + return num + +# ---------------------------------------------------------------------- +def str2hex( str ): + """ convert a string into a string of hex numbers + """ + ret = [] + for c in str: + h = hex( ord( c ) ) + ret.append( string.zfill( "%s" % ( h[2:] ), 2 ) ) + + return string.join( ret ) + +# ---------------------------------------------------------------------- +def print_offset( offset ): + """ print the offset nicely + """ + + # Turn the offset into a hex number and strip off the leading "0x". + val = "%s" % ( hex( offset ) ) + val = val[2:] + + out = "0x" + string.zfill( val, 8 ) + + print out, + +# ---------------------------------------------------------------------- +def get_string( data ): + """ dig a C string out of a data stream + + returns the string + """ + len = 0 + while data[len] != '\0': + len = len + 1 + + return data[:len] + +# ---------------------------------------------------------------------- +def dump_lib( file, verbose ): + """ dump information about a Metrowerks library file + """ + offset = 0 + + print "Dumping library:", file + + # Attempt to read the data. + try: + data = open( file ).read() + except IOError, retval: + print "*** Unable to open file %s: %s" % ( file, retval[1] ) + return + + # Check the magic number. + if verbose: + print_offset( offset ) + print "Magic:", + magic = data[offset:offset + 8] + print "'%s'" % ( magic ) + if magic != "MWOBPPC ": + print "*** Invalid magic number!" + return + + offset = offset + 8 + + # File flags + if verbose: + print_offset( offset ) + print "file flags:", + print mk_long( data[offset:offset + 4] ) + offset = offset + 4 + + if verbose: + print_offset( offset ) + print "file version:", + print mk_long( data[offset:offset + 4] ) + offset = offset + 4 + + # code size + if verbose: + print_offset( offset ) + print "code size:", mk_long( data[offset:offset + 4] ) + offset = offset + 4 + + # data size + if verbose: + print_offset( offset ) + print "data size:", mk_long( data[offset:offset + 4] ) + offset = offset + 4 + + # number of objects + if verbose: + print_offset( offset ) + print "number of objects:", + num_objs = mk_long( data[offset:offset + 4] ) + print num_objs + + offset = offset + 4 + + print + + # Now loop through the objects. + obj_sizes = [ 0, ] * num_objs + obj_data_offsets = [ 0, ] * num_objs + + for obj in range( num_objs ): + # Magic? + if verbose: + print_offset( offset ) + print "modification time:", + modtime = mk_long( data[offset:offset + 4] ) + print "[%s]" % ( ( time.localtime( modtime ), ) ) + + offset = offset + 4 + + # Offsets? + if verbose: + print_offset( offset ) + print "file name offset 1:", + file_offset1 = mk_long( data[offset:offset + 4] ) + unknown = "%s" % ( hex( file_offset1 ) ) + print "%s (%s)" % ( unknown, str2hex( data[offset:offset + 4] ) ) + + offset = offset + 4 + + if verbose: + print_offset( offset ) + print "file name offset 2:", + file_offset2 = mk_long( data[offset:offset + 4] ) + unknown = "%s" % ( hex( file_offset2 ) ) + print "%s (%s)" % ( unknown, str2hex( data[offset:offset + 4] ) ) + + offset = offset + 4 + + # Extra -1 for NUL character. + print " >>>> File name should be %s characters." % \ + ( file_offset2 - file_offset1 - 1) + + if verbose: + print_offset( offset ) + print "object data offset:", + file_data_offset = mk_long( data[offset:offset + 4] ) + unknown = "%s" % ( hex( file_data_offset ) ) + print "%s (%s)" % ( unknown, str2hex( data[offset:offset + 4] ) ) + + obj_data_offsets[obj] = file_data_offset + + offset = offset + 4 + + # object size + if verbose: + print_offset( offset ) + print "object size:", + obj_sizes[obj] = mk_long( data[offset:offset + 4] ) + print "%s bytes" % ( obj_sizes[obj] ) + + offset = offset + 4 + + print + + # Now loop through the object names. + for obj in range( num_objs ): + # First name + if verbose: + print_offset( offset ) + print "object", + print obj, + print "name 1:", + name1 = get_string( data[offset:] ) + print "[%s] %s chars" % ( name1, len( name1 ) ) + + offset = offset + len( name1 ) + 1 + + # Second name + if verbose: + print_offset( offset ) + print "object", + print obj, + print "name 2:", + name2 = get_string( data[offset:] ) + print "[%s] %s chars" % ( name2, len( name1 ) ) + + offset = offset + len( name2 ) + 1 + + # See if we've got a magic cookie in the object data + if verbose: + print_offset( obj_data_offsets[obj] ) + + cookie = data[obj_data_offsets[obj]:obj_data_offsets[obj] + 8] + print "object", + print obj, + print "cookie: '%s'" % ( cookie ) + + print + + # Now loop through the data and check for magic numbers there. + return + +# ---------------------------------------------------------------------- +def main(): + """ mainline + """ + + # Set up some defaults + be_verbose = 0 + + # First, check the command-line arguments + try: + opt, args = getopt.getopt( sys.argv[1:], "vh?" ) + except getopt.error: + print "*** Error parsing command-line options!" + usage() + + for o in opt: + if o[0] == "-h" or o[0] == "-?": + usage() + elif o[0] == "-v": + be_verbose = 1 + else: + print "*** Unknown command-line option!" + usage() + + # Now we can attempt to dump info about the arguments. + for lib in args: + dump_lib( lib, be_verbose ) + +if __name__ == "__main__": + main() |