import getopt
import sys
import struct
import os
import zlib
import hashlib
class MypException(Exception):
pass
def main():
try:
opts,args=getopt.getopt(sys.argv[1:],"d:",["directory="])
except getopt.GetoptError,err:
print str(err) # will print something like "option -a not recognized"
#usage()
sys.exit(2)
directory=None
for o,a in opts:
if o in ("-d","--directory"):
directory=a
else:
raise MypException('unhandled option')
if directory==None:
raise MypException('no directory specified')
files=os.listdir(directory)
for filename in files:
if '.tor' not in filename: continue
print '%s...'%(filename)
f=open(directory+os.sep+filename,'rb')
signature,version,endianness,tableOffset,_,_,_,_,_,_=struct.unpack('<LLLQLLLHHL',f.read(40)) #getbasicfileinfo
#print '0x%08x %d 0x%08x'%(signature,version,endianness)
if signature!=0x0050594d or endianness!=0xfd23ec43:
raise MypException('invalid file signature or endianness')
if version!=5:
raise MypException('invalid version')
while tableOffset!=0:
f.seek(tableOffset,os.SEEK_SET)
n,tableOffset=struct.unpack('<LQ',f.read(12))
#print '%d 0x%016x'%(n,tableOffset)
while n!=0:
streamOffset,h,compressedSize,uncompressedSize,qwordHash,X,isCompressed=struct.unpack('<QLLLQLH',f.read(34))
if streamOffset==0:
break #no need to continue
if isCompressed==0 and compressedSize!=uncompressedSize:
raise MypException('compression discrepency')
currentOffset=f.tell()
#print '0x%016x %d 0x%08x 0x%08x 0x%016x 0x%08x %d'%(streamOffset,h,compressedSize,uncompressedSize,qwordHash,X,isCompressed)
f.seek(streamOffset,os.SEEK_SET)
hashType,hashSize=struct.unpack('<HH',f.read(4)) #2 is sha256?
if hashType!=2:
raise MypException('unknown hash type')
streamHash=f.read(hashSize)
#print '%d %d %s'%(hashType,hashSize,streamHash.encode('hex'))
buffer=f.read(compressedSize)
if isCompressed==1: buffer=zlib.decompress(buffer)
h=hashlib.new('sha256')
h.update(buffer)
computedHash=h.digest()
if computedHash!=streamHash:
#print '%s!=%s'%(computedHash.encode('hex'),streamHash.encode('hex'))
#raise MypException('sha256 discrepency')
pass
if len(buffer)!=uncompressedSize:
raise MypException('size discrepency')
#XXX: DO SOMETHING HERE
f.seek(currentOffset,os.SEEK_SET)
n-=1
f.close()
if __name__=="__main__":
main()