Blame


1 1ab0f6f0 2005-01-07 devnull #include <u.h>
2 1ab0f6f0 2005-01-07 devnull #include <libc.h>
3 1ab0f6f0 2005-01-07 devnull #include <regexp.h>
4 1ab0f6f0 2005-01-07 devnull #include <thread.h>
5 1ab0f6f0 2005-01-07 devnull #include <fcall.h>
6 1ab0f6f0 2005-01-07 devnull
7 1ab0f6f0 2005-01-07 devnull int debug;
8 1ab0f6f0 2005-01-07 devnull int dfd;
9 1ab0f6f0 2005-01-07 devnull int srvfd;
10 351f474b 2008-12-07 rsc int netfd[2];
11 1ab0f6f0 2005-01-07 devnull int srv_to_net[2];
12 1ab0f6f0 2005-01-07 devnull int net_to_srv[2];
13 1ab0f6f0 2005-01-07 devnull char *srv;
14 1ab0f6f0 2005-01-07 devnull char *addr;
15 1ab0f6f0 2005-01-07 devnull char *ns;
16 351f474b 2008-12-07 rsc int export;
17 1ab0f6f0 2005-01-07 devnull
18 1ab0f6f0 2005-01-07 devnull void shuffle(void *arg);
19 1ab0f6f0 2005-01-07 devnull int post(char *srv);
20 351f474b 2008-12-07 rsc void remoteside(void*);
21 1ab0f6f0 2005-01-07 devnull int call(char *rsys, char *ns, char *srv);
22 1ab0f6f0 2005-01-07 devnull void* emalloc(int size);
23 351f474b 2008-12-07 rsc void localside(void*);
24 1ab0f6f0 2005-01-07 devnull
25 1ab0f6f0 2005-01-07 devnull char *REXEXEC = "ssh";
26 1ab0f6f0 2005-01-07 devnull char *prog = "import";
27 1ab0f6f0 2005-01-07 devnull
28 1ab0f6f0 2005-01-07 devnull enum
29 1ab0f6f0 2005-01-07 devnull {
30 cbeb0b26 2006-04-01 devnull Stack= 32*1024
31 1ab0f6f0 2005-01-07 devnull };
32 1ab0f6f0 2005-01-07 devnull
33 1ab0f6f0 2005-01-07 devnull void
34 1ab0f6f0 2005-01-07 devnull usage(void)
35 1ab0f6f0 2005-01-07 devnull {
36 c8b6342d 2005-01-13 devnull fprint(2, "usage: %s [-df] [-s service] [-n remote-ns] [-p remote-prog] remote-system\n", argv0);
37 38c10d1a 2005-01-17 devnull threadexitsall("usage");
38 1ab0f6f0 2005-01-07 devnull }
39 1ab0f6f0 2005-01-07 devnull
40 1ab0f6f0 2005-01-07 devnull void
41 1ab0f6f0 2005-01-07 devnull fatal(char *fmt, ...)
42 1ab0f6f0 2005-01-07 devnull {
43 1ab0f6f0 2005-01-07 devnull char buf[256];
44 1ab0f6f0 2005-01-07 devnull va_list arg;
45 1ab0f6f0 2005-01-07 devnull
46 1ab0f6f0 2005-01-07 devnull va_start(arg, fmt);
47 1ab0f6f0 2005-01-07 devnull vseprint(buf, buf+sizeof buf, fmt, arg);
48 1ab0f6f0 2005-01-07 devnull va_end(arg);
49 1ab0f6f0 2005-01-07 devnull
50 1ab0f6f0 2005-01-07 devnull fprint(2, "%s: %s\n", argv0 ? argv0 : "<prog>", buf);
51 1ab0f6f0 2005-01-07 devnull threadexitsall("fatal");
52 1ab0f6f0 2005-01-07 devnull }
53 1ab0f6f0 2005-01-07 devnull
54 1ab0f6f0 2005-01-07 devnull void
55 1ab0f6f0 2005-01-07 devnull threadmain(int argc, char *argv[])
56 1ab0f6f0 2005-01-07 devnull {
57 1ab0f6f0 2005-01-07 devnull int dofork;
58 1ab0f6f0 2005-01-07 devnull int rem;
59 351f474b 2008-12-07 rsc void (*fn)(void*);
60 1ab0f6f0 2005-01-07 devnull
61 1ab0f6f0 2005-01-07 devnull dofork = 1;
62 1ab0f6f0 2005-01-07 devnull rem = 0;
63 1ab0f6f0 2005-01-07 devnull ns = nil;
64 1ab0f6f0 2005-01-07 devnull srv = "plumb";
65 1ab0f6f0 2005-01-07 devnull
66 1ab0f6f0 2005-01-07 devnull ARGBEGIN{
67 1ab0f6f0 2005-01-07 devnull case 'd':
68 1ab0f6f0 2005-01-07 devnull debug = 1;
69 1ab0f6f0 2005-01-07 devnull break;
70 1ab0f6f0 2005-01-07 devnull case 'f':
71 1ab0f6f0 2005-01-07 devnull dofork = 0;
72 1ab0f6f0 2005-01-07 devnull break;
73 cbeb0b26 2006-04-01 devnull case 'n': /* name of remote namespace */
74 1ab0f6f0 2005-01-07 devnull ns = EARGF(usage());
75 1ab0f6f0 2005-01-07 devnull break;
76 1ab0f6f0 2005-01-07 devnull case 'p':
77 1ab0f6f0 2005-01-07 devnull prog = EARGF(usage());
78 1ab0f6f0 2005-01-07 devnull break;
79 cbeb0b26 2006-04-01 devnull case 's': /* name of service */
80 1ab0f6f0 2005-01-07 devnull srv = EARGF(usage());
81 1ab0f6f0 2005-01-07 devnull break;
82 1ab0f6f0 2005-01-07 devnull case 'R':
83 1ab0f6f0 2005-01-07 devnull rem = 1;
84 1ab0f6f0 2005-01-07 devnull break;
85 351f474b 2008-12-07 rsc case 'x':
86 351f474b 2008-12-07 rsc export = 1;
87 351f474b 2008-12-07 rsc break;
88 1ab0f6f0 2005-01-07 devnull }ARGEND
89 1ab0f6f0 2005-01-07 devnull
90 1ab0f6f0 2005-01-07 devnull if(debug){
91 1ab0f6f0 2005-01-07 devnull char *dbgfile;
92 1ab0f6f0 2005-01-07 devnull
93 1ab0f6f0 2005-01-07 devnull if(rem)
94 1ab0f6f0 2005-01-07 devnull dbgfile = smprint("/tmp/%s.export.debug", getuser());
95 1ab0f6f0 2005-01-07 devnull else
96 1ab0f6f0 2005-01-07 devnull dbgfile = smprint("/tmp/%s.import.debug", getuser());
97 1ab0f6f0 2005-01-07 devnull dfd = create(dbgfile, OWRITE, 0664);
98 1ab0f6f0 2005-01-07 devnull free(dbgfile);
99 1ab0f6f0 2005-01-07 devnull fmtinstall('F', fcallfmt);
100 1ab0f6f0 2005-01-07 devnull }
101 1ab0f6f0 2005-01-07 devnull
102 351f474b 2008-12-07 rsc
103 1ab0f6f0 2005-01-07 devnull if(rem){
104 351f474b 2008-12-07 rsc netfd[0] = 0;
105 351f474b 2008-12-07 rsc netfd[1] = 1;
106 351f474b 2008-12-07 rsc write(1, "OK", 2);
107 351f474b 2008-12-07 rsc }else{
108 351f474b 2008-12-07 rsc if(argc != 1)
109 351f474b 2008-12-07 rsc usage();
110 351f474b 2008-12-07 rsc addr = argv[0];
111 351f474b 2008-12-07 rsc /* connect to remote service */
112 351f474b 2008-12-07 rsc netfd[0] = netfd[1] = call(addr, ns, srv);
113 1ab0f6f0 2005-01-07 devnull }
114 1ab0f6f0 2005-01-07 devnull
115 351f474b 2008-12-07 rsc fn = localside;
116 351f474b 2008-12-07 rsc if(rem+export == 1)
117 351f474b 2008-12-07 rsc fn = remoteside;
118 351f474b 2008-12-07 rsc
119 351f474b 2008-12-07 rsc if(rem || !dofork)
120 351f474b 2008-12-07 rsc fn(nil);
121 1ab0f6f0 2005-01-07 devnull else
122 351f474b 2008-12-07 rsc proccreate(fn, nil, Stack);
123 1ab0f6f0 2005-01-07 devnull }
124 1ab0f6f0 2005-01-07 devnull
125 351f474b 2008-12-07 rsc
126 1ab0f6f0 2005-01-07 devnull void
127 351f474b 2008-12-07 rsc localside(void *arg)
128 1ab0f6f0 2005-01-07 devnull {
129 1ab0f6f0 2005-01-07 devnull USED(arg);
130 1ab0f6f0 2005-01-07 devnull
131 351f474b 2008-12-07 rsc /* start a loal service */
132 1ab0f6f0 2005-01-07 devnull srvfd = post(srv);
133 1ab0f6f0 2005-01-07 devnull
134 cbeb0b26 2006-04-01 devnull /* threads to shuffle messages each way */
135 1ab0f6f0 2005-01-07 devnull srv_to_net[0] = srvfd;
136 351f474b 2008-12-07 rsc srv_to_net[1] = netfd[1];
137 1ab0f6f0 2005-01-07 devnull proccreate(shuffle, srv_to_net, Stack);
138 351f474b 2008-12-07 rsc net_to_srv[0] = netfd[0];
139 1ab0f6f0 2005-01-07 devnull net_to_srv[1] = srvfd;
140 1ab0f6f0 2005-01-07 devnull shuffle(net_to_srv);
141 1ab0f6f0 2005-01-07 devnull }
142 1ab0f6f0 2005-01-07 devnull
143 1ab0f6f0 2005-01-07 devnull /* post a local service */
144 1ab0f6f0 2005-01-07 devnull int
145 1ab0f6f0 2005-01-07 devnull post(char *srv)
146 1ab0f6f0 2005-01-07 devnull {
147 1ab0f6f0 2005-01-07 devnull int p[2];
148 1ab0f6f0 2005-01-07 devnull
149 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
150 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
151 1ab0f6f0 2005-01-07 devnull
152 1ab0f6f0 2005-01-07 devnull /* 0 will be server end, 1 will be client end */
153 c77d5b8e 2010-02-23 rsc if(post9pservice(p[1], srv, nil) < 0)
154 1ab0f6f0 2005-01-07 devnull fatal("post9pservice plumb: %r");
155 1ab0f6f0 2005-01-07 devnull close(p[1]);
156 1ab0f6f0 2005-01-07 devnull
157 1ab0f6f0 2005-01-07 devnull return p[0];
158 1ab0f6f0 2005-01-07 devnull }
159 1ab0f6f0 2005-01-07 devnull
160 1ab0f6f0 2005-01-07 devnull /* start a stub on the remote server */
161 1ab0f6f0 2005-01-07 devnull int
162 1ab0f6f0 2005-01-07 devnull call(char *rsys, char *ns, char *srv)
163 1ab0f6f0 2005-01-07 devnull {
164 1ab0f6f0 2005-01-07 devnull int p[2];
165 1ab0f6f0 2005-01-07 devnull int ac;
166 1ab0f6f0 2005-01-07 devnull char *av[12];
167 1ab0f6f0 2005-01-07 devnull char buf[2];
168 1ab0f6f0 2005-01-07 devnull
169 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
170 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
171 1ab0f6f0 2005-01-07 devnull ac = 0;
172 1ab0f6f0 2005-01-07 devnull av[ac++] = REXEXEC;
173 1ab0f6f0 2005-01-07 devnull av[ac++] = rsys;
174 1ab0f6f0 2005-01-07 devnull av[ac++] = prog;
175 1ab0f6f0 2005-01-07 devnull if(debug)
176 1ab0f6f0 2005-01-07 devnull av[ac++] = "-d";
177 1ab0f6f0 2005-01-07 devnull av[ac++] = "-R";
178 1ab0f6f0 2005-01-07 devnull if(ns != nil){
179 1ab0f6f0 2005-01-07 devnull av[ac++] = "-n";
180 1ab0f6f0 2005-01-07 devnull av[ac++] = ns;
181 1ab0f6f0 2005-01-07 devnull }
182 1ab0f6f0 2005-01-07 devnull av[ac++] = "-s";
183 1ab0f6f0 2005-01-07 devnull av[ac++] = srv;
184 351f474b 2008-12-07 rsc if(export)
185 351f474b 2008-12-07 rsc av[ac++] = "-x";
186 1ab0f6f0 2005-01-07 devnull av[ac] = 0;
187 1ab0f6f0 2005-01-07 devnull
188 1ab0f6f0 2005-01-07 devnull if(debug){
189 1ab0f6f0 2005-01-07 devnull fprint(dfd, "execing ");
190 1ab0f6f0 2005-01-07 devnull for(ac = 0; av[ac]; ac++)
191 1ab0f6f0 2005-01-07 devnull fprint(dfd, " %s", av[ac]);
192 1ab0f6f0 2005-01-07 devnull fprint(dfd, "\n");
193 1ab0f6f0 2005-01-07 devnull }
194 1ab0f6f0 2005-01-07 devnull
195 1ab0f6f0 2005-01-07 devnull switch(fork()){
196 1ab0f6f0 2005-01-07 devnull case -1:
197 1ab0f6f0 2005-01-07 devnull fatal("%r");
198 1ab0f6f0 2005-01-07 devnull case 0:
199 1ab0f6f0 2005-01-07 devnull dup(p[1], 0);
200 1ab0f6f0 2005-01-07 devnull dup(p[1], 1);
201 1ab0f6f0 2005-01-07 devnull close(p[0]);
202 1ab0f6f0 2005-01-07 devnull close(p[1]);
203 1ab0f6f0 2005-01-07 devnull execvp(REXEXEC, av);
204 1ab0f6f0 2005-01-07 devnull fatal("can't exec %s", REXEXEC);
205 1ab0f6f0 2005-01-07 devnull default:
206 1ab0f6f0 2005-01-07 devnull break;
207 1ab0f6f0 2005-01-07 devnull }
208 1ab0f6f0 2005-01-07 devnull close(p[1]);
209 1ab0f6f0 2005-01-07 devnull
210 cbeb0b26 2006-04-01 devnull /* ignore crap that might come out of the .profile */
211 cbeb0b26 2006-04-01 devnull /* keep reading till we have an "OK" */
212 1ab0f6f0 2005-01-07 devnull if(read(p[0], &buf[0], 1) != 1)
213 1ab0f6f0 2005-01-07 devnull fatal("EOF");
214 1ab0f6f0 2005-01-07 devnull for(;;){
215 1ab0f6f0 2005-01-07 devnull if(read(p[0], &buf[1], 1) != 1)
216 1ab0f6f0 2005-01-07 devnull fatal("EOF");
217 1ab0f6f0 2005-01-07 devnull if(strncmp(buf, "OK", 2) == 0)
218 1ab0f6f0 2005-01-07 devnull break;
219 1ab0f6f0 2005-01-07 devnull buf[0] = buf[1];
220 1ab0f6f0 2005-01-07 devnull }
221 1ab0f6f0 2005-01-07 devnull if(debug)
222 1ab0f6f0 2005-01-07 devnull fprint(dfd, "got OK\n");
223 1ab0f6f0 2005-01-07 devnull
224 1ab0f6f0 2005-01-07 devnull return p[0];
225 1ab0f6f0 2005-01-07 devnull }
226 1ab0f6f0 2005-01-07 devnull
227 1ab0f6f0 2005-01-07 devnull enum
228 1ab0f6f0 2005-01-07 devnull {
229 1ab0f6f0 2005-01-07 devnull BLEN=16*1024
230 1ab0f6f0 2005-01-07 devnull };
231 1ab0f6f0 2005-01-07 devnull
232 1ab0f6f0 2005-01-07 devnull void
233 1ab0f6f0 2005-01-07 devnull shuffle(void *arg)
234 1ab0f6f0 2005-01-07 devnull {
235 1ab0f6f0 2005-01-07 devnull int *fd;
236 1ab0f6f0 2005-01-07 devnull char *buf, *tbuf;
237 1ab0f6f0 2005-01-07 devnull int n;
238 1ab0f6f0 2005-01-07 devnull Fcall *t;
239 1ab0f6f0 2005-01-07 devnull
240 1ab0f6f0 2005-01-07 devnull fd = (int*)arg;
241 1ab0f6f0 2005-01-07 devnull buf = emalloc(BLEN+1);
242 1ab0f6f0 2005-01-07 devnull t = nil;
243 1ab0f6f0 2005-01-07 devnull tbuf = nil;
244 1ab0f6f0 2005-01-07 devnull for(;;){
245 1ab0f6f0 2005-01-07 devnull n = read9pmsg(fd[0], buf, BLEN);
246 1ab0f6f0 2005-01-07 devnull if(n <= 0){
247 1ab0f6f0 2005-01-07 devnull if(debug)
248 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d read returns %d: %r\n", fd[0], fd[1], n);
249 1ab0f6f0 2005-01-07 devnull break;
250 1ab0f6f0 2005-01-07 devnull }
251 1ab0f6f0 2005-01-07 devnull if(debug){
252 1ab0f6f0 2005-01-07 devnull if(t == nil)
253 1ab0f6f0 2005-01-07 devnull t = emalloc(sizeof(Fcall));
254 1ab0f6f0 2005-01-07 devnull if(tbuf == nil)
255 1ab0f6f0 2005-01-07 devnull tbuf = emalloc(BLEN+1);
256 cbeb0b26 2006-04-01 devnull memmove(tbuf, buf, n); /* because convM2S is destructive */
257 0dc99502 2005-01-14 devnull if(convM2S((uchar*)tbuf, n, t) != n)
258 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d convert error in convM2S", fd[0], fd[1]);
259 1ab0f6f0 2005-01-07 devnull else
260 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d %F\n", fd[0], fd[1], t);
261 1ab0f6f0 2005-01-07 devnull }
262 1ab0f6f0 2005-01-07 devnull if(write(fd[1], buf, n) != n)
263 1ab0f6f0 2005-01-07 devnull break;
264 1ab0f6f0 2005-01-07 devnull }
265 dc6625ea 2010-11-03 rsc threadexitsall(0);
266 1ab0f6f0 2005-01-07 devnull }
267 1ab0f6f0 2005-01-07 devnull
268 1ab0f6f0 2005-01-07 devnull void
269 351f474b 2008-12-07 rsc remoteside(void *v)
270 1ab0f6f0 2005-01-07 devnull {
271 1ab0f6f0 2005-01-07 devnull int srv_to_net[2];
272 1ab0f6f0 2005-01-07 devnull int net_to_srv[2];
273 1ab0f6f0 2005-01-07 devnull char *addr;
274 1ab0f6f0 2005-01-07 devnull int srvfd;
275 1ab0f6f0 2005-01-07 devnull
276 1ab0f6f0 2005-01-07 devnull if(ns == nil)
277 1ab0f6f0 2005-01-07 devnull ns = getns();
278 1ab0f6f0 2005-01-07 devnull
279 1ab0f6f0 2005-01-07 devnull addr = smprint("unix!%s/%s", ns, srv);
280 1ab0f6f0 2005-01-07 devnull if(addr == nil)
281 1ab0f6f0 2005-01-07 devnull fatal("%r");
282 1ab0f6f0 2005-01-07 devnull if(debug)
283 1ab0f6f0 2005-01-07 devnull fprint(dfd, "remoteside starting %s\n", addr);
284 1ab0f6f0 2005-01-07 devnull
285 1ab0f6f0 2005-01-07 devnull srvfd = dial(addr, 0, 0, 0);
286 1ab0f6f0 2005-01-07 devnull if(srvfd < 0)
287 1ab0f6f0 2005-01-07 devnull fatal("dial %s: %r", addr);
288 1ab0f6f0 2005-01-07 devnull if(debug)
289 1ab0f6f0 2005-01-07 devnull fprint(dfd, "remoteside dial %s succeeded\n", addr);
290 1ab0f6f0 2005-01-07 devnull fcntl(srvfd, F_SETFL, FD_CLOEXEC);
291 1ab0f6f0 2005-01-07 devnull
292 1ab0f6f0 2005-01-07 devnull /* threads to shuffle messages each way */
293 1ab0f6f0 2005-01-07 devnull srv_to_net[0] = srvfd;
294 351f474b 2008-12-07 rsc srv_to_net[1] = netfd[1];
295 1ab0f6f0 2005-01-07 devnull proccreate(shuffle, srv_to_net, Stack);
296 351f474b 2008-12-07 rsc net_to_srv[0] = netfd[0];
297 1ab0f6f0 2005-01-07 devnull net_to_srv[1] = srvfd;
298 1ab0f6f0 2005-01-07 devnull shuffle(net_to_srv);
299 1ab0f6f0 2005-01-07 devnull
300 1ab0f6f0 2005-01-07 devnull threadexitsall(0);
301 1ab0f6f0 2005-01-07 devnull }
302 1ab0f6f0 2005-01-07 devnull
303 1ab0f6f0 2005-01-07 devnull void*
304 1ab0f6f0 2005-01-07 devnull emalloc(int size)
305 1ab0f6f0 2005-01-07 devnull {
306 1ab0f6f0 2005-01-07 devnull void *x;
307 1ab0f6f0 2005-01-07 devnull
308 1ab0f6f0 2005-01-07 devnull x = malloc(size);
309 1ab0f6f0 2005-01-07 devnull if(x == nil)
310 1ab0f6f0 2005-01-07 devnull fatal("allocation fails: %r");
311 1ab0f6f0 2005-01-07 devnull return x;
312 1ab0f6f0 2005-01-07 devnull }