#include "stdinc.h" #include "dat.h" #include "fns.h" int fast; VtSession *zsrc, *zdst; void usage(void) { fprint(2, "usage: copy src-host dst-host score [type]\n"); exits("usage"); } int parseScore(uchar *score, char *buf, int n) { int i, c; memset(score, 0, VtScoreSize); if(n < VtScoreSize*2) return 0; for(i=0; i= '0' && buf[i] <= '9') c = buf[i] - '0'; else if(buf[i] >= 'a' && buf[i] <= 'f') c = buf[i] - 'a' + 10; else if(buf[i] >= 'A' && buf[i] <= 'F') c = buf[i] - 'A' + 10; else { return 0; } if((i & 1) == 0) c <<= 4; score[i>>1] |= c; } return 1; } void walk(uchar score[VtScoreSize], uint type, int base) { int i, n, sub; uchar *buf; VtEntry e; VtRoot root; if(memcmp(score, vtZeroScore, VtScoreSize) == 0) return; buf = vtMemAllocZ(VtMaxLumpSize); if(fast && vtRead(zdst, score, type, buf, VtMaxLumpSize) >= 0){ fprint(2, "skip %V\n", score); free(buf); return; } n = vtRead(zsrc, score, type, buf, VtMaxLumpSize); if(n < 0){ fprint(2, "warning: could not read block %V %d: %R", score, type); return; } switch(type){ case VtRootType: if(!vtRootUnpack(&root, buf)){ fprint(2, "warning: could not unpack root in %V %d\n", score, type); break; } walk(root.score, VtDirType, 0); walk(root.prev, VtRootType, 0); break; case VtDirType: for(i=0; i= 0) break; } if(type == VtMaxType) vtFatal("could not find block %V of any type", score); } walk(score, type, VtDirType); if(!vtSync(zdst)) vtFatal("could not sync dst server: %R"); vtDetach(); exits(0); return 0; /* shut up compiler */ }