Esempio n. 1
0
static int
dirfixed(uchar *p, uchar *e, Dir *d)
{
	int len;

	len = GBIT16(p)+BIT16SZ;
	if(p + len > e)
		return -1;

	p += BIT16SZ;	/* ignore size */
	d->type = devno(GBIT16(p), 1);
	p += BIT16SZ;
	d->dev = GBIT32(p);
	p += BIT32SZ;
	d->qid.type = GBIT8(p);
	p += BIT8SZ;
	d->qid.vers = GBIT32(p);
	p += BIT32SZ;
	d->qid.path = GBIT64(p);
	p += BIT64SZ;
	d->mode = GBIT32(p);
	p += BIT32SZ;
	d->atime = GBIT32(p);
	p += BIT32SZ;
	d->mtime = GBIT32(p);
	p += BIT32SZ;
	d->length = GBIT64(p);

	return len;
}
Esempio n. 2
0
static int
dirpackage(uint8_t *buf, int ts, Dir **d, uint32_t *nd, int dotu)
{
	char *s;
	int ss, i, n, nn;
	uint m;
	
	*d = nil;
	*nd = 0;
	if(ts <= 0) 
		return 0;

	/*
	 * first find number of all stats, check they look like stats, & size all associated strings
	 */
	ss = 0;
	n = 0;
	for(i = 0; i < ts; i += m){
		m = BIT16SZ + GBIT16(&buf[i]);
		if(statcheck(&buf[i], m, dotu) < 0)
			break;
		ss += m;
		n++;
	}

	if(i != ts) {
		DEBUG("statcheck");
		return EBADRPC;
	}
	
	*d = malloc_9p(n * sizeof(Dir) + ss);
	if (*d == NULL)
		return ENOMEM;
	/*
	 * then convert all buffers
	 */
	s = (char*)*d + n * sizeof(Dir);
	nn = 0;
	for(i = 0; i < ts; i += m){
		m = BIT16SZ + GBIT16(&buf[i]);
		if(nn >= n || convM2D(&buf[i], m, *d + nn, s, dotu) != m){
			free_9p(*d);
			*d = nil;
			DEBUG("convM2D");
			return EBADRPC;
		}
		nn++;
		s += m;
	}
	*nd = nn;
	return 0;
}
Esempio n. 3
0
static
long
dirpackage(uchar *buf, long ts, Dir **d)
{
	char *s;
	long ss, i, n, nn, m;

	*d = nil;
	if(ts <= 0)
		return 0;

	/*
	 * first find number of all stats, check they look like stats, & size all associated strings
	 */
	ss = 0;
	n = 0;
	for(i = 0; i < ts; i += m){
		m = BIT16SZ + GBIT16(&buf[i]);
		if(statcheck(&buf[i], m) < 0)
			break;
		ss += m;
		n++;
	}

	if(i != ts)
		return -1;

	*d = malloc(n * sizeof(Dir) + ss);
	if(*d == nil)
		return -1;

	/*
	 * then convert all buffers
	 */
	s = (char*)*d + n * sizeof(Dir);
	nn = 0;
	for(i = 0; i < ts; i += m){
		m = BIT16SZ + GBIT16((uchar*)&buf[i]);
		if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){
			free(*d);
			*d = nil;
			return -1;
		}
		nn++;
		s += m;
	}

	return nn;
}
Esempio n. 4
0
File: srv.c Progetto: 99years/plan9
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;
	}
}
Esempio n. 5
0
Dir*
dirfstat(int fd)
{
	Dir *d;
	uint8_t *buf;
	int n, nd, i;

	nd = DIRSIZE;
	for(i=0; i<2; i++){	/* should work by the second try */
		d = malloc(sizeof(Dir) + BIT16SZ + nd);
		if(d == nil)
			return nil;
		buf = (uint8_t*)&d[1];
		n = fstat(fd, buf, BIT16SZ+nd);
		if(n < BIT16SZ){
			free(d);
			return nil;
		}
		nd = GBIT16(buf);	/* upper bound on size of Dir + strings */
		if(nd <= n){
			convM2D(buf, n, d, (char*)&d[1]);
			return d;
		}
		/* else sizeof(Dir)+BIT16SZ+nd is plenty */
		free(d);
	}
	return nil;
}
Esempio n. 6
0
/*
 * Mountfix might have caused the fixed results of the directory read
 * to overflow the buffer.  Catch the overflow in c->dirrock.
 */
