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 b3a20a96 2020-12-30 rsc }
53 b3a20a96 2020-12-30 rsc
54 b3a20a96 2020-12-30 rsc int
55 b3a20a96 2020-12-30 rsc threadmaybackground(void)
56 b3a20a96 2020-12-30 rsc {
57 b3a20a96 2020-12-30 rsc return 1;
58 1ab0f6f0 2005-01-07 devnull }
59 1ab0f6f0 2005-01-07 devnull
60 1ab0f6f0 2005-01-07 devnull void
61 1ab0f6f0 2005-01-07 devnull threadmain(int argc, char *argv[])
62 1ab0f6f0 2005-01-07 devnull {
63 1ab0f6f0 2005-01-07 devnull int dofork;
64 1ab0f6f0 2005-01-07 devnull int rem;
65 351f474b 2008-12-07 rsc void (*fn)(void*);
66 1ab0f6f0 2005-01-07 devnull
67 1ab0f6f0 2005-01-07 devnull dofork = 1;
68 1ab0f6f0 2005-01-07 devnull rem = 0;
69 1ab0f6f0 2005-01-07 devnull ns = nil;
70 1ab0f6f0 2005-01-07 devnull srv = "plumb";
71 1ab0f6f0 2005-01-07 devnull
72 1ab0f6f0 2005-01-07 devnull ARGBEGIN{
73 1ab0f6f0 2005-01-07 devnull case 'd':
74 1ab0f6f0 2005-01-07 devnull debug = 1;
75 1ab0f6f0 2005-01-07 devnull break;
76 1ab0f6f0 2005-01-07 devnull case 'f':
77 1ab0f6f0 2005-01-07 devnull dofork = 0;
78 1ab0f6f0 2005-01-07 devnull break;
79 cbeb0b26 2006-04-01 devnull case 'n': /* name of remote namespace */
80 1ab0f6f0 2005-01-07 devnull ns = EARGF(usage());
81 1ab0f6f0 2005-01-07 devnull break;
82 1ab0f6f0 2005-01-07 devnull case 'p':
83 1ab0f6f0 2005-01-07 devnull prog = EARGF(usage());
84 1ab0f6f0 2005-01-07 devnull break;
85 cbeb0b26 2006-04-01 devnull case 's': /* name of service */
86 1ab0f6f0 2005-01-07 devnull srv = EARGF(usage());
87 1ab0f6f0 2005-01-07 devnull break;
88 1ab0f6f0 2005-01-07 devnull case 'R':
89 1ab0f6f0 2005-01-07 devnull rem = 1;
90 1ab0f6f0 2005-01-07 devnull break;
91 351f474b 2008-12-07 rsc case 'x':
92 351f474b 2008-12-07 rsc export = 1;
93 351f474b 2008-12-07 rsc break;
94 1ab0f6f0 2005-01-07 devnull }ARGEND
95 1ab0f6f0 2005-01-07 devnull
96 1ab0f6f0 2005-01-07 devnull if(debug){
97 1ab0f6f0 2005-01-07 devnull char *dbgfile;
98 1ab0f6f0 2005-01-07 devnull
99 1ab0f6f0 2005-01-07 devnull if(rem)
100 1ab0f6f0 2005-01-07 devnull dbgfile = smprint("/tmp/%s.export.debug", getuser());
101 1ab0f6f0 2005-01-07 devnull else
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);
106 1ab0f6f0 2005-01-07 devnull }
107 1ab0f6f0 2005-01-07 devnull
108 fa325e9b 2020-01-10 cross
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);
113 351f474b 2008-12-07 rsc }else{
114 351f474b 2008-12-07 rsc if(argc != 1)
115 351f474b 2008-12-07 rsc usage();
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);
119 1ab0f6f0 2005-01-07 devnull }
120 1ab0f6f0 2005-01-07 devnull
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;
124 fa325e9b 2020-01-10 cross
125 351f474b 2008-12-07 rsc if(rem || !dofork)
126 351f474b 2008-12-07 rsc fn(nil);
127 1ab0f6f0 2005-01-07 devnull else
128 351f474b 2008-12-07 rsc proccreate(fn, nil, Stack);
129 1ab0f6f0 2005-01-07 devnull }
130 1ab0f6f0 2005-01-07 devnull
131 351f474b 2008-12-07 rsc
132 1ab0f6f0 2005-01-07 devnull void
133 351f474b 2008-12-07 rsc localside(void *arg)
134 1ab0f6f0 2005-01-07 devnull {
135 1ab0f6f0 2005-01-07 devnull USED(arg);
136 1ab0f6f0 2005-01-07 devnull
137 351f474b 2008-12-07 rsc /* start a loal service */
138 1ab0f6f0 2005-01-07 devnull srvfd = post(srv);
139 1ab0f6f0 2005-01-07 devnull
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);
147 1ab0f6f0 2005-01-07 devnull }
148 1ab0f6f0 2005-01-07 devnull
149 1ab0f6f0 2005-01-07 devnull /* post a local service */
150 1ab0f6f0 2005-01-07 devnull int
151 1ab0f6f0 2005-01-07 devnull post(char *srv)
152 1ab0f6f0 2005-01-07 devnull {
153 1ab0f6f0 2005-01-07 devnull int p[2];
154 1ab0f6f0 2005-01-07 devnull
155 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
156 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
157 1ab0f6f0 2005-01-07 devnull
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]);
162 1ab0f6f0 2005-01-07 devnull
163 1ab0f6f0 2005-01-07 devnull return p[0];
164 1ab0f6f0 2005-01-07 devnull }
165 1ab0f6f0 2005-01-07 devnull
166 1ab0f6f0 2005-01-07 devnull /* start a stub on the remote server */
167 1ab0f6f0 2005-01-07 devnull int
168 1ab0f6f0 2005-01-07 devnull call(char *rsys, char *ns, char *srv)
169 1ab0f6f0 2005-01-07 devnull {
170 1ab0f6f0 2005-01-07 devnull int p[2];
171 1ab0f6f0 2005-01-07 devnull int ac;
172 1ab0f6f0 2005-01-07 devnull char *av[12];
173 1ab0f6f0 2005-01-07 devnull char buf[2];
174 1ab0f6f0 2005-01-07 devnull
175 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
176 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
177 1ab0f6f0 2005-01-07 devnull ac = 0;
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;
187 1ab0f6f0 2005-01-07 devnull }
188 1ab0f6f0 2005-01-07 devnull av[ac++] = "-s";
189 1ab0f6f0 2005-01-07 devnull av[ac++] = srv;
190 351f474b 2008-12-07 rsc if(export)
191 351f474b 2008-12-07 rsc av[ac++] = "-x";
192 1ab0f6f0 2005-01-07 devnull av[ac] = 0;
193 1ab0f6f0 2005-01-07 devnull
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");
199 1ab0f6f0 2005-01-07 devnull }
200 1ab0f6f0 2005-01-07 devnull
201 1ab0f6f0 2005-01-07 devnull switch(fork()){
202 1ab0f6f0 2005-01-07 devnull case -1:
203 1ab0f6f0 2005-01-07 devnull fatal("%r");
204 1ab0f6f0 2005-01-07 devnull case 0:
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:
212 1ab0f6f0 2005-01-07 devnull break;
213 1ab0f6f0 2005-01-07 devnull }
214 1ab0f6f0 2005-01-07 devnull close(p[1]);
215 1ab0f6f0 2005-01-07 devnull
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)
224 1ab0f6f0 2005-01-07 devnull break;
225 1ab0f6f0 2005-01-07 devnull buf[0] = buf[1];
226 1ab0f6f0 2005-01-07 devnull }
227 1ab0f6f0 2005-01-07 devnull if(debug)
228 1ab0f6f0 2005-01-07 devnull fprint(dfd, "got OK\n");
229 1ab0f6f0 2005-01-07 devnull
230 1ab0f6f0 2005-01-07 devnull return p[0];
231 1ab0f6f0 2005-01-07 devnull }
232 1ab0f6f0 2005-01-07 devnull
233 1ab0f6f0 2005-01-07 devnull enum
234 1ab0f6f0 2005-01-07 devnull {
235 1ab0f6f0 2005-01-07 devnull BLEN=16*1024
236 1ab0f6f0 2005-01-07 devnull };
237 1ab0f6f0 2005-01-07 devnull
238 1ab0f6f0 2005-01-07 devnull void
239 1ab0f6f0 2005-01-07 devnull shuffle(void *arg)
240 1ab0f6f0 2005-01-07 devnull {
241 1ab0f6f0 2005-01-07 devnull int *fd;
242 1ab0f6f0 2005-01-07 devnull char *buf, *tbuf;
243 1ab0f6f0 2005-01-07 devnull int n;
244 1ab0f6f0 2005-01-07 devnull Fcall *t;
245 1ab0f6f0 2005-01-07 devnull
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);
255 1ab0f6f0 2005-01-07 devnull break;
256 1ab0f6f0 2005-01-07 devnull }
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]);
265 1ab0f6f0 2005-01-07 devnull else
266 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d %F\n", fd[0], fd[1], t);
267 1ab0f6f0 2005-01-07 devnull }
268 1ab0f6f0 2005-01-07 devnull if(write(fd[1], buf, n) != n)
269 1ab0f6f0 2005-01-07 devnull break;
270 1ab0f6f0 2005-01-07 devnull }
271 dc6625ea 2010-11-03 rsc threadexitsall(0);
272 1ab0f6f0 2005-01-07 devnull }
273 1ab0f6f0 2005-01-07 devnull
274 1ab0f6f0 2005-01-07 devnull void
275 351f474b 2008-12-07 rsc remoteside(void *v)
276 1ab0f6f0 2005-01-07 devnull {
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;
281 1ab0f6f0 2005-01-07 devnull
282 1ab0f6f0 2005-01-07 devnull if(ns == nil)
283 1ab0f6f0 2005-01-07 devnull ns = getns();
284 1ab0f6f0 2005-01-07 devnull
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);
290 1ab0f6f0 2005-01-07 devnull
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);
297 1ab0f6f0 2005-01-07 devnull
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);
305 1ab0f6f0 2005-01-07 devnull
306 1ab0f6f0 2005-01-07 devnull threadexitsall(0);
307 1ab0f6f0 2005-01-07 devnull }
308 1ab0f6f0 2005-01-07 devnull
309 1ab0f6f0 2005-01-07 devnull void*
310 1ab0f6f0 2005-01-07 devnull emalloc(int size)
311 1ab0f6f0 2005-01-07 devnull {
312 1ab0f6f0 2005-01-07 devnull void *x;
313 1ab0f6f0 2005-01-07 devnull
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;
318 1ab0f6f0 2005-01-07 devnull }