Esempio n. 1
0
File: vacfs.c Progetto: npe9/harvey
char *
rstat(Fid *f)
{
	VacDir dir;
	static uint8_t statbuf[1024];
	VacFile *parent;
	
	if(!f->busy)
		return vtstrdup(Enotexist);
	parent = vacfilegetparent(f->file);
	vacfilegetdir(f->file, &dir);
	thdr.stat = statbuf;
	thdr.nstat = vacstat(parent, &dir, thdr.stat, sizeof statbuf);
	vdcleanup(&dir);
	vacfiledecref(parent);
	return 0;
}
Esempio n. 2
0
File: vacfs.c Progetto: npe9/harvey
int
permf(VacFile *vf, char *user, int p)
{
	VacDir dir;
	uint32_t perm;

	if(vacfilegetdir(vf, &dir))
		return 0;
	perm = dir.mode & 0777;

	if(noperm)
		goto Good;
	if((p*Pother) & perm)
		goto Good;
	if(strcmp(user, dir.gid)==0 && ((p*Pgroup) & perm))
		goto Good;
	if(strcmp(user, dir.uid)==0 && ((p*Powner) & perm))
		goto Good;
	vdcleanup(&dir);
	return 0;
Good:
	vdcleanup(&dir);
	return 1;
}
Esempio n. 3
0
/*
 * Archive the file named name, which has stat info d,
 * into the vac directory fp (p = parent).
 *
 * If we're doing a vac -d against another archive, the
 * equivalent directory to fp in that archive is diffp.
 */
void
vac(VacFile *fp, VacFile *diffp, char *name, Dir *d)
{
	char *elem, *s;
	static char buf[65536];
	int fd, i, n, bsize;
	int64_t off;
	Dir *dk;	// kids
	VacDir vd, vddiff;
	VacFile *f, *fdiff;
	VtEntry e;

	if(!includefile(name)){
		warn("excluding %s%s", name, (d->mode&DMDIR) ? "/" : "");
		return;
	}

	if(d->mode&DMDIR)
		stats.ndir++;
	else
		stats.nfile++;

	if(merge && vacmerge(fp, name) >= 0)
		return;

	if(verbose)
		fprint(2, "%s%s\n", name, (d->mode&DMDIR) ? "/" : "");

	if((fd = open(name, OREAD)) < 0){
		warn("open %s: %r", name);
		return;
	}

	elem = strrchr(name, '/');
	if(elem)
		elem++;
	else
		elem = name;

	plan9tovacdir(&vd, d);
	if((f = vacfilecreate(fp, elem, vd.mode)) == nil){
		warn("vacfilecreate %s: %r", name);
		return;
	}
	if(diffp)
		fdiff = vacfilewalk(diffp, elem);
	else
		fdiff = nil;

	if(vacfilesetdir(f, &vd) < 0)
		warn("vacfilesetdir %s: %r", name);

	if(d->mode&DMDIR){
		while((n = dirread(fd, &dk)) > 0){
			for(i=0; i<n; i++){
				s = vtmalloc(strlen(name)+1+strlen(dk[i].name)+1);
				strcpy(s, name);
				strcat(s, "/");
				strcat(s, dk[i].name);
				vac(f, fdiff, s, &dk[i]);
				free(s);
			}
			free(dk);
		}
	}else{
		off = 0;
		bsize = fs->bsize;
		if(fdiff){
			/*
			 * Copy fdiff's contents into f by moving the score.
			 * We'll diff and update below.
			 */
			if(vacfilegetentries(fdiff, &e, nil) >= 0)
			if(vacfilesetentries(f, &e, nil) >= 0){
				bsize = e.dsize;

				/*
				 * Or if -q is set, and the metadata looks the same,
				 * don't even bother reading the file.
				 */
				if(qdiff && vacfilegetdir(fdiff, &vddiff) >= 0){
					if(vddiff.mtime == vd.mtime)
					if(vddiff.size == vd.size)
					if(!vddiff.plan9 || (/* vddiff.p9path == vd.p9path && */ vddiff.p9version == vd.p9version)){
						stats.skipfiles++;
						stats.nfile--;
						vdcleanup(&vddiff);
						goto Out;
					}

					/*
					 * Skip over presumably-unchanged prefix
					 * of an append-only file.
					 */
					if(vd.mode&ModeAppend)
					if(vddiff.size < vd.size)
					if(vddiff.plan9 && vd.plan9)
					if(vddiff.p9path == vd.p9path){
						off = vd.size/bsize*bsize;
						if(seek(fd, off, 0) >= 0)
							stats.skipdata += off;
						else{
							seek(fd, 0, 0);	// paranoia
							off = 0;
						}
					}

					vdcleanup(&vddiff);
					// XXX different verbose chatty prints for kaminsky?
				}
			}
		}
		if(qdiff && verbose)
			fprint(2, "+%s\n", name);
		while((n = readn(fd, buf, bsize)) > 0){
			if(fdiff && sha1matches(f, off/bsize, (uint8_t*)buf, n)){
				off += n;
				stats.skipdata += n;
				continue;
			}
			if(vacfilewrite(f, buf, n, off) < 0){
				warn("venti write %s: %r", name);
				goto Out;
			}
			stats.data += n;
			off += n;
		}
		/*
		 * Since we started with fdiff's contents,
		 * set the size in case fdiff was bigger.
		 */
		if(fdiff && vacfilesetsize(f, off) < 0)
			warn("vtfilesetsize %s: %r", name);
	}

Out:
	vacfileflush(f, 1);
	vacfiledecref(f);
	if(fdiff)
		vacfiledecref(fdiff);
	close(fd);
}