Beispiel #1
0
static void
rstat(Req *r, char *error)
{
	int n;
	uchar *statbuf;
	uchar tmp[BIT16SZ];

	if(error)
		return;
	if(convD2M(&r->d, tmp, BIT16SZ) != BIT16SZ){
		r->error = "convD2M(_,_,BIT16SZ) did not return BIT16SZ";
		return;
	}
	n = GBIT16(tmp)+BIT16SZ;
	statbuf = emalloc9p(n);
	if(statbuf == nil){
		r->error = "out of memory";
		return;
	}
	r->ofcall.nstat = convD2M(&r->d, statbuf, n);
	r->ofcall.stat = statbuf;	/* freed in closereq */
	if(r->ofcall.nstat <= BIT16SZ){
		r->error = "convD2M fails";
		free(statbuf);
		return;
	}
}
Beispiel #2
0
int
devstat(struct chan *c, uint8_t * db, int n,
        struct dirtab *tab, int ntab, Devgen * gen)
{
    int i;
    struct dir dir;
    char *p, *elem;

    dir.qid.path = 0;
    for (i = 0;; i++)
        switch ((*gen) (c, NULL, tab, ntab, i, &dir)) {
        case -1:
            if (c->qid.type & QTDIR) {
                printd("DEVSTAT got a dir: %llu\n", c->qid.path);
                if (c->name == NULL)
                    elem = "???";
                else if (strcmp(c->name->s, "/") == 0)
                    elem = "/";
                else
                    for (elem = p = c->name->s; *p; p++)
                        if (*p == '/')
                            elem = p + 1;
                devdir(c, c->qid, elem, 0, eve, DMDIR | 0555, &dir);
                n = convD2M(&dir, db, n);
                if (n == 0)
                    error(Ebadarg);
                return n;
            }
            printd("DEVSTAT fails:%c %llu\n", devtab[c->type].dc,
                   c->qid.path);
            set_errno(ENOENT);
            error(Enonexist);
        case 0:
            printd("DEVSTAT got 0\n");
            break;
        case 1:
            printd("DEVSTAT gen returns path %p name %s, want path %p\n",
                   dir.qid.path, dir.name, c->qid.path);
            if (c->qid.path == dir.qid.path) {
                if (c->flag & CMSG)
                    dir.mode |= DMMOUNT;
                n = convD2M(&dir, db, n);
                if (n == 0)
                    error(Ebadarg);
                return n;
            }
            break;
        }
}
Beispiel #3
0
__private_extern__ int
wstat_9p(mount_9p *nmp, fid_9p fid, dir_9p *dp)
{
	Fcall tx, rx;
	void *p;
	uint32_t n;
	int e, dotu;

	TRACE();
	dotu = ISSET(nmp->flags, F_DOTU);
	n = sizeD2M(dp, dotu);
	p = malloc_9p(n);
	if (p == NULL)
		return ENOMEM;
	
	if(convD2M(dp, p, n, dotu) != n){
		free_9p(p);
		return EINVAL;
	}
	tx.type = Twstat;
	tx.fid = fid;
	tx.stat = p;
	tx.nstat = n;
	e = rpc_9p(nmp, &tx, &rx, NULL);
	free_9p(p);

	return e;
}
Beispiel #4
0
/*
 *	Read a directory of IP addresses or account names
 */
