Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}