xref: /plan9/sys/src/cmd/srv.c (revision 3b56890da2282dbd3cc0fc1501f968e20f5e5f6a)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier #include <auth.h>
53e12c5d1SDavid du Colombier 
69a747e4fSDavid du Colombier char	*dest = "system";
77dd7cddfSDavid du Colombier int	mountflag = MREPL;
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier void	error(char *);
103e12c5d1SDavid du Colombier void	rpc(int, int);
113e12c5d1SDavid du Colombier void	post(char*, int);
123e12c5d1SDavid du Colombier void	mountfs(char*, int);
13*3b56890dSDavid du Colombier int	doauth = 1;
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier void
usage(void)163e12c5d1SDavid du Colombier usage(void)
173e12c5d1SDavid du Colombier {
189a747e4fSDavid du Colombier 	fprint(2, "usage: %s [-abcCm] [net!]host [srvname [mtpt]]\n", argv0);
19d9306527SDavid du Colombier 	fprint(2, "    or %s -e [-abcCm] command [srvname [mtpt]]\n", argv0);
20d9306527SDavid du Colombier 
213e12c5d1SDavid du Colombier 	exits("usage");
223e12c5d1SDavid du Colombier }
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier void
ignore(void * a,char * c)257dd7cddfSDavid du Colombier ignore(void *a, char *c)
267dd7cddfSDavid du Colombier {
277dd7cddfSDavid du Colombier 	USED(a);
287dd7cddfSDavid du Colombier 	if(strcmp(c, "alarm") == 0){
299a747e4fSDavid du Colombier 		fprint(2, "srv: timeout establishing connection to %s\n", dest);
307dd7cddfSDavid du Colombier 		exits("timeout");
317dd7cddfSDavid du Colombier 	}
32d9306527SDavid du Colombier 	if(strstr(c, "write on closed pipe") == 0){
33d9306527SDavid du Colombier 		fprint(2, "write on closed pipe\n");
34d9306527SDavid du Colombier 		noted(NCONT);
35d9306527SDavid du Colombier 	}
367dd7cddfSDavid du Colombier 	noted(NDFLT);
377dd7cddfSDavid du Colombier }
387dd7cddfSDavid du Colombier 
39d9306527SDavid du Colombier int
connectcmd(char * cmd)40d9306527SDavid du Colombier connectcmd(char *cmd)
41d9306527SDavid du Colombier {
42d9306527SDavid du Colombier 	int p[2];
43d9306527SDavid du Colombier 
44d9306527SDavid du Colombier 	if(pipe(p) < 0)
45d9306527SDavid du Colombier 		return -1;
46d9306527SDavid du Colombier 	switch(fork()){
47d9306527SDavid du Colombier 	case -1:
48d9306527SDavid du Colombier 		fprint(2, "fork failed: %r\n");
49d9306527SDavid du Colombier 		_exits("exec");
50d9306527SDavid du Colombier 	case 0:
516b6b9ac8SDavid du Colombier 		rfork(RFNOTEG);
52d9306527SDavid du Colombier 		dup(p[0], 0);
53d9306527SDavid du Colombier 		dup(p[0], 1);
54d9306527SDavid du Colombier 		close(p[1]);
55d9306527SDavid du Colombier 		execl("/bin/rc", "rc", "-c", cmd, nil);
56d9306527SDavid du Colombier 		fprint(2, "exec failed: %r\n");
57d9306527SDavid du Colombier 		_exits("exec");
58d9306527SDavid du Colombier 	default:
59d9306527SDavid du Colombier 		close(p[0]);
60d9306527SDavid du Colombier 		return p[1];
61d9306527SDavid du Colombier 	}
62d9306527SDavid du Colombier }
63d9306527SDavid du Colombier 
647dd7cddfSDavid du Colombier void
main(int argc,char * argv[])653e12c5d1SDavid du Colombier main(int argc, char *argv[])
663e12c5d1SDavid du Colombier {
67d9306527SDavid du Colombier 	int fd, doexec;
685411dee8SDavid du Colombier 	char *srv, *mtpt;
699a747e4fSDavid du Colombier 	char dir[1024];
709a747e4fSDavid du Colombier 	char err[ERRMAX];
71219b2ee8SDavid du Colombier 	char *p, *p2;
72d9306527SDavid du Colombier 	int domount, reallymount, try, sleeptime;
737dd7cddfSDavid du Colombier 
747dd7cddfSDavid du Colombier 	notify(ignore);
753e12c5d1SDavid du Colombier 
76bd389b36SDavid du Colombier 	domount = 0;
777dd7cddfSDavid du Colombier 	reallymount = 0;
78d9306527SDavid du Colombier 	doexec = 0;
79d9306527SDavid du Colombier 	sleeptime = 0;
807dd7cddfSDavid du Colombier 
813e12c5d1SDavid du Colombier 	ARGBEGIN{
827dd7cddfSDavid du Colombier 	case 'a':
837dd7cddfSDavid du Colombier 		mountflag |= MAFTER;
847dd7cddfSDavid du Colombier 		domount = 1;
857dd7cddfSDavid du Colombier 		reallymount = 1;
867dd7cddfSDavid du Colombier 		break;
877dd7cddfSDavid du Colombier 	case 'b':
887dd7cddfSDavid du Colombier 		mountflag |= MBEFORE;
897dd7cddfSDavid du Colombier 		domount = 1;
907dd7cddfSDavid du Colombier 		reallymount = 1;
917dd7cddfSDavid du Colombier 		break;
927dd7cddfSDavid du Colombier 	case 'c':
937dd7cddfSDavid du Colombier 		mountflag |= MCREATE;
947dd7cddfSDavid du Colombier 		domount = 1;
957dd7cddfSDavid du Colombier 		reallymount = 1;
967dd7cddfSDavid du Colombier 		break;
977dd7cddfSDavid du Colombier 	case 'C':
987dd7cddfSDavid du Colombier 		mountflag |= MCACHE;
997dd7cddfSDavid du Colombier 		domount = 1;
1007dd7cddfSDavid du Colombier 		reallymount = 1;
1017dd7cddfSDavid du Colombier 		break;
102d9306527SDavid du Colombier 	case 'e':
103d9306527SDavid du Colombier 		doexec = 1;
104d9306527SDavid du Colombier 		break;
1053e12c5d1SDavid du Colombier 	case 'm':
1063e12c5d1SDavid du Colombier 		domount = 1;
1077dd7cddfSDavid du Colombier 		reallymount = 1;
1087dd7cddfSDavid du Colombier 		break;
109*3b56890dSDavid du Colombier 	case 'n':
110*3b56890dSDavid du Colombier 		doauth = 0;
111*3b56890dSDavid du Colombier 		break;
1127dd7cddfSDavid du Colombier 	case 'q':
1137dd7cddfSDavid du Colombier 		domount = 1;
1147dd7cddfSDavid du Colombier 		reallymount = 0;
1153e12c5d1SDavid du Colombier 		break;
1163e12c5d1SDavid du Colombier 	case 'r':
1179a747e4fSDavid du Colombier 		/* deprecated -r flag; ignored for compatibility */
1183e12c5d1SDavid du Colombier 		break;
119d9306527SDavid du Colombier 	case 's':
120d9306527SDavid du Colombier 		sleeptime = atoi(EARGF(usage()));
121d9306527SDavid du Colombier 		break;
1223e12c5d1SDavid du Colombier 	default:
1233e12c5d1SDavid du Colombier 		usage();
1243e12c5d1SDavid du Colombier 		break;
1253e12c5d1SDavid du Colombier 	}ARGEND
1263e12c5d1SDavid du Colombier 
1277dd7cddfSDavid du Colombier 	if((mountflag&MAFTER)&&(mountflag&MBEFORE))
1287dd7cddfSDavid du Colombier 		usage();
1297dd7cddfSDavid du Colombier 
1303e12c5d1SDavid du Colombier 	switch(argc){
1313e12c5d1SDavid du Colombier 	case 1:	/* calculate srv and mtpt from address */
1323e12c5d1SDavid du Colombier 		p = strrchr(argv[0], '/');
1333e12c5d1SDavid du Colombier 		p = p ? p+1 : argv[0];
1345411dee8SDavid du Colombier 		srv = smprint("/srv/%s", p);
1353e12c5d1SDavid du Colombier 		p2 = strchr(p, '!');
1363e12c5d1SDavid du Colombier 		p2 = p2 ? p2+1 : p;
1375411dee8SDavid du Colombier 		mtpt = smprint("/n/%s", p2);
1383e12c5d1SDavid du Colombier 		break;
1393e12c5d1SDavid du Colombier 	case 2:	/* calculate mtpt from address, srv given */
1405411dee8SDavid du Colombier 		srv = smprint("/srv/%s", argv[1]);
1413e12c5d1SDavid du Colombier 		p = strrchr(argv[0], '/');
1423e12c5d1SDavid du Colombier 		p = p ? p+1 : argv[0];
1433e12c5d1SDavid du Colombier 		p2 = strchr(p, '!');
1443e12c5d1SDavid du Colombier 		p2 = p2 ? p2+1 : p;
1455411dee8SDavid du Colombier 		mtpt = smprint("/n/%s", p2);
1463e12c5d1SDavid du Colombier 		break;
1473e12c5d1SDavid du Colombier 	case 3:	/* srv and mtpt given */
1483e12c5d1SDavid du Colombier 		domount = 1;
1497dd7cddfSDavid du Colombier 		reallymount = 1;
1505411dee8SDavid du Colombier 		srv = smprint("/srv/%s", argv[1]);
1515411dee8SDavid du Colombier 		mtpt = smprint("%s", argv[2]);
1523e12c5d1SDavid du Colombier 		break;
1533e12c5d1SDavid du Colombier 	default:
1545411dee8SDavid du Colombier 		srv = mtpt = nil;
1553e12c5d1SDavid du Colombier 		usage();
1563e12c5d1SDavid du Colombier 	}
1573e12c5d1SDavid du Colombier 
1583e12c5d1SDavid du Colombier 	try = 0;
1599a747e4fSDavid du Colombier 	dest = *argv;
1603e12c5d1SDavid du Colombier Again:
1613e12c5d1SDavid du Colombier 	try++;
1629a747e4fSDavid du Colombier 
1633e12c5d1SDavid du Colombier 	if(access(srv, 0) == 0){
1643e12c5d1SDavid du Colombier 		if(domount){
1653e12c5d1SDavid du Colombier 			fd = open(srv, ORDWR);
1663e12c5d1SDavid du Colombier 			if(fd >= 0)
1673e12c5d1SDavid du Colombier 				goto Mount;
1683e12c5d1SDavid du Colombier 			remove(srv);
1693e12c5d1SDavid du Colombier 		}
1703e12c5d1SDavid du Colombier 		else{
1713e12c5d1SDavid du Colombier 			fprint(2, "srv: %s already exists\n", srv);
1723e12c5d1SDavid du Colombier 			exits(0);
1733e12c5d1SDavid du Colombier 		}
1743e12c5d1SDavid du Colombier 	}
1753e12c5d1SDavid du Colombier 
1769a747e4fSDavid du Colombier 	alarm(10000);
177d9306527SDavid du Colombier 	if(doexec)
178d9306527SDavid du Colombier 		fd = connectcmd(dest);
179d9306527SDavid du Colombier 	else{
1809a747e4fSDavid du Colombier 		dest = netmkaddr(dest, 0, "9fs");
1819a747e4fSDavid du Colombier 		fd = dial(dest, 0, dir, 0);
182d9306527SDavid du Colombier 	}
1833e12c5d1SDavid du Colombier 	if(fd < 0) {
1849a747e4fSDavid du Colombier 		fprint(2, "srv: dial %s: %r\n", dest);
1853e12c5d1SDavid du Colombier 		exits("dial");
1863e12c5d1SDavid du Colombier 	}
1879a747e4fSDavid du Colombier 	alarm(0);
1883e12c5d1SDavid du Colombier 
189d9306527SDavid du Colombier 	if(sleeptime){
190d9306527SDavid du Colombier 		fprint(2, "sleep...");
191d9306527SDavid du Colombier 		sleep(sleeptime*1000);
192d9306527SDavid du Colombier 	}
193d9306527SDavid du Colombier 
1943e12c5d1SDavid du Colombier 	post(srv, fd);
1953e12c5d1SDavid du Colombier 
1963e12c5d1SDavid du Colombier Mount:
1977dd7cddfSDavid du Colombier 	if(domount == 0 || reallymount == 0)
1983e12c5d1SDavid du Colombier 		exits(0);
1993e12c5d1SDavid du Colombier 
200*3b56890dSDavid du Colombier 	if((!doauth && mount(fd, -1, mtpt, mountflag, "") < 0)
201*3b56890dSDavid du Colombier 	|| (doauth && amount(fd, mtpt, mountflag, "") < 0)){
202219b2ee8SDavid du Colombier 		err[0] = 0;
2039a747e4fSDavid du Colombier 		errstr(err, sizeof err);
2043ff48bf5SDavid du Colombier 		if(strstr(err, "Hangup") || strstr(err, "hungup") || strstr(err, "timed out")){
2053e12c5d1SDavid du Colombier 			remove(srv);
2063e12c5d1SDavid du Colombier 			if(try == 1)
2073e12c5d1SDavid du Colombier 				goto Again;
2083e12c5d1SDavid du Colombier 		}
2093e12c5d1SDavid du Colombier 		fprint(2, "srv %s: mount failed: %s\n", dest, err);
2103e12c5d1SDavid du Colombier 		exits("mount");
2113e12c5d1SDavid du Colombier 	}
2123e12c5d1SDavid du Colombier 	exits(0);
2133e12c5d1SDavid du Colombier }
2143e12c5d1SDavid du Colombier 
2153e12c5d1SDavid du Colombier void
post(char * srv,int fd)2163e12c5d1SDavid du Colombier post(char *srv, int fd)
2173e12c5d1SDavid du Colombier {
2183e12c5d1SDavid du Colombier 	int f;
2193e12c5d1SDavid du Colombier 	char buf[128];
2203e12c5d1SDavid du Colombier 
2213e12c5d1SDavid du Colombier 	fprint(2, "post...\n");
2223e12c5d1SDavid du Colombier 	f = create(srv, OWRITE, 0666);
2233e12c5d1SDavid du Colombier 	if(f < 0){
2243e12c5d1SDavid du Colombier 		sprint(buf, "create(%s)", srv);
2253e12c5d1SDavid du Colombier 		error(buf);
2263e12c5d1SDavid du Colombier 	}
2273e12c5d1SDavid du Colombier 	sprint(buf, "%d", fd);
2283e12c5d1SDavid du Colombier 	if(write(f, buf, strlen(buf)) != strlen(buf))
2293e12c5d1SDavid du Colombier 		error("write");
2303e12c5d1SDavid du Colombier }
2313e12c5d1SDavid du Colombier 
2323e12c5d1SDavid du Colombier void
error(char * s)2333e12c5d1SDavid du Colombier error(char *s)
2343e12c5d1SDavid du Colombier {
2353e12c5d1SDavid du Colombier 	fprint(2, "srv %s: %s: %r\n", dest, s);
2363e12c5d1SDavid du Colombier 	exits("srv: error");
2373e12c5d1SDavid du Colombier }
238