verifyarena.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #include "stdinc.h"
  2. #include "dat.h"
  3. #include "fns.h"
  4. static int verbose;
  5. void
  6. usage(void)
  7. {
  8. fprint(2, "usage: verifyarena [-v]\n");
  9. exits(0);
  10. }
  11. static void
  12. readBlock(uchar *buf, int n)
  13. {
  14. int nr, m;
  15. for(nr = 0; nr < n; nr += m){
  16. m = n - nr;
  17. m = read(0, &buf[nr], m);
  18. if(m <= 0)
  19. fatal("can't read arena from standard input: %r");
  20. }
  21. }
  22. static void
  23. verifyArena(void)
  24. {
  25. Arena arena;
  26. ArenaHead head;
  27. ZBlock *b;
  28. VtSha1 *s;
  29. u64int n, e;
  30. u32int bs;
  31. u8int score[VtScoreSize];
  32. memset(&arena, 0, sizeof arena);
  33. fprint(2, "verify arena from standard input\n");
  34. s = vtSha1Alloc();
  35. if(s == nil)
  36. fatal("can't initialize sha1 state");
  37. vtSha1Init(s);
  38. /*
  39. * read the little bit, which will included the header
  40. */
  41. bs = MaxIoSize;
  42. b = allocZBlock(bs, 0);
  43. readBlock(b->data, HeadSize);
  44. vtSha1Update(s, b->data, HeadSize);
  45. if(!unpackArenaHead(&head, b->data))
  46. fatal("corrupted arena header: %R");
  47. if(head.version != ArenaVersion)
  48. fprint(2, "warning: unknown arena version %d\n", head.version);
  49. /*
  50. * now we know how much to read
  51. * read everything but the last block, which is special
  52. */
  53. e = head.size - head.blockSize;
  54. for(n = HeadSize; n < e; n += bs){
  55. if(n + bs > e)
  56. bs = e - n;
  57. readBlock(b->data, bs);
  58. vtSha1Update(s, b->data, bs);
  59. }
  60. /*
  61. * read the last block update the sum.
  62. * the sum is calculated assuming the slot for the sum is zero.
  63. */
  64. bs = head.blockSize;
  65. readBlock(b->data, bs);
  66. vtSha1Update(s, b->data, bs - VtScoreSize);
  67. vtSha1Update(s, zeroScore, VtScoreSize);
  68. vtSha1Final(s, score);
  69. vtSha1Free(s);
  70. /*
  71. * validity check on the trailer
  72. */
  73. arena.blockSize = head.blockSize;
  74. if(!unpackArena(&arena, b->data))
  75. fatal("corrupted arena trailer: %R");
  76. scoreCp(arena.score, &b->data[arena.blockSize - VtScoreSize]);
  77. if(!nameEq(arena.name, head.name))
  78. fatal("arena header and trailer names clash: %s vs. %s\n", head.name, arena.name);
  79. if(arena.version != head.version)
  80. fatal("arena header and trailer versions clash: %d vs. %d\n", head.version, arena.version);
  81. arena.size = head.size - 2 * head.blockSize;
  82. /*
  83. * check for no checksum or the same
  84. */
  85. if(!scoreEq(score, arena.score)){
  86. if(!scoreEq(zeroScore, arena.score))
  87. fprint(2, "warning: mismatched checksums for arena=%s, found=%V calculated=%V",
  88. arena.name, arena.score, score);
  89. scoreCp(arena.score, score);
  90. }else
  91. fprint(2, "matched score\n");
  92. printArena(2, &arena);
  93. }
  94. void
  95. main(int argc, char *argv[])
  96. {
  97. fmtinstall('V', vtScoreFmt);
  98. fmtinstall('R', vtErrFmt);
  99. vtAttach();
  100. statsInit();
  101. ARGBEGIN{
  102. case 'v':
  103. verbose++;
  104. break;
  105. default:
  106. usage();
  107. break;
  108. }ARGEND
  109. readonly = 1;
  110. if(argc != 0)
  111. usage();
  112. verifyArena();
  113. exits(0);
  114. }