commit - 115dbcecc8d35d12b54d17dc1cba39089ad37b5f
commit + 286bb40b76f35ffee1e6789895782af203e0dae3
blob - 7de41ee622c593018db745c48c99576f907efa0e
blob + 3ce718df103aec47e1150743db80b47cf95c2ac6
--- man/man1/vac.1
+++ man/man1/vac.1
.PP
.B unvac
[
-.B -Tctv
+.B -Tcdtv
] [
.B -h
.I host
.B -c
Write extracted files to standard output instead of creating a file.
.TP
+.B -d
+Reduce the number of blocks read from Venti by
+comparing the files to be stored with their counterparts
+in the file system.
+This option cannot be used with
+.BR -c .
+.TP
.B -t
Print a list of the files to standard output rather than extracting them.
.TP
blob - 598dae092b6b3b7a5bfc422cb30be97750952401
blob + faa558f3df96ea9d8aff6b39bb11c77a5f293eb4
--- src/cmd/vac/file.c
+++ src/cmd/vac/file.c
if(vtsync(fs->z) < 0)
return -1;
return 0;
+}
+
+int
+vacfiledsize(VacFile *f)
+{
+ VtEntry e;
+
+ if(vacfilegetentries(f,&e,nil) < 0)
+ return -1;
+ return e.dsize;
}
+
+/*
+ * Does block b of f have the same SHA1 hash as the n bytes at buf?
+ */
+int
+sha1matches(VacFile *f, ulong b, uchar *buf, int n)
+{
+ uchar fscore[VtScoreSize];
+ uchar bufscore[VtScoreSize];
+
+ if(vacfileblockscore(f, b, fscore) < 0)
+ return 0;
+ n = vtzerotruncate(VtDataType, buf, n);
+ sha1(buf, n, bufscore, nil);
+ if(memcmp(bufscore, fscore, VtScoreSize) == 0)
+ return 1;
+ return 0;
+}
+
blob - d4f863ccf86053e976b73c6c508b5fc73eef2638
blob + ab799cb0a9b79a31f283b2cc9a1821cc8fb52643
--- src/cmd/vac/unvac.c
+++ src/cmd/vac/unvac.c
VacFs *fs;
int tostdout;
+int diff;
int nwant;
char **want;
int *found;
void
usage(void)
{
- fprint(2, "usage: unvac [-TVctv] [-h host] file.vac [file ...]\n");
+ fprint(2, "usage: unvac [-TVcdtv] [-h host] file.vac [file ...]\n");
threadexitsall("usage");
}
+struct
+{
+ vlong data;
+ vlong skipdata;
+} stats;
+
void
threadmain(int argc, char *argv[])
{
- int i;
+ int i, printstats;
char *host;
VacFile *f;
fmtinstall('M', dirmodefmt);
host = nil;
+ printstats = 0;
+
ARGBEGIN{
case 'T':
settimes = 1;
break;
case 'c':
tostdout++;
+ break;
+ case 'd':
+ diff++;
break;
case 'h':
host = EARGF(usage());
break;
+ case 's':
+ printstats++;
+ break;
case 't':
table++;
break;
if(argc < 1)
usage();
+ if(tostdout && diff){
+ fprint(2, "cannot use -c with -d\n");
+ usage();
+ }
+
conn = vtdial(host);
if(conn == nil)
sysfatal("could not connect to server: %r");
}
if(errors)
threadexitsall("errors");
+ if(printstats)
+ fprint(2, "%lld bytes read, %lld bytes skipped\n",
+ stats.data, stats.skipdata);
threadexitsall(0);
}
unvac(VacFile *f, char *name, VacDir *vdir)
{
static char buf[65536];
- int fd, n;
+ int fd, n, m, bsize;
ulong mode, mode9;
char *newname;
char *what;
vdeclose(vde);
}else{
if(!table){
+ off = 0;
if(tostdout)
fd = dup(1, -1);
+ else if(diff && (fd = open(name, ORDWR)) >= 0){
+ bsize = vacfiledsize(f);
+ while((n = readn(fd, buf, bsize)) > 0){
+ if(sha1matches(f, off/bsize, (uchar*)buf, n)){
+ off += n;
+ stats.skipdata += n;
+ continue;
+ }
+ seek(fd, off, 0);
+ if((m = vacfileread(f, buf, n, off)) < 0)
+ break;
+ if(writen(fd, buf, m) != m){
+ fprint(2, "write %s: %r\n", name);
+ goto Err;
+ }
+ off += m;
+ stats.data += m;
+ if(m < n){
+ nulldir(&d);
+ d.length = off;
+ if(dirfwstat(fd, &d) < 0){
+ fprint(2, "dirfwstat %s: %r\n", name);
+ goto Err;
+ }
+ break;
+ }
+ }
+ }
else if((fd = create(name, OWRITE, mode&0777)) < 0){
fprint(2, "create %s: %r\n", name);
errors++;
return;
}
- off = 0;
while((n = vacfileread(f, buf, sizeof buf, off)) > 0){
if(writen(fd, buf, n) != n){
fprint(2, "write %s: %r\n", name);
+ Err:
errors++;
close(fd);
remove(name);
return;
}
off += n;
+ stats.data += n;
}
close(fd);
}
blob - 99651981b13c321e25a4fa5fc52f597a27203882
blob + d6c17b4b808274fe151a9f5f66258c5f3fc176ad
--- src/cmd/vac/vac.c
+++ src/cmd/vac/vac.c
DMDEVICE
};
#endif
-
-/*
- * Does block b of f have the same SHA1 hash as the n bytes at buf?
- */
-static int
-sha1matches(VacFile *f, ulong b, uchar *buf, int n)
-{
- uchar fscore[VtScoreSize];
- uchar bufscore[VtScoreSize];
-
- if(vacfileblockscore(f, b, fscore) < 0)
- return 0;
- n = vtzerotruncate(VtDataType, buf, n);
- sha1(buf, n, bufscore, nil);
- if(memcmp(bufscore, fscore, VtScoreSize) == 0)
- return 1;
- return 0;
-}
/*
* Archive the file named name, which has stat info d,
blob - 0b82d0ebf22965f92ad2d63a8320d1b229108fd2
blob + cb599a9c3c1b81a9ce6cae086343a6cd35dd4879
--- src/cmd/vac/vac.h
+++ src/cmd/vac/vac.h
void vdeclose(VacDirEnum*);
int vdeunread(VacDirEnum*);
+int vacfiledsize(VacFile *f);
+int sha1matches(VacFile *f, ulong b, uchar *buf, int n);
+