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 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;
16 1ab0f6f0 2005-01-07 devnull
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);
23 1ab0f6f0 2005-01-07 devnull
24 1ab0f6f0 2005-01-07 devnull char *REXEXEC = "ssh";
25 1ab0f6f0 2005-01-07 devnull char *prog = "import";
26 1ab0f6f0 2005-01-07 devnull
27 1ab0f6f0 2005-01-07 devnull enum
28 1ab0f6f0 2005-01-07 devnull {
29 1ab0f6f0 2005-01-07 devnull Stack= 32*1024,
30 1ab0f6f0 2005-01-07 devnull };
31 1ab0f6f0 2005-01-07 devnull
32 1ab0f6f0 2005-01-07 devnull void
33 1ab0f6f0 2005-01-07 devnull usage(void)
34 1ab0f6f0 2005-01-07 devnull {
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");
37 1ab0f6f0 2005-01-07 devnull }
38 1ab0f6f0 2005-01-07 devnull
39 1ab0f6f0 2005-01-07 devnull void
40 1ab0f6f0 2005-01-07 devnull fatal(char *fmt, ...)
41 1ab0f6f0 2005-01-07 devnull {
42 1ab0f6f0 2005-01-07 devnull char buf[256];
43 1ab0f6f0 2005-01-07 devnull va_list arg;
44 1ab0f6f0 2005-01-07 devnull
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);
48 1ab0f6f0 2005-01-07 devnull
49 1ab0f6f0 2005-01-07 devnull fprint(2, "%s: %s\n", argv0 ? argv0 : "<prog>", buf);
50 1ab0f6f0 2005-01-07 devnull threadexitsall("fatal");
51 1ab0f6f0 2005-01-07 devnull }
52 1ab0f6f0 2005-01-07 devnull
53 1ab0f6f0 2005-01-07 devnull void
54 1ab0f6f0 2005-01-07 devnull threadmain(int argc, char *argv[])
55 1ab0f6f0 2005-01-07 devnull {
56 1ab0f6f0 2005-01-07 devnull int dofork;
57 1ab0f6f0 2005-01-07 devnull int rem;
58 1ab0f6f0 2005-01-07 devnull
59 1ab0f6f0 2005-01-07 devnull dofork = 1;
60 1ab0f6f0 2005-01-07 devnull rem = 0;
61 1ab0f6f0 2005-01-07 devnull ns = nil;
62 1ab0f6f0 2005-01-07 devnull srv = "plumb";
63 1ab0f6f0 2005-01-07 devnull
64 1ab0f6f0 2005-01-07 devnull ARGBEGIN{
65 1ab0f6f0 2005-01-07 devnull case 'd':
66 1ab0f6f0 2005-01-07 devnull debug = 1;
67 1ab0f6f0 2005-01-07 devnull break;
68 1ab0f6f0 2005-01-07 devnull case 'f':
69 1ab0f6f0 2005-01-07 devnull dofork = 0;
70 1ab0f6f0 2005-01-07 devnull break;
71 1ab0f6f0 2005-01-07 devnull case 'n': // name of remote namespace
72 1ab0f6f0 2005-01-07 devnull ns = EARGF(usage());
73 1ab0f6f0 2005-01-07 devnull break;
74 1ab0f6f0 2005-01-07 devnull case 'p':
75 1ab0f6f0 2005-01-07 devnull prog = EARGF(usage());
76 1ab0f6f0 2005-01-07 devnull break;
77 1ab0f6f0 2005-01-07 devnull case 's': // name of service
78 1ab0f6f0 2005-01-07 devnull srv = EARGF(usage());
79 1ab0f6f0 2005-01-07 devnull break;
80 1ab0f6f0 2005-01-07 devnull case 'R':
81 1ab0f6f0 2005-01-07 devnull rem = 1;
82 1ab0f6f0 2005-01-07 devnull break;
83 1ab0f6f0 2005-01-07 devnull }ARGEND
84 1ab0f6f0 2005-01-07 devnull
85 1ab0f6f0 2005-01-07 devnull if(debug){
86 1ab0f6f0 2005-01-07 devnull char *dbgfile;
87 1ab0f6f0 2005-01-07 devnull
88 1ab0f6f0 2005-01-07 devnull if(rem)
89 1ab0f6f0 2005-01-07 devnull dbgfile = smprint("/tmp/%s.export.debug", getuser());
90 1ab0f6f0 2005-01-07 devnull else
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);
95 1ab0f6f0 2005-01-07 devnull }
96 1ab0f6f0 2005-01-07 devnull
97 1ab0f6f0 2005-01-07 devnull // is this the remote side?
98 1ab0f6f0 2005-01-07 devnull if(rem){
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);
103 1ab0f6f0 2005-01-07 devnull }
104 1ab0f6f0 2005-01-07 devnull
105 1ab0f6f0 2005-01-07 devnull if(argc != 1)
106 1ab0f6f0 2005-01-07 devnull usage();
107 1ab0f6f0 2005-01-07 devnull
108 1ab0f6f0 2005-01-07 devnull addr = argv[0];
109 1ab0f6f0 2005-01-07 devnull
110 1ab0f6f0 2005-01-07 devnull if(dofork)
111 1ab0f6f0 2005-01-07 devnull proccreate(runproc, nil, Stack);
112 1ab0f6f0 2005-01-07 devnull else
113 1ab0f6f0 2005-01-07 devnull runproc(nil);
114 1ab0f6f0 2005-01-07 devnull }
115 1ab0f6f0 2005-01-07 devnull
116 1ab0f6f0 2005-01-07 devnull void
117 1ab0f6f0 2005-01-07 devnull runproc(void *arg)
118 1ab0f6f0 2005-01-07 devnull {
119 1ab0f6f0 2005-01-07 devnull USED(arg);
120 1ab0f6f0 2005-01-07 devnull
121 1ab0f6f0 2005-01-07 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);
124 1ab0f6f0 2005-01-07 devnull
125 1ab0f6f0 2005-01-07 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);
132 1ab0f6f0 2005-01-07 devnull }
133 1ab0f6f0 2005-01-07 devnull
134 1ab0f6f0 2005-01-07 devnull /* post a local service */
135 1ab0f6f0 2005-01-07 devnull int
136 1ab0f6f0 2005-01-07 devnull post(char *srv)
137 1ab0f6f0 2005-01-07 devnull {
138 1ab0f6f0 2005-01-07 devnull int p[2];
139 1ab0f6f0 2005-01-07 devnull
140 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
141 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
142 1ab0f6f0 2005-01-07 devnull
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]);
147 1ab0f6f0 2005-01-07 devnull
148 1ab0f6f0 2005-01-07 devnull return p[0];
149 1ab0f6f0 2005-01-07 devnull }
150 1ab0f6f0 2005-01-07 devnull
151 1ab0f6f0 2005-01-07 devnull /* start a stub on the remote server */
152 1ab0f6f0 2005-01-07 devnull int
153 1ab0f6f0 2005-01-07 devnull call(char *rsys, char *ns, char *srv)
154 1ab0f6f0 2005-01-07 devnull {
155 1ab0f6f0 2005-01-07 devnull int p[2];
156 1ab0f6f0 2005-01-07 devnull int ac;
157 1ab0f6f0 2005-01-07 devnull char *av[12];
158 1ab0f6f0 2005-01-07 devnull char buf[2];
159 1ab0f6f0 2005-01-07 devnull
160 1ab0f6f0 2005-01-07 devnull if(pipe(p) < 0)
161 1ab0f6f0 2005-01-07 devnull fatal("can't create pipe: %r");
162 1ab0f6f0 2005-01-07 devnull ac = 0;
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;
172 1ab0f6f0 2005-01-07 devnull }
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;
176 1ab0f6f0 2005-01-07 devnull
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");
182 1ab0f6f0 2005-01-07 devnull }
183 1ab0f6f0 2005-01-07 devnull
184 1ab0f6f0 2005-01-07 devnull switch(fork()){
185 1ab0f6f0 2005-01-07 devnull case -1:
186 1ab0f6f0 2005-01-07 devnull fatal("%r");
187 1ab0f6f0 2005-01-07 devnull case 0:
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:
195 1ab0f6f0 2005-01-07 devnull break;
196 1ab0f6f0 2005-01-07 devnull }
197 1ab0f6f0 2005-01-07 devnull close(p[1]);
198 1ab0f6f0 2005-01-07 devnull
199 1ab0f6f0 2005-01-07 devnull // ignore crap that might come out of the .profile
200 1ab0f6f0 2005-01-07 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)
207 1ab0f6f0 2005-01-07 devnull break;
208 1ab0f6f0 2005-01-07 devnull buf[0] = buf[1];
209 1ab0f6f0 2005-01-07 devnull }
210 1ab0f6f0 2005-01-07 devnull if(debug)
211 1ab0f6f0 2005-01-07 devnull fprint(dfd, "got OK\n");
212 1ab0f6f0 2005-01-07 devnull
213 1ab0f6f0 2005-01-07 devnull return p[0];
214 1ab0f6f0 2005-01-07 devnull }
215 1ab0f6f0 2005-01-07 devnull
216 1ab0f6f0 2005-01-07 devnull enum
217 1ab0f6f0 2005-01-07 devnull {
218 1ab0f6f0 2005-01-07 devnull BLEN=16*1024
219 1ab0f6f0 2005-01-07 devnull };
220 1ab0f6f0 2005-01-07 devnull
221 1ab0f6f0 2005-01-07 devnull void
222 1ab0f6f0 2005-01-07 devnull shuffle(void *arg)
223 1ab0f6f0 2005-01-07 devnull {
224 1ab0f6f0 2005-01-07 devnull int *fd;
225 1ab0f6f0 2005-01-07 devnull char *buf, *tbuf;
226 1ab0f6f0 2005-01-07 devnull int n;
227 1ab0f6f0 2005-01-07 devnull Fcall *t;
228 1ab0f6f0 2005-01-07 devnull
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);
238 1ab0f6f0 2005-01-07 devnull break;
239 1ab0f6f0 2005-01-07 devnull }
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 1ab0f6f0 2005-01-07 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]);
248 1ab0f6f0 2005-01-07 devnull else
249 1ab0f6f0 2005-01-07 devnull fprint(dfd, "%d->%d %F\n", fd[0], fd[1], t);
250 1ab0f6f0 2005-01-07 devnull }
251 1ab0f6f0 2005-01-07 devnull if(write(fd[1], buf, n) != n)
252 1ab0f6f0 2005-01-07 devnull break;
253 1ab0f6f0 2005-01-07 devnull }
254 1ab0f6f0 2005-01-07 devnull }
255 1ab0f6f0 2005-01-07 devnull
256 1ab0f6f0 2005-01-07 devnull void
257 1ab0f6f0 2005-01-07 devnull remoteside(char *ns, char *srv)
258 1ab0f6f0 2005-01-07 devnull {
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;
263 1ab0f6f0 2005-01-07 devnull
264 1ab0f6f0 2005-01-07 devnull if(ns == nil)
265 1ab0f6f0 2005-01-07 devnull ns = getns();
266 1ab0f6f0 2005-01-07 devnull
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);
272 1ab0f6f0 2005-01-07 devnull
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);
279 1ab0f6f0 2005-01-07 devnull
280 1ab0f6f0 2005-01-07 devnull write(1, "OK", 2);
281 1ab0f6f0 2005-01-07 devnull
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);
289 1ab0f6f0 2005-01-07 devnull
290 1ab0f6f0 2005-01-07 devnull threadexitsall(0);
291 1ab0f6f0 2005-01-07 devnull }
292 1ab0f6f0 2005-01-07 devnull
293 1ab0f6f0 2005-01-07 devnull void*
294 1ab0f6f0 2005-01-07 devnull emalloc(int size)
295 1ab0f6f0 2005-01-07 devnull {
296 1ab0f6f0 2005-01-07 devnull void *x;
297 1ab0f6f0 2005-01-07 devnull
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;
302 1ab0f6f0 2005-01-07 devnull }