17 fprint(2, "usage: copy [-fir] [-t type] srchost dsthost score\n");
18 threadexitsall("usage");
22 walk(uchar score[VtScoreSize], uint type, int base)
29 if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
32 buf = vtmallocz(VtMaxLumpSize);
33 if(fast && vtread(zdst, score, type, buf, VtMaxLumpSize) >= 0){
35 fprint(2, "skip %V\n", score);
40 n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
44 memmove(score, vtzeroscore, VtScoreSize);
45 }else if(!ignoreerrors)
46 sysfatal("reading block %V (type %d): %r", score, type);
52 if(vtrootunpack(&root, buf) < 0){
53 fprint(2, "warning: could not unpack root in %V %d\n", score, type);
56 walk(root.score, VtDirType, 0);
57 walk(root.prev, VtRootType, 0);
58 vtrootpack(&root, buf); /* walk might have changed score */
62 for(i=0; i<n/VtEntrySize; i++){
63 if(vtentryunpack(&e, buf, i) < 0){
64 fprint(2, "warning: could not unpack entry #%d in %V %d\n", i, score, type);
67 if(!(e.flags & VtEntryActive))
69 walk(e.score, e.type, e.type&VtTypeBaseMask);
70 vtentrypack(&e, buf, i);
77 default: /* pointers */
78 for(i=0; i<n; i+=VtScoreSize)
79 if(memcmp(buf+i, vtzeroscore, VtScoreSize) != 0)
80 walk(buf+i, type-1, base);
84 if(vtwrite(zdst, score, type, buf, n) < 0){
85 /* figure out score for better error message */
86 /* can't use input argument - might have changed contents */
87 n = vtzerotruncate(type, buf, n);
88 sha1(buf, n, score, nil);
89 sysfatal("writing block %V (type %d): %r", score, type);
95 threadmain(int argc, char *argv[])
98 uchar score[VtScoreSize];
102 fmtinstall('F', vtfcallfmt);
103 fmtinstall('V', vtscorefmt);
121 type = atoi(EARGF(usage()));
131 if(vtparsescore(argv[2], &prefix, score) < 0)
132 sysfatal("could not parse score: %r");
134 buf = vtmallocz(VtMaxLumpSize);
136 zsrc = vtdial(argv[0]);
138 sysfatal("could not dial src server: %r");
139 if(vtconnect(zsrc) < 0)
140 sysfatal("vtconnect src: %r");
142 zdst = vtdial(argv[1]);
144 sysfatal("could not dial dst server: %r");
145 if(vtconnect(zdst) < 0)
146 sysfatal("vtconnect dst: %r");
149 n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
151 sysfatal("could not read block: %r");
153 for(type=0; type<VtMaxType; type++){
154 n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
158 if(type == VtMaxType)
159 sysfatal("could not find block %V of any type", score);
162 walk(score, type, VtDirType);
164 print("%s:%V (%d pointers rewritten)\n", prefix, score, changes);
167 sysfatal("could not sync dst server: %r");