printarena.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "stdinc.h"
  2. #include "dat.h"
  3. #include "fns.h"
  4. int wanttype;
  5. int readonly = 1; /* for part.c */
  6. void
  7. usage(void)
  8. {
  9. fprint(2, "usage: printarena arenafile [offset]\n");
  10. exits("usage");
  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. printArena(2, arena);
  21. a = arena->base;
  22. e = arena->base + arena->size;
  23. if(offset != ~(u64int)0) {
  24. if(offset >= e-a)
  25. vtFatal("bad offset %llud >= %llud\n",
  26. offset, e-a);
  27. aa = offset;
  28. } else
  29. aa = 0;
  30. for(; aa < e; aa += ClumpSize+cl.info.size) {
  31. magic = clumpMagic(arena, aa);
  32. if(magic == ClumpFreeMagic)
  33. break;
  34. if(magic != ClumpMagic) {
  35. fprint(2, "illegal clump magic number %#8.8ux offset %llud\n",
  36. magic, aa);
  37. break;
  38. }
  39. lump = loadClump(arena, aa, 0, &cl, score, 0);
  40. if(lump == nil) {
  41. fprint(2, "clump %llud failed to read: %R\n", aa);
  42. break;
  43. }
  44. if(cl.info.type != VtTypeCorrupt) {
  45. scoreMem(score, lump->data, cl.info.uncsize);
  46. if(!scoreEq(cl.info.score, score)) {
  47. fprint(2, "clump %llud has mismatched score\n", aa);
  48. break;
  49. }
  50. if(!vtTypeValid(cl.info.type)) {
  51. fprint(2, "clump %llud has bad type %d\n", aa, cl.info.type);
  52. break;
  53. }
  54. }
  55. if(wanttype == 0 || cl.info.type == wanttype)
  56. print("%V %d\n", score, cl.info.type);
  57. freeZBlock(lump);
  58. }
  59. print("end offset %llud\n", aa);
  60. }
  61. int
  62. main(int argc, char *argv[])
  63. {
  64. char *file;
  65. Arena *arena;
  66. u64int offset, aoffset;
  67. Part *part;
  68. Dir *d;
  69. uchar buf[8192];
  70. ArenaHead head;
  71. aoffset = 0;
  72. ARGBEGIN{
  73. case 't':
  74. wanttype = atoi(EARGF(usage()));
  75. break;
  76. case 'o':
  77. aoffset = strtoull(EARGF(usage()), 0, 0);
  78. break;
  79. default:
  80. usage();
  81. break;
  82. }ARGEND
  83. offset = ~(u64int)0;
  84. switch(argc) {
  85. default:
  86. usage();
  87. case 2:
  88. offset = strtoull(argv[1], 0, 0);
  89. /* fall through */
  90. case 1:
  91. file = argv[0];
  92. }
  93. vtAttach();
  94. fmtinstall('V', vtScoreFmt);
  95. fmtinstall('R', vtErrFmt);
  96. statsInit();
  97. if((d = dirstat(file)) == nil)
  98. vtFatal("can't stat file %s: %r", file);
  99. part = initPart(file, 0);
  100. if(part == nil)
  101. vtFatal("can't open file %s: %R", file);
  102. if(!readPart(part, aoffset, buf, sizeof buf))
  103. vtFatal("can't read file %s: %R", file);
  104. if(!unpackArenaHead(&head, buf))
  105. vtFatal("corrupted arena header: %R");
  106. if(aoffset+head.size > d->length)
  107. vtFatal("arena is truncated: want %llud bytes have %llud\n",
  108. head.size, d->length);
  109. partBlockSize(part, head.blockSize);
  110. initDCache(8 * MaxDiskBlock);
  111. arena = initArena(part, aoffset, head.size, head.blockSize);
  112. if(arena == nil)
  113. vtFatal("initArena: %R");
  114. rdArena(arena, offset);
  115. vtDetach();
  116. exits(0);
  117. return 0;
  118. }