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