wrarena.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "stdinc.h"
  2. #include "dat.h"
  3. #include "fns.h"
  4. char *host;
  5. void
  6. usage(void)
  7. {
  8. fprint(2, "usage: wrarena [-h host] arenafile [offset]\n");
  9. exits("usage");
  10. }
  11. static void
  12. rdArena(VtSession *z, Arena *arena, u64int offset)
  13. {
  14. u64int a, aa, e;
  15. u32int magic;
  16. Clump cl;
  17. uchar score[VtScoreSize];
  18. ZBlock *lump;
  19. fprint(2, "copying %s to venti\n", arena->name);
  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(!vtWrite(z, score, cl.info.type, lump->data, cl.info.uncsize))
  56. vtFatal("failed writing clump %llud: %R", aa);
  57. freeZBlock(lump);
  58. }
  59. if(!vtSync(z))
  60. vtFatal("failed executing sync: %R");
  61. print("end offset %llud\n", aa);
  62. }
  63. int
  64. main(int argc, char *argv[])
  65. {
  66. char *file;
  67. VtSession *z;
  68. Arena *arena;
  69. u64int offset, aoffset;
  70. Part *part;
  71. Dir *d;
  72. uchar buf[8192];
  73. ArenaHead head;
  74. aoffset = 0;
  75. ARGBEGIN{
  76. case 'h':
  77. host = EARGF(usage());
  78. break;
  79. case 'o':
  80. aoffset = strtoull(EARGF(usage()), 0, 0);
  81. break;
  82. default:
  83. usage();
  84. break;
  85. }ARGEND
  86. offset = ~(u64int)0;
  87. switch(argc) {
  88. default:
  89. usage();
  90. case 2:
  91. offset = strtoull(argv[1], 0, 0);
  92. /* fall through */
  93. case 1:
  94. file = argv[0];
  95. }
  96. vtAttach();
  97. fmtinstall('V', vtScoreFmt);
  98. fmtinstall('R', vtErrFmt);
  99. statsInit();
  100. if((d = dirstat(file)) == nil)
  101. vtFatal("can't stat file %s: %r", file);
  102. part = initPart(file, 0);
  103. if(part == nil)
  104. vtFatal("can't open file %s: %R", file);
  105. if(!readPart(part, aoffset, buf, sizeof buf))
  106. vtFatal("can't read file %s: %R", file);
  107. if(!unpackArenaHead(&head, buf))
  108. vtFatal("corrupted arena header: %R");
  109. if(aoffset+head.size > d->length)
  110. vtFatal("arena is truncated: want %llud bytes have %llud\n",
  111. head.size, d->length);
  112. partBlockSize(part, head.blockSize);
  113. initDCache(8 * MaxDiskBlock);
  114. arena = initArena(part, aoffset, head.size, head.blockSize);
  115. if(arena == nil)
  116. vtFatal("initArena: %R");
  117. z = vtDial(host, 0);
  118. if(z == nil)
  119. vtFatal("could not connect to server: %R");
  120. if(!vtConnect(z, 0))
  121. vtFatal("vtConnect: %r");
  122. rdArena(z, arena, offset);
  123. vtClose(z);
  124. vtDetach();
  125. exits(0);
  126. return 0;
  127. }