示例#1
0
文件: vac.c 项目: dancrossnyc/harvey
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;
}
示例#2
0
文件: vac.c 项目: dancrossnyc/harvey
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);
}
示例#3
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);
}
示例#4
0
文件: vacfs.c 项目: npe9/harvey
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);
}
示例#5
0
文件: vacfs.c 项目: 00001/plan9port
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);
}