1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <auth.h>
5
6 char *dest = "system";
7 int mountflag = MREPL;
8
9 void error(char *);
10 void rpc(int, int);
11 void post(char*, int);
12 void mountfs(char*, int);
13 int doauth = 1;
14
15 void
usage(void)16 usage(void)
17 {
18 fprint(2, "usage: %s [-abcCm] [net!]host [srvname [mtpt]]\n", argv0);
19 fprint(2, " or %s -e [-abcCm] command [srvname [mtpt]]\n", argv0);
20
21 exits("usage");
22 }
23
24 void
ignore(void * a,char * c)25 ignore(void *a, char *c)
26 {
27 USED(a);
28 if(strcmp(c, "alarm") == 0){
29 fprint(2, "srv: timeout establishing connection to %s\n", dest);
30 exits("timeout");
31 }
32 if(strstr(c, "write on closed pipe") == 0){
33 fprint(2, "write on closed pipe\n");
34 noted(NCONT);
35 }
36 noted(NDFLT);
37 }
38
39 int
connectcmd(char * cmd)40 connectcmd(char *cmd)
41 {
42 int p[2];
43
44 if(pipe(p) < 0)
45 return -1;
46 switch(fork()){
47 case -1:
48 fprint(2, "fork failed: %r\n");
49 _exits("exec");
50 case 0:
51 rfork(RFNOTEG);
52 dup(p[0], 0);
53 dup(p[0], 1);
54 close(p[1]);
55 execl("/bin/rc", "rc", "-c", cmd, nil);
56 fprint(2, "exec failed: %r\n");
57 _exits("exec");
58 default:
59 close(p[0]);
60 return p[1];
61 }
62 }
63
64 void
main(int argc,char * argv[])65 main(int argc, char *argv[])
66 {
67 int fd, doexec;
68 char *srv, *mtpt;
69 char dir[1024];
70 char err[ERRMAX];
71 char *p, *p2;
72 int domount, reallymount, try, sleeptime;
73
74 notify(ignore);
75
76 domount = 0;
77 reallymount = 0;
78 doexec = 0;
79 sleeptime = 0;
80
81 ARGBEGIN{
82 case 'a':
83 mountflag |= MAFTER;
84 domount = 1;
85 reallymount = 1;
86 break;
87 case 'b':
88 mountflag |= MBEFORE;
89 domount = 1;
90 reallymount = 1;
91 break;
92 case 'c':
93 mountflag |= MCREATE;
94 domount = 1;
95 reallymount = 1;
96 break;
97 case 'C':
98 mountflag |= MCACHE;
99 domount = 1;
100 reallymount = 1;
101 break;
102 case 'e':
103 doexec = 1;
104 break;
105 case 'm':
106 domount = 1;
107 reallymount = 1;
108 break;
109 case 'n':
110 doauth = 0;
111 break;
112 case 'q':
113 domount = 1;
114 reallymount = 0;
115 break;
116 case 'r':
117 /* deprecated -r flag; ignored for compatibility */
118 break;
119 case 's':
120 sleeptime = atoi(EARGF(usage()));
121 break;
122 default:
123 usage();
124 break;
125 }ARGEND
126
127 if((mountflag&MAFTER)&&(mountflag&MBEFORE))
128 usage();
129
130 switch(argc){
131 case 1: /* calculate srv and mtpt from address */
132 p = strrchr(argv[0], '/');
133 p = p ? p+1 : argv[0];
134 srv = smprint("/srv/%s", p);
135 p2 = strchr(p, '!');
136 p2 = p2 ? p2+1 : p;
137 mtpt = smprint("/n/%s", p2);
138 break;
139 case 2: /* calculate mtpt from address, srv given */
140 srv = smprint("/srv/%s", argv[1]);
141 p = strrchr(argv[0], '/');
142 p = p ? p+1 : argv[0];
143 p2 = strchr(p, '!');
144 p2 = p2 ? p2+1 : p;
145 mtpt = smprint("/n/%s", p2);
146 break;
147 case 3: /* srv and mtpt given */
148 domount = 1;
149 reallymount = 1;
150 srv = smprint("/srv/%s", argv[1]);
151 mtpt = smprint("%s", argv[2]);
152 break;
153 default:
154 srv = mtpt = nil;
155 usage();
156 }
157
158 try = 0;
159 dest = *argv;
160 Again:
161 try++;
162
163 if(access(srv, 0) == 0){
164 if(domount){
165 fd = open(srv, ORDWR);
166 if(fd >= 0)
167 goto Mount;
168 remove(srv);
169 }
170 else{
171 fprint(2, "srv: %s already exists\n", srv);
172 exits(0);
173 }
174 }
175
176 alarm(10000);
177 if(doexec)
178 fd = connectcmd(dest);
179 else{
180 dest = netmkaddr(dest, 0, "9fs");
181 fd = dial(dest, 0, dir, 0);
182 }
183 if(fd < 0) {
184 fprint(2, "srv: dial %s: %r\n", dest);
185 exits("dial");
186 }
187 alarm(0);
188
189 if(sleeptime){
190 fprint(2, "sleep...");
191 sleep(sleeptime*1000);
192 }
193
194 post(srv, fd);
195
196 Mount:
197 if(domount == 0 || reallymount == 0)
198 exits(0);
199
200 if((!doauth && mount(fd, -1, mtpt, mountflag, "") < 0)
201 || (doauth && amount(fd, mtpt, mountflag, "") < 0)){
202 err[0] = 0;
203 errstr(err, sizeof err);
204 if(strstr(err, "Hangup") || strstr(err, "hungup") || strstr(err, "timed out")){
205 remove(srv);
206 if(try == 1)
207 goto Again;
208 }
209 fprint(2, "srv %s: mount failed: %s\n", dest, err);
210 exits("mount");
211 }
212 exits(0);
213 }
214
215 void
post(char * srv,int fd)216 post(char *srv, int fd)
217 {
218 int f;
219 char buf[128];
220
221 fprint(2, "post...\n");
222 f = create(srv, OWRITE, 0666);
223 if(f < 0){
224 sprint(buf, "create(%s)", srv);
225 error(buf);
226 }
227 sprint(buf, "%d", fd);
228 if(write(f, buf, strlen(buf)) != strlen(buf))
229 error("write");
230 }
231
232 void
error(char * s)233 error(char *s)
234 {
235 fprint(2, "srv %s: %s: %r\n", dest, s);
236 exits("srv: error");
237 }
238