/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
 * Portions Copyright © 1997-1999 Vita Nuova Limited
 * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
 *                                (www.vitanuova.com)
 * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
 *
 * Modified for the Akaros operating system:
 * Copyright (c) 2013-2014 The Regents of the University of California
 * Copyright (c) 2013-2015 Google Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

#include <vfs.h>
#include <kfs.h>
#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <ip.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;
}
