xref: /plan9/sys/src/cmd/srv.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
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 
14 void
15 usage(void)
16 {
17 	fprint(2, "usage: %s [-abcCm] [net!]host [srvname [mtpt]]\n", argv0);
18 		exits("usage");
19 }
20 
21 void
22 ignore(void *a, char *c)
23 {
24 	USED(a);
25 	if(strcmp(c, "alarm") == 0){
26 		fprint(2, "srv: timeout establishing connection to %s\n", dest);
27 		exits("timeout");
28 	}
29 	noted(NDFLT);
30 }
31 
32 void
33 main(int argc, char *argv[])
34 {
35 	int fd;
36 	char srv[64], mtpt[64];
37 	char dir[1024];
38 	char err[ERRMAX];
39 	char *p, *p2;
40 	int domount, reallymount, try;
41 
42 	notify(ignore);
43 
44 	domount = 0;
45 	reallymount = 0;
46 
47 	ARGBEGIN{
48 	case 'a':
49 		mountflag |= MAFTER;
50 		domount = 1;
51 		reallymount = 1;
52 		break;
53 	case 'b':
54 		mountflag |= MBEFORE;
55 		domount = 1;
56 		reallymount = 1;
57 		break;
58 	case 'c':
59 		mountflag |= MCREATE;
60 		domount = 1;
61 		reallymount = 1;
62 		break;
63 	case 'C':
64 		mountflag |= MCACHE;
65 		domount = 1;
66 		reallymount = 1;
67 		break;
68 	case 'm':
69 		domount = 1;
70 		reallymount = 1;
71 		break;
72 	case 'q':
73 		domount = 1;
74 		reallymount = 0;
75 		break;
76 	case 'r':
77 		/* deprecated -r flag; ignored for compatibility */
78 		break;
79 	default:
80 		usage();
81 		break;
82 	}ARGEND
83 
84 	if((mountflag&MAFTER)&&(mountflag&MBEFORE))
85 		usage();
86 
87 	switch(argc){
88 	case 1:	/* calculate srv and mtpt from address */
89 		p = strrchr(argv[0], '/');
90 		p = p ? p+1 : argv[0];
91 		snprint(srv, sizeof(srv), "/srv/%.28s", p);
92 		p2 = strchr(p, '!');
93 		p2 = p2 ? p2+1 : p;
94 		snprint(mtpt, sizeof(mtpt), "/n/%.28s", p2);
95 		break;
96 	case 2:	/* calculate mtpt from address, srv given */
97 		snprint(srv, sizeof(srv), "/srv/%.28s", argv[1]);
98 		p = strrchr(argv[0], '/');
99 		p = p ? p+1 : argv[0];
100 		p2 = strchr(p, '!');
101 		p2 = p2 ? p2+1 : p;
102 		snprint(mtpt, sizeof(mtpt), "/n/%.28s", p2);
103 		break;
104 	case 3:	/* srv and mtpt given */
105 		domount = 1;
106 		reallymount = 1;
107 		snprint(srv, sizeof(srv), "/srv/%.28s", argv[1]);
108 		snprint(mtpt, sizeof(mtpt), "%.28s", argv[2]);
109 		break;
110 	default:
111 		usage();
112 	}
113 
114 	try = 0;
115 	dest = *argv;
116 Again:
117 	try++;
118 
119 	if(access(srv, 0) == 0){
120 		if(domount){
121 			fd = open(srv, ORDWR);
122 			if(fd >= 0)
123 				goto Mount;
124 			remove(srv);
125 		}
126 		else{
127 			fprint(2, "srv: %s already exists\n", srv);
128 			exits(0);
129 		}
130 	}
131 
132 	alarm(10000);
133 	dest = netmkaddr(dest, 0, "9fs");
134 	fd = dial(dest, 0, dir, 0);
135 	if(fd < 0) {
136 		fprint(2, "srv: dial %s: %r\n", dest);
137 		exits("dial");
138 	}
139 	alarm(0);
140 
141 	post(srv, fd);
142 
143 Mount:
144 	if(domount == 0 || reallymount == 0)
145 		exits(0);
146 
147 	if(amount(fd, mtpt, mountflag, "") < 0){
148 		err[0] = 0;
149 		errstr(err, sizeof err);
150 		if(strstr(err, "hungup") || strstr(err, "timed out")){
151 			remove(srv);
152 			if(try == 1)
153 				goto Again;
154 		}
155 		fprint(2, "srv %s: mount failed: %s\n", dest, err);
156 		exits("mount");
157 	}
158 	exits(0);
159 }
160 
161 void
162 post(char *srv, int fd)
163 {
164 	int f;
165 	char buf[128];
166 
167 	fprint(2, "post...\n");
168 	f = create(srv, OWRITE, 0666);
169 	if(f < 0){
170 		sprint(buf, "create(%s)", srv);
171 		error(buf);
172 	}
173 	sprint(buf, "%d", fd);
174 	if(write(f, buf, strlen(buf)) != strlen(buf))
175 		error("write");
176 }
177 
178 void
179 error(char *s)
180 {
181 	fprint(2, "srv %s: %s: %r\n", dest, s);
182 	exits("srv: error");
183 }
184