Esempio n. 1
0
void LaosFileSystem::cleanlist() {
    // * open filename translation table
    char longname[MAXFILESIZE];
    char shortname[SHORTFILESIZE];
    char tabletmpname[MAXFILESIZE+SHORTFILESIZE+1];
    strcpy (tabletmpname, tablename);
    tabletmpname[strlen(tabletmpname)-1] = '~';
    
    // make a full copy of the table
    FILE* fp1 = fopen(tablename, "rb");
    if (fp1 == NULL) return;
    FILE* fp2 = fopen(tabletmpname, "wb");
    if (fp2 == NULL) return;
    while (dirread(longname, shortname, fp1))
        dirwrite(longname, shortname, fp2);
    fclose(fp1);
    fclose(fp2);

    fp1 = fopen(tablename, "wb");
    if (fp1 == NULL) return;
    fp2 = fopen(tabletmpname, "rb");
    if (fp2 == NULL) return;
    FILE* fp;
    while (dirread(longname, shortname, fp2)) {
        char fullname[MAXFILESIZE+SHORTFILESIZE+1];
        sprintf(fullname, "%s%s", pathname, shortname);
        fp = fopen(fullname, "rb");
        if (fp != NULL) {
            fclose(fp);
            dirwrite(longname, shortname, fp1);
        } 
     }
     fclose(fp1);
     fclose(fp2);
}
Esempio n. 2
0
void
partall(void)
{
	Disk *d;
	Dir *ent;
	char *name;
	int fd, i, n;

	fd = open("#S", OREAD);
	if(fd == -1) {
		fprint(2, "No disk\n");
		return;
	}

	while((n = dirread(fd, &ent)) > 0) {
		for(i = 0; i < n; i++) {
			if(ent[i].mode & DMDIR) {
				name = smprint("#S/%s/data", ent[i].name);
				d = opendisk(name, 1, 0);
				if(!d) {
					fprint(2, "%s: %r\n", name);
					continue;
				}
				// XXX not safe yet: if(!mbrpart(d) && !cdpart(d) && !p9part(d, "data", 0))
				if(!mbrpart(d) && !cdpart(d))
					fprint(2, "%s: no partitions\n", name);
				close(d->fd);
			}
		}
	}
	close(fd);				
}
Esempio n. 3
0
File: cron.c Progetto: 99years/plan9
void
readalljobs(void)
{
	User *u;
	Dir *d, *du;
	char file[128];
	int i, n, fd;

	fd = open("/cron", OREAD);
	if(fd < 0)
		fatal("can't open /cron: %r");
	while((n = dirread(fd, &d)) > 0){
		for(i = 0; i < n; i++){
			if(strcmp(d[i].name, "log") == 0 ||
			    !(d[i].qid.type & QTDIR))
				continue;
			if(strcmp(d[i].name, d[i].uid) != 0){
				syslog(1, CRONLOG, "cron for %s owned by %s",
					d[i].name, d[i].uid);
				continue;
			}
			u = newuser(d[i].name);
			snprint(file, sizeof file, "/cron/%s/cron", d[i].name);
			du = dirstat(file);
			if(du == nil || qidcmp(u->lastqid, du->qid) != 0){
				freejobs(u->jobs);
				u->jobs = readjobs(file, u);
			}
			free(du);
		}
		free(d);
	}
	close(fd);
}
Esempio n. 4
0
void
renamedir(char *d)
{
	int n;
	Dir *dir;
	char *sub;
	int fd, i;
	Name *na;

	fd = open(d, OREAD);
	if (fd == -1)
		return;
	while((n = dirread(fd, &dir)) > 0){
		for(i = 0; i < n; i++){
			if(dir[i].mode & DMDIR){
				sub = malloc(strlen(d) + 1 + strlen(dir[i].name) + 1);
				sprint(sub, "%s/%s", d, dir[i].name);
				renamedir(sub);
				free(sub);
			}
			if(strlen(dir[i].name) != ENCLEN)
				continue;
			for (na = names; na != nil; na = na->next){
				if (strcmp(na->shortname, dir[i].name) == 0){
					rename(d, dir[i].name, na->longname);
					break;
				}
			}
		}
		free(dir);
	}
	close(fd);
}
Esempio n. 5
0
File: Inferno.c Progetto: 8l/cmm
void
dirtime(char *dir, char *path)
{
	int i, fd, n;
	void *t;
	Dir db[32];
	char buf[8192];

	fd = open(dir, OREAD);
	if(fd >= 0) {
		while((n = dirread(fd, db, sizeof db)) > 0){
			n /= sizeof(Dir);
			for(i = 0; i < n; i++){
				t = (void *)db[i].mtime;
				if (!t)			/* zero mode file */
					continue;
				sprint(buf, "%s%s", path, db[i].name);
				if(symlook(buf, S_TIME, 0))
					continue;
				symlook(strdup9(buf), S_TIME, t)->value = t;
			}
		}
		close(fd);
	}
}
Esempio n. 6
0
void
dirtime(char *dir, char *path)
{
	int i, fd, n;
	ulong mtime;
	Dir *d;
	char buf[4096];

	fd = open(dir, OREAD);
	if(fd >= 0){
		while((n = dirread(fd, &d)) > 0){
			for(i=0; i<n; i++){
				mtime = d[i].mtime;
				/* defensive driving: this does happen */
				if(mtime == 0)
					mtime = 1;
				snprint(buf, sizeof buf, "%s%s", path,
					d[i].name);
				if(symlook(buf, S_TIME, 0) == nil)
					symlook(strdup(buf), S_TIME,
						(void*)mtime)->u.value = mtime;
			}
			free(d);
		}
		close(fd);
	}
}
Esempio n. 7
0
File: plan9.c Progetto: aahud/harvey
/*
 * onlydirs is advisory -- it means you only
 * need to return the directories.  it's okay to
 * return files too (e.g., on unix where you can't
 * tell during the readdir), but that just makes 
 * the globber work harder.
 */
