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 1ab0f6f0 2005-01-07 devnull threadmain(int argc, char *argv[])
57 1ab0f6f0 2005-01-07 devnull int dofork;
59 351f474b 2008-12-07 rsc void (*fn)(void*);
61 1ab0f6f0 2005-01-07 devnull dofork = 1;
63 1ab0f6f0 2005-01-07 devnull ns = nil;
64 1ab0f6f0 2005-01-07 devnull srv = "plumb";
66 1ab0f6f0 2005-01-07 devnull ARGBEGIN{
67 1ab0f6f0 2005-01-07 devnull case 'd':
68 1ab0f6f0 2005-01-07 devnull debug = 1;
70 1ab0f6f0 2005-01-07 devnull case 'f':
71 1ab0f6f0 2005-01-07 devnull dofork = 0;
73 cbeb0b26 2006-04-01 devnull case 'n': /* name of remote namespace */
74 1ab0f6f0 2005-01-07 devnull ns = EARGF(usage());
76 1ab0f6f0 2005-01-07 devnull case 'p':
77 1ab0f6f0 2005-01-07 devnull prog = EARGF(usage());
79 cbeb0b26 2006-04-01 devnull case 's': /* name of service */
80 1ab0f6f0 2005-01-07 devnull srv = EARGF(usage());
82 1ab0f6f0 2005-01-07 devnull case 'R':
90 1ab0f6f0 2005-01-07 devnull if(debug){
91 1ab0f6f0 2005-01-07 devnull char *dbgfile;
94 1ab0f6f0 2005-01-07 devnull dbgfile = smprint("/tmp/%s.export.debug", getuser());
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);
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);
108 351f474b 2008-12-07 rsc if(argc != 1)
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);
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;
119 351f474b 2008-12-07 rsc if(rem || !dofork)
122 351f474b 2008-12-07 rsc proccreate(fn, nil, Stack);
127 351f474b 2008-12-07 rsc localside(void *arg)
129 1ab0f6f0 2005-01-07 devnull USED(arg);
131 351f474b 2008-12-07 rsc /* start a loal service */
132 1ab0f6f0 2005-01-07 devnull srvfd = post(srv);
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);
143 1ab0f6f0 2005-01-07 devnull /* post a local service */
145 1ab0f6f0 2005-01-07 devnull post(char *srv)
147 1ab0f6f0 2005-01-07 devnull int p[2];
149 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
150 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
152 1ab0f6f0 2005-01-07 devnull /* 0 will be server end, 1 will be client end */
153 a2660887 2008-05-07 rsc if(post9pservice(p[1], "plumb", nil) < 0)
154 1ab0f6f0 2005-01-07 devnull fatal("post9pservice plumb: %r");
155 1ab0f6f0 2005-01-07 devnull close(p[1]);
157 1ab0f6f0 2005-01-07 devnull return p[0];
160 1ab0f6f0 2005-01-07 devnull /* start a stub on the remote server */
162 1ab0f6f0 2005-01-07 devnull call(char *rsys, char *ns, char *srv)
164 1ab0f6f0 2005-01-07 devnull int p[2];
166 1ab0f6f0 2005-01-07 devnull char *av[12];
167 1ab0f6f0 2005-01-07 devnull char buf[2];
169 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
170 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
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;
182 1ab0f6f0 2005-01-07 devnull av[ac++] = "-s";
183 1ab0f6f0 2005-01-07 devnull av[ac++] = srv;
185 351f474b 2008-12-07 rsc av[ac++] = "-x";
186 1ab0f6f0 2005-01-07 devnull av[ac] = 0;
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");
195 1ab0f6f0 2005-01-07 devnull switch(fork()){
196 1ab0f6f0 2005-01-07 devnull case -1:
197 1ab0f6f0 2005-01-07 devnull fatal("%r");
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:
208 1ab0f6f0 2005-01-07 devnull close(p[1]);
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)
219 1ab0f6f0 2005-01-07 devnull buf[0] = buf[1];
221 1ab0f6f0 2005-01-07 devnull if(debug)
222 1ab0f6f0 2005-01-07 devnull fprint(dfd, "got OK\n");
224 1ab0f6f0 2005-01-07 devnull return p[0];
229 1ab0f6f0 2005-01-07 devnull BLEN=16*1024
233 1ab0f6f0 2005-01-07 devnull shuffle(void *arg)
235 1ab0f6f0 2005-01-07 devnull int *fd;
236 1ab0f6f0 2005-01-07 devnull char *buf, *tbuf;
238 1ab0f6f0 2005-01-07 devnull Fcall *t;
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);
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]);
260 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d %F\n", fd[0], fd[1], t);
262 1ab0f6f0 2005-01-07 devnull if(write(fd[1], buf, n) != n)
268 351f474b 2008-12-07 rsc remoteside(void *v)
270 1ab0f6f0 2005-01-07 devnull int srv_to_net[2];
271 1ab0f6f0 2005-01-07 devnull int net_to_srv[2];
272 1ab0f6f0 2005-01-07 devnull char *addr;
273 1ab0f6f0 2005-01-07 devnull int srvfd;
275 1ab0f6f0 2005-01-07 devnull if(ns == nil)
276 1ab0f6f0 2005-01-07 devnull ns = getns();
278 1ab0f6f0 2005-01-07 devnull addr = smprint("unix!%s/%s", ns, srv);
279 1ab0f6f0 2005-01-07 devnull if(addr == nil)
280 1ab0f6f0 2005-01-07 devnull fatal("%r");
281 1ab0f6f0 2005-01-07 devnull if(debug)
282 1ab0f6f0 2005-01-07 devnull fprint(dfd, "remoteside starting %s\n", addr);
284 1ab0f6f0 2005-01-07 devnull srvfd = dial(addr, 0, 0, 0);
285 1ab0f6f0 2005-01-07 devnull if(srvfd < 0)
286 1ab0f6f0 2005-01-07 devnull fatal("dial %s: %r", addr);
287 1ab0f6f0 2005-01-07 devnull if(debug)
288 1ab0f6f0 2005-01-07 devnull fprint(dfd, "remoteside dial %s succeeded\n", addr);
289 1ab0f6f0 2005-01-07 devnull fcntl(srvfd, F_SETFL, FD_CLOEXEC);
291 1ab0f6f0 2005-01-07 devnull /* threads to shuffle messages each way */
292 1ab0f6f0 2005-01-07 devnull srv_to_net[0] = srvfd;
293 351f474b 2008-12-07 rsc srv_to_net[1] = netfd[1];
294 1ab0f6f0 2005-01-07 devnull proccreate(shuffle, srv_to_net, Stack);
295 351f474b 2008-12-07 rsc net_to_srv[0] = netfd[0];
296 1ab0f6f0 2005-01-07 devnull net_to_srv[1] = srvfd;
297 1ab0f6f0 2005-01-07 devnull shuffle(net_to_srv);
299 1ab0f6f0 2005-01-07 devnull threadexitsall(0);
303 1ab0f6f0 2005-01-07 devnull emalloc(int size)
305 1ab0f6f0 2005-01-07 devnull void *x;
307 1ab0f6f0 2005-01-07 devnull x = malloc(size);
308 1ab0f6f0 2005-01-07 devnull if(x == nil)
309 1ab0f6f0 2005-01-07 devnull fatal("allocation fails: %r");
310 1ab0f6f0 2005-01-07 devnull return x;