int
hread(Fid *fidp, int cnt)
{
	uchar *q, *eq, *oq;
	int i, n, path;
	Address *p;
	Node *np;

	if(debugfd >= 0)
		fprint(debugfd, "hread %d\n", cnt);

	np = fidp->node;
	oq = q = rbuf+IOHDRSZ;
	eq = q+cnt;
	if(fidp->dirindex >= np->count)
		return 0;

	path = np->baseqid;
	for(i = fidp->dirindex; q < eq && i < np->count; i++){
		p = &np->addrs[i];
		dummy.d.name = p->name;
		dummy.d.qid.path = path++;
		if((n=convD2M(&dummy.d, q, eq-q)) <= BIT16SZ)
			break;
		q += n;
	}
	fidp->dirindex = i;
	return q - oq;
}
Beispiel #5
0
void
dirread9p(Req *r, Dirgen *gen, void *aux)
{
	int start;
	uchar *p, *ep;
	uint rv;
	Dir d;

	if(r->ifcall.offset == 0)
		start = 0;
	else
		start = r->fid->dirindex;

	p = (uchar*)r->ofcall.data;
	ep = p+r->ifcall.count;

	while(p < ep){
		memset(&d, 0, sizeof d);
		if((*gen)(start, &d, aux) < 0)
			break;
		rv = convD2M(&d, p, ep-p);
		free(d.name);
		free(d.muid);
		free(d.uid);
		free(d.gid);
		if(rv <= BIT16SZ)
			break;
		p += rv;
		start++;
	}
	r->fid->dirindex = start;
	r->ofcall.count = p - (uchar*)r->ofcall.data;
}
Beispiel #6
0
long
devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen)
{
	long m, dsz;
	struct{
		Dir d;
		char slop[100];
	}dir;

	for(m=0; m<n; c->dri++) {
		switch((*gen)(c, nil, tab, ntab, c->dri, &dir.d)){
		case -1:
			return m;

		case 0:
			break;

		case 1:
			dsz = convD2M(&dir.d, (uchar*)d, n-m);
			if(dsz <= BIT16SZ){	/* <= not < because this isn't stat; read is stuck */
				if(m == 0)
					error(Eshort);
				return m;
			}
			m += dsz;
			d += dsz;
			break;
		}
	}

	return m;
}
Beispiel #7
0
/*
 *	Read a directory
 */
