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 1ab0f6f0 2005-01-07 devnull int netfd;
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;
17 1ab0f6f0 2005-01-07 devnull void shuffle(void *arg);
18 1ab0f6f0 2005-01-07 devnull int post(char *srv);
19 1ab0f6f0 2005-01-07 devnull void remoteside(char *ns, char *srv);
20 1ab0f6f0 2005-01-07 devnull int call(char *rsys, char *ns, char *srv);
21 1ab0f6f0 2005-01-07 devnull void* emalloc(int size);
22 1ab0f6f0 2005-01-07 devnull void runproc(void *arg);
24 1ab0f6f0 2005-01-07 devnull char *REXEXEC = "ssh";
25 1ab0f6f0 2005-01-07 devnull char *prog = "import";
29 cbeb0b26 2006-04-01 devnull Stack= 32*1024
33 1ab0f6f0 2005-01-07 devnull usage(void)
35 c8b6342d 2005-01-13 devnull fprint(2, "usage: %s [-df] [-s service] [-n remote-ns] [-p remote-prog] remote-system\n", argv0);
36 38c10d1a 2005-01-17 devnull threadexitsall("usage");
40 1ab0f6f0 2005-01-07 devnull fatal(char *fmt, ...)
42 1ab0f6f0 2005-01-07 devnull char buf[256];
43 1ab0f6f0 2005-01-07 devnull va_list arg;
45 1ab0f6f0 2005-01-07 devnull va_start(arg, fmt);
46 1ab0f6f0 2005-01-07 devnull vseprint(buf, buf+sizeof buf, fmt, arg);
47 1ab0f6f0 2005-01-07 devnull va_end(arg);
49 1ab0f6f0 2005-01-07 devnull fprint(2, "%s: %s\n", argv0 ? argv0 : "<prog>", buf);
50 1ab0f6f0 2005-01-07 devnull threadexitsall("fatal");
54 1ab0f6f0 2005-01-07 devnull threadmain(int argc, char *argv[])
56 1ab0f6f0 2005-01-07 devnull int dofork;
59 1ab0f6f0 2005-01-07 devnull dofork = 1;
61 1ab0f6f0 2005-01-07 devnull ns = nil;
62 1ab0f6f0 2005-01-07 devnull srv = "plumb";
64 1ab0f6f0 2005-01-07 devnull ARGBEGIN{
65 1ab0f6f0 2005-01-07 devnull case 'd':
66 1ab0f6f0 2005-01-07 devnull debug = 1;
68 1ab0f6f0 2005-01-07 devnull case 'f':
69 1ab0f6f0 2005-01-07 devnull dofork = 0;
71 cbeb0b26 2006-04-01 devnull case 'n': /* name of remote namespace */
72 1ab0f6f0 2005-01-07 devnull ns = EARGF(usage());
74 1ab0f6f0 2005-01-07 devnull case 'p':
75 1ab0f6f0 2005-01-07 devnull prog = EARGF(usage());
77 cbeb0b26 2006-04-01 devnull case 's': /* name of service */
78 1ab0f6f0 2005-01-07 devnull srv = EARGF(usage());
80 1ab0f6f0 2005-01-07 devnull case 'R':
85 1ab0f6f0 2005-01-07 devnull if(debug){
86 1ab0f6f0 2005-01-07 devnull char *dbgfile;
89 1ab0f6f0 2005-01-07 devnull dbgfile = smprint("/tmp/%s.export.debug", getuser());
91 1ab0f6f0 2005-01-07 devnull dbgfile = smprint("/tmp/%s.import.debug", getuser());
92 1ab0f6f0 2005-01-07 devnull dfd = create(dbgfile, OWRITE, 0664);
93 1ab0f6f0 2005-01-07 devnull free(dbgfile);
94 1ab0f6f0 2005-01-07 devnull fmtinstall('F', fcallfmt);
97 cbeb0b26 2006-04-01 devnull /* is this the remote side? */
99 1ab0f6f0 2005-01-07 devnull if(srv == nil)
100 1ab0f6f0 2005-01-07 devnull fatal("-R requires -s");
101 1ab0f6f0 2005-01-07 devnull remoteside(ns, srv);
102 1ab0f6f0 2005-01-07 devnull threadexitsall(0);
105 1ab0f6f0 2005-01-07 devnull if(argc != 1)
106 1ab0f6f0 2005-01-07 devnull usage();
108 1ab0f6f0 2005-01-07 devnull addr = argv[0];
110 1ab0f6f0 2005-01-07 devnull if(dofork)
111 1ab0f6f0 2005-01-07 devnull proccreate(runproc, nil, Stack);
113 1ab0f6f0 2005-01-07 devnull runproc(nil);
117 1ab0f6f0 2005-01-07 devnull runproc(void *arg)
119 1ab0f6f0 2005-01-07 devnull USED(arg);
121 cbeb0b26 2006-04-01 devnull /* start a loal service and connect to remote service */
122 1ab0f6f0 2005-01-07 devnull srvfd = post(srv);
123 1ab0f6f0 2005-01-07 devnull netfd = call(addr, ns, srv);
125 cbeb0b26 2006-04-01 devnull /* threads to shuffle messages each way */
126 1ab0f6f0 2005-01-07 devnull srv_to_net[0] = srvfd;
127 1ab0f6f0 2005-01-07 devnull srv_to_net[1] = netfd;
128 1ab0f6f0 2005-01-07 devnull proccreate(shuffle, srv_to_net, Stack);
129 1ab0f6f0 2005-01-07 devnull net_to_srv[0] = netfd;
130 1ab0f6f0 2005-01-07 devnull net_to_srv[1] = srvfd;
131 1ab0f6f0 2005-01-07 devnull shuffle(net_to_srv);
134 1ab0f6f0 2005-01-07 devnull /* post a local service */
136 1ab0f6f0 2005-01-07 devnull post(char *srv)
138 1ab0f6f0 2005-01-07 devnull int p[2];
140 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
141 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
143 1ab0f6f0 2005-01-07 devnull /* 0 will be server end, 1 will be client end */
144 1ab0f6f0 2005-01-07 devnull if(post9pservice(p[1], "plumb") < 0)
145 1ab0f6f0 2005-01-07 devnull fatal("post9pservice plumb: %r");
146 1ab0f6f0 2005-01-07 devnull close(p[1]);
148 1ab0f6f0 2005-01-07 devnull return p[0];
151 1ab0f6f0 2005-01-07 devnull /* start a stub on the remote server */
153 1ab0f6f0 2005-01-07 devnull call(char *rsys, char *ns, char *srv)
155 1ab0f6f0 2005-01-07 devnull int p[2];
157 1ab0f6f0 2005-01-07 devnull char *av[12];
158 1ab0f6f0 2005-01-07 devnull char buf[2];
160 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
161 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
163 1ab0f6f0 2005-01-07 devnull av[ac++] = REXEXEC;
164 1ab0f6f0 2005-01-07 devnull av[ac++] = rsys;
165 1ab0f6f0 2005-01-07 devnull av[ac++] = prog;
166 1ab0f6f0 2005-01-07 devnull if(debug)
167 1ab0f6f0 2005-01-07 devnull av[ac++] = "-d";
168 1ab0f6f0 2005-01-07 devnull av[ac++] = "-R";
169 1ab0f6f0 2005-01-07 devnull if(ns != nil){
170 1ab0f6f0 2005-01-07 devnull av[ac++] = "-n";
171 1ab0f6f0 2005-01-07 devnull av[ac++] = ns;
173 1ab0f6f0 2005-01-07 devnull av[ac++] = "-s";
174 1ab0f6f0 2005-01-07 devnull av[ac++] = srv;
175 1ab0f6f0 2005-01-07 devnull av[ac] = 0;
177 1ab0f6f0 2005-01-07 devnull if(debug){
178 1ab0f6f0 2005-01-07 devnull fprint(dfd, "execing ");
179 1ab0f6f0 2005-01-07 devnull for(ac = 0; av[ac]; ac++)
180 1ab0f6f0 2005-01-07 devnull fprint(dfd, " %s", av[ac]);
181 1ab0f6f0 2005-01-07 devnull fprint(dfd, "\n");
184 1ab0f6f0 2005-01-07 devnull switch(fork()){
185 1ab0f6f0 2005-01-07 devnull case -1:
186 1ab0f6f0 2005-01-07 devnull fatal("%r");
188 1ab0f6f0 2005-01-07 devnull dup(p[1], 0);
189 1ab0f6f0 2005-01-07 devnull dup(p[1], 1);
190 1ab0f6f0 2005-01-07 devnull close(p[0]);
191 1ab0f6f0 2005-01-07 devnull close(p[1]);
192 1ab0f6f0 2005-01-07 devnull execvp(REXEXEC, av);
193 1ab0f6f0 2005-01-07 devnull fatal("can't exec %s", REXEXEC);
194 1ab0f6f0 2005-01-07 devnull default:
197 1ab0f6f0 2005-01-07 devnull close(p[1]);
199 cbeb0b26 2006-04-01 devnull /* ignore crap that might come out of the .profile */
200 cbeb0b26 2006-04-01 devnull /* keep reading till we have an "OK" */
201 1ab0f6f0 2005-01-07 devnull if(read(p[0], &buf[0], 1) != 1)
202 1ab0f6f0 2005-01-07 devnull fatal("EOF");
203 1ab0f6f0 2005-01-07 devnull for(;;){
204 1ab0f6f0 2005-01-07 devnull if(read(p[0], &buf[1], 1) != 1)
205 1ab0f6f0 2005-01-07 devnull fatal("EOF");
206 1ab0f6f0 2005-01-07 devnull if(strncmp(buf, "OK", 2) == 0)
208 1ab0f6f0 2005-01-07 devnull buf[0] = buf[1];
210 1ab0f6f0 2005-01-07 devnull if(debug)
211 1ab0f6f0 2005-01-07 devnull fprint(dfd, "got OK\n");
213 1ab0f6f0 2005-01-07 devnull return p[0];
218 1ab0f6f0 2005-01-07 devnull BLEN=16*1024
222 1ab0f6f0 2005-01-07 devnull shuffle(void *arg)
224 1ab0f6f0 2005-01-07 devnull int *fd;
225 1ab0f6f0 2005-01-07 devnull char *buf, *tbuf;
227 1ab0f6f0 2005-01-07 devnull Fcall *t;
229 1ab0f6f0 2005-01-07 devnull fd = (int*)arg;
230 1ab0f6f0 2005-01-07 devnull buf = emalloc(BLEN+1);
231 1ab0f6f0 2005-01-07 devnull t = nil;
232 1ab0f6f0 2005-01-07 devnull tbuf = nil;
233 1ab0f6f0 2005-01-07 devnull for(;;){
234 1ab0f6f0 2005-01-07 devnull n = read9pmsg(fd[0], buf, BLEN);
235 1ab0f6f0 2005-01-07 devnull if(n <= 0){
236 1ab0f6f0 2005-01-07 devnull if(debug)
237 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d read returns %d: %r\n", fd[0], fd[1], n);
240 1ab0f6f0 2005-01-07 devnull if(debug){
241 1ab0f6f0 2005-01-07 devnull if(t == nil)
242 1ab0f6f0 2005-01-07 devnull t = emalloc(sizeof(Fcall));
243 1ab0f6f0 2005-01-07 devnull if(tbuf == nil)
244 1ab0f6f0 2005-01-07 devnull tbuf = emalloc(BLEN+1);
245 cbeb0b26 2006-04-01 devnull memmove(tbuf, buf, n); /* because convM2S is destructive */
246 0dc99502 2005-01-14 devnull if(convM2S((uchar*)tbuf, n, t) != n)
247 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d convert error in convM2S", fd[0], fd[1]);
249 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d %F\n", fd[0], fd[1], t);
251 1ab0f6f0 2005-01-07 devnull if(write(fd[1], buf, n) != n)
257 1ab0f6f0 2005-01-07 devnull remoteside(char *ns, char *srv)
259 1ab0f6f0 2005-01-07 devnull int srv_to_net[2];
260 1ab0f6f0 2005-01-07 devnull int net_to_srv[2];
261 1ab0f6f0 2005-01-07 devnull char *addr;
262 1ab0f6f0 2005-01-07 devnull int srvfd;
264 1ab0f6f0 2005-01-07 devnull if(ns == nil)
265 1ab0f6f0 2005-01-07 devnull ns = getns();
267 1ab0f6f0 2005-01-07 devnull addr = smprint("unix!%s/%s", ns, srv);
268 1ab0f6f0 2005-01-07 devnull if(addr == nil)
269 1ab0f6f0 2005-01-07 devnull fatal("%r");
270 1ab0f6f0 2005-01-07 devnull if(debug)
271 1ab0f6f0 2005-01-07 devnull fprint(dfd, "remoteside starting %s\n", addr);
273 1ab0f6f0 2005-01-07 devnull srvfd = dial(addr, 0, 0, 0);
274 1ab0f6f0 2005-01-07 devnull if(srvfd < 0)
275 1ab0f6f0 2005-01-07 devnull fatal("dial %s: %r", addr);
276 1ab0f6f0 2005-01-07 devnull if(debug)
277 1ab0f6f0 2005-01-07 devnull fprint(dfd, "remoteside dial %s succeeded\n", addr);
278 1ab0f6f0 2005-01-07 devnull fcntl(srvfd, F_SETFL, FD_CLOEXEC);
280 1ab0f6f0 2005-01-07 devnull write(1, "OK", 2);
282 1ab0f6f0 2005-01-07 devnull /* threads to shuffle messages each way */
283 1ab0f6f0 2005-01-07 devnull srv_to_net[0] = srvfd;
284 1ab0f6f0 2005-01-07 devnull srv_to_net[1] = 1;
285 1ab0f6f0 2005-01-07 devnull proccreate(shuffle, srv_to_net, Stack);
286 1ab0f6f0 2005-01-07 devnull net_to_srv[0] = 0;
287 1ab0f6f0 2005-01-07 devnull net_to_srv[1] = srvfd;
288 1ab0f6f0 2005-01-07 devnull shuffle(net_to_srv);
290 1ab0f6f0 2005-01-07 devnull threadexitsall(0);
294 1ab0f6f0 2005-01-07 devnull emalloc(int size)
296 1ab0f6f0 2005-01-07 devnull void *x;
298 1ab0f6f0 2005-01-07 devnull x = malloc(size);
299 1ab0f6f0 2005-01-07 devnull if(x == nil)
300 1ab0f6f0 2005-01-07 devnull fatal("allocation fails: %r");
301 1ab0f6f0 2005-01-07 devnull return x;