int
Readdir(int f, void *p, int onlydirs)
{
	int n;

	if(f<0 || f>=NFD)
		return 0;
Again:
	if(dir[f].i==dir[f].n){	/* read */
		free(dir[f].dbuf);
		dir[f].dbuf = 0;
		n = dirread(f, &dir[f].dbuf);
		if(n>0){
			if(onlydirs){
				n = trimdirs(dir[f].dbuf, n);
				if(n == 0)
					goto Again;
			}	
			dir[f].n = n;
		}else
			dir[f].n = 0;
		dir[f].i = 0;
	}
	if(dir[f].i == dir[f].n)
		return 0;
	strcpy(p, dir[f].dbuf[dir[f].i].name);
	dir[f].i++;
	return 1;
}
Esempio n. 8
0
File: plan9.c Progetto: aahud/harvey
void
Xrdfn(void)
{
	int f, len;
	Dir *e;
	char envname[Maxenvname];
	static Dir *ent, *allocent;
	static int nent;

	for(;;){
		if(nent == 0){
			free(allocent);
			nent = dirread(envdir, &allocent);
			ent = allocent;
		}
		if(nent <= 0)
			break;
		while(nent){
			e = ent++;
			nent--;
			len = e->length;
			if(len && strncmp(e->name, "fn#", 3)==0){
				snprint(envname, sizeof envname, "/env/%s", e->name);
				if((f = open(envname, 0))>=0){
					execcmds(openfd(f));
					return;
				}
			}
		}
	}
	close(envdir);
	Xreturn();
}
Esempio n. 9
0
void
ls(char *file)
{
	Dir *d;
	int fd, i, nd;

	fd = open(file, OREAD);
	if(fd < 0)
		return;

	/*
	 * read box to find all messages
	 * each one has a directory, and is in numerical order
	 */
	d = dirfstat(fd);
	if(d == nil){
		close(fd);
		return;
	}
	if(!(d->mode & DMDIR)){
		fprint(2, "file %s\n", file);
		free(d);
		close(fd);
		return;
	}
	free(d);
	while((nd = dirread(fd, &d)) > 0){
		for(i = 0; i < nd; i++){
			fprint(2, "%s/%s %c\n", file, d[i].name, "-d"[(d[i].mode & DMDIR) == DMDIR]);
		}
		free(d);
	}
	close(fd);
}
Esempio n. 10
0
int
preaddir(Fid *f, uchar *data, int n, vlong offset)
{
	int r = 0, m;
	Dir *d;

	DEBUG(DFD, "\tpreaddir n=%d wo=%lld fo=%lld\n", n, offset, f->offset);
	if(offset == 0 && f->offset != 0){
		if(seek(f->fid, 0, 0) != 0)
			return -1;
		f->offset = f->cdir = f->ndir = 0;
		free(f->dir);
		f->dir = nil;
	}else if(offset != f->offset){
		werrstr("can't seek dir %lld to %lld", f->offset, offset);
		return -1;
	}

	while(n > 0){
		if(f->dir == nil){
			f->ndir = dirread(f->fid, &f->dir);
			if(f->ndir < 0)
				return f->ndir;
			if(f->ndir == 0)
				return r;
		}
		d = &f->dir[f->cdir++];
		if(exclude){
			char *p = makepath(f->f, d->name);
			if(excludefile(p)){
				free(p);
				goto skipentry;
			}
			free(p);
		}
		m = convD2M(d, data, n);
		DEBUG(DFD, "\t\tconvD2M %d\n", m);
		if(m <= BIT16SZ){
			DEBUG(DFD, "\t\t\tneeded %d\n", GBIT16(data));
			/* not enough room for full entry; leave for next time */
			f->cdir--;
			return r;
		}else{
			data += m;
			n -= m;
			r += m;
			f->offset += m;
		}
skipentry:	if(f->cdir >= f->ndir){
			f->cdir = f->ndir = 0;
			free(f->dir);
			f->dir = nil;
		}
	}
	return r;
}
Esempio n. 11
0
void
refreshwin(void)
{
	char label[128];
	int i, fd, lfd, n, nr, nw, m;
	Dir *pd;

	if((fd = open("/dev/wsys", OREAD)) < 0)
		return;

	nw = 0;
/* i'd rather read one at a time but rio won't let me */
	while((nr=dirread(fd, &pd)) > 0){
		for(i=0; i<nr; i++){
			n = atoi(pd[i].name);
			sprint(label, "/dev/wsys/%d/label", n);
			if((lfd = open(label, OREAD)) < 0)
				continue;
			m = read(lfd, label, sizeof(label)-1);
			close(lfd);
			if(m < 0)
				continue;
			label[m] = '\0';
			if(exclude != nil && regexec(exclude,label,nil,0))
				continue;

			if(nw < nwin && win[nw].n == n && strcmp(win[nw].label, label)==0){
				nw++;
				continue;
			}
	
			if(nw < nwin){
				free(win[nw].label);
				win[nw].label = nil;
			}
			
			if(nw >= mwin){
				mwin += 8;
				win = erealloc(win, mwin*sizeof(win[0]));
			}
			win[nw].n = n;
			win[nw].label = estrdup(label);
			win[nw].dirty = 1;
			win[nw].r = Rect(0,0,0,0);
			nw++;
		}
		free(pd);
	}
	while(nwin > nw)
		free(win[--nwin].label);
	nwin = nw;
	close(fd);
}
Esempio n. 12
0
File: plan9.c Progetto: aahud/harvey
void
Vinit(void)
{
	int dir, f, len, i, n, nent;
	char *buf, *s;
	char envname[Maxenvname];
	word *val;
	Dir *ent;

	dir = open("/env", OREAD);
	if(dir<0){
		pfmt(err, "rc: can't open /env: %r\n");
		return;
	}
	ent = nil;
	for(;;){
		nent = dirread(dir, &ent);
		if(nent <= 0)
			break;
		for(i = 0; i<nent; i++){
			len = ent[i].length;
			if(len && strncmp(ent[i].name, "fn#", 3)!=0){
				snprint(envname, sizeof envname, "/env/%s", ent[i].name);
				if((f = open(envname, 0))>=0){
					buf = emalloc(len+1);
					n = readn(f, buf, len);
					if (n <= 0)
						buf[0] = '\0';
					else
						buf[n] = '\0';
					val = 0;
					/* Charitably add a 0 at the end if need be */
					if(buf[len-1])
						buf[len++]='\0';
					s = buf+len-1;
					for(;;){
						while(s!=buf && s[-1]!='\0') --s;
						val = newword(s, val);
						if(s==buf)
							break;
						--s;
					}
					setvar(ent[i].name, val);
					vlook(ent[i].name)->changed = 0;
					close(f);
					efree(buf);
				}
			}
		}
		free(ent);
	}
	close(dir);
}
Esempio n. 13
0
vlong
du(char *name, Dir *dir)
{
	int fd, i, n;
	Dir *buf, *d;
	String *file;
	vlong nk, t;

	if(dir == nil)
		return warn(name);

	if((dir->qid.type&QTDIR) == 0)
		return dirval(dir, blkmultiple(dir->length));

	fd = open(name, OREAD);
	if(fd < 0)
		return warn(name);
	nk = 0;
	while((n=dirread(fd, &buf)) > 0) {
		d = buf;
		for(i = n; i > 0; i--, d++) {
			if((d->qid.type&QTDIR) == 0) {
				nk += dufile(name, d);
				continue;
			}

			if(strcmp(d->name, ".") == 0 ||
			   strcmp(d->name, "..") == 0 ||
			   /* !readflg && */ seen(d))
				continue;	/* don't get stuck */

			file = s_copy(name);
			s_append(file, "/");
			s_append(file, d->name);

			t = du(s_to_c(file), d);

			nk += t;
			t = dirval(d, t);
			if(!sflag)
				printamt(t, s_to_c(file));
			s_free(file);
		}
		free(buf);
	}
	if(n < 0)
		warn(name);
	close(fd);
	return dirval(dir, nk);
}
Esempio n. 14
0
void
readenv(void)
{
	char *p;
	int envf, f;
	Dir *e;
	char nam[1024];
	int i, n, len;
	Word *w;

	rfork(RFENVG);	/*  use copy of the current environment variables */

	envf = open("/env", OREAD);
	if(envf < 0)
		return;
	while((n = dirread(envf, &e)) > 0){
		for(i = 0; i < n; i++){
			len = e[i].length;
				/* don't import funny names, NULL values,
				 * or internal mk variables
				 */
			if(len <= 0 || *shname(e[i].name) != '\0')
				continue;
			if (symlook(e[i].name, S_INTERNAL, 0))
				continue;
			snprint(nam, sizeof nam, "/env/%s", e[i].name);
			f = open(nam, OREAD);
			if(f < 0)
				continue;
			p = Malloc(len+1);
			if(read(f, p, len) != len){
				perror(nam);
				close(f);
				continue;
			}
			close(f);
			if (p[len-1] == 0)
				len--;
			else
				p[len] = 0;
			w = encodenulls(p, len);
			free(p);
			p = strdup(e[i].name);
			setvar(p, (void *) w);
			symlook(p, S_EXPORTED, (void*)"")->u.ptr = "";
		}
		free(e);
	}
	close(envf);
}
Esempio n. 15
0
void LaosFileSystem::getlongname(char *result, char *searchname) {
    FILE *fp = fopen(tablename, "r");
    if (fp) {
        char longname[MAXFILESIZE];
        char shortname[SHORTFILESIZE];
        while (dirread(longname, shortname, fp))
            if (! strcmp(shortname, searchname))
                break;
        if (strcmp(shortname, searchname))
            strcpy(result, searchname);
        else
            strcpy(result, longname);
        fclose(fp);
    } else {
        strcpy(result, searchname);
    }
}
Esempio n. 16
0
File: main.c Progetto: 99years/plan9
void
loadmboxfaces(char *maildir)
{
	int dirfd;
	Dir *d;
	int i, n;

	dirfd = open(maildir, OREAD);
	if(dirfd >= 0){
		chdir(maildir);
		while((n = dirread(dirfd, &d)) > 0){
			for(i=0; i<n; i++)
				addface(dirface(maildir, d[i].name));
			free(d);
		}
		close(dirfd);
	}
}
Esempio n. 17
0
void mkentry(uint16_t inum)
{
    struct dinode rootino;
    struct direct dentry;
    uint16_t d;

    iread(ROOTINODE, &rootino);
    for (d = 0; d < swizzle32(rootino.i_size)/32; ++d) {
        dirread(&rootino, d, &dentry);
        if (dentry.d_ino == 0 && dentry.d_name[0] == '\0') {
            dentry.d_ino = swizzle16(inum);
            sprintf(dentry.d_name, "l+f%d", inum);
            dirwrite(&rootino, d, &dentry);
            return;
        }
    }
    printf("Sorry... No empty slots in root directory.\n");
}
Esempio n. 18
0
void LaosFileSystem::getshortname(char* shortname, char* name) {
    // * open filename translation table
    // * and see if a file with that name exists
    if (isshortname(name)) {
        strcpy(shortname, name);
    } else {
        int found = 0;
        char longname[MAXFILESIZE];
        FILE *fp = fopen(tablename, "r");
        if (fp) {
            while (dirread(longname, shortname, fp)) {
                if (!strcmp(longname, name)) {
                    found = 1;
                    break;
                }
            }
            if (! found) strcpy(shortname, "");
            fclose(fp);
        }
    }
}
Esempio n. 19
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);
}
Esempio n. 20
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);
}
Esempio n. 21
0
uint
textload(Text *t, uint q0, char *file, int setqid)
{
	Rune *rp;
	Dirlist *dl, **dlp;
	int fd, i, j, n, ndl, nulls;
	uint q, q1;
	Dir *d, *dbuf;
	char *tmp;
	Text *u;

	if(t->ncache!=0 || t->file->nc || t->w==nil || t!=&t->w->body)
		error("text.load");
	if(t->w->isdir && t->file->nname==0){
		warning(nil, "empty directory name\n");
		return 0;
	}
	fd = open(file, OREAD);
	if(fd < 0){
		warning(nil, "can't open %s: %r\n", file);
		return 0;
	}
	d = dirfstat(fd);
	if(d == nil){
		warning(nil, "can't fstat %s: %r\n", file);
		goto Rescue;
	}
	nulls = FALSE;
	if(d->qid.type & QTDIR){
		/* this is checked in get() but it's possible the file changed underfoot */
		if(t->file->ntext > 1){
			warning(nil, "%s is a directory; can't read with multiple windows on it\n", file);
			goto Rescue;
		}
		t->w->isdir = TRUE;
		t->w->filemenu = FALSE;
		if(t->file->name[t->file->nname-1] != '/'){
			rp = runemalloc(t->file->nname+1);
			runemove(rp, t->file->name, t->file->nname);
			rp[t->file->nname] = '/';
			winsetname(t->w, rp, t->file->nname+1);
			free(rp);
		}
		dlp = nil;
		ndl = 0;
		dbuf = nil;
		while((n=dirread(fd, &dbuf)) > 0){
			for(i=0; i<n; i++){
				dl = emalloc(sizeof(Dirlist));
				j = strlen(dbuf[i].name);
				tmp = emalloc(j+1+1);
				memmove(tmp, dbuf[i].name, j);
				if(dbuf[i].qid.type & QTDIR)
					tmp[j++] = '/';
				tmp[j] = '\0';
				dl->r = bytetorune(tmp, &dl->nr);
				dl->wid = stringwidth(t->font, tmp);
				free(tmp);
				ndl++;
				dlp = realloc(dlp, ndl*sizeof(Dirlist*));
				dlp[ndl-1] = dl;
			}
			free(dbuf);
		}
		qsort(dlp, ndl, sizeof(Dirlist*), dircmp);
		t->w->dlp = dlp;
		t->w->ndl = ndl;
		textcolumnate(t, dlp, ndl);
		q1 = t->file->nc;
	}else{
		t->w->isdir = FALSE;
		t->w->filemenu = TRUE;
		q1 = q0 + fileload(t->file, q0, fd, &nulls);
	}
	if(setqid){
		t->file->dev = d->dev;
		t->file->mtime = d->mtime;
		t->file->qidpath = d->qid.path;
	}
	close(fd);
	rp = fbufalloc();
	for(q=q0; q<q1; q+=n){
		n = q1-q;
		if(n > RBUFSIZE)
			n = RBUFSIZE;
		bufread(t->file, q, rp, n);
		if(q < t->org)
			t->org += n;
		else if(q <= t->org+t->nchars)
			frinsert(t, rp, rp+n, q-t->org);
		if(t->lastlinefull)
			break;
	}
	fbuffree(rp);
	for(i=0; i<t->file->ntext; i++){
		u = t->file->text[i];
		if(u != t){
			if(u->org > u->file->nc)	/* will be 0 because of reset(), but safety first */
				u->org = 0;
			textresize(u, u->all);
			textbacknl(u, u->org, 0);	/* go to beginning of line */
		}
		textsetselect(u, q0, q0);
	}
	if(nulls)
		warning(nil, "%s: NUL bytes elided\n", file);
	free(d);
	return q1-q0;

    Rescue:
	close(fd);
	return 0;
}
Esempio n. 22
0
static
int
check_dir(uint32_t ino, uint32_t parentino, const char *pathsofar)
{
	struct sfs_inode sfi;
	struct sfs_dir *direntries;
	int *sortvector;
	uint32_t dirsize, ndirentries, maxdirentries, subdircount, i;
	int ichanged=0, dchanged=0, dotseen=0, dotdotseen=0;

	diskread(&sfi, ino);
	swapinode(&sfi);

	if (remember_dir(ino, pathsofar)) {
		/* crosslinked dir */
		return 1;
	}

	bitmap_mark(ino, B_INODE, ino);
	count_dirs++;

	if (sfi.sfi_size % sizeof(struct sfs_dir) != 0) {
		setbadness(EXIT_RECOV);
		warnx("Directory /%s has illegal size %lu (fixed)",
		      pathsofar, (unsigned long) sfi.sfi_size);
		sfi.sfi_size = SFS_ROUNDUP(sfi.sfi_size,
					   sizeof(struct sfs_dir));
		ichanged = 1;
	}

	if (check_inode_blocks(ino, &sfi, 1)) {
		ichanged = 1;
	}

	ndirentries = sfi.sfi_size/sizeof(struct sfs_dir);
	maxdirentries = SFS_ROUNDUP(ndirentries,
				    SFS_BLOCKSIZE/sizeof(struct sfs_dir));
	dirsize = maxdirentries * sizeof(struct sfs_dir);
	direntries = domalloc(dirsize);
	sortvector = domalloc(ndirentries * sizeof(int));

	dirread(&sfi, direntries, ndirentries);
	for (i=ndirentries; i<maxdirentries; i++) {
		direntries[i].sfd_ino = SFS_NOINO;
		bzero(direntries[i].sfd_name, sizeof(direntries[i].sfd_name));
	}

	for (i=0; i<ndirentries; i++) {
		if (check_dir_entry(pathsofar, i, &direntries[i])) {
			dchanged = 1;
		}
		sortvector[i] = i;
	}

	sortdir(sortvector, direntries, ndirentries);

	/* don't use ndirentries-1 here in case ndirentries == 0 */
	for (i=0; i+1<ndirentries; i++) {
		struct sfs_dir *d1 = &direntries[sortvector[i]];
		struct sfs_dir *d2 = &direntries[sortvector[i+1]];
		assert(d1 != d2);

		if (d1->sfd_ino == SFS_NOINO) {
			continue;
		}

		if (!strcmp(d1->sfd_name, d2->sfd_name)) {
			if (d1->sfd_ino == d2->sfd_ino) {
				setbadness(EXIT_RECOV);
				warnx("Directory /%s: Duplicate entries for "
				      "%s (merged)",
				      pathsofar, d1->sfd_name);
				d1->sfd_ino = SFS_NOINO;
				d1->sfd_name[0] = 0;
			}
			else {
				snprintf(d1->sfd_name, sizeof(d1->sfd_name),
					 "FSCK.%lu.%lu",
					 (unsigned long) d1->sfd_ino,
					 (unsigned long) uniquecounter++);
				setbadness(EXIT_RECOV);
				warnx("Directory /%s: Duplicate names %s "
				      "(one renamed: %s)",
				      pathsofar, d2->sfd_name, d1->sfd_name);
			}
			dchanged = 1;
		}
	}

	for (i=0; i<ndirentries; i++) {
		if (!strcmp(direntries[i].sfd_name, ".")) {
			if (direntries[i].sfd_ino != ino) {
				setbadness(EXIT_RECOV);
				warnx("Directory /%s: Incorrect `.' entry "
				      "(fixed)", pathsofar);
				direntries[i].sfd_ino = ino;
				dchanged = 1;
			}
			assert(dotseen==0); /* due to duplicate checking */
			dotseen = 1;
		}
		else if (!strcmp(direntries[i].sfd_name, "..")) {
			if (direntries[i].sfd_ino != parentino) {
				setbadness(EXIT_RECOV);
				warnx("Directory /%s: Incorrect `..' entry "
				      "(fixed)", pathsofar);
				direntries[i].sfd_ino = parentino;
				dchanged = 1;
			}
			assert(dotdotseen==0); /* due to duplicate checking */
			dotdotseen = 1;
		}
	}

	if (!dotseen) {
		if (dir_tryadd(direntries, ndirentries, ".", ino)==0) {
			setbadness(EXIT_RECOV);
			warnx("Directory /%s: No `.' entry (added)",
			      pathsofar);
			dchanged = 1;
		}
		else if (dir_tryadd(direntries, maxdirentries, ".", ino)==0) {
			setbadness(EXIT_RECOV);
			warnx("Directory /%s: No `.' entry (added)",
			      pathsofar);
			ndirentries++;
			dchanged = 1;
			sfi.sfi_size += sizeof(struct sfs_dir);
			ichanged = 1;
		}
		else {
			setbadness(EXIT_UNRECOV);
			warnx("Directory /%s: No `.' entry (NOT FIXED)",
			      pathsofar);
		}
	}

	if (!dotdotseen) {
		if (dir_tryadd(direntries, ndirentries, "..", parentino)==0) {
			setbadness(EXIT_RECOV);
			warnx("Directory /%s: No `..' entry (added)",
			      pathsofar);
			dchanged = 1;
		}
		else if (dir_tryadd(direntries, maxdirentries, "..",
				    parentino)==0) {
			setbadness(EXIT_RECOV);
			warnx("Directory /%s: No `..' entry (added)",
			      pathsofar);
			ndirentries++;
			dchanged = 1;
			sfi.sfi_size += sizeof(struct sfs_dir);
			ichanged = 1;
		}
		else {
			setbadness(EXIT_UNRECOV);
			warnx("Directory /%s: No `..' entry (NOT FIXED)",
			      pathsofar);
		}
	}

	subdircount=0;
	for (i=0; i<ndirentries; i++) {
		if (!strcmp(direntries[i].sfd_name, ".")) {
			/* nothing */
		}
		else if (!strcmp(direntries[i].sfd_name, "..")) {
			/* nothing */
		}
		else if (direntries[i].sfd_ino == SFS_NOINO) {
			/* nothing */
		}
		else {
			char path[strlen(pathsofar)+SFS_NAMELEN+1];
			struct sfs_inode subsfi;

			diskread(&subsfi, direntries[i].sfd_ino);
			swapinode(&subsfi);
			snprintf(path, sizeof(path), "%s/%s",
				 pathsofar, direntries[i].sfd_name);

			switch (subsfi.sfi_type) {
			    case SFS_TYPE_FILE:
				if (check_inode_blocks(direntries[i].sfd_ino,
						       &subsfi, 0)) {
					swapinode(&subsfi);
					diskwrite(&subsfi,
						  direntries[i].sfd_ino);
				}
				observe_filelink(direntries[i].sfd_ino);
				break;
			    case SFS_TYPE_DIR:
				if (check_dir(direntries[i].sfd_ino,
					      ino,
					      path)) {
					setbadness(EXIT_RECOV);
					warnx("Directory /%s: Crosslink to "
					      "other directory (removed)",
					      path);
					direntries[i].sfd_ino = SFS_NOINO;
					direntries[i].sfd_name[0] = 0;
					dchanged = 1;
				}
				else {
					subdircount++;
				}
				break;
			    default:
				setbadness(EXIT_RECOV);
				warnx("Object /%s: Invalid inode type "
				      "(removed)", path);
				direntries[i].sfd_ino = SFS_NOINO;
				direntries[i].sfd_name[0] = 0;
				dchanged = 1;
				break;
			}
		}
	}

	if (sfi.sfi_linkcount != subdircount+2) {
		setbadness(EXIT_RECOV);
		warnx("Directory /%s: Link count %lu should be %lu (fixed)",
		      pathsofar, (unsigned long) sfi.sfi_linkcount,
		      (unsigned long) subdircount+2);
		sfi.sfi_linkcount = subdircount+2;
		ichanged = 1;
	}

	if (dchanged) {
		dirwrite(&sfi, direntries, ndirentries);
	}

	if (ichanged) {
		swapinode(&sfi);
		diskwrite(&sfi, ino);
	}

	free(direntries);
	free(sortvector);

	return 0;
}
Esempio n. 23
0
void ckdir(uint16_t inum, uint16_t pnum, char *name)
{
    struct dinode ino;
    struct direct dentry;
    uint16_t j;
    int c;
    int nentries;
    char ename[150];

    iread(inum, &ino);
    if ((swizzle16(ino.i_mode) & F_MASK) != F_DIR)
        return;
    ++depth;

    if (swizzle32(ino.i_size) % 32 != 0) {
        printf("Directory inode %d has improper length. Fix? ", inum);
        if (yes()) {
            ino.i_size = swizzle32(swizzle32(ino.i_size) & ~0x1f);
            iwrite(inum, &ino);
        }
    }
    nentries = swizzle32(ino.i_size)/32;

    for (j = 0; j < nentries; ++j) {
        dirread(&ino, j, &dentry);

#if 1 /**HP**/
        {
            int i;

            for (i = 0; i < 30; ++i) if (dentry.d_name[i] == '\0') break;
            for (     ; i < 30; ++i) dentry.d_name[i] = '\0';
            dirwrite(&ino, j, &dentry);
        }
#endif

        if (dentry.d_ino == 0)
            continue;

        if (swizzle16(dentry.d_ino) < ROOTINODE ||
                swizzle16(dentry.d_ino) >= 8 * swizzle16(superblock.s_isize)) {
            printf("Directory entry %s%-1.14s has out-of-range inode %u. Zap? ",
                    name, dentry.d_name, swizzle16(dentry.d_ino));
            if (yes()) {
                dentry.d_ino = 0;
                dentry.d_name[0] = '\0';
                dirwrite(&ino, j, &dentry);
                continue;
            }
        }
        if (dentry.d_ino && linkmap[swizzle16(dentry.d_ino)] == -1) {
            printf("Directory entry %s%-1.14s points to bogus inode %u. Zap? ",
                    name, dentry.d_name, swizzle16(dentry.d_ino));
            if (yes()) {
                dentry.d_ino = 0;
                dentry.d_name[0] = '\0';
                dirwrite(&ino, j, &dentry);
                continue;
            }
        }
        ++linkmap[swizzle16(dentry.d_ino)];

        for (c = 0; c < 30 && dentry.d_name[c]; ++c) {
            if (dentry.d_name[c] == '/') {
                printf("Directory entry %s%-1.30s contains slash. Fix? ",
                        name, dentry.d_name);
                if (yes()) {
                    dentry.d_name[c] = 'X';
                    dirwrite(&ino, j, &dentry);
                }
            }
        }

        if (strncmp(dentry.d_name, ".", 30) == 0 && swizzle16(dentry.d_ino) != inum) {
            printf("Dot entry %s%-1.30s points to wrong place. Fix? ",
                    name, dentry.d_name);
            if (yes()) {
                dentry.d_ino = swizzle16(inum);
                dirwrite(&ino, j, &dentry);
            }
        }
        if (strncmp(dentry.d_name, "..", 30) == 0 && swizzle16(dentry.d_ino) != pnum) {
            printf("DotDot entry %s%-1.30s points to wrong place. Fix? ",
                    name, dentry.d_name);
            if (yes()) {
                dentry.d_ino = swizzle16(pnum);
                dirwrite(&ino, j, &dentry);
            }
        }
        if (swizzle16(dentry.d_ino) != pnum &&
                swizzle16(dentry.d_ino) != inum && depth < MAXDEPTH) {
            strcpy(ename, name);
            strcat(ename, dentry.d_name);
            strcat(ename, "/");
            ckdir(swizzle16(dentry.d_ino), inum, ename);
        }
    }
    --depth;
}
Esempio n. 24
0
ssize_t
getdents(int fd, void* buf, size_t siz)
{
	struct stat		st;

	if (siz < DIRBLKSIZ)
	{
		errno = EINVAL;
		return(-1);
	}
	if (fstat(fd, &st)) return(-1);
	if (!S_ISDIR(st.st_mode))
	{
#ifdef ENOTDIR
		errno = ENOTDIR;
#else
		errno = EBADF;
#endif
		return(-1);
	}
#if _lib_getdirentries
	{
		long		off;
		return(getdirentries(fd, buf, siz, &off));
	}
#else
#if _lib_dirread
	{
		register char*		sp;	/* system */
		register struct dirent*	up;	/* user */
		char*			u;
		int			n;
		int			m;
		int			i;

		m = (siz * 6) / 10;
		m = roundof(m, 8);
		sp = (char*)buf + siz - m - 1;
		if (!(n = dirread(fd, sp, m))) return(0);
		if (n > 0)
		{
			up = (struct dirent*)buf;
			sp[n] = 0;
			while (sp < (char*)buf + siz - m + n)
			{
				i = 0;
				while (*sp >= '0' && *sp <= '9')
					i = 10 * i + *sp++ - '0';
				while (*sp && *sp != '\t') sp++;
				if (*sp++)
				{
					up->d_fileno = i;
					u = up->d_name;
					while ((*u = *sp++) && u < up->d_name + MAXNAMLEN) u++;
					*u = 0;
					up->d_reclen = sizeof(struct dirent) - sizeof(up->d_name) + (up->d_namlen = u - up->d_name) + 1;
					up->d_reclen = roundof(up->d_reclen, 8);
					up = (struct dirent*)((char*)up + up->d_reclen);
				}
			}
			return((char*)up - (char*)buf);
		}
	}
#else
#if _mem_d_reclen_direct
	return(read(fd, buf, siz));
#else
	{

#define MAXREC	roundof(sizeof(*up)-sizeof(up->d_name)+sizeof(sp->d_name)+1,8)

		register struct direct*	sp;	/* system */
		register struct dirent*	up;	/* user */
		register char*		s;
		register char*		u;
		int			n;
		int			m;
		char			tmp[sizeof(sp->d_name) + 1];

		/*
		 * we assume sizeof(struct dirent) > sizeof(struct direct)
		 */

		up = (struct dirent*)buf;
		n = (siz / MAXREC) * sizeof(struct direct);
		if ((!(m = n & ~511) || m < MAXREC) && (!(m = n & ~255) || m < MAXREC)) m = n;
		do
		{
			if ((n = read(fd, (char*)buf + siz - m, m)) <= 0) break;
			sp = (struct direct*)((char*)buf + siz - m);
			while (sp < (struct direct*)((char*)buf + siz - m + n))
			{
				if (sp->d_ino)
				{
					up->d_fileno = sp->d_ino;
					s = sp->d_name;
					u = tmp;
					while (s < sp->d_name + sizeof(sp->d_name) && *s)
						*u++ = *s++;
					*u = 0;
					strcpy(up->d_name, tmp);
					up->d_reclen = sizeof(struct dirent) - sizeof(up->d_name) + (up->d_namlen = u - tmp) + 1;
					up->d_reclen = roundof(up->d_reclen, 8);
					up = (struct dirent*)((char*)up + up->d_reclen);
				}
				sp++;
			}
		} while (up == (struct dirent*)buf);
		return((char*)up - (char*)buf);
	}
#endif
#endif
#endif
}