static void
mountrock(Chan *c, uint8_t *p, uint8_t **pe)
{
	uint8_t *e, *r;
	int len, n;

	e = *pe;

	/* find last directory entry */
	for(;;){
		len = BIT16SZ+GBIT16(p);
		if(p+len >= e)
			break;
		p += len;
	}

	/* save it away */
	qlock(&c->rockqlock);
	if(c->nrock+len > c->mrock){
		n = ROUNDUP(c->nrock+len, 1024);
		r = smalloc(n);
		memmove(r, c->dirrock, c->nrock);
		free(c->dirrock);
		c->dirrock = r;
		c->mrock = n;
	}
	memmove(c->dirrock+c->nrock, p, len);
	c->nrock += len;
	qunlock(&c->rockqlock);

	/* drop it */
	*pe = p;
}
Esempio n. 7
0
void
validstat(uint8_t *s, usize n)
{
	usize m;
	char buf[64];

	if(statcheck(s, n) < 0)
		error(Ebadstat);
	/* verify that name entry is acceptable */
	s += STATFIXLEN - 4*BIT16SZ;	/* location of first string */
	/*
	 * s now points at count for first string.
	 * if it's too long, let the server decide; this is
	 * only for his protection anyway. otherwise
	 * we'd have to allocate and waserror.
	 */
	m = GBIT16(s);
	s += BIT16SZ;
	if(m+1 > sizeof buf)
		return;
	memmove(buf, s, m);
	buf[m] = '\0';
	/* name could be '/' */
	if(strcmp(buf, "/") != 0)
		validname(buf, 0);
}
Esempio n. 8
0
Dir*
_dirfstat(int fd)
{
	Dir *d;
	uint8_t *buf;
	int n, nd, i;

	nd = DIRSIZE;
	for(i=0; i<2; i++){	/* should work by the second try */
		d = malloc(sizeof(Dir) + nd);
		if(d == nil)
			return nil;
		buf = (uint8_t*)&d[1];
		n = _FSTAT(fd, buf, nd);
		if(n < BIT16SZ){
			free(d);
			return nil;
		}
		nd = GBIT16(buf);	/* size needed to store whole stat buffer */
		if(nd <= n){
			_convM2D(buf, n, d, (char*)&d[1]);
			return d;
		}
		/* else sizeof(Dir)+nd is plenty */
		free(d);
	}
	return nil;
}
Esempio n. 9
0
__private_extern__ int
stat_9p(mount_9p *nmp, fid_9p fid, dir_9p **dpp)
{
	Fcall tx, rx;
	Dir *dp;
	void *p;
	int e, n;
	
	TRACE();
	p = NULL;
	dp = NULL;
	tx.type = Tstat;
	tx.fid = fid;
	if ((e=rpc_9p(nmp, &tx, &rx, &p)))
		return e;

	n = GBIT16((uint8_t*)p);
	dp = malloc_9p(sizeof(Dir) + BIT16SZ + n);
	if (dp == NULL) {
		e = ENOMEM;
		goto error;
	}

	if(convM2D(rx.stat, rx.nstat, dp, (char*)&dp[1], ISSET(nmp->flags, F_DOTU)) != rx.nstat) {
		DEBUG("convM2D");
		e = EBADRPC;
		goto error;
	}

error:
	free_9p(p);
	*dpp = dp;
	return e;
}
Esempio n. 10
0
static char*
dirname(uchar *p, int *n)
{
	p += BIT16SZ+BIT16SZ+BIT32SZ+BIT8SZ+BIT32SZ+BIT64SZ
		+ BIT32SZ+BIT32SZ+BIT32SZ+BIT64SZ;
	*n = GBIT16(p);
	return (char*)p+BIT16SZ;
}
Esempio n. 11
0
static char*
dirname(uint8_t *p, usize *n)
{
	p += BIT16SZ+BIT16SZ+BIT32SZ+BIT8SZ+BIT32SZ+BIT64SZ
		+ BIT32SZ+BIT32SZ+BIT32SZ+BIT64SZ;
	*n = GBIT16(p);

	return (char*)p+BIT16SZ;
}
Esempio n. 12
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. 13
0
static usize
dirfixed(uint8_t *p, uint8_t *e, Dir *d)
{
	int len;
	Dev *dev;

	len = GBIT16(p)+BIT16SZ;
	if(p + len > e)
		return 0;

	p += BIT16SZ;	/* ignore size */
	dev = devtabget(GBIT16(p), 1);			//XDYNX
	if(dev != nil){
		d->type = dev->dc;
		//devtabdecr(dev);
	}
	else
		d->type = -1;
	p += BIT16SZ;
	d->dev = GBIT32(p);
	p += BIT32SZ;
	d->qid.type = GBIT8(p);
	p += BIT8SZ;
	d->qid.vers = GBIT32(p);
	p += BIT32SZ;
	d->qid.path = GBIT64(p);
	p += BIT64SZ;
	d->mode = GBIT32(p);
	p += BIT32SZ;
	d->atime = GBIT32(p);
	p += BIT32SZ;
	d->mtime = GBIT32(p);
	p += BIT32SZ;
	d->length = GBIT64(p);

	return len;
}
Esempio n. 14
0
unsigned int convM2kstat(uint8_t * buf, unsigned int nbuf, struct kstat *ks)
{
	uint8_t *p, *ebuf;
	char *sv[4];
	int i, ns;
	uint32_t junk;

	if (nbuf < STATFIXLEN)
		return 0;

	p = buf;
	ebuf = buf + nbuf;

	p += BIT16SZ;	/* ignore size */
	junk /*kd->d_type */  = GBIT16(p);
	p += BIT16SZ;
	ks->st_rdev = ks->st_dev = GBIT32(p);
	p += BIT32SZ;
	junk /*qid.type */  = GBIT8(p);
	p += BIT8SZ;
	junk /*qid.vers */  = GBIT32(p);
	p += BIT32SZ;
	ks->st_ino = GBIT64(p);
	p += BIT64SZ;
	ks->st_mode = GBIT32(p);
	if (ks->st_mode & DMDIR) {
		ks->st_mode &= ~DMDIR;
		ks->st_mode |= __S_IFDIR;
	} else if (ks->st_mode & DMSYMLINK) {
		ks->st_mode &= ~DMSYMLINK;
		ks->st_mode |= __S_IFLNK;
	} else {
		ks->st_mode |= __S_IFREG;
	}
	p += BIT32SZ;
	ks->st_atime.tv_sec = GBIT32(p);
	p += BIT32SZ;
	ks->st_mtime.tv_sec = GBIT32(p);
	p += BIT32SZ;
	ks->st_size = GBIT64(p);
	p += BIT64SZ;
	ks->st_blksize = 512;
	ks->st_blocks = ROUNDUP(ks->st_size, ks->st_blksize) / ks->st_blksize;

	ks->st_nlink = 2;	// links make no sense any more. 
	ks->st_uid = ks->st_gid = 0;

	return p - buf;
}
Esempio n. 15
0
int
statcheck(uchar *buf, uint nbuf)
{
	uchar *ebuf;
	int i;

	ebuf = buf + nbuf;

	if(nbuf < STATFIXLEN || nbuf != BIT16SZ + GBIT16(buf))
		return -1;

	buf += STATFIXLEN - 4 * BIT16SZ;

	for(i = 0; i < 4; i++){
		if(buf + BIT16SZ > ebuf)
			return -1;
		buf += BIT16SZ + GBIT16(buf);
	}

	if(buf != ebuf)
		return -1;

	return 0;
}
Esempio n. 16
0
void
inputthread(void *arg)
{
	uchar *pkt;
	int n, nn, tag;
	Msg *m;
	Ioproc *io;

	threadsetname("input");
	if(verbose) fprint(2, "%T input thread\n");
	io = ioproc();
	USED(arg);
	while((pkt = read9ppkt(io, 0)) != nil){
		n = GBIT32(pkt);
		if(n < 7){
			fprint(2, "%T short 9P packet from server\n");
			free(pkt);
			continue;
		}
		if(verbose > 2) fprint(2, "%T read %.*H\n", n, pkt);
		tag = GBIT16(pkt+5);
		if((m = msgget(tag)) == nil){
			fprint(2, "%T unexpected 9P response tag %d\n", tag);
			free(pkt);
			continue;
		}
		if((nn = convM2S(pkt, n, &m->rx)) != n){
			fprint(2, "%T bad packet - convM2S %d but %d\n", nn, n);
			free(pkt);
			msgput(m);
			continue;
		}
		if(verbose > 1) fprint(2, "%T * -> %F%s\n", &m->rx,
			m->internal ? " (internal)" : "");
		m->rpkt = pkt;
		m->rx.tag = m->ctag;
		if(m->internal)
			sendp(m->c->internal, m);
		else if(m->c->outq)
			sendq(m->c->outq, m);
		else
			msgput(m);
	}
	closeioproc(io);
	/*fprint(2, "%T input eof\n"); */
	threadexitsall(0);
}
Esempio n. 17
0
static u8* gstring(u8 *p, u8 *ep, char **s)
{
	u16 n;

	if(p+BIT16SZ > ep)
		return nil;
	n = GBIT16(p);
	p += BIT16SZ - 1;
	if(p+n+1 > ep)
		return nil;
	/* move it down, on top of count, to make room for '\0' */
	memmove(p, p + 1, n);
	p[n] = '\0';
	*s = (char*)p;
	p += n+1;
	return p;
}
Esempio n. 18
0
static int
readmsg(Chan *c, void *abuf, int n, int *ninep)
{
	int fd, len;
	uint8_t *buf;

	buf = abuf;
	fd = c->chan;
	qlock(&c->rlock);
	if(readn(fd, buf, 3) != 3){
		qunlock(&c->rlock);
		print("readn(3) fails: %r\n");
		return -1;
	}
	if((50 <= buf[0] && buf[0] <= 87 && (buf[0]&1)==0 && GBIT16(buf+1) == 0xFFFF)
	|| buf[0] == 86	/* Tattach */){
		*ninep = 1;
		/* assume message boundaries */
		n = read(fd, buf+3, n-3);
		if(n < 0){
			qunlock(&c->rlock);
			return -1;
		}
		return n+3;
	}

	*ninep = 2;
	if(read(fd, buf+3, 1) != 1){
		qunlock(&c->rlock);
		print("read(1) fails: %r\n");
		return -1;
	}
	len = GBIT32(buf);
	if(len > n){
		print("msg too large\n");
		qunlock(&c->rlock);
		return -1;
	}
	if(readn(fd, buf+4, len-4) != len-4){
		print("readn(%d) fails: %r\n", len-4);
		qunlock(&c->rlock);
		return -1;
	}
	qunlock(&c->rlock);
	return len;
}
Esempio n. 19
0
static
uint8_t *gstring(uint8_t * p, uint8_t * ep, char **s)
{
	unsigned int n;

	if (p + BIT16SZ > ep)
		return NULL;
	n = GBIT16(p);
	p += BIT16SZ - 1;
	if (p + n + 1 > ep)
		return NULL;
	/* move it down, on top of count, to make room for '\0' */
	memmove(p, p + 1, n);
	p[n] = '\0';
	*s = (char *)p;
	p += n + 1;
	return p;
}
Esempio n. 20
0
static uchar*
gstring(uchar *p, uchar *ep, char **s)
{
	uint n;

	if(p == nil)
		return nil;
	if(p+BIT16SZ > ep)
		return nil;
	n = GBIT16(p);
	p += BIT16SZ;
	if(p+n > ep)
		return nil;
	*s = malloc(n+1);
	memmove((*s), p, n);
	(*s)[n] = '\0';
	p += n;
	return p;
}
Esempio n. 21
0
int
logfsgn(uchar **pp, uchar *mep, char **v)
{
	uchar *p = *pp;
	int l;
	if(p + BIT16SZ > mep)
		return 0;
	l = GBIT16(p); p += BIT16SZ;
	if(p + l > mep)
		return 0;
	*pp = p + l;
	if(l == 0) {
		*v = 0;
		return 1;
	}
	*v = (char *)(p - 1);
	memmove(p - 1, p, l);
	p[l - 1] = 0;
	return 1;
}
Esempio n. 22
0
static uchar*
gcarray(uchar *p, uchar *ep, uchar **s, int *np)
{
	uint n;

	if(p == nil)
		return nil;
	if(p+BIT16SZ > ep)
		return nil;
	n = GBIT16(p);
	p += BIT16SZ;
	if(p+n > ep)
		return nil;
	*s = malloc(n);
	if(*s == nil)
		return nil;
	memmove((*s), p, n);
	*np = n;
	p += n;
	return p;
}
Esempio n. 23
0
File: dirread.c Progetto: sevki/apex
static int
statcheck(char *buf, uint32_t nbuf)
{
	char *ebuf;
	int i;

	ebuf = buf + nbuf;

	buf += STATFIXLEN - 4 * BIT16SZ;

	for(i = 0; i < 4; i++){
		if(buf + BIT16SZ > ebuf)
			return -1;
		buf += BIT16SZ + GBIT16(buf);
	}

	if(buf != ebuf)
		return -1;

	return 0;
}
Esempio n. 24
0
/*
 * Satisfy a directory read with the results saved in c->dirrock.
 */
