int vacmerge(VacFile *fp, char *name) { VacFs *mfs; VacDir vd; VacDirEnum *de; VacFile *mp; uint64_t maxqid, offset; if(strlen(name) < 4 || strcmp(name+strlen(name)-4, ".vac") != 0) return -1; if((mfs = vacfsopen(z, name, VtOREAD, 100)) == nil) return -1; if(verbose) fprint(2, "merging %s\n", name); mp = vacfsgetroot(mfs); de = vdeopen(mp); if(de){ offset = 0; if(vacfsgetmaxqid(mfs, &maxqid) >= 0){ _vacfsnextqid(fs, &offset); vacfsjumpqid(fs, maxqid+1); } while(vderead(de, &vd) > 0){ if(vd.qid > maxqid){ warn("vacmerge %s: maxqid=%lld but %s has %lld", name, maxqid, vd.elem, vd.qid); vacfsjumpqid(fs, vd.qid - maxqid); maxqid = vd.qid; } vacmergefile(fp, mp, &vd, name, offset, maxqid); vdcleanup(&vd); } vdeclose(de); } vacfiledecref(mp); vacfsclose(mfs); return 0; }
void threadmain(int argc, char **argv) { int i, j, fd, n, printstats; Dir *d; char *s; uint64_t u; VacFile *f, *fdiff; VacFs *fsdiff; int blocksize; int outfd; char *stdinname; char *diffvac; uint64_t qid; fmtinstall('F', vtfcallfmt); fmtinstall('H', encodefmt); fmtinstall('V', vtscorefmt); blocksize = BlockSize; stdinname = nil; printstats = 0; fsdiff = nil; diffvac = nil; ARGBEGIN{ case 'V': chattyventi++; break; case 'a': archivefile = EARGF(usage()); break; case 'b': u = unittoull(EARGF(usage())); if(u < 512) u = 512; if(u > VtMaxLumpSize) u = VtMaxLumpSize; blocksize = u; break; case 'd': diffvac = EARGF(usage()); break; case 'e': excludepattern(EARGF(usage())); break; case 'f': vacfile = EARGF(usage()); break; case 'h': host = EARGF(usage()); break; case 'i': stdinname = EARGF(usage()); break; case 'm': merge++; break; case 'q': qdiff++; break; case 's': printstats++; break; case 'v': verbose++; break; case 'x': loadexcludefile(EARGF(usage())); break; default: usage(); }ARGEND if(argc == 0 && !stdinname) usage(); if(archivefile && (vacfile || diffvac)){ fprint(2, "cannot use -a with -f, -d\n"); usage(); } z = vtdial(host); if(z == nil) sysfatal("could not connect to server: %r"); if(vtconnect(z) < 0) sysfatal("vtconnect: %r"); // Setup: // fs is the output vac file system // f is directory in output vac to write new files // fdiff is corresponding directory in existing vac if(archivefile){ VacFile *fp; char yyyy[5]; char mmdd[10]; char oldpath[40]; Tm tm; fdiff = nil; if((outfd = open(archivefile, ORDWR)) < 0){ if(access(archivefile, 0) >= 0) sysfatal("open %s: %r", archivefile); if((outfd = create(archivefile, OWRITE, 0666)) < 0) sysfatal("create %s: %r", archivefile); atexit(removevacfile); // because it is new if((fs = vacfscreate(z, blocksize, 512)) == nil) sysfatal("vacfscreate: %r"); }else{ if((fs = vacfsopen(z, archivefile, VtORDWR, 512)) == nil) sysfatal("vacfsopen %s: %r", archivefile); if((fdiff = recentarchive(fs, oldpath)) != nil){ if(verbose) fprint(2, "diff %s\n", oldpath); }else if(verbose) fprint(2, "no recent archive to diff against\n"); } // Create yyyy/mmdd. tm = *localtime(time(0)); snprint(yyyy, sizeof yyyy, "%04d", tm.year+1900); fp = vacfsgetroot(fs); if((f = vacfilewalk(fp, yyyy)) == nil && (f = vacfilecreate(fp, yyyy, ModeDir|0555)) == nil) sysfatal("vacfscreate %s: %r", yyyy); vacfiledecref(fp); fp = f; snprint(mmdd, sizeof mmdd, "%02d%02d", tm.mon+1, tm.mday); n = 0; while((f = vacfilewalk(fp, mmdd)) != nil){ vacfiledecref(f); n++; snprint(mmdd+4, sizeof mmdd-4, ".%d", n); } f = vacfilecreate(fp, mmdd, ModeDir|0555); if(f == nil) sysfatal("vacfscreate %s/%s: %r", yyyy, mmdd); vacfiledecref(fp); if(verbose) fprint(2, "archive %s/%s\n", yyyy, mmdd); }else{ if(vacfile == nil) outfd = 1; else if((outfd = create(vacfile, OWRITE, 0666)) < 0) sysfatal("create %s: %r", vacfile); atexit(removevacfile); if((fs = vacfscreate(z, blocksize, 512)) == nil) sysfatal("vacfscreate: %r"); f = vacfsgetroot(fs); fdiff = nil; if(diffvac){ if((fsdiff = vacfsopen(z, diffvac, VtOREAD, 128)) == nil) warn("vacfsopen %s: %r", diffvac); else fdiff = vacfsgetroot(fsdiff); } } if(stdinname) vacstdin(f, stdinname); for(i=0; i<argc; i++){ // We can't use / and . and .. and ../.. as valid archive // names, so expand to the list of files in the directory. if(argv[i][0] == 0){ warn("empty string given as command-line argument"); continue; } cleanname(argv[i]); if(strcmp(argv[i], "/") == 0 || strcmp(argv[i], ".") == 0 || strcmp(argv[i], "..") == 0 || (strlen(argv[i]) > 3 && strcmp(argv[i]+strlen(argv[i])-3, "/..") == 0)){ if((fd = open(argv[i], OREAD)) < 0){ warn("open %s: %r", argv[i]); continue; } while((n = dirread(fd, &d)) > 0){ for(j=0; j<n; j++){ s = vtmalloc(strlen(argv[i])+1+strlen(d[j].name)+1); strcpy(s, argv[i]); strcat(s, "/"); strcat(s, d[j].name); cleanname(s); vac(f, fdiff, s, &d[j]); } free(d); } close(fd); continue; } if((d = dirstat(argv[i])) == nil){ warn("stat %s: %r", argv[i]); continue; } vac(f, fdiff, argv[i], d); free(d); } if(fdiff) vacfiledecref(fdiff); /* * Record the maximum qid so that vacs can be merged * without introducing overlapping qids. Older versions * of vac arranged that the root would have the largest * qid in the file system, but we can't do that anymore * (the root gets created first!). */ if(_vacfsnextqid(fs, &qid) >= 0) vacfilesetqidspace(f, 0, qid); vacfiledecref(f); /* * Copy fsdiff's root block score into fs's slot for that, * so that vacfssync will copy it into root.prev for us. * Just nice documentation, no effect. */ if(fsdiff) memmove(fs->score, fsdiff->score, VtScoreSize); if(vacfssync(fs) < 0) fprint(2, "vacfssync: %r\n"); fprint(outfd, "vac:%V\n", fs->score); atexitdont(removevacfile); vacfsclose(fs); vthangup(z); if(printstats){ fprint(2, "%d files, %d files skipped, %d directories\n" "%lld data bytes written, %lld data bytes skipped\n", stats.nfile, stats.skipfiles, stats.ndir, stats.data, stats.skipdata); dup(2, 1); packetstats(); } threadexitsall(0); }
void threadmain(int argc, char *argv[]) { int i, printstats; char *host; VacFile *f; fmtinstall('H', encodefmt); fmtinstall('V', vtscorefmt); fmtinstall('F', vtfcallfmt); fmtinstall('t', mtimefmt); fmtinstall('M', dirmodefmt); host = nil; printstats = 0; ARGBEGIN{ case 'T': settimes = 1; break; case 'V': chattyventi = 1; break; case 'c': tostdout++; break; case 'd': diff++; break; case 'h': host = EARGF(usage()); break; case 's': printstats++; break; case 't': table++; break; case 'v': chatty++; break; default: usage(); }ARGEND 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(vtconnect(conn) < 0) sysfatal("vtconnect: %r"); fs = vacfsopen(conn, argv[0], VtOREAD, 128); if(fs == nil) sysfatal("vacfsopen: %r"); nwant = argc-1; want = argv+1; found = vtmallocz(nwant*sizeof found[0]); if((f = vacfsgetroot(fs)) == nil) sysfatal("vacfsgetroot: %r"); unvac(f, nil, nil); for(i=0; i<nwant; i++){ if(want[i] && !found[i]){ fprint(2, "warning: didn't find %s\n", want[i]); errors++; } } if(errors) threadexitsall("errors"); if(printstats) fprint(2, "%lld bytes read, %lld bytes skipped\n", stats.data, stats.skipdata); threadexitsall(0); }
void threadmain(int argc, char *argv[]) { char *defsrv, *srvname; int p[2], fd; int stdio; char *host = nil; long ncache; stdio = 0; ncache = 256; fmtinstall('H', encodefmt); fmtinstall('V', vtscorefmt); fmtinstall('F', vtfcallfmt); defmnt = nil; defsrv = nil; ARGBEGIN{ case 'd': fmtinstall('F', fcallfmt); dflag = 1; break; case 'c': ncache = atoi(EARGF(usage())); break; case 'i': defmnt = nil; stdio = 1; mfd[0] = 0; mfd[1] = 1; break; case 'h': host = EARGF(usage()); break; case 'S': defsrv = EARGF(usage()); break; case 's': defsrv = "vacfs"; break; case 'm': defmnt = EARGF(usage()); break; case 'p': noperm = 1; break; case 'V': chattyventi = 1; break; default: usage(); }ARGEND if(argc != 1) usage(); if(defsrv == nil && defmnt == nil && !stdio) defmnt = "/n/vac"; if(stdio && defmnt) sysfatal("cannot use -m with -i"); initfcalls(); notify(notifyf); user = getuser(); conn = vtdial(host); if(conn == nil) sysfatal("could not connect to server: %r"); if(vtconnect(conn) < 0) sysfatal("vtconnect: %r"); fs = vacfsopen(conn, argv[0], VtOREAD, ncache); if(fs == nil) sysfatal("vacfsopen: %r"); if(!stdio){ if(pipe(p) < 0) sysfatal("pipe failed: %r"); mfd[0] = p[0]; mfd[1] = p[0]; srvfd = p[1]; if(defsrv){ srvname = smprint("/srv/%s", defsrv); fd = create(srvname, OWRITE|ORCLOSE, 0666); if(fd < 0) sysfatal("create %s: %r", srvname); if(fprint(fd, "%d", srvfd) < 0) sysfatal("write %s: %r", srvname); free(srvname); } } procrfork(srv, 0, Stacksize, RFFDG|RFNAMEG|RFNOTEG); if(!stdio){ close(p[0]); if(defmnt){ if(mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0) sysfatal("mount %s: %r", defmnt); } } threadexits(0); }
void threadmain(int argc, char *argv[]) { char *defsrv, *srvname; int p[2], fd; int stdio; char *host = nil; ulong mem; mem = 16<<20; stdio = 0; fmtinstall('H', encodefmt); fmtinstall('V', vtscorefmt); fmtinstall('F', vtfcallfmt); defmnt = nil; defsrv = nil; ARGBEGIN{ case 'd': fmtinstall('F', fcallfmt); dflag = 1; break; case 'i': defmnt = nil; stdio = 1; mfd[0] = 0; mfd[1] = 1; break; case 'h': host = EARGF(usage()); break; case 'S': defsrv = EARGF(usage()); break; case 's': defsrv = "vacfs"; break; case 'M': mem = unittoull(EARGF(usage())); break; case 'm': defmnt = EARGF(usage()); break; case 'p': noperm = 1; break; case 'V': chattyventi = 1; break; default: usage(); }ARGEND if(argc != 1) usage(); #ifdef PLAN9PORT if(defsrv == nil && defmnt == nil && !stdio){ srvname = strchr(argv[0], '/'); if(srvname) srvname++; else srvname = argv[0]; defsrv = vtmalloc(6+strlen(srvname)+1); strcpy(defsrv, "vacfs."); strcat(defsrv, srvname); if(strcmp(defsrv+strlen(defsrv)-4, ".vac") == 0) defsrv[strlen(defsrv)-4] = 0; } #else if(defsrv == nil && defmnt == nil && !stdio) defmnt = "/n/vac"; #endif if(stdio && defmnt) sysfatal("cannot use -m with -i"); initfcalls(); notify(notifyf); user = getuser(); conn = vtdial(host); if(conn == nil) sysfatal("could not connect to server: %r"); if(vtconnect(conn) < 0) sysfatal("vtconnect: %r"); fs = vacfsopen(conn, argv[0], VtOREAD, mem); if(fs == nil) sysfatal("vacfsopen: %r"); if(!stdio){ if(pipe(p) < 0) sysfatal("pipe failed: %r"); mfd[0] = p[0]; mfd[1] = p[0]; srvfd = p[1]; #ifndef PLAN9PORT if(defsrv){ srvname = smprint("/srv/%s", defsrv); fd = create(srvname, OWRITE|ORCLOSE, 0666); if(fd < 0) sysfatal("create %s: %r", srvname); if(fprint(fd, "%d", srvfd) < 0) sysfatal("write %s: %r", srvname); free(srvname); } #endif } #ifdef PLAN9PORT USED(fd); proccreate(srv, 0, 32 * 1024); if(!stdio && post9pservice(p[1], defsrv, defmnt) < 0) sysfatal("post9pservice"); #else procrfork(srv, 0, 32 * 1024, RFFDG|RFNAMEG|RFNOTEG); if(!stdio){ close(p[0]); if(defmnt){ if(mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0) sysfatal("mount %s: %r", defmnt); } } #endif threadexits(0); }