plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

printarena.c (2682B)


      1 #include "stdinc.h"
      2 #include "dat.h"
      3 #include "fns.h"
      4 
      5 void
      6 usage(void)
      7 {
      8 	fprint(2, "usage: printarena [-o aoffset] arenafile [offset]\n");
      9 	threadexitsall("usage");
     10 }
     11 
     12 static void
     13 rdarena(Arena *arena, u64int offset)
     14 {
     15 	u64int a, aa, e;
     16 	u32int magic;
     17 	Clump cl;
     18 	uchar score[VtScoreSize];
     19 	ZBlock *lump;
     20 
     21 	printarena(2, arena);
     22 
     23 	a = arena->base;
     24 	e = arena->base + arena->size;
     25 	if(offset != ~(u64int)0) {
     26 		if(offset >= e-a)
     27 			sysfatal("bad offset %llud >= %llud",
     28 				offset, e-a);
     29 		aa = offset;
     30 	} else
     31 		aa = 0;
     32 
     33 	for(; aa < e; aa += ClumpSize+cl.info.size) {
     34 		magic = clumpmagic(arena, aa);
     35 		if(magic == ClumpFreeMagic)
     36 			break;
     37 		if(magic != arena->clumpmagic) {
     38 			fprint(2, "illegal clump magic number %#8.8ux offset %llud\n",
     39 				magic, aa);
     40 			break;
     41 		}
     42 		lump = loadclump(arena, aa, 0, &cl, score, 0);
     43 		if(lump == nil) {
     44 			fprint(2, "clump %llud failed to read: %r\n", aa);
     45 			break;
     46 		}
     47 		if(cl.info.type != VtCorruptType) {
     48 			scoremem(score, lump->data, cl.info.uncsize);
     49 			if(scorecmp(cl.info.score, score) != 0) {
     50 				fprint(2, "clump %llud has mismatched score\n", aa);
     51 				break;
     52 			}
     53 			if(vttypevalid(cl.info.type) < 0) {
     54 				fprint(2, "clump %llud has bad type %d\n", aa, cl.info.type);
     55 				break;
     56 			}
     57 		}
     58 		print("%22llud %V %3d %5d\n", aa, score, cl.info.type, cl.info.uncsize);
     59 		freezblock(lump);
     60 	}
     61 	print("end offset %llud\n", aa);
     62 }
     63 
     64 void
     65 threadmain(int argc, char *argv[])
     66 {
     67 	char *file;
     68 	Arena *arena;
     69 	u64int offset, aoffset;
     70 	Part *part;
     71 	static uchar buf[8192];
     72 	ArenaHead head;
     73 
     74 	readonly = 1;	/* for part.c */
     75 	aoffset = 0;
     76 	ARGBEGIN{
     77 	case 'o':
     78 		aoffset = strtoull(EARGF(usage()), 0, 0);
     79 		break;
     80 	default:
     81 		usage();
     82 		break;
     83 	}ARGEND
     84 
     85 	offset = ~(u64int)0;
     86 	switch(argc) {
     87 	default:
     88 		usage();
     89 	case 2:
     90 		offset = strtoull(argv[1], 0, 0);
     91 		/* fall through */
     92 	case 1:
     93 		file = argv[0];
     94 	}
     95 
     96 
     97 	ventifmtinstall();
     98 	statsinit();
     99 
    100 	part = initpart(file, OREAD|ODIRECT);
    101 	if(part == nil)
    102 		sysfatal("can't open file %s: %r", file);
    103 	if(readpart(part, aoffset, buf, sizeof buf) < 0)
    104 		sysfatal("can't read file %s: %r", file);
    105 
    106 	if(unpackarenahead(&head, buf) < 0)
    107 		sysfatal("corrupted arena header: %r");
    108 
    109 	print("# arena head version=%d name=%.*s blocksize=%d size=%lld clumpmagic=0x%.8ux\n",
    110 		head.version, ANameSize, head.name, head.blocksize,
    111 		head.size, head.clumpmagic);
    112 
    113 	if(aoffset+head.size > part->size)
    114 		sysfatal("arena is truncated: want %llud bytes have %llud",
    115 			head.size, part->size);
    116 
    117 	partblocksize(part, head.blocksize);
    118 	initdcache(8 * MaxDiskBlock);
    119 
    120 	arena = initarena(part, aoffset, head.size, head.blocksize);
    121 	if(arena == nil)
    122 		sysfatal("initarena: %r");
    123 
    124 	rdarena(arena, offset);
    125 	threadexitsall(0);
    126 }