#!/usr/bin/python # Python program for reading info from a DRS archive. # By Bryce Schroeder, bryce@lanset.com (IM: AIM4Bryce) # This program is in the Public Domain, but feel free to # contact me. I wrote it mostly after 10 PM, and it may show :) from sys import argv, stdout import os def ltob4int(little): """Convert a 4 byte interger from the so-called 'little endian' format.""" return ord(little[0]) + ord(little[1])*256 + ord(little[2])*65536 + ord(little[3])*16777216 # presently does not bother to actual convert little[3], becuase no drs has # that many tables # Get the header def getHeader(ourDRS): owner = ourDRS.read(60) version = float(ourDRS.read(4)) type = ourDRS.read(12) ntables = ltob4int(ourDRS.read(4)) offset = ltob4int(ourDRS.read(4)) return owner, version, type, ntables, offset def flip(string): nstr = '' for char in string: nstr = char + nstr return nstr def getTableInfo(ourDRS): mysteryByte = ourDRS.read(1) extension = flip(ourDRS.read(3)) tableOffset = ltob4int(ourDRS.read(4)) numberOfFiles = ltob4int(ourDRS.read(4)) return mysteryByte, extension, tableOffset, numberOfFiles def parseTable(ourDRS, numberOfFiles): i = 1 table = {} while i <= numberOfFiles: table[i] = [ltob4int(ourDRS.read(4)),ltob4int(ourDRS.read(4)),ltob4int(ourDRS.read(4)), ourDRS.tell()] i += 1 return table def printTableDatabase(database): num = 1 for n, file in database.items(): print " %4d [%X-%X] -> ID: %d, Offset: %X, Size: %X" % ( num, file[3], file[3]+12, file[0], file[1], file[2] ) num += 1 try: if argv[1] != '--dump': theDRS = open(argv[1],"r") dump = 0 else: directory = argv[2] theDRS = open(argv[3], "r") dump = 1 except IndexError: print "Please Specify a file." except IOError: print "Please Specify a file that really exists!" owner, version, type, ntables, ffoffset = getHeader(theDRS) print "---------------------------------" print " Header:" print " Copyright: '%s'" % owner print " Version: %1.2f" % version print " Type: '%s'" % type print " Number of Tables: %d" % ntables print " First File Offset: %X" % ffoffset print "---------------------------------" i = 1 tables = {} while i <= ntables: mysteryByte, type, tableOffset, numFiles = getTableInfo(theDRS) print " Table %d:" % i print " MysteryByte: %d ('%s')" % (ord(mysteryByte), mysteryByte) print " File Type: '%s'" % type print " Table Offset: %X" % tableOffset print " Number of Files: %d" % numFiles print " -----------------------------" tables[i] = [mysteryByte, type, tableOffset, numFiles] i += 1 i = 1 while i <= ntables: theDRS.seek(tables[i][2]) tables[i].append(parseTable(theDRS, tables[i][3])) print " TABLE %d DATABASE: " % i printTableDatabase(tables[i][4]) print " =============================" i += 1 if dump == 1: print "Dumping files..." if directory[-1:] != '/': directory += '/' name = argv[4] os.system("mkdir %s%s" % (directory, name) ) i = 1 while i <= ntables: for finum, file in tables[i][4].items(): theDRS.seek(file[1]) tmp = open("%s%s/%s.%s" % (directory, name, str(file[0]), tables[i][1]), "w") tmp.write(theDRS.read(file[2])) tmp.close() if finum % 10 == 0: stdout.write('.') stdout.flush() i += 1 print "\nDump Done" #[ltob4int(ourDRS.read(4)),ltob4int(ourDRS.read(4)),ltob4int(ourDRS.read(4)), ourDRS.tell()]