Add 9P2000.u extensions.
This commit is contained in:
parent
6e504e308a
commit
215993f844
1 changed files with 135 additions and 15 deletions
|
|
@ -30,6 +30,7 @@ struct Fid
|
||||||
int ref;
|
int ref;
|
||||||
int cfid;
|
int cfid;
|
||||||
int openfd;
|
int openfd;
|
||||||
|
int isdir;
|
||||||
Fid *next;
|
Fid *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -67,6 +68,7 @@ struct Conn
|
||||||
Hash *fid[NHASH];
|
Hash *fid[NHASH];
|
||||||
Queue *outq;
|
Queue *outq;
|
||||||
Queue *inq;
|
Queue *inq;
|
||||||
|
int dotu;
|
||||||
};
|
};
|
||||||
|
|
||||||
char *xaname;
|
char *xaname;
|
||||||
|
|
@ -82,11 +84,12 @@ int msize = 8192;
|
||||||
u32int xafid = NOFID;
|
u32int xafid = NOFID;
|
||||||
int attached;
|
int attached;
|
||||||
int versioned;
|
int versioned;
|
||||||
|
int dotu;
|
||||||
|
|
||||||
void *gethash(Hash**, uint);
|
void *gethash(Hash**, uint);
|
||||||
int puthash(Hash**, uint, void*);
|
int puthash(Hash**, uint, void*);
|
||||||
int delhash(Hash**, uint, void*);
|
int delhash(Hash**, uint, void*);
|
||||||
Msg *mread9p(Ioproc*, int);
|
Msg *mread9p(Ioproc*, int, int);
|
||||||
int mwrite9p(Ioproc*, int, uchar*);
|
int mwrite9p(Ioproc*, int, uchar*);
|
||||||
uchar *read9ppkt(Ioproc*, int);
|
uchar *read9ppkt(Ioproc*, int);
|
||||||
int write9ppkt(int, uchar*);
|
int write9ppkt(int, uchar*);
|
||||||
|
|
@ -108,7 +111,7 @@ void listenthread(void*);
|
||||||
void outputthread(void*);
|
void outputthread(void*);
|
||||||
void inputthread(void*);
|
void inputthread(void*);
|
||||||
void rewritehdr(Fcall*, uchar*);
|
void rewritehdr(Fcall*, uchar*);
|
||||||
void repack(Fcall*, uchar**);
|
void repack(Fcall*, uchar**, int);
|
||||||
int tlisten(char*, char*);
|
int tlisten(char*, char*);
|
||||||
int taccept(int, char*);
|
int taccept(int, char*);
|
||||||
int iolisten(Ioproc*, char*, char*);
|
int iolisten(Ioproc*, char*, char*);
|
||||||
|
|
@ -119,6 +122,8 @@ void mainproc(void*);
|
||||||
int ignorepipe(void*, char*);
|
int ignorepipe(void*, char*);
|
||||||
int timefmt(Fmt*);
|
int timefmt(Fmt*);
|
||||||
void dorootstat(void);
|
void dorootstat(void);
|
||||||
|
int stripudirread(Msg*);
|
||||||
|
int stripustat(Fcall*, uchar**, int);
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
|
|
@ -211,7 +216,7 @@ mainproc(void *v)
|
||||||
|
|
||||||
if(!versioned){
|
if(!versioned){
|
||||||
f.type = Tversion;
|
f.type = Tversion;
|
||||||
f.version = "9P2000";
|
f.version = "9P2000.u";
|
||||||
f.msize = msize;
|
f.msize = msize;
|
||||||
f.tag = NOTAG;
|
f.tag = NOTAG;
|
||||||
n = convS2M(&f, vbuf, sizeof vbuf);
|
n = convS2M(&f, vbuf, sizeof vbuf);
|
||||||
|
|
@ -225,6 +230,7 @@ mainproc(void *v)
|
||||||
if(f.msize < msize)
|
if(f.msize < msize)
|
||||||
msize = f.msize;
|
msize = f.msize;
|
||||||
if(verbose > 1) fprint(2, "%T * -> %F\n", &f);
|
if(verbose > 1) fprint(2, "%T * -> %F\n", &f);
|
||||||
|
dotu = strncmp(f.version, "9P2000.u", 8) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
threadcreate(inputthread, nil, STACK);
|
threadcreate(inputthread, nil, STACK);
|
||||||
|
|
@ -281,9 +287,9 @@ send9pmsg(Msg *m)
|
||||||
{
|
{
|
||||||
int n, nn;
|
int n, nn;
|
||||||
|
|
||||||
n = sizeS2M(&m->rx);
|
n = sizeS2Mu(&m->rx, m->c->dotu);
|
||||||
m->rpkt = emalloc(n);
|
m->rpkt = emalloc(n);
|
||||||
nn = convS2M(&m->rx, m->rpkt, n);
|
nn = convS2Mu(&m->rx, m->rpkt, n, m->c->dotu);
|
||||||
if(nn != n)
|
if(nn != n)
|
||||||
sysfatal("sizeS2M + convS2M disagree");
|
sysfatal("sizeS2M + convS2M disagree");
|
||||||
sendq(m->c->outq, m);
|
sendq(m->c->outq, m);
|
||||||
|
|
@ -294,9 +300,9 @@ sendomsg(Msg *m)
|
||||||
{
|
{
|
||||||
int n, nn;
|
int n, nn;
|
||||||
|
|
||||||
n = sizeS2M(&m->tx);
|
n = sizeS2Mu(&m->tx, m->c->dotu);
|
||||||
m->tpkt = emalloc(n);
|
m->tpkt = emalloc(n);
|
||||||
nn = convS2M(&m->tx, m->tpkt, n);
|
nn = convS2Mu(&m->tx, m->tpkt, n, m->c->dotu);
|
||||||
if(nn != n)
|
if(nn != n)
|
||||||
sysfatal("sizeS2M + convS2M disagree");
|
sysfatal("sizeS2M + convS2M disagree");
|
||||||
sendq(outq, m);
|
sendq(outq, m);
|
||||||
|
|
@ -342,7 +348,7 @@ connthread(void *arg)
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
c->fd = fd;
|
c->fd = fd;
|
||||||
threadcreate(connoutthread, c, STACK);
|
threadcreate(connoutthread, c, STACK);
|
||||||
while((m = mread9p(io, c->fd)) != nil){
|
while((m = mread9p(io, c->fd, c->dotu)) != nil){
|
||||||
if(verbose > 1) fprint(2, "%T fd#%d -> %F\n", c->fd, &m->tx);
|
if(verbose > 1) fprint(2, "%T fd#%d -> %F\n", c->fd, &m->tx);
|
||||||
m->c = c;
|
m->c = c;
|
||||||
m->ctag = m->tx.tag;
|
m->ctag = m->tx.tag;
|
||||||
|
|
@ -360,6 +366,11 @@ connthread(void *arg)
|
||||||
if(m->rx.msize > msize)
|
if(m->rx.msize > msize)
|
||||||
m->rx.msize = msize;
|
m->rx.msize = msize;
|
||||||
m->rx.version = "9P2000";
|
m->rx.version = "9P2000";
|
||||||
|
c->dotu = 0;
|
||||||
|
if(dotu && strncmp(m->tx.version, "9P2000.u", 8) == 0){
|
||||||
|
m->rx.version = "9P2000.u";
|
||||||
|
c->dotu = 1;
|
||||||
|
}
|
||||||
m->rx.type = Rversion;
|
m->rx.type = Rversion;
|
||||||
send9pmsg(m);
|
send9pmsg(m);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -395,7 +406,7 @@ connthread(void *arg)
|
||||||
m->tx.afid = xafid;
|
m->tx.afid = xafid;
|
||||||
m->tx.aname = xaname;
|
m->tx.aname = xaname;
|
||||||
m->tx.uname = estrdup(m->tx.uname);
|
m->tx.uname = estrdup(m->tx.uname);
|
||||||
repack(&m->tx, &m->tpkt);
|
repack(&m->tx, &m->tpkt, c->dotu);
|
||||||
free(m->tx.uname);
|
free(m->tx.uname);
|
||||||
m->tx.uname = "XXX";
|
m->tx.uname = "XXX";
|
||||||
}
|
}
|
||||||
|
|
@ -452,6 +463,12 @@ connthread(void *arg)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
m->fid->ref++;
|
m->fid->ref++;
|
||||||
|
if(m->tx.type==Twstat && dotu && !c->dotu){
|
||||||
|
if(stripustat(&m->tx, &m->tpkt, 1) < 0){
|
||||||
|
err(m, "cannot convert stat buffer");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -720,6 +737,7 @@ xopenfd(Msg *m)
|
||||||
void
|
void
|
||||||
connoutthread(void *arg)
|
connoutthread(void *arg)
|
||||||
{
|
{
|
||||||
|
char *ename;
|
||||||
int err;
|
int err;
|
||||||
Conn *c;
|
Conn *c;
|
||||||
Queue *outq;
|
Queue *outq;
|
||||||
|
|
@ -766,6 +784,24 @@ connoutthread(void *arg)
|
||||||
if(delhash(m->c->fid, m->newfid->cfid, m->newfid) == 0)
|
if(delhash(m->c->fid, m->newfid->cfid, m->newfid) == 0)
|
||||||
fidput(m->newfid);
|
fidput(m->newfid);
|
||||||
break;
|
break;
|
||||||
|
case Tread:
|
||||||
|
if(!err && m->fid->isdir && dotu && !m->c->dotu)
|
||||||
|
stripudirread(m);
|
||||||
|
break;
|
||||||
|
case Tstat:
|
||||||
|
if(!err && dotu && !m->c->dotu)
|
||||||
|
stripustat(&m->rx, &m->rpkt, 0);
|
||||||
|
break;
|
||||||
|
case Topen:
|
||||||
|
case Tcreate:
|
||||||
|
m->fid->isdir = (m->rx.qid.type & QTDIR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(m->rx.type==Rerror && dotu && !c->dotu){
|
||||||
|
ename = estrdup(m->rx.ename);
|
||||||
|
m->rx.ename = ename;
|
||||||
|
repack(&m->rx, &m->rpkt, c->dotu);
|
||||||
|
free(ename);
|
||||||
}
|
}
|
||||||
if(delhash(m->c->tag, m->ctag, m) == 0)
|
if(delhash(m->c->tag, m->ctag, m) == 0)
|
||||||
msgput(m);
|
msgput(m);
|
||||||
|
|
@ -829,7 +865,7 @@ inputthread(void *arg)
|
||||||
free(pkt);
|
free(pkt);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if((nn = convM2S(pkt, n, &m->rx)) != n){
|
if((nn = convM2Su(pkt, n, &m->rx, dotu)) != n){
|
||||||
fprint(2, "%T bad packet - convM2S %d but %d\n", nn, n);
|
fprint(2, "%T bad packet - convM2S %d but %d\n", nn, n);
|
||||||
free(pkt);
|
free(pkt);
|
||||||
msgput(m);
|
msgput(m);
|
||||||
|
|
@ -918,6 +954,7 @@ fidnew(int cfid)
|
||||||
freefid = f->next;
|
freefid = f->next;
|
||||||
f->cfid = cfid;
|
f->cfid = cfid;
|
||||||
f->ref = 1;
|
f->ref = 1;
|
||||||
|
f->isdir = -1;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1168,7 +1205,7 @@ read9ppkt(Ioproc *io, int fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
Msg*
|
Msg*
|
||||||
mread9p(Ioproc *io, int fd)
|
mread9p(Ioproc *io, int fd, int dotu)
|
||||||
{
|
{
|
||||||
int n, nn;
|
int n, nn;
|
||||||
uchar *pkt;
|
uchar *pkt;
|
||||||
|
|
@ -1180,7 +1217,7 @@ mread9p(Ioproc *io, int fd)
|
||||||
m = msgnew(0);
|
m = msgnew(0);
|
||||||
m->tpkt = pkt;
|
m->tpkt = pkt;
|
||||||
n = GBIT32(pkt);
|
n = GBIT32(pkt);
|
||||||
nn = convM2S(pkt, n, &m->tx);
|
nn = convM2Su(pkt, n, &m->tx, dotu);
|
||||||
if(nn != n){
|
if(nn != n){
|
||||||
fprint(2, "%T read bad packet from %d\n", fd);
|
fprint(2, "%T read bad packet from %d\n", fd);
|
||||||
return nil;
|
return nil;
|
||||||
|
|
@ -1225,20 +1262,20 @@ restring(uchar *pkt, int pn, char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
repack(Fcall *f, uchar **ppkt)
|
repack(Fcall *f, uchar **ppkt, int dotu)
|
||||||
{
|
{
|
||||||
uint n, nn;
|
uint n, nn;
|
||||||
uchar *pkt;
|
uchar *pkt;
|
||||||
|
|
||||||
pkt = *ppkt;
|
pkt = *ppkt;
|
||||||
n = GBIT32(pkt);
|
n = GBIT32(pkt);
|
||||||
nn = sizeS2M(f);
|
nn = sizeS2Mu(f, dotu);
|
||||||
if(nn > n){
|
if(nn > n){
|
||||||
free(pkt);
|
free(pkt);
|
||||||
pkt = emalloc(nn);
|
pkt = emalloc(nn);
|
||||||
*ppkt = pkt;
|
*ppkt = pkt;
|
||||||
}
|
}
|
||||||
convS2M(f, pkt, nn);
|
convS2Mu(f, pkt, nn, dotu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1337,3 +1374,86 @@ timefmt(Fmt *fmt)
|
||||||
mon[tm.mon], tm.mday, tm.hour, tm.min, tm.sec,
|
mon[tm.mon], tm.mday, tm.hour, tm.min, tm.sec,
|
||||||
(int)(ns%1000000000)/1000000);
|
(int)(ns%1000000000)/1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stripustat(Fcall *f, uchar **fpkt, int s2u)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
char *buf;
|
||||||
|
char *str;
|
||||||
|
Dir dir;
|
||||||
|
|
||||||
|
str = emalloc(f->nstat);
|
||||||
|
n = convM2Du(f->stat, f->nstat, &dir, str, s2u);
|
||||||
|
if(n <= BIT16SZ)
|
||||||
|
return -1;
|
||||||
|
n = sizeD2Mu(&dir, !s2u);
|
||||||
|
buf = emalloc(n);
|
||||||
|
|
||||||
|
n = convD2Mu(&dir, buf, n, !s2u);
|
||||||
|
if(n <= BIT16SZ)
|
||||||
|
return -1;
|
||||||
|
f->nstat = n;
|
||||||
|
f->stat = buf;
|
||||||
|
|
||||||
|
repack(f, fpkt, dotu);
|
||||||
|
free(buf);
|
||||||
|
free(str);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stripudirread(Msg* msg)
|
||||||
|
{
|
||||||
|
int i, m, n, nn;
|
||||||
|
char *buf, *str;
|
||||||
|
Dir d;
|
||||||
|
Fcall* rx;
|
||||||
|
|
||||||
|
buf = nil;
|
||||||
|
str = nil;
|
||||||
|
rx = &msg->rx;
|
||||||
|
n = 0;
|
||||||
|
nn = 0;
|
||||||
|
for(i = 0; i < rx->count; i += m){
|
||||||
|
m = BIT16SZ + GBIT16(&rx->data[i]);
|
||||||
|
if(statchecku(&rx->data[i], m, 1) < 0)
|
||||||
|
return -1;
|
||||||
|
if(nn < m)
|
||||||
|
nn = m;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = emalloc(nn);
|
||||||
|
buf = emalloc(rx->count);
|
||||||
|
|
||||||
|
nn = 0;
|
||||||
|
for(i = 0; i < rx->count; i += m){
|
||||||
|
m = BIT16SZ + GBIT16(&rx->data[i]);
|
||||||
|
if(convM2Du(&rx->data[i], m, &d, str, 1) != m){
|
||||||
|
free(buf);
|
||||||
|
free(str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = convD2M(&d, &buf[nn], rx->count - nn);
|
||||||
|
if(n <= BIT16SZ){
|
||||||
|
free(buf);
|
||||||
|
free(str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
rx->count = nn;
|
||||||
|
rx->data = buf;
|
||||||
|
|
||||||
|
repack(&msg->rx, &msg->rpkt, 0);
|
||||||
|
free(str);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue