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 }