Avoid numeric problems
[dormin.git] / index / index.py
blob30845535f9e3f9948864b156575ffea9beb3868c
1 #!/usr/bin/env python
2 import sys, md5, os, mmap
3 from struct import unpack
6 # We can brute force everything
9 def xfferr (msg):
10 sys.stderr.write (msg)
11 sys.exit (1)
13 digs = {}
14 def ent (map, pos):
15 buf = map[pos:pos+20*4]
16 D = unpack ("<20I", buf)
18 def r4 (off):
19 return map[pos+off:pos+off+4]
21 if not buf[0:4] in ["xff\x00", "xff2"]:
22 return None
24 if D[1] <> 0:
25 return None
27 if D[2] <> 0:
28 return None
30 size = D[5]
31 entr = D[19]
33 buf = r4 (0x50 + 3*4)
34 sechdroff = unpack ("<I", buf)[0] + 8 * 4
35 secoff = unpack ("<I", r4 (sechdroff + 7*4))[0]
36 buf = r4 (secoff + entr)
37 if buf == "\x01\x00\x00\x00":
38 return (size, "skb")
39 elif buf == "\x0c\x00\x00\x00":
40 return (size, "anb")
41 elif buf == "NMO\x00":
42 return (size, "nmo")
43 elif buf == "NTO2":
44 return (size, "nto")
45 else:
46 return None
48 def findname (map, pos, ext):
49 startpos = pos - 16384
50 if startpos < 0:
51 startpos = 0
52 buf = map[startpos:pos]
53 pos = buf.rfind ("." + ext)
54 if pos == -1:
55 return None
56 else:
57 pos1 = buf[:pos].rfind ("\x00")
58 if pos1 == -1:
59 pos1 = 0
60 return buf[pos1+1:pos+4]
62 def main (path):
63 x = open (path, "rb")
64 x.seek (0, 2)
65 s = x.tell ()
66 m = mmap.mmap (x.fileno (), s, mmap.MAP_PRIVATE, mmap.PROT_READ)
67 h = {}
69 pos = 0
70 chunk = 40000
71 while pos < s:
72 buf = m[pos:pos+chunk]
73 off = buf.find ("xff\x00")
75 if off == -1:
76 pos += chunk
77 continue
79 pos += off
80 tup = ent (m, pos)
81 if tup == None:
82 pos += 1
83 continue
85 size, ext = tup
86 name = findname (m, pos, ext)
87 if not name in h:
88 if name != None and name[0] <> 0x80: # oh well
89 print "%x %10d %s" % (pos, size, name)
90 h[name] = True
91 pos += size
93 main (sys.argv[1])