summaryrefslogtreecommitdiffstats
path: root/BeOS/ar-1.1/docs/dumpar.py
diff options
context:
space:
mode:
Diffstat (limited to 'BeOS/ar-1.1/docs/dumpar.py')
-rw-r--r--BeOS/ar-1.1/docs/dumpar.py271
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()