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>
7 1ab0f6f0 2005-01-07 devnull int debug;
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;
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*);
25 1ab0f6f0 2005-01-07 devnull char *REXEXEC = "ssh";
26 1ab0f6f0 2005-01-07 devnull char *prog = "import";
30 cbeb0b26 2006-04-01 devnull Stack= 32*1024
34 1ab0f6f0 2005-01-07 devnull usage(void)
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");
41 1ab0f6f0 2005-01-07 devnull fatal(char *fmt, ...)
43 1ab0f6f0 2005-01-07 devnull char buf[256];
44 1ab0f6f0 2005-01-07 devnull va_list arg;
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);
50 1ab0f6f0 2005-01-07 devnull fprint(2, "%s: %s\n", argv0 ? argv0 : "<prog>", buf);
51 1ab0f6f0 2005-01-07 devnull threadexitsall("fatal");
55 b3a20a96 2020-12-30 rsc threadmaybackground(void)
61 1ab0f6f0 2005-01-07 devnull threadmain(int argc, char *argv[])
63 1ab0f6f0 2005-01-07 devnull int dofork;
65 351f474b 2008-12-07 rsc void (*fn)(void*);
67 1ab0f6f0 2005-01-07 devnull dofork = 1;
69 1ab0f6f0 2005-01-07 devnull ns = nil;
70 1ab0f6f0 2005-01-07 devnull srv = "plumb";
72 1ab0f6f0 2005-01-07 devnull ARGBEGIN{
73 1ab0f6f0 2005-01-07 devnull case 'd':
74 1ab0f6f0 2005-01-07 devnull debug = 1;
76 1ab0f6f0 2005-01-07 devnull case 'f':
77 1ab0f6f0 2005-01-07 devnull dofork = 0;
79 cbeb0b26 2006-04-01 devnull case 'n': /* name of remote namespace */
80 1ab0f6f0 2005-01-07 devnull ns = EARGF(usage());
82 1ab0f6f0 2005-01-07 devnull case 'p':
83 1ab0f6f0 2005-01-07 devnull prog = EARGF(usage());
85 cbeb0b26 2006-04-01 devnull case 's': /* name of service */
86 1ab0f6f0 2005-01-07 devnull srv = EARGF(usage());
88 1ab0f6f0 2005-01-07 devnull case 'R':
96 1ab0f6f0 2005-01-07 devnull if(debug){
97 1ab0f6f0 2005-01-07 devnull char *dbgfile;
100 1ab0f6f0 2005-01-07 devnull dbgfile = smprint("/tmp/%s.export.debug", getuser());
102 1ab0f6f0 2005-01-07 devnull dbgfile = smprint("/tmp/%s.import.debug", getuser());
103 1ab0f6f0 2005-01-07 devnull dfd = create(dbgfile, OWRITE, 0664);
104 1ab0f6f0 2005-01-07 devnull free(dbgfile);
105 1ab0f6f0 2005-01-07 devnull fmtinstall('F', fcallfmt);
109 1ab0f6f0 2005-01-07 devnull if(rem){
110 351f474b 2008-12-07 rsc netfd[0] = 0;
111 fa325e9b 2020-01-10 cross netfd[1] = 1;
112 351f474b 2008-12-07 rsc write(1, "OK", 2);
114 351f474b 2008-12-07 rsc if(argc != 1)
116 351f474b 2008-12-07 rsc addr = argv[0];
117 351f474b 2008-12-07 rsc /* connect to remote service */
118 351f474b 2008-12-07 rsc netfd[0] = netfd[1] = call(addr, ns, srv);
121 351f474b 2008-12-07 rsc fn = localside;
122 351f474b 2008-12-07 rsc if(rem+export == 1)
123 351f474b 2008-12-07 rsc fn = remoteside;
125 351f474b 2008-12-07 rsc if(rem || !dofork)
128 351f474b 2008-12-07 rsc proccreate(fn, nil, Stack);
133 351f474b 2008-12-07 rsc localside(void *arg)
135 1ab0f6f0 2005-01-07 devnull USED(arg);
137 351f474b 2008-12-07 rsc /* start a loal service */
138 1ab0f6f0 2005-01-07 devnull srvfd = post(srv);
140 cbeb0b26 2006-04-01 devnull /* threads to shuffle messages each way */
141 1ab0f6f0 2005-01-07 devnull srv_to_net[0] = srvfd;
142 351f474b 2008-12-07 rsc srv_to_net[1] = netfd[1];
143 1ab0f6f0 2005-01-07 devnull proccreate(shuffle, srv_to_net, Stack);
144 351f474b 2008-12-07 rsc net_to_srv[0] = netfd[0];
145 1ab0f6f0 2005-01-07 devnull net_to_srv[1] = srvfd;
146 1ab0f6f0 2005-01-07 devnull shuffle(net_to_srv);
149 1ab0f6f0 2005-01-07 devnull /* post a local service */
151 1ab0f6f0 2005-01-07 devnull post(char *srv)
153 1ab0f6f0 2005-01-07 devnull int p[2];
155 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
156 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
158 1ab0f6f0 2005-01-07 devnull /* 0 will be server end, 1 will be client end */
159 c77d5b8e 2010-02-23 rsc if(post9pservice(p[1], srv, nil) < 0)
160 1ab0f6f0 2005-01-07 devnull fatal("post9pservice plumb: %r");
161 1ab0f6f0 2005-01-07 devnull close(p[1]);
163 1ab0f6f0 2005-01-07 devnull return p[0];
166 1ab0f6f0 2005-01-07 devnull /* start a stub on the remote server */
168 1ab0f6f0 2005-01-07 devnull call(char *rsys, char *ns, char *srv)
170 1ab0f6f0 2005-01-07 devnull int p[2];
172 1ab0f6f0 2005-01-07 devnull char *av[12];
173 1ab0f6f0 2005-01-07 devnull char buf[2];
175 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
176 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
178 1ab0f6f0 2005-01-07 devnull av[ac++] = REXEXEC;
179 1ab0f6f0 2005-01-07 devnull av[ac++] = rsys;
180 1ab0f6f0 2005-01-07 devnull av[ac++] = prog;
181 1ab0f6f0 2005-01-07 devnull if(debug)
182 1ab0f6f0 2005-01-07 devnull av[ac++] = "-d";
183 1ab0f6f0 2005-01-07 devnull av[ac++] = "-R";
184 1ab0f6f0 2005-01-07 devnull if(ns != nil){
185 1ab0f6f0 2005-01-07 devnull av[ac++] = "-n";
186 1ab0f6f0 2005-01-07 devnull av[ac++] = ns;
188 1ab0f6f0 2005-01-07 devnull av[ac++] = "-s";
189 1ab0f6f0 2005-01-07 devnull av[ac++] = srv;
191 351f474b 2008-12-07 rsc av[ac++] = "-x";
192 1ab0f6f0 2005-01-07 devnull av[ac] = 0;
194 1ab0f6f0 2005-01-07 devnull if(debug){
195 1ab0f6f0 2005-01-07 devnull fprint(dfd, "execing ");
196 1ab0f6f0 2005-01-07 devnull for(ac = 0; av[ac]; ac++)
197 1ab0f6f0 2005-01-07 devnull fprint(dfd, " %s", av[ac]);
198 1ab0f6f0 2005-01-07 devnull fprint(dfd, "\n");
201 1ab0f6f0 2005-01-07 devnull switch(fork()){
202 1ab0f6f0 2005-01-07 devnull case -1:
203 1ab0f6f0 2005-01-07 devnull fatal("%r");
205 1ab0f6f0 2005-01-07 devnull dup(p[1], 0);
206 1ab0f6f0 2005-01-07 devnull dup(p[1], 1);
207 1ab0f6f0 2005-01-07 devnull close(p[0]);
208 1ab0f6f0 2005-01-07 devnull close(p[1]);
209 1ab0f6f0 2005-01-07 devnull execvp(REXEXEC, av);
210 1ab0f6f0 2005-01-07 devnull fatal("can't exec %s", REXEXEC);
211 1ab0f6f0 2005-01-07 devnull default:
214 1ab0f6f0 2005-01-07 devnull close(p[1]);
216 cbeb0b26 2006-04-01 devnull /* ignore crap that might come out of the .profile */
217 cbeb0b26 2006-04-01 devnull /* keep reading till we have an "OK" */
218 1ab0f6f0 2005-01-07 devnull if(read(p[0], &buf[0], 1) != 1)
219 1ab0f6f0 2005-01-07 devnull fatal("EOF");
220 1ab0f6f0 2005-01-07 devnull for(;;){
221 1ab0f6f0 2005-01-07 devnull if(read(p[0], &buf[1], 1) != 1)
222 1ab0f6f0 2005-01-07 devnull fatal("EOF");
223 1ab0f6f0 2005-01-07 devnull if(strncmp(buf, "OK", 2) == 0)
225 1ab0f6f0 2005-01-07 devnull buf[0] = buf[1];
227 1ab0f6f0 2005-01-07 devnull if(debug)
228 1ab0f6f0 2005-01-07 devnull fprint(dfd, "got OK\n");
230 1ab0f6f0 2005-01-07 devnull return p[0];
235 1ab0f6f0 2005-01-07 devnull BLEN=16*1024
239 1ab0f6f0 2005-01-07 devnull shuffle(void *arg)
241 1ab0f6f0 2005-01-07 devnull int *fd;
242 1ab0f6f0 2005-01-07 devnull char *buf, *tbuf;
244 1ab0f6f0 2005-01-07 devnull Fcall *t;
246 1ab0f6f0 2005-01-07 devnull fd = (int*)arg;
247 1ab0f6f0 2005-01-07 devnull buf = emalloc(BLEN+1);
248 1ab0f6f0 2005-01-07 devnull t = nil;
249 1ab0f6f0 2005-01-07 devnull tbuf = nil;
250 1ab0f6f0 2005-01-07 devnull for(;;){
251 1ab0f6f0 2005-01-07 devnull n = read9pmsg(fd[0], buf, BLEN);
252 1ab0f6f0 2005-01-07 devnull if(n <= 0){
253 1ab0f6f0 2005-01-07 devnull if(debug)
254 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d read returns %d: %r\n", fd[0], fd[1], n);
257 1ab0f6f0 2005-01-07 devnull if(debug){
258 1ab0f6f0 2005-01-07 devnull if(t == nil)
259 1ab0f6f0 2005-01-07 devnull t = emalloc(sizeof(Fcall));
260 1ab0f6f0 2005-01-07 devnull if(tbuf == nil)
261 1ab0f6f0 2005-01-07 devnull tbuf = emalloc(BLEN+1);
262 cbeb0b26 2006-04-01 devnull memmove(tbuf, buf, n); /* because convM2S is destructive */
263 0dc99502 2005-01-14 devnull if(convM2S((uchar*)tbuf, n, t) != n)
264 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d convert error in convM2S", fd[0], fd[1]);
266 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d %F\n", fd[0], fd[1], t);
268 1ab0f6f0 2005-01-07 devnull if(write(fd[1], buf, n) != n)
271 dc6625ea 2010-11-03 rsc threadexitsall(0);
275 351f474b 2008-12-07 rsc remoteside(void *v)
277 1ab0f6f0 2005-01-07 devnull int srv_to_net[2];
278 1ab0f6f0 2005-01-07 devnull int net_to_srv[2];
279 1ab0f6f0 2005-01-07 devnull char *addr;
280 1ab0f6f0 2005-01-07 devnull int srvfd;
282 1ab0f6f0 2005-01-07 devnull if(ns == nil)
283 1ab0f6f0 2005-01-07 devnull ns = getns();
285 1ab0f6f0 2005-01-07 devnull addr = smprint("unix!%s/%s", ns, srv);
286 1ab0f6f0 2005-01-07 devnull if(addr == nil)
287 1ab0f6f0 2005-01-07 devnull fatal("%r");
288 1ab0f6f0 2005-01-07 devnull if(debug)
289 1ab0f6f0 2005-01-07 devnull fprint(dfd, "remoteside starting %s\n", addr);
291 1ab0f6f0 2005-01-07 devnull srvfd = dial(addr, 0, 0, 0);
292 1ab0f6f0 2005-01-07 devnull if(srvfd < 0)
293 1ab0f6f0 2005-01-07 devnull fatal("dial %s: %r", addr);
294 1ab0f6f0 2005-01-07 devnull if(debug)
295 1ab0f6f0 2005-01-07 devnull fprint(dfd, "remoteside dial %s succeeded\n", addr);
296 1ab0f6f0 2005-01-07 devnull fcntl(srvfd, F_SETFL, FD_CLOEXEC);
298 1ab0f6f0 2005-01-07 devnull /* threads to shuffle messages each way */
299 1ab0f6f0 2005-01-07 devnull srv_to_net[0] = srvfd;
300 351f474b 2008-12-07 rsc srv_to_net[1] = netfd[1];
301 1ab0f6f0 2005-01-07 devnull proccreate(shuffle, srv_to_net, Stack);
302 351f474b 2008-12-07 rsc net_to_srv[0] = netfd[0];
303 1ab0f6f0 2005-01-07 devnull net_to_srv[1] = srvfd;
304 1ab0f6f0 2005-01-07 devnull shuffle(net_to_srv);
306 1ab0f6f0 2005-01-07 devnull threadexitsall(0);
310 1ab0f6f0 2005-01-07 devnull emalloc(int size)
312 1ab0f6f0 2005-01-07 devnull void *x;
314 1ab0f6f0 2005-01-07 devnull x = malloc(size);
315 1ab0f6f0 2005-01-07 devnull if(x == nil)
316 1ab0f6f0 2005-01-07 devnull fatal("allocation fails: %r");
317 1ab0f6f0 2005-01-07 devnull return x;