tRelated to issue http://bitbucket.org/rsc/plan9port/issue/38/ - 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 4fe82be00a18d3d4841cc43b63095d588354c716
 (DIR) parent 63479cfb79c3d93cf70345f24e4fabf5907e4606
 (HTM) Author: Michael Teichgräber <mt4swm@googlemail.com>
       Date:   Mon, 30 Nov 2009 12:39:50 -0800
       
       Related to issue
       http://bitbucket.org/rsc/plan9port/issue/38/
       
       This patch tries to make 9pserve work again with
       9P2000 clients, in case the server handled by 9pserve
       expects 9P2000.u.
       
       (Since changeset
       http://bitbucket.org/rsc/plan9port/changeset/d9843471f0bc/
       servers using srv() stop communicating after they
       received a 9P2000 msg that has a different .u
       definition.)
       
       Tattach, Tauth and Tcreate 9P2000 messages will
       be translated now, if neccessary, to 9P2000.u by
       growing them to the new size, and providing the
       missing (default) values.
       
       The code of the first two message types has been
       ttested with drawterm on linux (dialing factotum),
       and mounts from within 9vx to plan9port's factotum
       and dossrv.
       
       The code for Tcreate couldn't be tested due to lack
       of file servers both speaking 9P2000.u and allowing file
       creation.
       
       R=rsc_swtch, rsc
       CC=codebot
       http://codereview.appspot.com/151052
       
       Diffstat:
         M src/cmd/9pserve.c                   |      53 ++++++++++++++++++++++++++++++
       
       1 file changed, 53 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/9pserve.c b/src/cmd/9pserve.c
       t@@ -132,6 +132,8 @@ int timefmt(Fmt*);
        void dorootstat(void);
        int stripudirread(Msg*);
        int cvtustat(Fcall*, uchar**, int);
       +void cvtuauthattach(Fcall*, uchar**);
       +void cvtucreate(Fcall*, uchar**);
        
        void
        usage(void)
       t@@ -439,6 +441,8 @@ connthread(void *arg)
                                        m->tx.uname = getuser();        /* what srv.c used */
                                        repack(&m->tx, &m->tpkt, c->dotu);
                                }
       +                        if(dotu && !c->dotu)
       +                                cvtuauthattach(&m->tx, &m->tpkt);
                                break;
                        case Twalk:
                                if((m->fid = gethash(c->fid, m->tx.fid)) == nil){
       t@@ -473,12 +477,16 @@ connthread(void *arg)
                                        continue;
                                }
                                m->afid->ref++;
       +                        if(dotu && !c->dotu)
       +                                cvtuauthattach(&m->tx, &m->tpkt);
                                break;
                        case Tcreate:
                                if(dotu && !c->dotu && (m->tx.perm&(DMSYMLINK|DMDEVICE|DMNAMEDPIPE|DMSOCKET))){
                                        err(m, "unsupported file type");
                                        continue;
                                }
       +                        if(dotu && !c->dotu)
       +                                cvtucreate(&m->tx, &m->tpkt);
                                goto caseTopen;
                        case Topenfd:
                                if(m->tx.mode&~(OTRUNC|3)){
       t@@ -1532,3 +1540,48 @@ stripudirread(Msg* msg)
                return 0;
        }
        
       +void*
       +updateptr(uchar *p0, uchar *p0old, void *p)
       +{
       +        return p0 + ((uchar*)p - p0old);
       +}
       +
       +uchar*
       +growpkt(uchar **ppkt, int sz)
       +{
       +        int n;
       +        uchar *ap, *pkt;
       +
       +        pkt = *ppkt;
       +        n = GBIT32(pkt);
       +        pkt = erealloc(pkt, n+sz);
       +        PBIT32(pkt, n+sz);
       +        ap = &pkt[n];
       +        memset(ap, 0, sz);
       +        *ppkt = pkt;
       +        return ap;        
       +}
       +void
       +cvtuauthattach(Fcall *f, uchar **ppkt)
       +{
       +        uchar *opkt, *ap;
       +        
       +        opkt = *ppkt;
       +        ap = growpkt(ppkt, BIT32SZ);
       +        PBIT32(ap, NOUID);
       +
       +        if(*ppkt != opkt){
       +                f->uname = updateptr(*ppkt, opkt, f->uname);
       +                f->aname = updateptr(*ppkt, opkt, f->aname);
       +        }
       +}
       +void
       +cvtucreate(Fcall *f, uchar **ppkt)
       +{
       +        uchar *opkt;
       +
       +        opkt = *ppkt;
       +        growpkt(ppkt, BIT16SZ);        /* add an empty `extension' */
       +        if(*ppkt != opkt)
       +                f->name = updateptr(*ppkt, opkt, f->name);
       +}