xref: /plan9/sys/src/cmd/srv.c (revision 3b56890da2282dbd3cc0fc1501f968e20f5e5f6a)
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