Пример #1
0
void
attachprocess(void)
{
	char buf[100];
	Dir *sym, *mem;
	int fd;

	if (!adrflg) {
		dprint("used pid$a\n");
		return;
	}
	sym = dirfstat(fsym);
	sprint(buf, "/proc/%lu/mem", adrval);
	corfil = buf;
	setcor();
	sprint(buf, "/proc/%lu/text", adrval);
	fd = open(buf, OREAD);
	mem = nil;
	if (sym==nil || fd < 0 || (mem=dirfstat(fd))==nil
				|| sym->qid.path != mem->qid.path)
		dprint("warning: text images may be inconsistent\n");
	free(sym);
	free(mem);
	if (fd >= 0)
		close(fd);
}
Пример #2
0
void
checkqid(int f1, int pid)
{
	int fd;
	Dir *d1, *d2;
	char buf[128];

	if(kernel || rdebug)
		return;

	d1 = dirfstat(f1);
	if(d1 == nil)
		fatal("checkqid: (qid not checked) dirfstat: %r");

	sprint(buf, "/proc/%d/text", pid);
	fd = open(buf, OREAD);
	if(fd < 0 || (d2 = dirfstat(fd)) == nil){
		fatal("checkqid: (qid not checked) dirstat %s: %r", buf);
		return;	/* not reached */
	}

	close(fd);

	if(d1->qid.path != d2->qid.path || d1->qid.vers != d2->qid.vers || d1->qid.type != d2->qid.type){
		print("path %llux %llux vers %lud %lud type %d %d\n",
			d1->qid.path, d2->qid.path, d1->qid.vers, d2->qid.vers, d1->qid.type, d2->qid.type);
		print("warning: image does not match text for pid %d\n", pid);
	}
	free(d1);
	free(d2);
}
Пример #3
0
char*
readfile(char *dir, char *name, int *np)
{
	char *file, *data;
	int fd, len;
	Dir *d;

	if(np != nil)
		*np = 0;
	file = estrstrdup(dir, name);
	fd = open(file, OREAD);
	if(fd < 0)
		return nil;
	d = dirfstat(fd);
	free(file);
	len = 0;
	if(d != nil)
		len = d->length;
	free(d);
	data = emalloc(len+1);
	read(fd, data, len);
	close(fd);
	if(np != nil)
		*np = len;
	return data;
}
Пример #4
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);
}
Пример #5
0
/*
 *	Copy the file referenced by fd to the temp file
 */
void
armove(Biobuf *b, Arfile *ap, Armember *bp)
{
    char *cp;
    Dir *d;

    if ((d = dirfstat(Bfildes(b))) == nil) {
        fprint(2, "ar: cannot stat %s: %r\n", file);
        return;
    }
    trim(file, bp->hdr.name, sizeof(bp->hdr.name));
    for (cp = strchr(bp->hdr.name, 0);		/* blank pad on right */
            cp < bp->hdr.name+sizeof(bp->hdr.name); cp++)
        *cp = ' ';
    sprint(bp->hdr.date, "%-12ld", d->mtime);
    sprint(bp->hdr.uid, "%-6d", 0);
    sprint(bp->hdr.gid, "%-6d", 0);
    sprint(bp->hdr.mode, "%-8lo", d->mode);
    sprint(bp->hdr.size, "%-10lld", (vlong)d->length);
    strncpy(bp->hdr.fmag, ARFMAG, 2);
    bp->size = d->length;
    bp->date = d->mtime;
    arread(b, bp, bp->size);
    if (d->length&0x01)
        d->length++;
    if (ap) {
        arinsert(ap, bp);
        ap->size += d->length+SAR_HDR;
    }
    free(d);
}
Пример #6
0
/*
 * copies while holding the mail lock,
 * then tries to copy permissions and group ownership
 */
