printarena.c 2.6 KB

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