| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- #!/usr/bin/env python2
- import struct
- import binascii
- TYPES = {
- (0x700, 0x400): 'splice',
- (0x7ff, 0x401): 'create',
- (0x7ff, 0x4ff): 'delete',
- (0x700, 0x000): 'name',
- (0x7ff, 0x001): 'name reg',
- (0x7ff, 0x002): 'name dir',
- (0x7ff, 0x0ff): 'name superblock',
- (0x700, 0x200): 'struct',
- (0x7ff, 0x200): 'struct dir',
- (0x7ff, 0x202): 'struct ctz',
- (0x7ff, 0x201): 'struct inline',
- (0x700, 0x300): 'userattr',
- (0x700, 0x600): 'tail',
- (0x7ff, 0x600): 'tail soft',
- (0x7ff, 0x601): 'tail hard',
- (0x700, 0x700): 'gstate',
- (0x7ff, 0x7ff): 'gstate move',
- (0x700, 0x500): 'crc',
- }
- def typeof(type):
- for prefix in range(12):
- mask = 0x7ff & ~((1 << prefix)-1)
- if (mask, type & mask) in TYPES:
- return TYPES[mask, type & mask] + (
- ' %0*x' % (prefix/4, type & ((1 << prefix)-1))
- if prefix else '')
- else:
- return '%02x' % type
- def main(*blocks):
- # find most recent block
- file = None
- rev = None
- crc = None
- versions = []
- for block in blocks:
- try:
- nfile = open(block, 'rb')
- ndata = nfile.read(4)
- ncrc = binascii.crc32(ndata)
- nrev, = struct.unpack('<I', ndata)
- assert rev != nrev
- if not file or ((rev - nrev) & 0x80000000):
- file = nfile
- rev = nrev
- crc = ncrc
- versions.append((nrev, '%s (rev %d)' % (block, nrev)))
- except (IOError, struct.error):
- pass
- if not file:
- print 'Bad metadata pair {%s}' % ', '.join(blocks)
- return 1
- print "--- %s ---" % ', '.join(v for _,v in sorted(versions, reverse=True))
- # go through each tag, print useful information
- print "%-4s %-8s %-14s %3s %4s %s" % (
- 'off', 'tag', 'type', 'id', 'len', 'dump')
- tag = 0xffffffff
- off = 4
- while True:
- try:
- data = file.read(4)
- crc = binascii.crc32(data, crc)
- ntag, = struct.unpack('>I', data)
- except struct.error:
- break
- tag ^= ntag
- off += 4
- type = (tag & 0x7ff00000) >> 20
- id = (tag & 0x000ffc00) >> 10
- size = (tag & 0x000003ff) >> 0
- iscrc = (type & 0x700) == 0x500
- data = file.read(size if size != 0x3ff else 0)
- if iscrc:
- crc = binascii.crc32(data[:4], crc)
- else:
- crc = binascii.crc32(data, crc)
- print '%04x: %08x %-15s %3s %4s %-23s %-8s' % (
- off, tag,
- typeof(type) + (' bad!' if iscrc and ~crc else ''),
- hex(id)[2:] if id != 0x3ff else '.',
- size if size != 0x3ff else 'x',
- ' '.join('%02x' % ord(c) for c in data[:8]),
- ''.join(c if c >= ' ' and c <= '~' else '.' for c in data[:8]))
- off += size if size != 0x3ff else 0
- if iscrc:
- crc = 0
- tag ^= (type & 1) << 31
- return 0
- if __name__ == "__main__":
- import sys
- sys.exit(main(*sys.argv[1:]))
|