17 void shuffle(void *arg);
19 void remoteside(char *ns, char *srv);
20 int call(char *rsys, char *ns, char *srv);
21 void* emalloc(int size);
22 void runproc(void *arg);
24 char *REXEXEC = "ssh";
25 char *prog = "import";
35 fprint(2, "usage: %s [-df] [-s service] [-n remote-ns] [-p remote-prog] remote-system\n", argv0);
36 threadexitsall("usage");
46 vseprint(buf, buf+sizeof buf, fmt, arg);
49 fprint(2, "%s: %s\n", argv0 ? argv0 : "<prog>", buf);
50 threadexitsall("fatal");
54 threadmain(int argc, char *argv[])
71 case 'n': /* name of remote namespace */
75 prog = EARGF(usage());
77 case 's': /* name of service */
89 dbgfile = smprint("/tmp/%s.export.debug", getuser());
91 dbgfile = smprint("/tmp/%s.import.debug", getuser());
92 dfd = create(dbgfile, OWRITE, 0664);
94 fmtinstall('F', fcallfmt);
97 /* is this the remote side? */
100 fatal("-R requires -s");
111 proccreate(runproc, nil, Stack);
121 /* start a loal service and connect to remote service */
123 netfd = call(addr, ns, srv);
125 /* threads to shuffle messages each way */
126 srv_to_net[0] = srvfd;
127 srv_to_net[1] = netfd;
128 proccreate(shuffle, srv_to_net, Stack);
129 net_to_srv[0] = netfd;
130 net_to_srv[1] = srvfd;
134 /* post a local service */
141 fatal("can't create pipe: %r");
143 /* 0 will be server end, 1 will be client end */
144 if(post9pservice(p[1], "plumb") < 0)
145 fatal("post9pservice plumb: %r");
151 /* start a stub on the remote server */
153 call(char *rsys, char *ns, char *srv)
161 fatal("can't create pipe: %r");
178 fprint(dfd, "execing ");
179 for(ac = 0; av[ac]; ac++)
180 fprint(dfd, " %s", av[ac]);
193 fatal("can't exec %s", REXEXEC);
199 /* ignore crap that might come out of the .profile */
200 /* keep reading till we have an "OK" */
201 if(read(p[0], &buf[0], 1) != 1)
204 if(read(p[0], &buf[1], 1) != 1)
206 if(strncmp(buf, "OK", 2) == 0)
211 fprint(dfd, "got OK\n");
230 buf = emalloc(BLEN+1);
234 n = read9pmsg(fd[0], buf, BLEN);
237 fprint(dfd, "%d->%d read returns %d: %r\n", fd[0], fd[1], n);
242 t = emalloc(sizeof(Fcall));
244 tbuf = emalloc(BLEN+1);
245 memmove(tbuf, buf, n); /* because convM2S is destructive */
246 if(convM2S((uchar*)tbuf, n, t) != n)
247 fprint(dfd, "%d->%d convert error in convM2S", fd[0], fd[1]);
249 fprint(dfd, "%d->%d %F\n", fd[0], fd[1], t);
251 if(write(fd[1], buf, n) != n)
257 remoteside(char *ns, char *srv)
267 addr = smprint("unix!%s/%s", ns, srv);
271 fprint(dfd, "remoteside starting %s\n", addr);
273 srvfd = dial(addr, 0, 0, 0);
275 fatal("dial %s: %r", addr);
277 fprint(dfd, "remoteside dial %s succeeded\n", addr);
278 fcntl(srvfd, F_SETFL, FD_CLOEXEC);
282 /* threads to shuffle messages each way */
283 srv_to_net[0] = srvfd;
285 proccreate(shuffle, srv_to_net, Stack);
287 net_to_srv[1] = srvfd;
300 fatal("allocation fails: %r");