186 lines
3.6 KiB
C
186 lines
3.6 KiB
C
#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);
|
|
}
|