/* 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 <net/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;
}
