Blob


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