xref: /plan9/sys/src/cmd/9nfs/mport.c (revision 883a8c51bed350ea85a0220461d31e311550db04)
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