]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/nfsmount.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / aux / nfsmount.c
1 /* Copyright © 2003 Russ Cox, MIT; see /sys/src/libsunrpc/COPYING */
2 #include <u.h>
3 #include <libc.h>
4 #include <thread.h>
5 #include <sunrpc.h>
6 #include <nfs3.h>
7
8 int chatty;
9 SunClient *client;
10
11 void
12 usage(void)
13 {
14         fprint(2, "usage: nfsmount address [cmd]\n"
15                 "cmd is one of:\n"
16                 "\tnull\n"
17                 "\tmnt path\n"
18                 "\tdump\n"
19                 "\tumnt path\n"
20                 "\tumntall\n"
21                 "\texport (default)\n");
22         threadexitsall("usage");
23 }
24
25 void
26 portCall(SunCall *c, PortCallType type)
27 {
28         c->rpc.prog = PortProgram;
29         c->rpc.vers = PortVersion;
30         c->rpc.proc = type>>1;
31         c->rpc.iscall = !(type&1);
32         c->type = type;
33 }
34
35 int
36 getport(SunClient *client, uint prog, uint vers, uint prot, uint *port)
37 {
38         PortTGetport tx;
39         PortRGetport rx;
40
41         memset(&tx, 0, sizeof tx);
42         portCall(&tx.call, PortCallTGetport);
43         tx.map.prog = prog;
44         tx.map.vers = vers;
45         tx.map.prot = prot;
46
47         memset(&rx, 0, sizeof rx);
48         portCall(&rx.call, PortCallRGetport);
49
50         if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
51                 return -1;
52         *port = rx.port;
53         return 0;
54 }
55
56 uchar unixauth[] = {
57         0x12, 0x23, 0x34, 0x45, /* stamp */
58         0x00, 0x00, 0x00, 0x04, /* gnot */
59         0x67, 0x6e, 0x6f, 0x74,
60         0x00, 0x00, 0x03, 0xE9, /* 1001 */
61         0x00, 0x00, 0x03, 0xE9, /* 1001 */
62         0x00, 0x00, 0x00, 0x00, /* gid list */
63 };
64 void
65 mountCall(SunCall *c, NfsMount3CallType type)
66 {
67         c->rpc.prog = NfsMount3Program;
68         c->rpc.vers = NfsMount3Version;
69         c->rpc.proc = type>>1;
70         c->rpc.iscall = !(type&1);
71         if(c->rpc.iscall){
72                 c->rpc.cred.flavor = SunAuthSys;
73                 c->rpc.cred.data = unixauth;
74                 c->rpc.cred.ndata = sizeof unixauth;
75         }
76         c->type = type;
77 }
78
79 void
80 tnull(char **argv)
81 {
82         NfsMount3TNull tx;
83         NfsMount3RNull rx;
84
85         USED(argv);
86
87         memset(&tx, 0, sizeof tx);
88         mountCall(&tx.call, NfsMount3CallTNull);
89
90         memset(&rx, 0, sizeof rx);
91         mountCall(&rx.call, NfsMount3CallRNull);
92
93         if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
94                 sysfatal("rpc: %r");
95 }
96
97 void
98 tmnt(char **argv)
99 {
100         int i;
101         NfsMount3TMnt tx;
102         NfsMount3RMnt rx;
103
104         memset(&tx, 0, sizeof tx);
105         mountCall(&tx.call, NfsMount3CallTMnt);
106         tx.path = argv[0];
107
108         memset(&rx, 0, sizeof rx);
109         mountCall(&rx.call, NfsMount3CallRMnt);
110
111         if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
112                 sysfatal("rpc: %r");
113
114         if(rx.status != 0){
115                 nfs3Errstr(rx.status);
116                 sysfatal("mnt: %r");
117         }
118
119         print("handle %.*H\n", rx.len, rx.handle);
120         print("auth:");
121         for(i=0; i<rx.nauth; i++)
122                 print(" %ud", (uint)rx.auth[i]);
123         print("\n");
124 }
125
126 void
127 tdump(char **argv)
128 {
129         uchar *p, *ep;
130         NfsMount3TDump tx;
131         NfsMount3RDump rx;
132         NfsMount3Entry e;
133
134         memset(&tx, 0, sizeof tx);
135         mountCall(&tx.call, NfsMount3CallTDump);
136         USED(argv);
137
138         memset(&rx, 0, sizeof rx);
139         mountCall(&rx.call, NfsMount3CallRDump);
140
141         if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
142                 sysfatal("rpc: %r");
143
144         p = rx.data;
145         ep = p+rx.count;
146         while(p < ep){
147                 if(nfsMount3EntryUnpack(p, ep, &p, &e) < 0)
148                         sysfatal("unpack entry structure failed");
149                 print("%s %s\n", e.host, e.path);
150         }
151 }
152
153 void
154 tumnt(char **argv)
155 {
156         NfsMount3TUmnt tx;
157         NfsMount3RUmnt rx;
158
159         memset(&tx, 0, sizeof tx);
160         mountCall(&tx.call, NfsMount3CallTUmnt);
161         tx.path = argv[0];
162
163         memset(&rx, 0, sizeof rx);
164         mountCall(&rx.call, NfsMount3CallRUmnt);
165
166         if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
167                 sysfatal("rpc: %r");
168
169         print("\n");
170 }
171
172 void
173 tumntall(char **argv)
174 {
175         NfsMount3TUmntall tx;
176         NfsMount3RUmntall rx;
177
178         memset(&tx, 0, sizeof tx);
179         mountCall(&tx.call, NfsMount3CallTUmntall);
180         USED(argv);
181
182         memset(&rx, 0, sizeof rx);
183         mountCall(&rx.call, NfsMount3CallRUmntall);
184
185         if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
186                 sysfatal("rpc: %r");
187
188         print("\n");
189 }
190
191 void
192 texport(char **argv)
193 {
194         uchar *p, *ep, *tofree;
195         char **g, **gg;
196         int ng, i, n;
197         NfsMount3TDump tx;
198         NfsMount3RDump rx;
199         NfsMount3Export e;
200
201         memset(&tx, 0, sizeof tx);
202         mountCall(&tx.call, NfsMount3CallTExport);
203         USED(argv);
204
205         memset(&rx, 0, sizeof rx);
206         mountCall(&rx.call, NfsMount3CallRExport);
207
208         if(sunClientRpc(client, 0, &tx.call, &rx.call, &tofree) < 0)
209                 sysfatal("rpc: %r");
210
211         p = rx.data;
212         ep = p+rx.count;
213         g = nil;
214         ng = 0;
215         while(p < ep){
216                 n = nfsMount3ExportGroupSize(p);
217                 if(n > ng){
218                         ng = n;
219                         g = erealloc(g, sizeof(g[0])*ng);
220                 }
221                 if(nfsMount3ExportUnpack(p, ep, &p, g, &gg, &e) < 0)
222                         sysfatal("unpack export structure failed");
223                 print("%s", e.path);
224                 for(i=0; i<e.ng; i++)
225                         print(" %s", e.g[i]);
226                 print("\n");
227         }
228         free(tofree);
229 }
230
231 static struct {
232         char *cmd;
233         int narg;
234         void (*fn)(char**);
235 } tab[] = {
236         "null", 0,      tnull,
237         "mnt",  1,      tmnt,
238         "dump", 0,      tdump,
239         "umnt", 1,      tumnt,
240         "umntall",      1,      tumntall,
241         "export",       0,      texport,
242 };
243
244 char*
245 netchangeport(char *addr, char *port)
246 {
247         static char buf[256];
248         char *r;
249
250         strecpy(buf, buf+sizeof buf, addr);
251         r = strrchr(buf, '!');
252         if(r == nil)
253                 return nil;
254         r++;
255         strecpy(r, buf+sizeof buf, port);
256         return buf;
257 }
258
259 void
260 threadmain(int argc, char **argv)
261 {
262         char *dflt[] = { "export", };
263         char *addr, *cmd;
264         int i, proto;
265         uint port;
266         char buf[32];
267         int mapit;
268
269         mapit = 1;
270         ARGBEGIN{
271         case 'R':
272                 chatty++;
273                 break;
274         case 'm':
275                 mapit = 0;
276                 break;
277         }ARGEND
278
279         if(argc < 1)
280                 usage();
281
282         fmtinstall('B', sunRpcFmt);
283         fmtinstall('C', sunCallFmt);
284         fmtinstall('H', encodefmt);
285         sunFmtInstall(&portProg);
286         sunFmtInstall(&nfsMount3Prog);
287
288         addr = netmkaddr(argv[0], "udp", "portmap");
289         if(mapit){
290                 /* translate with port mapper */
291                 fprint(2, "connecting to %s\n", addr);
292                 if((client = sunDial(addr)) == nil)
293                         sysfatal("dial %s: %r", addr);
294                 client->chatty = chatty;
295                 sunClientProg(client, &portProg);
296                 if(strstr(addr, "udp!"))
297                         proto = PortProtoUdp;
298                 else
299                         proto = PortProtoTcp;
300                 if(getport(client, NfsMount3Program, NfsMount3Version, proto, &port) < 0)
301                         sysfatal("getport: %r");
302                 snprint(buf, sizeof buf, "%ud!r", port);
303                 addr = netchangeport(addr, buf);
304                 sunClientClose(client);
305         }
306
307         fprint(2, "connecting to %s\n", addr);
308         if((client = sunDial(addr)) == nil)
309                 sysfatal("dial %s: %r", addr);
310
311         client->chatty = chatty;
312         sunClientProg(client, &nfsMount3Prog);
313
314         argv++;
315         argc--;
316
317         if(argc == 0){
318                 argc = 1;
319                 argv = dflt;
320         }
321         cmd = argv[0];
322         argv++;
323         argc--;
324
325         for(i=0; i<nelem(tab); i++){
326                 if(strcmp(tab[i].cmd, cmd) == 0){
327                         if(tab[i].narg != argc)
328                                 usage();
329                         (*tab[i].fn)(argv);
330                         threadexitsall(nil);
331                 }
332         }
333         usage();
334 }