]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/srv.c
ip/ipconfig: format ipmask with %M instead of %I
[plan9front.git] / sys / src / cmd / srv.c
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4
5 char    *dest = "system";
6 int     mountflag = MREPL;
7
8 void    error(char *);
9 void    rpc(int, int);
10 void    post(char*, int);
11 void    mountfs(char*, int);
12 int     doauth = 1;
13 int     asnone = 0;
14
15 void
16 usage(void)
17 {
18         fprint(2, "usage: %s [-abcCmnNq] [net!]host [srvname [mtpt]]\n", argv0);
19         fprint(2, "    or %s -e [-abcCmnNq] 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[0]);
55                 close(p[1]);
56                 execl("/bin/rc", "rc", "-c", cmd, nil);
57                 fprint(2, "exec failed: %r\n");
58                 _exits("exec");
59         default:
60                 close(p[0]);
61                 return p[1];
62         }
63 }
64
65 void
66 main(int argc, char *argv[])
67 {
68         int fd, doexec;
69         char *srv, *mtpt;
70         char dir[1024];
71         char err[ERRMAX];
72         char *p, *p2;
73         int domount, reallymount, try, sleeptime;
74
75         notify(ignore);
76
77         domount = 0;
78         reallymount = 0;
79         doexec = 0;
80         sleeptime = 0;
81
82         ARGBEGIN{
83         case 'a':
84                 mountflag |= MAFTER;
85                 domount = 1;
86                 reallymount = 1;
87                 break;
88         case 'b':
89                 mountflag |= MBEFORE;
90                 domount = 1;
91                 reallymount = 1;
92                 break;
93         case 'c':
94                 mountflag |= MCREATE;
95                 domount = 1;
96                 reallymount = 1;
97                 break;
98         case 'C':
99                 mountflag |= MCACHE;
100                 domount = 1;
101                 reallymount = 1;
102                 break;
103         case 'e':
104                 doexec = 1;
105                 break;
106         case 'm':
107                 domount = 1;
108                 reallymount = 1;
109                 break;
110         case 'N':
111                 asnone = 1;
112                 /* no break */
113         case 'n':
114                 doauth = 0;
115                 break;
116         case 'q':
117                 domount = 1;
118                 reallymount = 0;
119                 break;
120         case 'r':
121                 /* deprecated -r flag; ignored for compatibility */
122                 break;
123         case 's':
124                 sleeptime = atoi(EARGF(usage()));
125                 break;
126         default:
127                 usage();
128                 break;
129         }ARGEND
130
131         if((mountflag&MAFTER)&&(mountflag&MBEFORE))
132                 usage();
133
134         switch(argc){
135         case 1: /* calculate srv and mtpt from address */
136                 p = strrchr(argv[0], '/');
137                 p = p ? p+1 : argv[0];
138                 srv = smprint("/srv/%s", p);
139                 p2 = strchr(p, '!');
140                 p2 = p2 ? p2+1 : p;
141                 mtpt = smprint("/n/%s", p2);
142                 break;
143         case 2: /* calculate mtpt from address, srv given */
144                 srv = smprint("/srv/%s", argv[1]);
145                 p = strrchr(argv[0], '/');
146                 p = p ? p+1 : argv[0];
147                 p2 = strchr(p, '!');
148                 p2 = p2 ? p2+1 : p;
149                 mtpt = smprint("/n/%s", p2);
150                 break;
151         case 3: /* srv and mtpt given */
152                 domount = 1;
153                 reallymount = 1;
154                 srv = smprint("/srv/%s", argv[1]);
155                 mtpt = smprint("%s", argv[2]);
156                 break;
157         default:
158                 srv = mtpt = nil;
159                 usage();
160         }
161
162         try = 0;
163         dest = *argv;
164 Again:
165         try++;
166
167         if(access(srv, 0) == 0){
168                 if(domount){
169                         fd = open(srv, ORDWR);
170                         if(fd >= 0)
171                                 goto Mount;
172                         remove(srv);
173                 }
174                 else{
175                         fprint(2, "srv: %s already exists\n", srv);
176                         exits(0);
177                 }
178         }
179
180         alarm(10000);
181         if(doexec)
182                 fd = connectcmd(dest);
183         else{
184                 dest = netmkaddr(dest, 0, "9fs");
185                 fd = dial(dest, 0, dir, 0);
186         }
187         if(fd < 0) {
188                 fprint(2, "srv: dial %s: %r\n", dest);
189                 exits("dial");
190         }
191         alarm(0);
192
193         if(sleeptime){
194                 fprint(2, "sleep...");
195                 sleep(sleeptime*1000);
196         }
197
198         post(srv, fd);
199
200 Mount:
201         if(domount == 0 || reallymount == 0)
202                 exits(0);
203
204         if(asnone){
205                 try = open("#c/user", OWRITE);
206                 if(try < 0 || write(try, "none", 4) != 4){
207                         fprint(2, "srv %s: can't become none: %r\n", dest);
208                         exits("becomenone");
209                 }
210                 try = 0;
211         }
212
213         if((!doauth && mount(fd, -1, mtpt, mountflag, "") < 0)
214         || (doauth && amount(fd, mtpt, mountflag, "") < 0)){
215                 err[0] = 0;
216                 errstr(err, sizeof err);
217                 if(strstr(err, "Hangup") || strstr(err, "hungup") || strstr(err, "timed out")){
218                         remove(srv);
219                         if(try == 1)
220                                 goto Again;
221                 }
222                 fprint(2, "srv %s: mount failed: %s\n", dest, err);
223                 exits("mount");
224         }
225         exits(0);
226 }
227
228 void
229 post(char *srv, int fd)
230 {
231         int f;
232         char buf[128];
233
234         fprint(2, "post...\n");
235         f = create(srv, OWRITE, 0666);
236         if(f < 0){
237                 sprint(buf, "create(%s)", srv);
238                 error(buf);
239         }
240         sprint(buf, "%d", fd);
241         if(write(f, buf, strlen(buf)) != strlen(buf))
242                 error("write");
243 }
244
245 void
246 error(char *s)
247 {
248         fprint(2, "srv %s: %s: %r\n", dest, s);
249         exits("srv: error");
250 }