static int
mountrockread(Chan *c, uint8_t *op, int32_t n, int32_t *nn)
{
	int32_t dirlen;
	uint8_t *rp, *erp, *ep, *p;

	/* common case */
	if(c->nrock == 0)
		return 0;

	/* copy out what we can */
	qlock(&c->rockqlock);
	rp = c->dirrock;
	erp = rp+c->nrock;
	p = op;
	ep = p+n;
	while(rp+BIT16SZ <= erp){
		dirlen = BIT16SZ+GBIT16(rp);
		if(p+dirlen > ep)
			break;
		memmove(p, rp, dirlen);
		p += dirlen;
		rp += dirlen;
	}

	if(p == op){
		qunlock(&c->rockqlock);
		return 0;
	}

	/* shift the rest */
	if(rp != erp)
		memmove(c->dirrock, rp, erp-rp);
	c->nrock = erp - rp;

	*nn = p - op;
	qunlock(&c->rockqlock);
	return 1;
}
Esempio n. 25
0
static int
pcicfgrw(Pcidev *pcidev, int rno, int data, int len, int read)
{
	uchar buf[4];

	if(read){
		memset(buf, 0, sizeof(buf));
		if(pread(pcidev->rawfd, buf, len, rno) != len)
			return -1;
		switch(len){
		case 1:
			return GBIT8(buf);
		case 2:
			return GBIT16(buf);
		case 4:
			return GBIT32(buf);
		default:
			abort();
		}
	} else {
		switch(len){
		case 1:
			PBIT8(buf, data);
			break;
		case 2:
			PBIT16(buf, data);
			break;
		case 4:
			PBIT32(buf, data);
			break;
		default:
			abort();
		}
		if(pwrite(pcidev->rawfd, buf, len, rno) != len)
			return -1;
	}
	return 0;
}
Esempio n. 26
0
static int
fswstat(Chan *c, uchar *buf, int n)
{
	char *elem, *path, *npath, *strs, *t;
	int nn;
	Dir d;
	UnixFd *ufd;

	if(n < 2)
		error(Ebadstat);

	nn = GBIT16((uchar*)buf);
	strs = smalloc(nn);
	if(convM2D(buf, n, &d, strs) != n){
		free(strs);
		error(Ebadstat);
	}
	
	path = fspath(c, nil);
	if(waserror()){
		free(path);
		free(strs);
		nexterror();
	}
	
	if(d.muid[0])
		error("cannot change muid");

	if(d.uid[0] || d.gid[0]){
		int uid, gid;
		
		uid = -1;
		gid = -1;
		if(d.uid[0] && (uid = nametouid(d.uid)) < 0)
			error("unknown uid");
		if(d.gid[0] && (gid = nametogid(d.gid)) < 0)
			error("unknown gid");
		if(chown(path, uid, gid) < 0)
			oserror();
	}
	
	ufd = c->aux;
	elem = lastelem(path);
	if(d.name[0] && strcmp(d.name, elem) != 0){
		if(strchr(d.name, '/'))
			error(Ebadarg);
		npath = smalloc(strlen(path)+strlen(d.name)+1);
		strcpy(npath, path);
		t = strrchr(npath, '/');
		strcpy(t+1, d.name);
		if(rename(path, npath) < 0){
			free(npath);
			oserror();
		}
		free(npath);
	}
	
	if(~d.mode != 0 && chmod(path, d.mode&0777) < 0)
		oserror();

	// TODO: Code to change uid, gid.
	
	poperror();
	return n;
}
Esempio n. 27
0
/*
 * no syntactic checks.
 * three causes for error:
 *  1. message size field is incorrect
 *  2. input buffer too short for its own data (counts too long, etc.)
 *  3. too many names or qids
 * gqid() and gstring() return nil if they would reach beyond buffer.
 * main switch statement checks range and also can fall through
 * to test at end of routine.
 */