int
dread(Fid *fidp, int cnt)
{
	uchar *q, *eq, *oq;
	int n, skip;
	Node *np;

	if(debugfd >= 0)
		fprint(debugfd, "dread %d\n", cnt);

	np = fidp->node;
	oq = q = rbuf+IOHDRSZ;
	eq = q+cnt;
	if(fidp->dirindex >= np->count)
		return 0;

	skip = fidp->dirindex;
	for(np = np->children; skip > 0 && np; np = np->sibs)
		skip--;
	if(np == 0)
		return 0;

	for(; q < eq && np; np = np->sibs){
		if(debugfd >= 0)
			printnode(np);
		if((n=convD2M(&np->d, q, eq-q)) <= BIT16SZ)
			break;
		q += n;
		fidp->dirindex++;
	}
	return q - oq;
}
Beispiel #8
0
int32_t
devdirread(Chan *c, char *d, int32_t n, Dirtab *tab, int ntab,
	   Devgen *gen)
{
	if (0) print_func_entry();
	int32_t m, dsz;
	Dir dir;

	for(m=0; m<n; c->dri++) {
		switch((*gen)(c, nil, tab, ntab, c->dri, &dir)){
		case -1:
			if (0) print_func_exit();
			return m;

		case 0:
			break;

		case 1:
			dsz = convD2M(&dir, (uint8_t*)d, n-m);
			if(dsz <= BIT16SZ){	/* <= not < because this isn't stat; read is stuck */
				if(m == 0)
					error(Eshort);
				if (0) print_func_exit();
				return m;
			}
			m += dsz;
			d += dsz;
			break;
		}
	}

	if (0) print_func_exit();
	return m;
}
Beispiel #9
0
static int
cmd9pTwstat(Fcall* f, int, char **argv)
{
	Dir d;
	static uchar buf[DIRMAX];

	memset(&d, 0, sizeof d);
	nulldir(&d);
	d.name = argv[1];
	d.uid = argv[2];
	d.gid = argv[3];
	d.mode = cmd9pStrtoul(argv[4]);
	d.mtime = cmd9pStrtoul(argv[5]);
	d.length = cmd9pStrtoull(argv[6]);

	f->fid = strtol(argv[0], 0, 0);
	f->stat = buf;
	f->nstat = convD2M(&d, buf, sizeof buf);
	if(f->nstat < BIT16SZ){
		vtSetError("Twstat: convD2M failed (internal error)");
		return 0;
	}

	return 1;
}
Beispiel #10
0
void
fsstat(Fs *fs, Request *r, Fid *f)
{
	char err[ERRMAX];
	Dir d;
	Symbol *dp;
	int n;
	uchar statbuf[Nstat];

	if(f->qid.type & QTDIR)
		n = stat(f->path, statbuf, sizeof statbuf);
	else {
		dp = f->dp;
		d.name = dp->sym;
		d.uid = "none";
		d.gid = "none";
		d.muid = "none";
		d.qid.type = QTFILE;
		d.qid.path = (uvlong)dp;
		d.qid.vers = 0;
		d.length = f->df->file[dp->fno].tarlen;
		d.mode = 0444;
		d.mtime = time(nil);
		d.atime = time(nil);
		n = convD2M(&d, statbuf, sizeof statbuf);
	}
	if(n <= BIT16SZ){
		errstr(err, sizeof err);
		fsreply(fs, r, err);
	} else {
		r->f.stat = statbuf;
		r->f.nstat = n;
		fsreply(fs, r, nil);
	}
}
Beispiel #11
0
static void
rread(Fcall* f)
{
	ulong	n, rn, nn, delta;
	Dir	d;
	Fid*	fp;

	if (!isfdir(f, &fp))
		return;
	if (f->count == 0)
		goto done;
	cleannames();
	for (n = nn = 0; n < f->count; n += rn){
		rn = convM2D((uchar*)f->data + n, f->count - n, &d, statbuf);
		if (rn <= BIT16SZ)
			break;
		d.name = importname(d.name);
		//dprint("⇒ %D\n", &d);
		nn += convD2M(&d, (uchar*)dirbuf + nn, sizeof(dirbuf) - nn);
	}
	delta = nn - n;
	setaux(fp, getaux(fp) + delta);
	f->count = nn;
	f->data = dirbuf;
done:
	closefid(fp);
}
Beispiel #12
0
static int
fsstat(Chan *c, uchar *buf, int n)
{
	Dir d;
	char *path;
	UnixFd *ufd;

	ufd = c->aux;
	if(Trace)
		print("fsstat %s\n", ufd->path->s);

	if(n < BIT16SZ)
		error(Eshortstat);

	path = fspath(c, nil);
	if(fsdirstat(path, c->dev, &d) < 0){
		free(path);
		oserror();
	}
	if(strcmp(ufd->path->s, "/") == 0)
		d.name = "/";
	n = convD2M(&d, buf, n);
	free(path);
	return n;
}
Beispiel #13
0
static int
pipestat(Chan *c, uchar *db, int n)
{
	Pipe *p;
	Dir dir;

	p = c->aux;

	switch(NETTYPE(c->qid.path)){
	case Qdir:
		devdir(c, c->qid, ".", 0, eve, DMDIR|0555, &dir);
		break;
	case Qdata0:
		devdir(c, c->qid, "data", qlen(p->q[0]), eve, p->perm, &dir);
		break;
	case Qdata1:
		devdir(c, c->qid, "data1", qlen(p->q[1]), eve, p->perm, &dir);
		break;
	default:
		panic("pipestat");
	}
	n = convD2M(&dir, db, n);
	if(n < BIT16SZ)
		error(Eshortstat);
	return n;
}
Beispiel #14
0
static int pipestat(struct chan *c, uint8_t * db, int n)
{
	Pipe *p;
	struct dir dir;
	struct dirtab *tab;
	int perm;

	p = c->aux;
	tab = p->pipedir;

	switch (NETTYPE(c->qid.path)) {
		case Qdir:
			devdir(c, c->qid, ".", 0, eve, DMDIR | 0555, &dir);
			break;
		case Qdata0:
			perm = tab[1].perm;
			perm |= qreadable(p->q[0]) ? DMREADABLE : 0;
			perm |= qwritable(p->q[0]) ? DMWRITABLE : 0;
			devdir(c, c->qid, tab[1].name, qlen(p->q[0]), eve, perm, &dir);
			break;
		case Qdata1:
			perm = tab[2].perm;
			perm |= qreadable(p->q[1]) ? DMREADABLE : 0;
			perm |= qwritable(p->q[1]) ? DMWRITABLE : 0;
			devdir(c, c->qid, tab[2].name, qlen(p->q[1]), eve, perm, &dir);
			break;
		default:
			panic("pipestat");
	}
	n = convD2M(&dir, db, n);
	if (n < BIT16SZ)
		error(ENODATA, ERROR_FIXME);
	return n;
}
Beispiel #15
0
int32_t
devstat(Chan *c, uint8_t *db, int32_t n, Dirtab *tab, int ntab,
	Devgen *gen)
{
	if (0) print_func_entry();
	int i;
	Dir dir;
	char *p, *elem;

	for(i=0;; i++){
		switch((*gen)(c, nil, tab, ntab, i, &dir)){
		case -1:
			if(c->qid.type & QTDIR){
				if(c->path == nil)
					elem = "???";
				else if(strcmp(c->path->s, "/") == 0)
					elem = "/";
				else
					for(elem=p=c->path->s; *p; p++)
						if(*p == '/')
							elem = p+1;
				devdir(c, c->qid, elem, 0, eve, DMDIR|0555, &dir);
				n = convD2M(&dir, db, n);
				if(n == 0)
					error(Ebadarg);
				if (0) print_func_exit();
				return n;
			}

			error(Enonexist);
		case 0:
			break;
		case 1:
			if(c->qid.path == dir.qid.path) {
				if(c->flag&CMSG)
					dir.mode |= DMMOUNT;
				n = convD2M(&dir, db, n);
				if(n == 0)
					error(Ebadarg);
				if (0) print_func_exit();
				return n;
			}
			break;
		}
	}
	if (0) print_func_exit();
}
Beispiel #16
0
int
devstat(Chan *c, uchar *db, int n, Dirtab *tab, int ntab, Devgen *gen)
{
	int i;
	Dir dir;
	char *p, *elem;

	for(i=0;; i++)
		switch((*gen)(c, nil, tab, ntab, i, &dir)){
		case -1:
			if(c->qid.type & QTDIR){
				if(c->name == nil)
					elem = "???";
				else if(strcmp(c->name->s, "/") == 0)
					elem = "/";
				else
					for(elem=p=c->name->s; *p; p++)
						if(*p == '/')
							elem = p+1;
				devdir(c, c->qid, elem, 0, eve, DMDIR|0555, &dir);
				n = convD2M(&dir, db, n);
				if(n == 0)
					error(Ebadarg);
				return n;
			}
			print("devstat %C %llux\n", devtab[c->type]->dc, c->qid.path);

			error(Enonexist);
		case 0:
			break;
		case 1:
			if(c->qid.path == dir.qid.path) {
				if(c->flag&CMSG)
					dir.mode |= DMMOUNT;
				n = convD2M(&dir, db, n);
				if(n == 0)
					error(Ebadarg);
				return n;
			}
			break;
		}
	error(Egreg);	/* not reached? */
	return -1;
}
Beispiel #17
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;
}
Beispiel #18
0
static long
fsdirread(Chan *c, uchar *va, long count, vlong offset)
{
	char *path;
	int n, total;
	struct dirent *de;
	UnixFd *ufd;
	Dir d;

	ufd = c->aux;
	qlock(&ufd->dirlock);
	if(waserror()){
		qunlock(&ufd->dirlock);
		nexterror();
	}

	if(ufd->diroffset != offset){
		if(offset != 0)
			error(Ebadarg);
		ufd->diroffset = 0;
		ufd->nextde = nil;
		rewinddir(ufd->dir);
	}

	total = 0;
	while(total+BIT16SZ < count) {
		if(ufd->nextde){
			de = ufd->nextde;
			ufd->nextde = nil;
		}
		else if((de = readdir(ufd->dir)) == nil)
			break;
		if(isdots(de->d_name))
			continue;
		path = fspath(c, de->d_name);
		if(fsdirstat(path, c->dev, &d) < 0){
			free(path);
			continue;
		}
		n = convD2M(&d, (uchar*)va+total, count-total);
		free(path);
		if(n == BIT16SZ){
			ufd->nextde = de;
			break;
		}
		total += n;
	}
	ufd->diroffset += total;
	qunlock(&ufd->dirlock);
	poperror();
	return total;
}
Beispiel #19
0
static void
rstat(Fcall* f)
{
	Dir	d;

	cleannames();
	convM2D(f->stat, f->nstat, &d, statbuf);
	d.name = importname(d.name);
	f->nstat = convD2M(&d, (uchar*)dirbuf, sizeof(dirbuf));
	f->stat = (uchar*)dirbuf;
	if (statcheck(f->stat, f->nstat) < 0)
		dprint("stat fails\n");
}
Beispiel #20
0
static void
twstat(Fcall* f)
{
	Dir	d;

	cleannames();
	if (convM2D(f->stat, f->nstat, &d, statbuf) <= BIT16SZ)
		return;
	d.name = exportname(d.name);
	f->nstat = convD2M(&d, (uchar*)dirbuf, sizeof(dirbuf));
	f->stat = (uchar*)dirbuf;
	if (statcheck(f->stat, f->nstat) < 0)
		dprint("stat fails\n");
}
Beispiel #21
0
void
rread(Job *job, Mfile *mf)
{
	int i, n;
	long clock;
	ulong cnt;
	vlong off;
	char *err;
	uchar buf[Maxfdata];
	Dir dir;

	n = 0;
	err = nil;
	off = job->request.offset;
	cnt = job->request.count;
	*buf = '\0';
	job->reply.data = (char*)buf;
	if(mf->qid.type & QTDIR){
		clock = time(nil);
		if(off == 0){
			memset(&dir, 0, sizeof dir);
			dir.name = "dns";
			dir.qid.type = QTFILE;
			dir.qid.vers = vers;
			dir.qid.path = Qdns;
			dir.mode = 0666;
			dir.length = 0;
			dir.uid = dir.gid = dir.muid = mf->user;
			dir.atime = dir.mtime = clock;		/* wrong */
			n = convD2M(&dir, buf, sizeof buf);
		}
	} else if (off < 0)
		err = "negative read offset";
	else {
		/* first offset will always be zero */
		for(i = 1; i <= mf->nrr; i++)
			if(mf->rr[i] > off)
				break;
		if(i <= mf->nrr) {
			if(off + cnt > mf->rr[i])
				n = mf->rr[i] - off;
			else
				n = cnt;
			assert(n >= 0);
			job->reply.data = mf->reply + off;
		}
	}
	job->reply.count = n;
	sendmsg(job, err);
}
Beispiel #22
0
int
dirwstat(char *name, Dir *d)
{
	uchar *buf;
	int r;

	r = sizeD2M(d);
	buf = malloc(r);
	if(buf == nil)
		return -1;
	convD2M(d, buf, r);
	r = wstat(name, buf, r);
	free(buf);
	return r;
}
Beispiel #23
0
int32_t
readdirfile(Readdir *r, uint8_t *buf, int32_t n)
{
	int32_t x, m;
	Filelist *fl;

	for(fl=r->fl, m=0; fl && m+2<=n; fl=fl->link, m+=x){
		if(fl->f == nil)
			x = 0;
		else if((x=convD2M(&fl->f->Dir, buf+m, n-m)) <= BIT16SZ)
			break;
	}
	r->fl = fl;
	return m;
}
Beispiel #24
0
void
rstat(void)
{
	Xfile *f;
	Dir dir;

	chat("stat(fid=%d)...", req->fid);
	f=xfile(req->fid, Asis);
	setnames(&dir, fdata);
	(*f->xf->s->stat)(f, &dir);
	if(chatty)
		showdir(2, &dir);
	rep->nstat = convD2M(&dir, statbuf, sizeof statbuf);
	rep->stat = statbuf;
}
Beispiel #25
0
int
dirfwstat(int fd, Dir *d)
{
	uint8_t *buf;
	int r;

	r = sizeD2M(d);
	buf = malloc(r);
	if(buf == nil)
		return -1;
	convD2M(d, buf, r);
	r = fwstat(fd, buf, r);
	free(buf);
	return r;
}
Beispiel #26
0
static int
fsstat(Chan *c, uchar *buf, int n)
{
	Dir d;
	Ufsinfo *uif;

	if(n < BIT16SZ)
		error(Eshortstat);
	uif = c->aux;
	d.name = lastelem(c);
	wfdtodir(uif->path, &d, nil);
	d.type = 'U';
	d.dev = c->dev;
	return convD2M(&d, buf, n);
}
Beispiel #27
0
static void
rstat(Fcall *f)
{
    Fid *fidp;

    fidp = newfid(f->fid);
    if (fidp->node->d.type == Dummynode)
        dummy.d.name = fidp->name;
    f->stat = (uchar*)rbuf+4+1+2+2;	/* knows about stat(5) */
    f->nstat = convD2M(&fidp->node->d, f->stat, MAXRPC);
    if(f->nstat <= BIT16SZ)
        reply(f, "ratfs: convD2M");
    else
        reply(f, 0);
    return;
}
Beispiel #28
0
int
ramstat(Ram *r, uchar *buf, int nbuf)
{
	Dir dir;

	dir.name = r->name;
	dir.qid = r->qid;
	dir.mode = r->perm;
	dir.length = r->ndata;
	dir.uid = r->user;
	dir.gid = r->group;
	dir.muid = r->user;
	dir.atime = r->atime;
	dir.mtime = r->mtime;
	return convD2M(&dir, buf, nbuf);
}
Beispiel #29
0
void
rread(Job *job, Mfile *mf)
{
	int i, n, cnt;
	long off;
	Dir dir;
	uchar buf[Maxfdata];
	char *err;
	long clock;

	n = 0;
	err = 0;
	off = job->request.offset;
	cnt = job->request.count;
	if(mf->qid.type & QTDIR){
		clock = time(0);
		if(off == 0){
			dir.name = "dns";
			dir.qid.type = QTFILE;
			dir.qid.vers = vers;
			dir.qid.path = Qdns;
			dir.mode = 0666;
			dir.length = 0;
			dir.uid = mf->user;
			dir.gid = mf->user;
			dir.muid = mf->user;
			dir.atime = clock;	/* wrong */
			dir.mtime = clock;	/* wrong */
			n = convD2M(&dir, buf, sizeof buf);
		}
		job->reply.data = (char*)buf;
	} else {
		for(i = 1; i <= mf->nrr; i++)
			if(mf->rr[i] > off)
				break;
		if(i > mf->nrr)
			goto send;
		if(off + cnt > mf->rr[i])
			n = mf->rr[i] - off;
		else
			n = cnt;
		job->reply.data = mf->reply + off;
	}
send:
	job->reply.count = n;
	sendmsg(job, err);
}
Beispiel #30
0
int
dostat(int id, Dirtab *dir, uint8_t *buf, int nbuf, uint clock)
{
    Dir d;

    d.qid.path = QID(id, dir->qid);
    d.qid.vers = 0;
    d.qid.type = dir->type;
    d.mode = dir->perm;
    d.length = 0;	/* would be nice to do better */
    d.name = dir->name;
    d.uid = user;
    d.gid = user;
    d.muid = user;
    d.atime = clock;
    d.mtime = clock;
    return convD2M(&d, buf, nbuf);
}