static int
copyData(int ffd, int tfd, MbLock *ml)
{
	Dir *fd, td;
	char buf[BufSize];
	int n;

	for(;;){
		n = read(ffd, buf, BufSize);
		if(n <= 0){
			if(n < 0)
				return 0;
			break;
		}
		if(write(tfd, buf, n) != n)
			return 0;
		mbLockRefresh(ml);
	}
	fd = dirfstat(ffd);
	if(fd != nil){
		nulldir(&td);
		td.mode = fd->mode;
		if(dirfwstat(tfd, &td) >= 0){
			nulldir(&td);
			td.gid = fd->gid;
			dirfwstat(tfd, &td);
		}
	}
	return 1;
}
Пример #7
0
Font*
openfont(Display *d, char *name)
{
	Font *fnt;
	int fd, i, n;
	char *buf;
	Dir *dir;

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

	dir = dirfstat(fd);
	if(dir == nil){
    Err0:
		close(fd);
		return 0;
	}
	n = dir->length;
	free(dir);
	buf = malloc(n+1);
	if(buf == 0)
		goto Err0;
	buf[n] = 0;
	i = read(fd, buf, n);
	close(fd);
	if(i != n){
		free(buf);
		return 0;
	}
	fnt = buildfont(d, buf, name);
	free(buf);
	return fnt;
}
Пример #8
0
Файл: devfs.c Проект: 8l/inferno
void
fscreate(Chan *c, char *name, int mode, ulong perm)
{
	Dir *d;
	Cname *n;

	if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
		error(Efilename);
	n = addelem(newcname(FS(c)->name->s), name);
	osenter();
	FS(c)->fd = create(n->s, mode, perm);
	osleave();
	if(FS(c)->fd < 0) {
		cnameclose(n);
		fserr(FS(c));
	}
	d = dirfstat(FS(c)->fd);
	if(d == nil) {
		cnameclose(n);
		close(FS(c)->fd);
		FS(c)->fd = -1;
		fserr(FS(c));
	}
	c->qid = d->qid;
	free(d);

	cnameclose(FS(c)->name);
	FS(c)->name = n;

	c->mode = openmode(mode);
	c->offset = 0;
	FS(c)->offset = 0;
	c->flag |= COPEN;
}
Пример #9
0
/*
 *  return true if any part of the database has changed
 */
int
ndbchanged(struct ndb *db)
{
	/* TODO: implement me (no one calls this yet) */
	assert(0);
	return 0;
#if 0
	struct ndb *ndb;
	struct dir *d;

/* FIX ME */
	for(ndb = db; ndb != NULL; ndb = ndb->next){
		d = dirfstat(Bfildes(&ndb->b));
		if(d == NULL)
			continue;
		if(ndb->qid.path != d->qid.path
		|| ndb->qid.vers != d->qid.vers){
			free(d);
			return 1;
		}
		free(d);
	}
	return 0;
#endif
}
Пример #10
0
/*
 *  dump any cached information, forget the hash tables, and reopen a single file
 */