uint
convM2S(uchar *ap, uint nap, Fcall *f)
{
	uchar *p, *ep;
	uint i, size;

	p = ap;
	ep = p + nap;

	if(p+BIT32SZ+BIT8SZ+BIT16SZ > ep)
		return 0;
	size = GBIT32(p);
	p += BIT32SZ;

	if(size < BIT32SZ+BIT8SZ+BIT16SZ)
		return 0;

	f->type = GBIT8(p);
	p += BIT8SZ;
	f->tag = GBIT16(p);
	p += BIT16SZ;

	switch(f->type)
	{
	default:
		return 0;

	case Tversion:
		if(p+BIT32SZ > ep)
			return 0;
		f->msize = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->version);
		break;

	case Tflush:
		if(p+BIT16SZ > ep)
			return 0;
		f->oldtag = GBIT16(p);
		p += BIT16SZ;
		break;

	case Tauth:
		if(p+BIT32SZ > ep)
			return 0;
		f->afid = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->uname);
		if(p == nil)
			break;
		p = gstring(p, ep, &f->aname);
		if(p == nil)
			break;
		break;

	case Tattach:
		if(p+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		if(p+BIT32SZ > ep)
			return 0;
		f->afid = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->uname);
		if(p == nil)
			break;
		p = gstring(p, ep, &f->aname);
		if(p == nil)
			break;
		break;

	case Twalk:
		if(p+BIT32SZ+BIT32SZ+BIT16SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->newfid = GBIT32(p);
		p += BIT32SZ;
		f->nwname = GBIT16(p);
		p += BIT16SZ;
		if(f->nwname > MAXWELEM)
			return 0;
		for(i=0; i<f->nwname; i++){
			p = gstring(p, ep, &f->wname[i]);
			if(p == nil)
				break;
		}
		break;

	case Topen:
		if(p+BIT32SZ+BIT8SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->mode = GBIT8(p);
		p += BIT8SZ;
		break;

	case Tcreate:
		if(p+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->name);
		if(p == nil)
			break;
		if(p+BIT32SZ+BIT8SZ > ep)
			return 0;
		f->perm = GBIT32(p);
		p += BIT32SZ;
		f->mode = GBIT8(p);
		p += BIT8SZ;
		break;

	case Tread:
		if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->offset = GBIT64(p);
		p += BIT64SZ;
		f->count = GBIT32(p);
		p += BIT32SZ;
		break;

	case Twrite:
		if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->offset = GBIT64(p);
		p += BIT64SZ;
		f->count = GBIT32(p);
		p += BIT32SZ;
		if(p+f->count > ep)
			return 0;
		f->data = (char*)p;
		p += f->count;
		break;

	case Tclunk:
	case Tremove:
		if(p+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		break;

	case Tstat:
		if(p+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		break;

	case Twstat:
		if(p+BIT32SZ+BIT16SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->nstat = GBIT16(p);
		p += BIT16SZ;
		if(p+f->nstat > ep)
			return 0;
		f->stat = p;
		p += f->nstat;
		break;

/*
 */
	case Rversion:
		if(p+BIT32SZ > ep)
			return 0;
		f->msize = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->version);
		break;

	case Rerror:
		p = gstring(p, ep, &f->ename);
		break;

	case Rflush:
		break;

	case Rauth:
		p = gqid(p, ep, &f->aqid);
		if(p == nil)
			break;
		break;

	case Rattach:
		p = gqid(p, ep, &f->qid);
		if(p == nil)
			break;
		break;

	case Rwalk:
		if(p+BIT16SZ > ep)
			return 0;
		f->nwqid = GBIT16(p);
		p += BIT16SZ;
		if(f->nwqid > MAXWELEM)
			return 0;
		for(i=0; i<f->nwqid; i++){
			p = gqid(p, ep, &f->wqid[i]);
			if(p == nil)
				break;
		}
		break;

	case Ropen:
	case Rcreate:
		p = gqid(p, ep, &f->qid);
		if(p == nil)
			break;
		if(p+BIT32SZ > ep)
			return 0;
		f->iounit = GBIT32(p);
		p += BIT32SZ;
		break;

	case Rread:
		if(p+BIT32SZ > ep)
			return 0;
		f->count = GBIT32(p);
		p += BIT32SZ;
		if(p+f->count > ep)
			return 0;
		f->data = (char*)p;
		p += f->count;
		break;

	case Rwrite:
		if(p+BIT32SZ > ep)
			return 0;
		f->count = GBIT32(p);
		p += BIT32SZ;
		break;

	case Rclunk:
	case Rremove:
		break;

	case Rstat:
		if(p+BIT16SZ > ep)
			return 0;
		f->nstat = GBIT16(p);
		p += BIT16SZ;
		if(p+f->nstat > ep)
			return 0;
		f->stat = p;
		p += f->nstat;
		break;

	case Rwstat:
		break;
	}

	if(p==nil || p>ep)
		return 0;
	if(ap+size == p)
		return size;
	return 0;
}
Esempio n. 28
0
uint
_convM2D(uint8_t *buf, uint nbuf, Dir *d, char *strs)
{
	uint8_t *p, *ebuf;
	char *sv[4];
	int i, ns, nsv[4];

	p = buf;
	ebuf = buf + nbuf;

	p += BIT16SZ;	/* ignore size */
	d->type = GBIT16(p);
	p += BIT16SZ;
	d->dev = GBIT32(p);
	p += BIT32SZ;
	d->qid.type = GBIT8(p);
	p += BIT8SZ;
	d->qid.vers = GBIT32(p);
	p += BIT32SZ;
	d->qid.path = GBIT64(p);
	p += BIT64SZ;
	d->mode = GBIT32(p);
	p += BIT32SZ;
	d->atime = GBIT32(p);
	p += BIT32SZ;
	d->mtime = GBIT32(p);
	p += BIT32SZ;
	d->length = GBIT64(p);
	p += BIT64SZ;

	d->name = nil;
	d->uid = nil;
	d->gid = nil;
	d->muid = nil;

	for(i = 0; i < 4; i++){
		if(p + BIT16SZ > ebuf)
			return 0;
		ns = GBIT16(p);
		p += BIT16SZ;
		if(p + ns > ebuf)
			return 0;
		if(strs){
			nsv[i] = ns;
			sv[i] = strs;
			memmove(strs, p, ns);
			strs += ns;
			*strs++ = '\0';
		}
		p += ns;
	}

	if(strs){
		d->name = sv[0];
		d->uid = sv[1];
		d->gid = sv[2];
		d->muid = sv[3];
	}else{
		d->name = nullstring;
		d->uid = nullstring;
		d->gid = nullstring;
		d->muid = nullstring;
	}
	
	return p - buf;
}
Esempio n. 29
0
u16 convM2S(u8 *ap, u16 nap, estyx_fcall_t *f)
{
	u8 *p, *ep;
	u16 i, size;

	p = ap;
	ep = p + nap;

	if(p+BIT32SZ+BIT8SZ+BIT16SZ > ep)
		return 0;
	size = GBIT32(p);
	p += BIT32SZ;

	if (size<BIT32SZ+BIT8SZ+BIT16SZ)
		return 0;

	f->type = GBIT8(p);
	p += BIT8SZ;
	f->tag = GBIT16(p);
	p += BIT16SZ;

	switch(f->type) {
	default:
		return 0;

	case Tversion:
		if(p+BIT32SZ > ep)
			return 0;
		f->u.version.msize = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->u.version.version);
		break;

	case Tflush:
		if(p+BIT16SZ > ep)
			return 0;
		f->u.oldtag = GBIT16(p);
		p += BIT16SZ;
		break;

	case Tauth:
		if(p+BIT32SZ > ep)
			return 0;
		f->u.attach.afid = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->u.attach.uname);
		if(p == nil)
			break;
		p = gstring(p, ep, &f->u.attach.aname);
		if(p == nil)
			break;
		break;

	case Tattach:
		if(p+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		if(p+BIT32SZ > ep)
			return 0;
		f->u.attach.afid = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->u.attach.uname);
		if(p == nil)
			break;
		p = gstring(p, ep, &f->u.attach.aname);
		if(p == nil)
			break;
		break;

	case Twalk:
		if(p+BIT32SZ+BIT32SZ+BIT16SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->u.twalk.newfid = GBIT32(p);
		p += BIT32SZ;
		f->u.twalk.nwname = GBIT16(p);
		p += BIT16SZ;
		if(f->u.twalk.nwname > MAXWELEM)
			return 0;
		for(i=0; i<f->u.twalk.nwname; i++){
			p = gstring(p, ep, &f->u.twalk.wname[i]);
			if(p == nil)
				break;
		}
		break;

	case Topen:
		if(p+BIT32SZ+BIT8SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->u.create.mode = GBIT8(p);
		p += BIT8SZ;
		break;

	case Tcreate:
		if(p+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->u.create.name);
		if(p == nil)
			break;
		if(p+BIT32SZ+BIT8SZ > ep)
			return 0;
		f->u.create.perm = GBIT32(p);
		p += BIT32SZ;
		f->u.create.mode = GBIT8(p);
		p += BIT8SZ;
		break;

	case Tread:
		if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->u.rw.offset = GBIT32(p);
		p += BIT64SZ;
		f->u.rw.count = GBIT32(p);
		p += BIT32SZ;
		break;

	case Twrite:
		if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->u.rw.offset = GBIT32(p);
		p += BIT64SZ;
		f->u.rw.count = GBIT32(p);
		p += BIT32SZ;
		if(p+f->u.rw.count > ep)
			return 0;
		f->u.rw.data = p;
		p += f->u.rw.count;
		break;

	case Tclunk:
	case Tremove:
		if(p+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		break;

	case Tstat:
		if(p+BIT32SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		break;

	case Twstat:
		if(p+BIT32SZ+BIT16SZ > ep)
			return 0;
		f->fid = GBIT32(p);
		p += BIT32SZ;
		f->u.stat.nstat = GBIT16(p);
		p += BIT16SZ;
		if(p+f->u.stat.nstat > ep)
			return 0;
		f->u.stat.stat = p;
		p += f->u.stat.nstat;
		break;
#if 0
// we never receive R packets so no need for this
/*
 */
	case Rversion:
		if(p+BIT32SZ > ep)
			return 0;
		f->u.version.msize = GBIT32(p);
		p += BIT32SZ;
		p = gstring(p, ep, &f->u.version.version);
		break;

	case Rerror:
		p = gstring(p, ep, &f->u.ename);
		break;

	case Rflush:
		break;

	case Rauth:
		p = gqid(p, ep, &f->u.aqid);
		if(p == nil)
			break;
		break;

	case Rattach:
		p = gqid(p, ep, &f->u.open.qid);
		if(p == nil)
			break;
		break;

	case Rwalk:
		if(p+BIT16SZ > ep)
			return 0;
		f->u.rwalk.nwqid = GBIT16(p);
		p += BIT16SZ;
		if(f->u.rwalk.nwqid > MAXWELEM)
			return 0;
		for(i=0; i<f->u.rwalk.nwqid; i++){
			p = gqid(p, ep, &f->u.rwalk.wqid[i]);
			if(p == nil)
				break;
		}
		break;

	case Ropen:
	case Rcreate:
		p = gqid(p, ep, &f->u.open.qid);
		if(p == nil)
			break;
		if(p+BIT32SZ > ep)
			return 0;
		f->u.open.iounit = GBIT32(p);
		p += BIT32SZ;
		break;

	case Rread:
		if(p+BIT32SZ > ep)			return 0;
		f->u.rw.count = GBIT32(p);
		p += BIT32SZ;
		if(p+f->u.rw.count > ep)
			return 0;
		f->u.rw.data = data;
		p += f->u.rw.count;
		break;

	case Rwrite:
		if(p+BIT32SZ > ep)
			return 0;
		f->u.rw.count = GBIT32(p);
		p += BIT32SZ;
		break;

	case Rclunk:
	case Rremove:
		break;

	case Rstat:
		if(p+BIT16SZ > ep)
			return 0;
		f->u.stat.nstat = GBIT16(p);
		p += BIT16SZ;
		if(p+f->u.stat.nstat > ep)
			return 0;
		f->u.stat.stat = p;
		p += f->u.stat.nstat;
		break;

	case Rwstat:
		break;
#endif
	}

	if(p==nil || p>ep)
		return 0;
	if(ap+size == p)
		return size;
	return 0;
}
Esempio n. 30
0
unsigned int convM2kdirent(uint8_t * buf, unsigned int nbuf, struct kdirent *kd,
						   char *strs)
{
	uint8_t *p, *ebuf;
	char *sv[4];
	int i, ns;
	uint32_t junk;
	printd("%s >>>>>>>>>nbuf %d STATFIXLEN %d\n", __func__, nbuf, STATFIXLEN);
	if (nbuf < STATFIXLEN)
		return 0;

	p = buf;
	ebuf = buf + nbuf;

	p += BIT16SZ;	/* ignore size */
	kd->d_type = GBIT16(p);
	p += BIT16SZ;
	junk = GBIT32(p);
	p += BIT32SZ;
	junk = GBIT8(p);
	p += BIT8SZ;
	junk = GBIT32(p);
	p += BIT32SZ;
	kd->d_ino = GBIT64(p);
	p += BIT64SZ;
	junk /* mode */  = GBIT32(p);
	p += BIT32SZ;
	junk /*d->atime */  = GBIT32(p);
	p += BIT32SZ;
	junk /*d->mtime */  = GBIT32(p);
	p += BIT32SZ;
	junk /*d->length */  = GBIT64(p);
	p += BIT64SZ;

	/* for now, uids in akaros are ints. Does not
	 * matter; kdirents are limited in what they tell you.
	 * get the name, ignore the rest. Maybe we can
	 * fix this later. 
	 */
	for (i = 0; i < 4; i++) {
		if (p + BIT16SZ > ebuf)
			return 0;
		ns = GBIT16(p);
		p += BIT16SZ;
		if (p + ns > ebuf)
			return 0;
		if (strs) {
			sv[i] = strs;
			memmove(strs, p, ns);
			strs += ns;
			*strs++ = '\0';
		}
		if (i == 0) {
			kd->d_reclen = ns;
			printd("memmove %p %p %d\n", kd->d_name, p, ns);
			memmove(kd->d_name, p, ns);
			kd->d_name[ns] = 0;
		}
		p += ns;
	}

	printd("%s returns %d %s\n", __func__, p - buf, kd->d_name);
	return p - buf;
}