Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <thread.h>
6 enum {
7 Encnone,
8 Encssl,
9 Enctls,
10 };
12 static char *encprotos[] = {
13 [Encnone] = "clear",
14 [Encssl] = "ssl",
15 [Enctls] = "tls",
16 nil,
17 };
19 char *keyspec = "";
20 char *filterp;
21 char *ealgs = "rc4_256 sha1";
22 int encproto = Encnone;
23 AuthInfo *ai;
24 int debug;
25 int doauth = 1;
26 int timedout;
28 int connectez(char*, char*);
29 void sysfatal(char*, ...);
30 void usage(void);
31 int filter(int, char *, char *);
33 int
34 catcher(void *v, char *msg)
35 {
36 timedout = 1;
37 if(strcmp(msg, "alarm") == 0)
38 return 1;
39 return 0;
40 }
42 static int
43 lookup(char *s, char *l[])
44 {
45 int i;
47 for (i = 0; l[i] != 0; i++)
48 if (strcmp(l[i], s) == 0)
49 return i;
50 return -1;
51 }
53 static char*
54 srvname(char *addr)
55 {
56 int i;
58 for(i=0; i<strlen(addr); i++){
59 if(addr[i] == '!')
60 addr[i] = ':';
61 }
62 return addr;
63 }
65 void
66 threadmain(int argc, char **argv)
67 {
68 char *mntpt, *srvpost, srvfile[64];
69 int fd;
71 quotefmtinstall();
72 srvpost = nil;
73 ARGBEGIN{
74 case 'A':
75 doauth = 0;
76 break;
77 case 'd':
78 debug++;
79 break;
80 case 'E':
81 if ((encproto = lookup(EARGF(usage()), encprotos)) < 0)
82 usage();
83 break;
84 case 'e':
85 ealgs = EARGF(usage());
86 if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
87 ealgs = nil;
88 break;
89 case 'k':
90 keyspec = EARGF(usage());
91 break;
92 case 'p':
93 filterp = unsharp("#9/bin/aan");
94 break;
95 case 's':
96 srvpost = EARGF(usage());
97 break;
98 default:
99 usage();
100 }ARGEND;
102 mntpt = 0; /* to shut up compiler */
103 switch(argc) {
104 case 2:
105 mntpt = argv[1];
106 break;
107 case 3:
108 mntpt = argv[2];
109 break;
110 default:
111 usage();
114 if(encproto != Encnone)
115 sysfatal("%s: tls and ssl have not yet been implemented", argv[0]);
117 threadnotify(catcher, 1);
118 alarm(60*1000);
120 fd = connectez(argv[0], argv[1]);
122 fprint(fd, "impo %s %s\n", filterp? "aan": "nofilter",
123 encprotos[encproto]);
125 if (filterp)
126 fd = filter(fd, filterp, argv[0]);
128 if(srvpost == nil)
129 srvpost = srvname(argv[0]);
130 sprint(srvfile, "%s", srvpost);
132 if(post9pservice(fd, srvfile, mntpt) < 0)
133 sysfatal("can't post %s: %r", argv[1]);
134 alarm(0);
136 threadexitsall(0);
139 /* the name "connect" is special */
140 int
141 connectez(char *system, char *tree)
143 char buf[ERRMAX], *na;
144 int fd, n;
145 char *authp;
147 na = netmkaddr(system, "tcp", "exportfs");
148 threadsetname("dial %s", na);
149 if((fd = dial(na, nil, nil, nil)) < 0)
150 sysfatal("can't dial %s: %r", system);
152 if(doauth){
153 authp = "p9any";
154 threadsetname("auth_proxy auth_getkey proto=%q role=client %s",
155 authp, keyspec);
156 ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s",
157 authp, keyspec);
158 if(ai == nil)
159 sysfatal("%r: %s", system);
162 threadsetname("writing tree name %s", tree);
163 n = write(fd, tree, strlen(tree));
164 if(n < 0)
165 sysfatal("can't write tree: %r");
167 strcpy(buf, "can't read tree");
169 threadsetname("awaiting OK for %s", tree);
170 n = read(fd, buf, sizeof buf - 1);
171 if(n!=2 || buf[0]!='O' || buf[1]!='K'){
172 if (timedout)
173 sysfatal("timed out connecting to %s", na);
174 buf[sizeof buf - 1] = '\0';
175 sysfatal("bad remote tree: %s", buf);
178 return fd;
181 void
182 usage(void)
184 fprint(2, "usage: 9import [-A] [-E clear|ssl|tls] "
185 "[-e 'crypt auth'|clear] [-k keypattern] [-p] [-s srv] host remotefs [mountpoint]\n");
186 threadexitsall("usage");
189 /* Network on fd1, mount driver on fd0 */
190 int
191 filter(int fd, char *cmd, char *host)
193 int p[2], len, argc;
194 char newport[256], buf[256], *s;
195 char *argv[16], *file, *pbuf;
197 if ((len = read(fd, newport, sizeof newport - 1)) < 0)
198 sysfatal("filter: cannot write port; %r");
199 newport[len] = '\0';
201 if ((s = strchr(newport, '!')) == nil)
202 sysfatal("filter: illegally formatted port %s", newport);
204 strecpy(buf, buf+sizeof buf, netmkaddr(host, "tcp", "0"));
205 pbuf = strrchr(buf, '!');
206 strecpy(pbuf, buf+sizeof buf, s);
208 if(debug)
209 fprint(2, "filter: remote port %s\n", newport);
211 argc = tokenize(cmd, argv, nelem(argv)-2);
212 if (argc == 0)
213 sysfatal("filter: empty command");
214 argv[argc++] = "-c";
215 argv[argc++] = buf;
216 argv[argc] = nil;
217 file = argv[0];
218 if (s = strrchr(argv[0], '/'))
219 argv[0] = s+1;
221 if(pipe(p) < 0)
222 sysfatal("pipe: %r");
224 switch(rfork(RFNOWAIT|RFPROC|RFFDG)) {
225 case -1:
226 sysfatal("rfork record module: %r");
227 case 0:
228 dup(p[0], 1);
229 dup(p[0], 0);
230 close(p[0]);
231 close(p[1]);
232 exec(file, argv);
233 sysfatal("exec record module: %r");
234 default:
235 close(fd);
236 close(p[0]);
238 return p[1];