#!/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()]
