#!/usr/local/bin/python
#
# $Id: recover-disklabel,v 1.2 2000/09/05 16:10:06 simokawa Exp $
#	Recover disklabel for ufs from superblock magic number.
#	Usage: ./recover-disklabel /dev/ad0s1


do_seek = 1
import sys,struct

#block_size=512
block_size=8192
sector_size=512
magic = 0x00011954
magic_offset = 1372 + 8192
size_offset = 4 * 9
fsize_offset = 4 * 13
sblkno_offset = 4 * 2
offset = magic_offset % block_size
first_interval = 8192
bufsize = 1024 * 1024

fd=open(sys.argv[1], 'r', bufsize)

label = []
last_magic = 0
last_partition = 0
pos = long(offset)
while 1:
	d = fd.read(block_size)
	if len(d) < offset+3:
		break
	m = struct.unpack("I", d[offset:offset+4])[0]
	if m == magic:
		size = struct.unpack("I", d[size_offset:size_offset+4])[0]
		fsize = struct.unpack("I", d[fsize_offset:fsize_offset+4])[0]
		sblkno = struct.unpack("I", d[sblkno_offset:sblkno_offset+4])[0]
		interval = pos - last_magic
		psize = long(size) * fsize
		print "Superblock in %d blocks at %s bytes, interval %s bytes, size %s bytes" % (sblkno, pos, interval, psize)
		if interval == first_interval:
			b = (last_magic - magic_offset)
			bb = b / sector_size
			print "%s bytes (= %s blocks) must be the beginning of a partition" % (b, bb)
			label.append((psize/sector_size, bb))
			last_partition = bb
			last_magic = pos
			if do_seek:
				next_b = b + psize
				print "seek to", next_b
				fd.seek(next_b)
				pos = next_b + offset - block_size
		else:
			last_magic = pos
	pos = pos + block_size

print "%10s %10s" % ("size", "offset")
for i in label:
	print "%10d %10d" % i


syntax highlighted by Code2HTML, v. 0.9.1