Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include "all.h"

typedef struct Rpcconn  Rpcconn;

struct Rpcconn
{
        int     data;
        int     ctl;
        Rpccall cmd;
        Rpccall reply;
        uchar   rpcbuf[8192];
        uchar   argbuf[8192];
};

void    putauth(char*, Auth*);
int     rpccall(Rpcconn*, int);

int     rpcdebug;

Rpcconn r;
char *  mach;

void
main(int argc, char **argv)
{
        char addr[64], dir[64], name[128];
        char buf[33], *p;
        uchar *dataptr, *argptr;
        int i, fd, n, remport;

        ARGBEGIN{
        case 'm':
                mach = ARGF();
                break;
        case 'D':
                ++rpcdebug;
                break;
        }ARGEND
        if(argc != 1)
                exits("usage");

        snprint(addr, sizeof addr, "udp!%s!111", argv[0]);
        r.data = dial(addr, 0, dir, &r.ctl);
        if(r.data < 0){
                fprint(2, "dial %s: %r\n", addr);
                exits("dial");
        }
        if(rpcdebug)
                fprint(2, "dial %s: dir=%s\n", addr, dir);
        if(fprint(r.ctl, "headers") < 0){
                fprint(2, "can't set header mode: %r\n");
                exits("headers");
        }
        sprint(name, "%s/remote", dir);
        fd = open(name, OREAD);
        if(fd < 0){
                fprint(2, "can't open %s: %r\n", name);
                exits("remote");
        }
        n = read(fd, buf, sizeof buf-1);
        if(n < 0){
                fprint(2, "can't read %s: %r\n", name);
                exits("remote");
        }
        close(fd);
        buf[n] = 0;
        p = buf;
        r.cmd.host = 0;
        for(i=0; i<4; i++, p++)
                r.cmd.host = (r.cmd.host<<8)|strtol(p, &p, 10);
        r.cmd.port = strtol(p, 0, 10);
        fprint(2, "host=%ld.%ld.%ld.%ld, port=%lud\n",
                (r.cmd.host>>24)&0xff, (r.cmd.host>>16)&0xff,
                (r.cmd.host>>8)&0xff, r.cmd.host&0xff, r.cmd.port);
        fprint(r.ctl, "disconnect");

        r.cmd.xid = time(0);
        r.cmd.mtype = CALL;
        r.cmd.rpcvers = 2;
        r.cmd.args = r.argbuf;
        if(mach)
                putauth(mach, &r.cmd.cred);

        r.cmd.prog = 100000;    /* portmapper */
        r.cmd.vers = 2;         /* vers */
        r.cmd.proc = 3;         /* getport */
        dataptr = r.cmd.args;

        PLONG(100005);          /* mount */
        PLONG(1);               /* vers */
        PLONG(IPPROTO_UDP);
        PLONG(0);

        i = rpccall(&r, dataptr-(uchar*)r.cmd.args);
        if(i != 4)
                exits("trouble");
        argptr = r.reply.results;
        remport = GLONG();
        fprint(2, "remote port = %d\n", remport);

        r.cmd.port = remport;
        r.cmd.prog = 100005;    /* mount */
        r.cmd.vers = 1;         /* vers */
        r.cmd.proc = 0;         /* null */
        dataptr = r.cmd.args;

        i = rpccall(&r, dataptr-(uchar*)r.cmd.args);
        if(i != 0)
                exits("trouble");
        fprint(2, "OK ping mount\n");

        r.cmd.prog = 100005;    /* mount */
        r.cmd.vers = 1;         /* vers */
        r.cmd.proc = 5;         /* export */
        dataptr = r.cmd.args;

        i = rpccall(&r, dataptr-(uchar*)r.cmd.args);
        fprint(2, "export: %d bytes returned\n", i);
        argptr = r.reply.results;
        while (GLONG() != 0) {
                n = GLONG();
                p = GPTR(n);
                print("%.*s\n", utfnlen(p, n), p);
                while (GLONG() != 0) {
                        n = GLONG();
                        p = GPTR(n);
                        print("\t%.*s\n", utfnlen(p, n), p);
                }
        }

        exits(0);
}

void
putauth(char *mach, Auth *a)
{
        uchar *dataptr;
        long stamp = time(0);
        int n = strlen(mach);

        dataptr = realloc(a->data, 2*4+ROUNDUP(n)+4*4);
        a->data = dataptr;
        a->flavor = AUTH_UNIX;
        PLONG(stamp);
        PLONG(n);
        PPTR(mach, n);
        PLONG(0);
        PLONG(1);
        PLONG(1);
        PLONG(0);
        a->count = dataptr - (uchar*)a->data;
}

int
rpccall(Rpcconn *r, int narg)
{
        int n;

        r->cmd.xid++;
        n = rpcS2M(&r->cmd, narg, r->rpcbuf);
        if(rpcdebug)
                rpcprint(2, &r->cmd);
        if(write(r->data, r->rpcbuf, n) < 0){
                fprint(2, "rpc write: %r\n");
                exits("rpc");
        }
        n = read(r->data, r->rpcbuf, sizeof r->rpcbuf);
        if(n < 0){
                fprint(2, "rpc read: %r\n");
                exits("rpc");
        }
        if(rpcM2S(r->rpcbuf, &r->reply, n) != 0){
                fprint(2, "rpc reply format error\n");
                exits("rpc");
        }
        if(rpcdebug)
                rpcprint(2, &r->reply);
        if(r->reply.mtype != REPLY || r->reply.stat != MSG_ACCEPTED ||
           r->reply.astat != SUCCESS){
                fprint(2, "rpc mtype, stat, astat = %ld, %ld, %ld\n",
                        r->reply.mtype, r->reply.stat, r->reply.astat);
                exits("rpc");
        }
        return n - (((uchar *)r->reply.results) - r->rpcbuf);
}