tAdd 9P2000.u extensions. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 215993f8445c0313153566ffb36382573803e48b
 (DIR) parent 6e504e308a515a1c4dc2c10fca99738cc0eee5d2
 (HTM) Author: rsc <devnull@localhost>
       Date:   Tue, 13 Sep 2005 01:55:31 +0000
       
       Add 9P2000.u extensions.
       
       Diffstat:
         M src/cmd/9pserve.c                   |     150 ++++++++++++++++++++++++++++----
       
       1 file changed, 135 insertions(+), 15 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/9pserve.c b/src/cmd/9pserve.c
       t@@ -30,6 +30,7 @@ struct Fid
                int ref;
                int cfid;
                int openfd;
       +        int isdir;
                Fid *next;
        };
        
       t@@ -67,6 +68,7 @@ struct Conn
                Hash *fid[NHASH];
                Queue *outq;
                Queue *inq;
       +        int dotu;
        };
        
        char *xaname;
       t@@ -82,11 +84,12 @@ int msize = 8192;
        u32int xafid = NOFID;
        int attached;
        int versioned;
       +int dotu;
        
        void *gethash(Hash**, uint);
        int puthash(Hash**, uint, void*);
        int delhash(Hash**, uint, void*);
       -Msg *mread9p(Ioproc*, int);
       +Msg *mread9p(Ioproc*, int, int);
        int mwrite9p(Ioproc*, int, uchar*);
        uchar *read9ppkt(Ioproc*, int);
        int write9ppkt(int, uchar*);
       t@@ -108,7 +111,7 @@ void listenthread(void*);
        void outputthread(void*);
        void inputthread(void*);
        void rewritehdr(Fcall*, uchar*);
       -void repack(Fcall*, uchar**);
       +void repack(Fcall*, uchar**, int);
        int tlisten(char*, char*);
        int taccept(int, char*);
        int iolisten(Ioproc*, char*, char*);
       t@@ -119,6 +122,8 @@ void mainproc(void*);
        int ignorepipe(void*, char*);
        int timefmt(Fmt*);
        void dorootstat(void);
       +int stripudirread(Msg*);
       +int stripustat(Fcall*, uchar**, int);
        
        void
        usage(void)
       t@@ -211,7 +216,7 @@ mainproc(void *v)
        
                if(!versioned){
                        f.type = Tversion;
       -                f.version = "9P2000";
       +                f.version = "9P2000.u";
                        f.msize = msize;
                        f.tag = NOTAG;
                        n = convS2M(&f, vbuf, sizeof vbuf);
       t@@ -225,6 +230,7 @@ mainproc(void *v)
                        if(f.msize < msize)
                                msize = f.msize;
                        if(verbose > 1) fprint(2, "%T * -> %F\n", &f);
       +                dotu = strncmp(f.version, "9P2000.u", 8) == 0;
                }
        
                threadcreate(inputthread, nil, STACK);
       t@@ -281,9 +287,9 @@ send9pmsg(Msg *m)
        {
                int n, nn;
        
       -        n = sizeS2M(&m->rx);
       +        n = sizeS2Mu(&m->rx, m->c->dotu);
                m->rpkt = emalloc(n);
       -        nn = convS2M(&m->rx, m->rpkt, n);
       +        nn = convS2Mu(&m->rx, m->rpkt, n, m->c->dotu);
                if(nn != n)
                        sysfatal("sizeS2M + convS2M disagree");
                sendq(m->c->outq, m);
       t@@ -294,9 +300,9 @@ sendomsg(Msg *m)
        {
                int n, nn;
        
       -        n = sizeS2M(&m->tx);
       +        n = sizeS2Mu(&m->tx, m->c->dotu);
                m->tpkt = emalloc(n);
       -        nn = convS2M(&m->tx, m->tpkt, n);
       +        nn = convS2Mu(&m->tx, m->tpkt, n, m->c->dotu);
                if(nn != n)
                        sysfatal("sizeS2M + convS2M disagree");
                sendq(outq, m);
       t@@ -342,7 +348,7 @@ connthread(void *arg)
                close(c->fd);
                c->fd = fd;
                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);
                        m->c = c;
                        m->ctag = m->tx.tag;
       t@@ -360,6 +366,11 @@ connthread(void *arg)
                                if(m->rx.msize > msize)
                                        m->rx.msize = msize;
                                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;
                                send9pmsg(m);
                                continue;
       t@@ -395,7 +406,7 @@ connthread(void *arg)
                                        m->tx.afid = xafid;
                                        m->tx.aname = xaname;
                                        m->tx.uname = estrdup(m->tx.uname);
       -                                repack(&m->tx, &m->tpkt);
       +                                repack(&m->tx, &m->tpkt, c->dotu);
                                        free(m->tx.uname);
                                        m->tx.uname = "XXX";
                                }
       t@@ -452,6 +463,12 @@ connthread(void *arg)
                                        continue;
                                }
                                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;
                        }
        
       t@@ -720,6 +737,7 @@ xopenfd(Msg *m)
        void
        connoutthread(void *arg)
        {
       +        char *ename;
                int err;
                Conn *c;
                Queue *outq;
       t@@ -766,6 +784,24 @@ connoutthread(void *arg)
                                        if(delhash(m->c->fid, m->newfid->cfid, m->newfid) == 0)
                                                fidput(m->newfid);
                                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)
                                msgput(m);
       t@@ -829,7 +865,7 @@ inputthread(void *arg)
                                free(pkt);
                                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);
                                free(pkt);
                                msgput(m);
       t@@ -918,6 +954,7 @@ fidnew(int cfid)
                freefid = f->next;
                f->cfid = cfid;
                f->ref = 1;
       +        f->isdir = -1;
                return f;
        }
        
       t@@ -1168,7 +1205,7 @@ read9ppkt(Ioproc *io, int fd)
        }
        
        Msg*
       -mread9p(Ioproc *io, int fd)
       +mread9p(Ioproc *io, int fd, int dotu)
        {
                int n, nn;
                uchar *pkt;
       t@@ -1180,7 +1217,7 @@ mread9p(Ioproc *io, int fd)
                m = msgnew(0);
                m->tpkt = pkt;
                n = GBIT32(pkt);
       -        nn = convM2S(pkt, n, &m->tx);
       +        nn = convM2Su(pkt, n, &m->tx, dotu);
                if(nn != n){
                        fprint(2, "%T read bad packet from %d\n", fd);
                        return nil;
       t@@ -1225,20 +1262,20 @@ restring(uchar *pkt, int pn, char *s)
        }
        
        void
       -repack(Fcall *f, uchar **ppkt)
       +repack(Fcall *f, uchar **ppkt, int dotu)
        {
                uint n, nn;
                uchar *pkt;
                
                pkt = *ppkt;
                n = GBIT32(pkt);
       -        nn = sizeS2M(f);
       +        nn = sizeS2Mu(f, dotu);
                if(nn > n){
                        free(pkt);
                        pkt = emalloc(nn);
                        *ppkt = pkt;
                }
       -        convS2M(f, pkt, nn);        
       +        convS2Mu(f, pkt, nn, dotu);        
        }
        
        void
       t@@ -1337,3 +1374,86 @@ timefmt(Fmt *fmt)
                        mon[tm.mon], tm.mday, tm.hour, tm.min, tm.sec,
                        (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;
       +}
       +