int
ndbreopen(struct ndb *db)
{
	int fd;
	struct dir *d;

	/* forget what we know about the open files */
	if(db->isopen){
		_ndbcacheflush(db);
		hffree(db);
		fclose(db->b);
		db->mtime = 0;
		db->isopen = 0;
	}

	/* try the open again */
	db->b = fopen(db->file, "r");
	if(! db->b)
		return -1;
#if 0
	d = dirfstat(fd);
	if(d == NULL){
		close(fd);
		return -1;
	}

	db->qid = d->qid;
	db->mtime = d->mtime;
	db->length = d->length;
	free(d);
#endif
	db->isopen = 1;
	return 0;
}
Пример #11
0
void
main(int argc, char *argv[])
{
    Dir *d;
    char *p, *file;
    int fd, len;

    ARGBEGIN{
    case 'p':
        usepass = 1;
        break;
    case 'v':
        verb = 1;
        break;
    case 'a':
        convaes = 1;
        break;
    default:
        usage();
    } ARGEND

    if(argc != 1)
        usage();
    file = argv[0];

    /* get original key */
    if(usepass) {
        print("enter password file is encoded with\n");
        getpass(&okey, nil, 0, 1);
    } else {
        getauthkey(&okey);
    }
    if(!verb) {
        print("enter password to reencode with\n");
        getpass(&nkey, nil, 0, 1);
    }

    fd = open(file, ORDWR);
    if(fd < 0)
        error("can't open %s: %r\n", file);
    d = dirfstat(fd);
    if(d == nil)
        error("can't stat %s: %r\n", file);
    len = d->length;
    p = malloc(len);
    if(p == nil)
        error("out of memory");
    if(read(fd, p, len) != len)
        error("can't read key file: %r\n");
    len = convert(&p, len);
    if(pwrite(fd, p, len, 0) != len)
        error("can't write key file: %r\n");
    close(fd);
    exits(nil);
}
Пример #12
0
void
print_item(char *file)
{
	char name[4096], *p, *ep;
	Dir *dbuf;
	int f, c;
	int bol, bop;

	sprint(name, "%s/%s", NEWS, file);
	f = open(name, OREAD);
	if(f < 0) {
		fprint(2, "news: ");
		perror(name);
		return;
	}
	strcpy(name, "...");
	dbuf = dirfstat(f);
	if(dbuf == nil)
		return;
	Bprint(&bout, "\n%s (%s) %s\n", file,
		dbuf->muid[0]? dbuf->muid : dbuf->uid,
		asctime(localtime(dbuf->mtime)));
	free(dbuf);

	bol = 1;	/* beginning of line ...\n */
	bop = 1;	/* beginning of page ...\n\n */
	for(;;) {
		c = read(f, name, sizeof(name));
		if(c <= 0)
			break;
		p = name;
		ep = p+c;
		while(p < ep) {
			c = *p++;
			if(c == '\n') {
				if(!bop) {
					Bputc(&bout, c);
					if(bol)
						bop = 1;
					bol = 1;
				}
				continue;
			}
			if(bol) {
				Bputc(&bout, '\t');
				bol = 0;
				bop = 0;
			}
			Bputc(&bout, c);
		}
	}
	if(!bol)
		Bputc(&bout, '\n');
	close(f);
}
Пример #13
0
void
main(int argc, char *argv[])
{
	Dir *d;
	char *p, *np, *file, key[DESKEYLEN];
	int fd, len;

	ARGBEGIN{
	case 'v':
		verb = 1;
		break;
	case 'p':
		usepass = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();
	file = argv[0];

	/* get original key */
	if(usepass){
		print("enter password file is encoded with\n");
		getpass(authkey, nil, 0, 1);
	} else
		getauthkey(authkey);
	print("enter password to reencode with\n");
	getpass(key, nil, 0, 1);

	fd = open(file, ORDWR);
	if(fd < 0)
		error("can't open %s: %r\n", file);
	d = dirfstat(fd);
	if(d == nil)
		error("can't stat %s: %r\n", file);
	len = d->length;
	p = malloc(len);
	if(!p)
		error("out of memory");
	np = malloc((len/OKEYDBLEN)*KEYDBLEN + KEYDBOFF);
	if(!np)
		error("out of memory");
	if(read(fd, p, len) != len)
		error("can't read key file: %r\n");
	len = convert(p, np, key, len);
	if(verb)
		exits(0);
	if(pwrite(fd, np, len, 0) != len)
		error("can't write key file: %r\n");
	close(fd);
	exits(0);
}
Пример #14
0
void
hintprint(HConnect *hc, Hio *hout, char *uri, int thresh, int havej)
{
	int i, j, pr, prefix, fd, siz, havei, newhint = 0, n;
	char *query, *sf, etag[32], *wurl;
	Dir *dir;
	Hint *h, *haveh;

	query = hstrdup(hc, uri);
	urlcanon(query);
	j = urllookup(hashstr(query));
	if(j < 0)
		return;
	query = strrchr(uri,'/');
	if(!query)
		return;  /* can't happen */
	prefix = query-uri+1;  /* = strlen(dirname)+1 */
	h = hints[j];
	for(i=0; i<nhint[j]; i++){
		if(havej > 0 && havej < URLmax){ /* exclude hints client has */
			haveh = hints[havej];
			for(havei=0; havei<nhint[havej]; havei++)
				if( haveh[havei].url == h[i].url)
					goto continuei;
		}
		sf = urlname[h[i].url];
		pr = h[i].prob;
		if(pr<thresh)
			break;
		n = strlen(webroot) + strlen(sf) + 1;
		wurl = halloc(hc, n);
		strcpy(wurl, webroot);
		strcat(wurl, sf);
		fd = open(wurl, OREAD);
		if(fd<0)
			continue;
		dir = dirfstat(fd);
		if(dir == nil){
			close(fd);
			continue;
		}
		close(fd);
		snprint(etag, sizeof(etag), "\"%lluxv%lx\"", dir->qid.path, dir->qid.vers);
		siz = (int)( log((double)dir->length) * RECIPLOG2 + 0.9999);
		free(dir);
		if(strncmp(uri,sf,prefix)==0 && strchr(sf+prefix,'/')==0 && sf[prefix]!=0)
			sf = sf+prefix;
		hprint(hout, "Fresh: %d,%s,%d,%s\r\n", pr, etag, siz, sf);
		newhint++;
continuei: ;
	}
	if(newhint)
		hprint(hout, "Fresh: have/%d\r\n", j);
}
Пример #15
0
void
mminit(char *file, int mode)
{
	Dir *d;
	uintptr va;
	void *p, *np;
	int hashsize; /* make it a power of two -- see why later */

	ventifd = open(file, mode);
	if (ventifd < 0)
		sysfatal("Can't open %s: %r\n", file);
	d = dirfstat(ventifd);
	if (! d)
		sysfatal("Can't stat %s: %r", file);

	/* allocate: size for the file, 1/32 that size for the map, and 
	 * start it at the 1 GB boundary, please. 
	 */
	/* get top of heap */
	p = segbrk(0, 0);
	va = (uintptr)p;
	/* no non-nix systems we just usr sbrk and only have little pages */
	hashsize = d->length/32;
	maxmap = hashsize / sizeof(*maps);
	hashb = log2(maxmap);
	if (va == (uintptr)-1) {
		p = sbrk(0);
		va = (uintptr)p;
		maps = (void *)va;
		va += hashsize;
		mmventidatabase = mmventidata = (void *)va;
		va += d->length;
		va = ROUNDUP((va), 4096);
		if (brk((void *)va) < 0)
			sysfatal("brk to %#p failed\n", (void *)va);
	} else {
		va = ROUNDUP((va), 1ULL*GiB);
		maps = (void *)va;
		va += hashsize;
		mmventidatabase = mmventidata = (void *)va;
		va += d->length;
		va = ROUNDUP((va), 1ULL*GiB);
		segbrk(0, (void *)va);
	}
	fprint(2, "mmventidatabase is %#p\n", mmventidatabase);

	fprint(2, "File size %lld, hashsize %d, maps %#p, data %#p\n", d->length, 
		hashsize, maps, mmventidata);
	/* morecore */
	np=(void*)va;
	segbrk(p, np);

	reload();
}
Пример #16
0
static u64int
fdsize(int fd)
{
	Dir *dir;
	u64int size;

	dir = dirfstat(fd);
	if(dir == nil)
		vtFatal("could not stat file: %r");
	size = dir->length;
	free(dir);
	return size;
}
Пример #17
0
Ident
getident(int fd)
{
	Dir *d;
	Ident i;
	
	d = dirfstat(fd);
	if(d == nil)
		return (Ident){-1, -1, (Qid){0, 0, 0}};
	i = (Ident){d->type, d->dev, d->qid};
	free(d);
	return i;
}
Пример #18
0
static int
fromwebdir(HConnect *c)
{
	char buf[4096], *p, *ext, *type;
	int i, fd, n, defaulted;
	Dir *d;
	
	if(webroot == nil || strstr(c->req.uri, ".."))
		return hnotfound(c);
	snprint(buf, sizeof buf-20, "%s/%s", webroot, c->req.uri+1);
	defaulted = 0;
reopen:
	if((fd = open(buf, OREAD)) < 0)
		return hnotfound(c);
	d = dirfstat(fd);
	if(d == nil){
		close(fd);
		return hnotfound(c);
	}
	if(d->mode&DMDIR){
		if(!defaulted){
			defaulted = 1;
			strcat(buf, "/index.html");
			free(d);
			close(fd);
			goto reopen;
		}
		free(d);
		return hnotfound(c);
	}
	free(d);
	p = buf+strlen(buf);
	type = "application/octet-stream";
	for(i=0; exttab[i].ext; i++){
		ext = exttab[i].ext;
		if(p-strlen(ext) >= buf && strcmp(p-strlen(ext), ext) == 0){
			type = exttab[i].type;
			break;
		}
	}
	if(hsettype(c, type) < 0){
		close(fd);
		return 0;
	}
	while((n = read(fd, buf, sizeof buf)) > 0)
		if(hwrite(&c->hout, buf, n) < 0)
			break;
	close(fd);
	hflush(&c->hout);
	return 0;
}
Пример #19
0
int
Bage(Biobuf *b)
{
	Dir *dir;
	int32_t mtime;

	dir = dirfstat(Bfildes(b));
	if(dir != nil)
		mtime = dir->mtime;
	else
		mtime = 0;
	free(dir);
	return time(nil) - mtime;
}
Пример #20
0
void
openfiles(void)
{
	Dir *d;
	int i;

	for(i = 0; i < 20; i++){
		d = dirfstat(i);
		if(d != nil){
			fprint(2, "fd[%d]='%s' type=%c dev=%d user='******'%s'\n", i, d->name, d->type, d->dev, d->uid, d->gid);
			free(d);
		}
	}
}
Пример #21
0
static Srv*
srvAlloc(char* service, int mode, int fd)
{
	Dir *dir;
	Srv *srv;
	int srvfd;
	char *mntpnt;

	vtLock(sbox.lock);
	for(srv = sbox.head; srv != nil; srv = srv->next){
		if(strcmp(srv->service, service) != 0)
			continue;
		/*
		 * If the service exists, but is stale,
		 * free it up and let the name be reused.
		 */
		if((dir = dirfstat(srv->srvfd)) != nil){
			free(dir);
			vtSetError("srv: already serving '%s'", service);
			vtUnlock(sbox.lock);
			return nil;
		}
		srvFree(srv);
		break;
	}

	if((srvfd = srvFd(service, mode, fd, &mntpnt)) < 0){
		vtUnlock(sbox.lock);
		return nil;
	}
	close(fd);

	srv = vtMemAllocZ(sizeof(Srv));
	srv->srvfd = srvfd;
	srv->service = vtStrDup(service);
	srv->mntpnt = mntpnt;

	if(sbox.tail != nil){
		srv->prev = sbox.tail;
		sbox.tail->next = srv;
	}
	else{
		sbox.head = srv;
		srv->prev = nil;
	}
	sbox.tail = srv;
	vtUnlock(sbox.lock);

	return srv;
}
Пример #22
0
void
main(int argc, char *argv[]) {
	char *lockfile;
	int fd, ppid, ssize;
	struct Dir *statbuf;

	if (argc != 4) {
		fprint(2, "usage: LOCK lockfile hostname ppid\n");
		exits("lock failed on usage");
	}
	lockfile = argv[1];
	if ((fd=create(lockfile, ORDWR, DMEXCL|0666)) < 0) {
		exits("lock failed on create");
	}
	ppid = atoi(argv[3]);
	ssize = sprint(lockstring, "%s %s\n", argv[2], argv[3]);
	if (write(fd, lockstring, ssize) != ssize) {
		fprint(2, "LOCK:write(): %r\n");
		exits("lock failed on write to lockfile");
	}

	switch(fork()) {
	default:
		exits("");
	case 0:
		break;
	case -1:
		fprint(2, "LOCK:fork(): %r\n");
		exits("lock failed on fork");
	}

	for(;;) {
		statbuf = dirfstat(fd);
		if(statbuf == nil)
			break;
		if (statbuf->length == 0){
			free(statbuf);
			break;
		}
		free(statbuf);
		if (write(fd, "", 0) < 0)
			break;
		sleep(3000);
	}

	close(fd);
	postnote(PNGROUP, ppid, "kill");
	exits("");
}
Пример #23
0
int
updateQid(int fd, Qid *q)
{
	Dir *dir;
	Qid dq;

	dir = dirfstat(fd);
	if(dir == nil)
		sysfatal("can't dirfstat");
	dq = dir->qid;
	free(dir);
	if(q->path == dq.path && q->vers == dq.vers && q->type == dq.type)
		return 0;
	*q = dq;
	return 1;
}
Пример #24
0
static int
gunzip(int ofd, char *ofile, Biobuf *bin)
{
	Dir *d;
	GZHead h;
	int err;

	h.file = nil;
	gzok = 0;
	for(;;){
		if(Bgetc(bin) < 0)
			return 1;
		Bungetc(bin);

		if(setjmp(zjmp))
			return 0;
		header(bin, &h);
		gzok = 0;

		wlen = 0;
		crc = 0;

		if(!table && verbose)
			fprint(2, "extracting %s to %s\n", h.file, ofile);

		err = inflate((void*)ofd, crcwrite, bin, (int(*)(void*))Bgetc);
		if(err != FlateOk)
			error("inflate failed: %s", flateerr(err));

		trailer(bin, wlen);

		if(table){
			if(verbose)
				print("%-32s %10ld %s", h.file, wlen, ctime(h.mtime));
			else
				print("%s\n", h.file);
		}else if(settimes && h.mtime && (d=dirfstat(ofd)) != nil){
			d->mtime = h.mtime;
			dirfwstat(ofd, d);
			free(d);
		}

		free(h.file);
		h.file = nil;
		gzok = Boffset(bin);
	}
}
Пример #25
0
Файл: io.c Проект: bhanug/harvey
static String*
Brdstring(Biobuf *b)
{
	int32_t len;
	String *s;
	Dir *d;

	d = dirfstat(Bfildes(b));
	if (d == nil)	/* shouldn't happen, we just opened it */
		len = 0;
	else
		len = d->length;
	free(d);
	s = s_newalloc(len);
	s_read(b, s, len);
	return s;
}
Пример #26
0
void
sayhi(void)
{
	Dir *dp;

	reply("220-%s ESMTP\r\n", dom);
	sleep(3000);
	dp = dirfstat(0);
	if (dp && dp->length > 0) {
		syslog(0, "smtpd", "Hung up on impatient spammer %s", nci->rsys);
		if(Dflag)
			sleep(delaysecs()*1000);
		reply("554 5.7.0 Spammer!\r\n");
		exits("spammer didn't wait for greeting to finish");
	}
	free(dp);
	reply("220 \r\n");
}
Пример #27
0
static Disk*
openfile(Disk *disk)
{
	Dir *d;

	if((d = dirfstat(disk->fd)) == nil){
		free(disk);
		return nil;
	}

	disk->secsize = 512;
	disk->size = d->length;
	disk->secs = disk->size / disk->secsize;
	disk->offset = 0;
	free(d);

	findgeometry(disk);
	return mkwidth(disk);
}
Пример #28
0
/*
 *  return true if any part of the database has changed
 */
int
ndbchanged(Ndb *db)
{
	Ndb *ndb;
	Dir *d;

	for(ndb = db; ndb != nil; ndb = ndb->next){
		d = dirfstat(Bfildes(&ndb->b));
		if(d == nil)
			continue;
		if(ndb->qid.path != d->qid.path
		|| ndb->qid.vers != d->qid.vers){
			free(d);
			return 1;
		}
		free(d);
	}
	return 0;
}
Пример #29
0
Obj*
openobj(char *name)
{
	Dir *d;
	Obj *obj;

	obj = emalloc(sizeof *obj);
	obj->name = name;
	obj->version = version++;
	if((obj->fd = open(name, ORDWR)) < 0)
		sysfatal("open %s: %r", name);
	if((d = dirfstat(obj->fd)) == nil)
		sysfatal("dirfstat: %r");
	obj->bp = emalloc(d->length);
	if(readn(obj->fd, obj->bp, d->length) != d->length)
		sysfatal("read %s: %r", name);
	obj->ep = obj->bp+d->length;
	return obj;
}
Пример #30
0
/*
 *  dump any cached information, forget the hash tables, and reopen a single file
 */
int
ndbreopen(struct ndb *db)
{

	int fd;
	struct dir *d;

	/* forget what we know about the open files */
	if(db->isopen){
		_ndbcacheflush(db);
		hffree(db);
		fclose(db->b);
		db->mtime = 0;
		db->isopen = 0;
	}

	/* try the open again */
	db->b = fopen(db->file, "r");
	if(! db->b) {
		return -1;
	}
#if 0
	d = dirfstat(fd);
	if(d == NULL){
		close(fd);
		return -1;
	}

	db->qid.path = d->qid.path;
	db->mtime = d->mtime;
	db->length = d->length;
	free(d);
#else
	struct stat s;
	/* we opened it, this WILL work */
	stat(db->file, &s);
	db->qid.path = s.st_ino;
	db->mtime = s.st_mtime + 1;
	db->length = s.st_size;
#endif
	db->isopen = 1;
	return 0;
}