jehanne/sys/src/lib/9p2000/convS2M.c

399 lines
5.5 KiB
C

/*
* 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 <u.h>
#include <lib9.h>
#include <9P2000.h>
static
uint8_t*
pstring(uint8_t *p, char *s)
{
uint32_t n;
if(s == nil){
PBIT16(p, 0);
p += BIT16SZ;
return p;
}
n = strlen(s);
/*
* We are moving the string before the length,
* so you can S2M a struct into an existing message
*/
memmove(p + BIT16SZ, s, n);
PBIT16(p, n);
p += n + BIT16SZ;
return p;
}
static
uint8_t*
pqid(uint8_t *p, Qid *q)
{
PBIT8(p, q->type);
p += BIT8SZ;
PBIT32(p, q->vers);
p += BIT32SZ;
PBIT64(p, q->path);
p += BIT64SZ;
return p;
}
static
uint32_t
stringsz(char *s)
{
if(s == nil)
return BIT16SZ;
return BIT16SZ+strlen(s);
}
uint32_t
sizeS2M(Fcall *f)
{
uint32_t n;
int i;
n = 0;
n += BIT32SZ; /* size */
n += BIT8SZ; /* type */
n += BIT16SZ; /* tag */
switch(f->type)
{
default:
return 0;
case Tversion:
n += BIT32SZ;
n += stringsz(f->version);
break;
case Tflush:
n += BIT16SZ;
break;
case Tauth:
n += BIT32SZ;
n += stringsz(f->uname);
n += stringsz(f->aname);
break;
case Tattach:
n += BIT32SZ;
n += BIT32SZ;
n += stringsz(f->uname);
n += stringsz(f->aname);
break;
case Twalk:
n += BIT32SZ;
n += BIT32SZ;
n += BIT16SZ;
for(i=0; i<f->nwname; i++)
n += stringsz(f->wname[i]);
break;
case Topen:
n += BIT32SZ;
n += BIT8SZ;
break;
case Tcreate:
n += BIT32SZ;
n += stringsz(f->name);
n += BIT32SZ;
n += BIT8SZ;
break;
case Tread:
n += BIT32SZ;
n += BIT64SZ;
n += BIT32SZ;
break;
case Twrite:
n += BIT32SZ;
n += BIT64SZ;
n += BIT32SZ;
n += f->count;
break;
case Tclunk:
case Tremove:
n += BIT32SZ;
break;
case Tstat:
n += BIT32SZ;
break;
case Twstat:
n += BIT32SZ;
n += BIT16SZ;
n += f->nstat;
break;
/*
*/
case Rversion:
n += BIT32SZ;
n += stringsz(f->version);
break;
case Rerror:
n += stringsz(f->ename);
break;
case Rflush:
break;
case Rauth:
n += QIDSZ;
break;
case Rattach:
n += QIDSZ;
break;
case Rwalk:
n += BIT16SZ;
n += f->nwqid*QIDSZ;
break;
case Ropen:
case Rcreate:
n += QIDSZ;
n += BIT32SZ;
break;
case Rread:
n += BIT32SZ;
n += f->count;
break;
case Rwrite:
n += BIT32SZ;
break;
case Rclunk:
break;
case Rremove:
break;
case Rstat:
n += BIT16SZ;
n += f->nstat;
break;
case Rwstat:
break;
}
return n;
}
uint32_t
convS2M(Fcall *f, uint8_t *ap, uint32_t nap)
{
uint8_t *p;
uint32_t i, size;
size = sizeS2M(f);
if(size == 0)
return 0;
if(size > nap)
return 0;
p = (uint8_t*)ap;
PBIT32(p, size);
p += BIT32SZ;
PBIT8(p, f->type);
p += BIT8SZ;
PBIT16(p, f->tag);
p += BIT16SZ;
switch(f->type)
{
default:
return 0;
case Tversion:
PBIT32(p, f->msize);
p += BIT32SZ;
p = pstring(p, f->version);
break;
case Tflush:
PBIT16(p, f->oldtag);
p += BIT16SZ;
break;
case Tauth:
PBIT32(p, f->afid);
p += BIT32SZ;
p = pstring(p, f->uname);
p = pstring(p, f->aname);
break;
case Tattach:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT32(p, f->afid);
p += BIT32SZ;
p = pstring(p, f->uname);
p = pstring(p, f->aname);
break;
case Twalk:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT32(p, f->newfid);
p += BIT32SZ;
PBIT16(p, f->nwname);
p += BIT16SZ;
if(f->nwname > MAXWELEM)
return 0;
for(i=0; i<f->nwname; i++)
p = pstring(p, f->wname[i]);
break;
case Topen:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT8(p, f->mode);
p += BIT8SZ;
break;
case Tcreate:
PBIT32(p, f->fid);
p += BIT32SZ;
p = pstring(p, f->name);
PBIT32(p, f->perm);
p += BIT32SZ;
PBIT8(p, f->mode);
p += BIT8SZ;
break;
case Tread:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT64(p, f->offset);
p += BIT64SZ;
PBIT32(p, f->count);
p += BIT32SZ;
break;
case Twrite:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT64(p, f->offset);
p += BIT64SZ;
PBIT32(p, f->count);
p += BIT32SZ;
memmove(p, f->data, f->count);
p += f->count;
break;
case Tclunk:
case Tremove:
PBIT32(p, f->fid);
p += BIT32SZ;
break;
case Tstat:
PBIT32(p, f->fid);
p += BIT32SZ;
break;
case Twstat:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT16(p, f->nstat);
p += BIT16SZ;
memmove(p, f->stat, f->nstat);
p += f->nstat;
break;
/*
*/
case Rversion:
PBIT32(p, f->msize);
p += BIT32SZ;
p = pstring(p, f->version);
break;
case Rerror:
p = pstring(p, f->ename);
break;
case Rflush:
break;
case Rauth:
p = pqid(p, &f->aqid);
break;
case Rattach:
p = pqid(p, &f->qid);
break;
case Rwalk:
PBIT16(p, f->nwqid);
p += BIT16SZ;
if(f->nwqid > MAXWELEM)
return 0;
for(i=0; i<f->nwqid; i++)
p = pqid(p, &f->wqid[i]);
break;
case Ropen:
case Rcreate:
p = pqid(p, &f->qid);
PBIT32(p, f->iounit);
p += BIT32SZ;
break;
case Rread:
PBIT32(p, f->count);
p += BIT32SZ;
memmove(p, f->data, f->count);
p += f->count;
break;
case Rwrite:
PBIT32(p, f->count);
p += BIT32SZ;
break;
case Rclunk:
break;
case Rremove:
break;
case Rstat:
PBIT16(p, f->nstat);
p += BIT16SZ;
memmove(p, f->stat, f->nstat);
p += f->nstat;
break;
case Rwstat:
break;
}
if(size != p-ap)
return 0;
return size;
}