diff options
author | Russ Cox <rsc@swtch.com> | 2008-06-14 13:28:49 -0400 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2008-06-14 13:28:49 -0400 |
commit | 64f9764ea9f958a1abc7a32424f43019723e9e53 (patch) | |
tree | cca50bfb352edfb70de5e63d98d2234aac598def /src/cmd/vac/vac.c | |
parent | 01cea2ecb8c0b101a22e7883d87fbf1d28a03043 (diff) | |
download | plan9port-64f9764ea9f958a1abc7a32424f43019723e9e53.tar.gz plan9port-64f9764ea9f958a1abc7a32424f43019723e9e53.tar.bz2 plan9port-64f9764ea9f958a1abc7a32424f43019723e9e53.zip |
vac: clean up, add unvac
Diffstat (limited to 'src/cmd/vac/vac.c')
-rw-r--r-- | src/cmd/vac/vac.c | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/src/cmd/vac/vac.c b/src/cmd/vac/vac.c index 963a56a0..7637e034 100644 --- a/src/cmd/vac/vac.c +++ b/src/cmd/vac/vac.c @@ -5,7 +5,18 @@ #include "dat.h" #include "fns.h" -int mainstacksize = 128*1024; +/* + * We're between a rock and a hard place here. + * The pw library (getpwnam, etc.) reads the + * password and group files into an on-stack buffer, + * so if you have some huge groups, you overflow + * the stack. Because of this, the thread library turns + * it off by default, so that dirstat returns "14571" instead of "rsc". + * But for vac we want names. So cautiously turn the pwlibrary + * back on (see threadmain) and make the main thread stack huge. + */ +extern int _p9usepwlibrary; +int mainstacksize = 4*1024*1024; typedef struct Sink Sink; typedef struct MetaSink MetaSink; @@ -101,6 +112,8 @@ int nowrite; int merge; char *isi; +char **expandargv(char**); + static void usage(void) { @@ -116,6 +129,9 @@ threadmain(int argc, char *argv[]) char *host = nil; int statsflag = 0; + /* see comment above */ + _p9usepwlibrary = 1; + atexit(cleanup); ARGBEGIN{ @@ -194,20 +210,71 @@ threadmain(int argc, char *argv[]) qsort(exclude, nexclude, sizeof(char*), strpcmp); + argv = expandargv(argv); + vac(z, argv); if(vtsync(z) < 0) fprint(2, "warning: could not ask server to flush pending writes: %r\n"); - if(statsflag) + if(statsflag){ fprint(2, "files %ld:%ld data %ld:%ld:%ld meta %ld\n", stats.file, stats.sfile, stats.data, stats.skip, stats.sdata, stats.meta); -/*packetStats(); */ + dup(2, 1); + packetstats(); + } vthangup(z); threadexitsall(0); } +// Expand special directory names like / and . and .. into a list of their files. +char** +expandargv(char **argv) +{ + char **nargv; + int nargc; + int i, n; + Dir *d; + int fd; + char *s; + + nargc = 0; + nargv = nil; + for(; *argv; argv++){ + cleanname(*argv); + if(strcmp(*argv, "/") == 0 || strcmp(*argv, ".") == 0 || strcmp(*argv, "..") == 0 + || (strlen(*argv) > 3 && strcmp(*argv+strlen(*argv)-3, "/..") == 0)){ + if((fd = open(*argv, OREAD)) < 0){ + warn("could not open %s: %r", *argv); + continue; + } + n = dirreadall(fd, &d); + close(fd); + if(n < 0){ + warn("could not read %s: %r", *argv); + continue; + } + nargv = vtrealloc(nargv, (nargc+n)*sizeof nargv[0]); + for(i=0; i<n; i++){ + s = vtmalloc(strlen(*argv)+1+strlen(d[i].name)+1); + strcpy(s, *argv); + strcat(s, "/"); + strcat(s, d[i].name); + cleanname(s); + nargv[nargc++] = s; + } + free(d); + continue; + } + nargv = vtrealloc(nargv, (nargc+1)*sizeof nargv[0]); + nargv[nargc++] = *argv; + } + nargv = vtrealloc(nargv, (nargc+1)*sizeof nargv[0]); + nargv[nargc] = nil; + return nargv; +} + static int strpcmp(const void *p0, const void *p1) { @@ -353,7 +420,7 @@ vac(VtConn *z, char *argv[]) vtrootpack(&root, buf); if(vacwrite(z, score, VtRootType, buf, VtRootSize) < 0) - sysfatal("vacWrite failed: %r"); + sysfatal("vacwrite: %r"); fprint(fd, "vac:%V\n", score); @@ -566,7 +633,6 @@ vacdata(DirSink *dsink, int fd, char *lname, VacFile *vf, Dir *dir) if(vfblocks > 1) block += vacdataskip(sink, vf, fd, vfblocks, buf, lname); -if(0) fprint(2, "vacData: %s: %ld\n", lname, block); for(;;) { n = readn(fd, buf, bsize); if(0 && n < 0) @@ -857,7 +923,7 @@ sinkwrite(Sink *k, uchar *p, int n) return; if(n > k->dir.dsize) - sysfatal("sinkWrite: size too big"); + sysfatal("sinkwrite: size too big"); if((k->dir.type&~VtTypeDepthMask) == VtDirType){ type = VtDirType; @@ -867,7 +933,7 @@ sinkwrite(Sink *k, uchar *p, int n) stats.data++; } if(vacwrite(k->z, score, type, p, n) < 0) - sysfatal("vacWrite failed: %r"); + sysfatal("vacwrite: %r"); sinkwritescore(k, score, n); } @@ -924,7 +990,7 @@ sinkclose(Sink *k) p = k->buf+i*kd->psize; stats.meta++; if(vacwrite(k->z, k->pbuf[i+1], base+1+i, p, k->pbuf[i]-p) < 0) - sysfatal("vacWrite failed: %r"); + sysfatal("vacwrite: %r"); k->pbuf[i+1] += VtScoreSize; } memmove(kd->score, k->pbuf[i] - VtScoreSize, VtScoreSize); @@ -1141,6 +1207,7 @@ metasinkwrite(MetaSink *k, uchar *data, int n) void metasinkwritedir(MetaSink *ms, VacDir *dir) { + metasinkputuint32(ms, DirMagic); metasinkputc(ms, Version>>8); metasinkputc(ms, Version); @@ -1218,7 +1285,6 @@ plan9tovacdir(VacDir *vd, Dir *dir, ulong entry, uvlong qid) vd->p9version = dir->qid.vers; } - void metasinkeor(MetaSink *k) { |