#include <plan9.h>
#include <fcall.h>
#include <oldfcall.h>
/*
* routines to package the old protocol in the new structures.
*/
#define SHORT(x) p[0]=f->x; p[1]=f->x>>8; p += 2
#define LONG(x) p[0]=f->x; p[1]=f->x>>8; p[2]=f->x>>16; p[3]=f->x>>24; p += 4
#define VLONG(x) p[0]=f->x; p[1]=f->x>>8;\
p[2]=f->x>>16; p[3]=f->x>>24;\
p[4]=f->x>>32; p[5]=f->x>>40;\
p[6]=f->x>>48; p[7]=f->x>>56;\
p += 8
#define STRING(x,n) strecpy((char*)p, (char*)p+n, f->x); p += n;
#define FIXQID(q) q.path ^= (q.path>>33); q.path &= 0x7FFFFFFF; q.path |= (q.type&0x80)<<24
uint
oldhdrsize(uchar type)
{
switch(type){
default:
return 0;
case oldTnop:
return 3;
case oldTflush:
return 3+2;
case oldTclone:
return 3+2+2;
case oldTwalk:
return 3+2+28;
case oldTopen:
return 3+2+1;
case oldTcreate:
return 3+2+28+4+1;
case oldTread:
return 3+2+8+2;
case oldTwrite:
return 3+2+8+2+1;
case oldTclunk:
return 3+2;
case oldTremove:
return 3+2;
case oldTstat:
return 3+2;
case oldTwstat:
return 3+2+116;
case oldTsession:
return 3+8;
case oldTattach:
return 3+2+28+28+72+13;
}
}
uint
iosize(uchar *p)
{
if(p[0] != oldTwrite)
return 0;
return p[3+2+8] | (p[3+2+8+1]<<8);
}
uint
sizeS2M(Fcall *f)
{
switch(f->type)
{
default:
abort();
return 0;
/* no T messages */
/*
*/
case Rversion:
return 1+2;
/*
case Rsession:
return 1+2+8+28+48;
*/
case Rattach:
return 1+2+2+4+4+13;
case Rerror:
return 1+2+64;
case Rflush:
if(f->tag&0x8000)
return 1+2+8+28+48; /* session */
return 1+2;
/* assumes we don't ever see Tclwalk requests ... */
case Rwalk:
if(f->nwqid == 0)
return 1+2+2;
else
return 1+2+2+4+4;
case Ropen:
return 1+2+2+4+4;
case Rcreate:
return 1+2+2+4+4;
case Rread:
return 1+2+2+2+1+f->count;
case Rwrite:
return 1+2+2+2;
case Rclunk:
return 1+2+2;
case Rremove:
return 1+2+2;
case Rstat:
return 1+2+2+116;
case Rwstat:
return 1+2+2;
}
}
uint
convS2Mold(Fcall *f, uchar *ap, uint nap)
{
uchar *p;
if(nap < sizeS2M(f))
return 0;
p = ap;
switch(f->type)
{
default:
abort();
return 0;
/* no T messages */
/*
*/
case Rversion:
*p++ = oldRnop;
SHORT(tag);
break;
/*
case Rsession:
*p++ = oldRsession;
SHORT(tag);
if(f->nchal > 8)
f->nchal = 8;
memmove(p, f->chal, f->nchal);
p += f->nchal;
if(f->nchal < 8){
memset(p, 0, 8 - f->nchal);
p += 8 - f->nchal;
}
STRING(authid, 28);
STRING(authdom, 48);
break;
*/
case Rattach:
*p++ = oldRattach;
SHORT(tag);
SHORT(fid);
FIXQID(f->qid);
LONG(qid.path);
LONG(qid.vers);
memset(p, 0, 13);
p += 13;
break;
case Rerror:
*p++ = oldRerror;
SHORT(tag);
STRING(ename, 64);
break;
case Rflush:
if(f->tag&0x8000){
*p++ = oldRsession;
f->tag &= ~0x8000;
SHORT(tag);
memset(p, 0, 8+28+48);
p += 8+28+48;
}else{
*p++ = oldRflush;
SHORT(tag);
}
break;
/* assumes we don't ever see Tclwalk requests ... */
case Rwalk:
if(f->nwqid == 0){ /* successful clone */
*p++ = oldRclone;
SHORT(tag);
SHORT(fid);
}else{ /* successful 1-element walk */
*p++ = oldRwalk;
SHORT(tag);
SHORT(fid);
FIXQID(f->wqid[0]);
LONG(wqid[0].path);
LONG(wqid[0].vers);
}
break;
case Ropen:
*p++ = oldRopen;
SHORT(tag);
SHORT(fid);
FIXQID(f->qid);
LONG(qid.path);
LONG(qid.vers);
break;
case Rcreate:
*p++ = oldRcreate;
SHORT(tag);
SHORT(fid);
FIXQID(f->qid);
LONG(qid.path);
LONG(qid.vers);
break;
case Rread:
*p++ = oldRread;
SHORT(tag);
SHORT(fid);
SHORT(count);
p++; /* pad(1) */
memmove(p, f->data, f->count);
p += f->count;
break;
case Rwrite:
*p++ = oldRwrite;
SHORT(tag);
SHORT(fid);
SHORT(count);
break;
case Rclunk:
*p++ = oldRclunk;
SHORT(tag);
SHORT(fid);
break;
case Rremove:
*p++ = oldRremove;
SHORT(tag);
SHORT(fid);
break;
case Rstat:
*p++ = oldRstat;
SHORT(tag);
SHORT(fid);
memmove(p, f->stat, 116);
p += 116;
break;
case Rwstat:
*p++ = oldRwstat;
SHORT(tag);
SHORT(fid);
break;
}
return p - ap;
}
uint
sizeD2Mold(Dir *d)
{
return 116;
}
uint
convD2Mold(Dir *f, uchar *ap, uint nap)
{
uchar *p;
if(nap < 116)
return 0;
p = ap;
STRING(name, 28);
STRING(uid, 28);
STRING(gid, 28);
FIXQID(f->qid);
LONG(qid.path);
LONG(qid.vers);
LONG(mode);
LONG(atime);
LONG(mtime);
VLONG(length);
SHORT(type);
SHORT(dev);
return p - ap;
}
#undef SHORT
#undef LONG
#undef VLONG
#undef STRING
#define CHAR(x) f->x = *p++
#define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2
#define LONG(x) f->x = (p[0] | (p[1]<<8) |\
(p[2]<<16) | (p[3]<<24)); p += 4
#define VLONG(x) f->x = (ulong)(p[0] | (p[1]<<8) |\
(p[2]<<16) | (p[3]<<24)) |\
((vlong)(p[4] | (p[5]<<8) |\
(p[6]<<16) | (p[7]<<24)) << 32); p += 8
#define STRING(x,n) f->x = (char*)p; p += n
uint
convM2Sold(uchar *ap, uint nap, Fcall *f)
{
uchar *p, *q, *ep;
p = ap;
ep = p + nap;
if(p+3 > ep)
return 0;
switch(*p++){
case oldTnop:
f->type = Tversion;
SHORT(tag);
f->msize = 0;
f->version = "9P1";
break;
case oldTflush:
f->type = Tflush;
SHORT(tag);
if(p+2 > ep)
return 0;
SHORT(oldtag);
break;
case oldTclone:
f->type = Twalk;
SHORT(tag);
if(p+2+2 > ep)
return 0;
SHORT(fid);
SHORT(newfid);
f->nwname = 0;
break;
case oldTwalk:
f->type = Twalk;
SHORT(tag);
if(p+2+28 > ep)
return 0;
SHORT(fid);
f->newfid = f->fid;
f->nwname = 1;
f->wname[0] = (char*)p;
p += 28;
break;
case oldTopen:
f->type = Topen;
SHORT(tag);
if(p+2+1 > ep)
return 0;
SHORT(fid);
CHAR(mode);
break;
case oldTcreate:
f->type = Tcreate;
SHORT(tag);
if(p+2+28+4+1 > ep)
return 0;
SHORT(fid);
f->name = (char*)p;
p += 28;
LONG(perm);
CHAR(mode);
break;
case oldTread:
f->type = Tread;
SHORT(tag);
if(p+2+8+2 > ep)
return 0;
SHORT(fid);
VLONG(offset);
SHORT(count);
break;
case oldTwrite:
f->type = Twrite;
SHORT(tag);
if(p+2+8+2+1 > ep)
return 0;
SHORT(fid);
VLONG(offset);
SHORT(count);
p++; /* pad(1) */
if(p+f->count > ep)
return 0;
f->data = (char*)p;
p += f->count;
break;
case oldTclunk:
f->type = Tclunk;
SHORT(tag);
if(p+2 > ep)
return 0;
SHORT(fid);
break;
case oldTremove:
f->type = Tremove;
SHORT(tag);
if(p+2 > ep)
return 0;
SHORT(fid);
break;
case oldTstat:
f->type = Tstat;
f->nstat = 116;
SHORT(tag);
if(p+2 > ep)
return 0;
SHORT(fid);
break;
case oldTwstat:
f->type = Twstat;
SHORT(tag);
if(p+2+116 > ep)
return 0;
SHORT(fid);
f->stat = p;
q = p+28*3+5*4;
memset(q, 0xFF, 8); /* clear length to ``don't care'' */
p += 116;
break;
/*
case oldTsession:
f->type = Tsession;
SHORT(tag);
if(p+8 > ep)
return 0;
f->chal = p;
p += 8;
f->nchal = 8;
break;
*/
case oldTsession:
f->type = Tflush;
SHORT(tag);
f->tag |= 0x8000;
f->oldtag = f->tag;
p += 8;
break;
case oldTattach:
f->type = Tattach;
SHORT(tag);
if(p+2+28+28+72+13 > ep)
return 0;
SHORT(fid);
STRING(uname, 28);
STRING(aname, 28);
p += 72+13;
f->afid = NOFID;
break;
default:
return 0;
}
return p-ap;
}
uint
convM2Dold(uchar *ap, uint nap, Dir *f, char *strs)
{
uchar *p;
USED(strs);
if(nap < 116)
return 0;
p = (uchar*)ap;
STRING(name, 28);
STRING(uid, 28);
STRING(gid, 28);
LONG(qid.path);
LONG(qid.vers);
LONG(mode);
LONG(atime);
LONG(mtime);
VLONG(length);
SHORT(type);
SHORT(dev);
f->qid.type = (f->mode>>24)&0xF0;
return p - (uchar*)ap;
}
|