1 #include "all.h"
2
3 typedef struct Rpcconn Rpcconn;
4
5 struct Rpcconn
6 {
7 int data;
8 int ctl;
9 Rpccall cmd;
10 Rpccall reply;
11 uchar rpcbuf[8192];
12 uchar argbuf[8192];
13 };
14
15 void putauth(char*, Auth*);
16 int rpccall(Rpcconn*, int);
17
18 int rpcdebug;
19
20 Rpcconn r;
21 char * mach;
22
23 void
main(int argc,char ** argv)24 main(int argc, char **argv)
25 {
26 char addr[64], dir[64], name[128];
27 char buf[33], *p;
28 uchar *dataptr, *argptr;
29 int i, fd, n, remport;
30
31 ARGBEGIN{
32 case 'm':
33 mach = ARGF();
34 break;
35 case 'D':
36 ++rpcdebug;
37 break;
38 }ARGEND
39 if(argc != 1)
40 exits("usage");
41
42 snprint(addr, sizeof addr, "udp!%s!111", argv[0]);
43 r.data = dial(addr, 0, dir, &r.ctl);
44 if(r.data < 0){
45 fprint(2, "dial %s: %r\n", addr);
46 exits("dial");
47 }
48 if(rpcdebug)
49 fprint(2, "dial %s: dir=%s\n", addr, dir);
50 if(fprint(r.ctl, "headers") < 0){
51 fprint(2, "can't set header mode: %r\n");
52 exits("headers");
53 }
54 sprint(name, "%s/remote", dir);
55 fd = open(name, OREAD);
56 if(fd < 0){
57 fprint(2, "can't open %s: %r\n", name);
58 exits("remote");
59 }
60 n = read(fd, buf, sizeof buf-1);
61 if(n < 0){
62 fprint(2, "can't read %s: %r\n", name);
63 exits("remote");
64 }
65 close(fd);
66 buf[n] = 0;
67 p = buf;
68 r.cmd.host = 0;
69 for(i=0; i<4; i++, p++)
70 r.cmd.host = (r.cmd.host<<8)|strtol(p, &p, 10);
71 r.cmd.port = strtol(p, 0, 10);
72 fprint(2, "host=%ld.%ld.%ld.%ld, port=%lud\n",
73 (r.cmd.host>>24)&0xff, (r.cmd.host>>16)&0xff,
74 (r.cmd.host>>8)&0xff, r.cmd.host&0xff, r.cmd.port);
75 fprint(r.ctl, "disconnect");
76
77 r.cmd.xid = time(0);
78 r.cmd.mtype = CALL;
79 r.cmd.rpcvers = 2;
80 r.cmd.args = r.argbuf;
81 if(mach)
82 putauth(mach, &r.cmd.cred);
83
84 r.cmd.prog = 100000; /* portmapper */
85 r.cmd.vers = 2; /* vers */
86 r.cmd.proc = 3; /* getport */
87 dataptr = r.cmd.args;
88
89 PLONG(100005); /* mount */
90 PLONG(1); /* vers */
91 PLONG(IPPROTO_UDP);
92 PLONG(0);
93
94 i = rpccall(&r, dataptr-(uchar*)r.cmd.args);
95 if(i != 4)
96 exits("trouble");
97 argptr = r.reply.results;
98 remport = GLONG();
99 fprint(2, "remote port = %d\n", remport);
100
101 r.cmd.port = remport;
102 r.cmd.prog = 100005; /* mount */
103 r.cmd.vers = 1; /* vers */
104 r.cmd.proc = 0; /* null */
105 dataptr = r.cmd.args;
106
107 i = rpccall(&r, dataptr-(uchar*)r.cmd.args);
108 if(i != 0)
109 exits("trouble");
110 fprint(2, "OK ping mount\n");
111
112 r.cmd.prog = 100005; /* mount */
113 r.cmd.vers = 1; /* vers */
114 r.cmd.proc = 5; /* export */
115 dataptr = r.cmd.args;
116
117 i = rpccall(&r, dataptr-(uchar*)r.cmd.args);
118 fprint(2, "export: %d bytes returned\n", i);
119 argptr = r.reply.results;
120 while (GLONG() != 0) {
121 n = GLONG();
122 p = GPTR(n);
123 print("%.*s\n", utfnlen(p, n), p);
124 while (GLONG() != 0) {
125 n = GLONG();
126 p = GPTR(n);
127 print("\t%.*s\n", utfnlen(p, n), p);
128 }
129 }
130
131 exits(0);
132 }
133
134 void
putauth(char * mach,Auth * a)135 putauth(char *mach, Auth *a)
136 {
137 uchar *dataptr;
138 long stamp = time(0);
139 int n = strlen(mach);
140
141 dataptr = realloc(a->data, 2*4+ROUNDUP(n)+4*4);
142 a->data = dataptr;
143 a->flavor = AUTH_UNIX;
144 PLONG(stamp);
145 PLONG(n);
146 PPTR(mach, n);
147 PLONG(0);
148 PLONG(1);
149 PLONG(1);
150 PLONG(0);
151 a->count = dataptr - (uchar*)a->data;
152 }
153
154 int
rpccall(Rpcconn * r,int narg)155 rpccall(Rpcconn *r, int narg)
156 {
157 int n;
158
159 r->cmd.xid++;
160 n = rpcS2M(&r->cmd, narg, r->rpcbuf);
161 if(rpcdebug)
162 rpcprint(2, &r->cmd);
163 if(write(r->data, r->rpcbuf, n) < 0){
164 fprint(2, "rpc write: %r\n");
165 exits("rpc");
166 }
167 n = read(r->data, r->rpcbuf, sizeof r->rpcbuf);
168 if(n < 0){
169 fprint(2, "rpc read: %r\n");
170 exits("rpc");
171 }
172 if(rpcM2S(r->rpcbuf, &r->reply, n) != 0){
173 fprint(2, "rpc reply format error\n");
174 exits("rpc");
175 }
176 if(rpcdebug)
177 rpcprint(2, &r->reply);
178 if(r->reply.mtype != REPLY || r->reply.stat != MSG_ACCEPTED ||
179 r->reply.astat != SUCCESS){
180 fprint(2, "rpc mtype, stat, astat = %ld, %ld, %ld\n",
181 r->reply.mtype, r->reply.stat, r->reply.astat);
182 exits("rpc");
183 }
184 return n - (((uchar *)r->reply.results) - r->rpcbuf);
185 }
186