]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/srv.c
cwfs: back to previous version
[plan9front.git] / sys / src / cmd / srv.c
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
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
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
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
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
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
233 error(char *s)
234 {
235         fprint(2, "srv %s: %s: %r\n", dest, s);
236         exits("srv: error");
237 }