Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
Arquivo: vacfs.c Projeto: npe9/harvey
int
vacdirread(Fid *f, char *p, int32_t off, int32_t cnt)
{
	int i, n, nb;
	VacDir vd;

	/*
	 * special case of rewinding a directory
	 * otherwise ignore the offset
	 */
	if(off == 0 && f->vde){
		vdeclose(f->vde);
		f->vde = nil;
	}

	if(f->vde == nil){
		f->vde = vdeopen(f->file);
		if(f->vde == nil)
			return -1;
	}

	for(nb = 0; nb < cnt; nb += n) {
		i = vderead(f->vde, &vd);
		if(i < 0)
			return -1;
		if(i == 0)
			break;
		n = vacstat(f->file, &vd, (uint8_t*)p, cnt-nb);
		if(n <= BIT16SZ) {
			vdeunread(f->vde);
			break;
		}
		vdcleanup(&vd);
		p += n;
	}
	return nb;
}
Exemplo n.º 3
0
VacFile*
recentarchive(VacFs *fs, char *path)
{
	VacFile *fp, *f;
	VacDirEnum *de;
	VacDir vd;
	char buf[10];
	int year, mmdd, nn, n, n1;
	char *p;

	fp = vacfsgetroot(fs);
	de = vdeopen(fp);
	year = 0;
	if(de){
		for(; vderead(de, &vd) > 0; vdcleanup(&vd)){
			if(strlen(vd.elem) != 4)
				continue;
			if((n = strtol(vd.elem, &p, 10)) < 1900 || *p != 0)
				continue;
			if(year < n)
				year = n;
		}
	}
	vdeclose(de);
	if(year == 0){
		vacfiledecref(fp);
		return nil;
	}
	snprint(buf, sizeof buf, "%04d", year);
	if((f = vacfilewalk(fp, buf)) == nil){
		fprint(2, "warning: dirread %s but cannot walk", buf);
		vacfiledecref(fp);
		return nil;
	}
	fp = f;

	de = vdeopen(fp);
	mmdd = 0;
	nn = 0;
	if(de){
		for(; vderead(de, &vd) > 0; vdcleanup(&vd)){
			if(strlen(vd.elem) < 4)
				continue;
			if((n = strtol(vd.elem, &p, 10)) < 100 || n > 1231 || p != vd.elem+4)
				continue;
			if(*p == '.'){
				if(p[1] == '0' || (n1 = strtol(p+1, &p, 10)) == 0 || *p != 0)
					continue;
			}else{
				if(*p != 0)
					continue;
				n1 = 0;
			}
			if(n < mmdd || (n == mmdd && n1 < nn))
				continue;
			mmdd = n;
			nn = n1;
		}
	}
	vdeclose(de);
	if(mmdd == 0){
		vacfiledecref(fp);
		return nil;
	}
	if(nn == 0)
		snprint(buf, sizeof buf, "%04d", mmdd);
	else
		snprint(buf, sizeof buf, "%04d.%d", mmdd, nn);
	if((f = vacfilewalk(fp, buf)) == nil){
		fprint(2, "warning: dirread %s but cannot walk", buf);
		vacfiledecref(fp);
		return nil;
	}
	vacfiledecref(fp);

	sprint(path, "%04d/%s", year, buf);
	return f;
}
Exemplo n.º 4
0
void
unvac(VacFile *f, char *name, VacDir *vdir)
{
	static char buf[65536];
	int fd, n, m,  bsize;
	ulong mode, mode9;
	char *newname;
	char *what;
	vlong off;
	Dir d, *dp;
	VacDirEnum *vde;
	VacDir newvdir;
	VacFile *newf;

	if(vdir)
		mode = vdir->mode;
	else
		mode = vacfilegetmode(f);

	if(vdir){
		if(table){
			if(chatty){
				mode9 = vdir->mode&0777;
				if(mode&ModeDir)
					mode9 |= DMDIR;
				if(mode&ModeAppend)
					mode9 |= DMAPPEND;
				if(mode&ModeExclusive)
					mode9 |= DMEXCL;
				print("%M %-10s %-10s %11lld %t %s\n",
					mode9, vdir->uid, vdir->gid, vdir->size,
					vdir->mtime, name);
			}else
				print("%s%s\n", name, (mode&ModeDir) ? "/" : "");
		}
		else if(chatty)
			fprint(2, "%s%s\n", name, (mode&ModeDir) ? "/" : "");
	}

	if(mode&(ModeDevice|ModeLink|ModeNamedPipe|ModeExclusive)){
		if(table)
			return;
		if(mode&ModeDevice)
			what = "device";
		else if(mode&ModeLink)
			what = "link";
		else if(mode&ModeNamedPipe)
			what = "named pipe";
		else if(mode&ModeExclusive)
			what = "lock";
		else
			what = "unknown type of file";
		fprint(2, "warning: ignoring %s %s\n", what, name);
		return;
	}
	
	if(mode&ModeDir){
		if((vde = vdeopen(f)) == nil){
			fprint(2, "vdeopen %s: %r", name);
			errors++;
			return;
		}
		if(!table && !tostdout && vdir){
			// create directory
			if((dp = dirstat(name)) == nil){
				if((fd = create(name, OREAD, DMDIR|(mode&0777))) < 0){
					fprint(2, "mkdir %s: %r\n", name);
					vdeclose(vde);
				}
				close(fd);
			}else{
				if(!(dp->mode&DMDIR)){
					fprint(2, "%s already exists and is not a directory\n", name);
					errors++;
					free(dp);
					vdeclose(vde);
					return;
				}
				free(dp);
			}
		}
		while(vderead(vde, &newvdir) > 0){
			if(name == nil)
				newname = newvdir.elem;
			else
				newname = smprint("%s/%s", name, newvdir.elem);
			if(wantfile(newname)){
				if((newf = vacfilewalk(f, newvdir.elem)) == nil){
					fprint(2, "walk %s: %r\n", name);
					errors++;
				}else if(newf == f){
					fprint(2, "walk loop: %s\n", newname);
					vacfiledecref(newf);
				}else{
					unvac(newf, newname, &newvdir);
					vacfiledecref(newf);
				}
			}
			if(newname != newvdir.elem)
				free(newname);
			vdcleanup(&newvdir);
		}
		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;
			}
			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);
		}
	}
	if(vdir && settimes && !tostdout){
		nulldir(&d);
		d.mtime = vdir->mtime;
		if(dirwstat(name, &d) < 0)
			fprint(2, "warning: setting mtime on %s: %r", name);
	}
}