/* 
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

#include <string.h>
#include <fcall.h>

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;
}

static
uint8_t *gqid(uint8_t * p, uint8_t * ep, struct qid *q)
{
	if (p + QIDSZ > ep)
		return NULL;
	q->type = GBIT8(p);
	p += BIT8SZ;
	q->vers = GBIT32(p);
	p += BIT32SZ;
	q->path = GBIT64(p);
	p += BIT64SZ;
	return p;
}

void init_empty_dir(struct dir *d)
{
	d->type = ~0;
	d->dev = ~0;
	d->qid.path = ~0;
	d->qid.vers = ~0;
	d->qid.type = ~0;
	d->mode = ~0;
	d->atime = ~0;
	d->mtime = ~0;
	d->length = ~0;
	d->name = "";
	d->uid = "";
	d->gid = "";
	d->muid = "";
}

/*
 * 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 NULL if they would reach beyond buffer.
 * main switch statement checks range and also can fall through
 * to test at end of routine.
 */
unsigned int convM2S(uint8_t * ap, unsigned int nap, struct fcall *f)
{
	uint8_t *p, *ep;
	unsigned int 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 == NULL)
				break;
			p = gstring(p, ep, &f->aname);
			if (p == NULL)
				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 == NULL)
				break;
			p = gstring(p, ep, &f->aname);
			if (p == NULL)
				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 == NULL)
					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 == NULL)
				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 == NULL)
				break;
			break;

		case Rattach:
			p = gqid(p, ep, &f->qid);
			if (p == NULL)
				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 == NULL)
					break;
			}
			break;

		case Ropen:
		case Rcreate:
			p = gqid(p, ep, &f->qid);
			if (p == NULL)
				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 == NULL || p > ep)
		return 0;
	if (ap + size == p)
		return size;
	return 0;
}
