xref: /plan9/sys/src/cmd/srv.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <auth.h>
5 #include <fcall.h>
6 
7 Fcall	hdr;
8 char	dest[2*NAMELEN];
9 
10 void	error(char *);
11 int	cyclone(void);
12 void	rpc(int, int);
13 void	post(char*, int);
14 void	mountfs(char*, int);
15 
16 void
17 usage(void)
18 {
19 	fprint(2, "usage: %s [-m] [net!]host [srvname [mtpt]]\n", argv0);
20 		exits("usage");
21 }
22 
23 void
24 main(int argc, char *argv[])
25 {
26 	int fd, cfd;
27 	char srv[64], mtpt[64];
28 	char dir[NAMELEN*4];
29 	char err[ERRLEN];
30 	char tickets[2*TICKETLEN];
31 	char *p, *p2;
32 	int domount, record, try;
33 
34 	domount = 0;
35 	record = 0;
36 	ARGBEGIN{
37 	case 'm':
38 		domount = 1;
39 		break;
40 	case 'r':
41 		record = 1;
42 		break;
43 	default:
44 		usage();
45 		break;
46 	}ARGEND
47 
48 	switch(argc){
49 	case 1:	/* calculate srv and mtpt from address */
50 		p = strrchr(argv[0], '/');
51 		p = p ? p+1 : argv[0];
52 		sprint(srv, "/srv/%.28s", p);
53 		p2 = strchr(p, '!');
54 		p2 = p2 ? p2+1 : p;
55 		sprint(mtpt, "/n/%.28s", p2);
56 		break;
57 	case 2:	/* calculate mtpt from address, srv given */
58 		sprint(srv, "/srv/%.28s", argv[1]);
59 		p = strrchr(argv[0], '/');
60 		p = p ? p+1 : argv[0];
61 		p2 = strchr(p, '!');
62 		p2 = p2 ? p2+1 : p;
63 		sprint(mtpt, "/n/%.28s", p2);
64 		break;
65 	case 3:	/* srv and mtpt given */
66 		domount = 1;
67 		sprint(srv, "/srv/%.28s", argv[1]);
68 		sprint(mtpt, "%.28s", argv[2]);
69 		break;
70 	default:
71 		usage();
72 	}
73 
74 	try = 0;
75 Again:
76 	try++;
77 	if(access(srv, 0) == 0){
78 		if(domount){
79 			fd = open(srv, ORDWR);
80 			if(fd >= 0)
81 				goto Mount;
82 			remove(srv);
83 		}
84 		else{
85 			fprint(2, "srv: %s already exists\n", srv);
86 			exits(0);
87 		}
88 	}
89 
90 	strcpy(dest, *argv);
91 
92 	if(strncmp(*argv, "cyc!", 4) == 0)
93 		fd = cyclone();
94 	else {
95 		fd = dial(netmkaddr(*argv, 0, "9fs"), 0, dir, &cfd);
96 		if(fd < 0) {
97 			fprint(2, "srv: dial %s: %r\n", netmkaddr(*argv, 0, "9fs"));
98 			exits("dial");
99 		}
100 		if(record || strstr(dir, "tcp")) {
101 			if(write(cfd, "push fcall", 10) < 0) {
102 				fprint(2, "srv: push fcall %r\n");
103 				exits(0);
104 			}
105 			close(cfd);
106 		}
107 	}
108 
109 	fprint(2, "session...");
110 	fsession(fd, tickets);
111 	post(srv, fd);
112 
113 Mount:
114 	if(domount == 0)
115 		exits(0);
116 
117 	if(amount(fd, mtpt, MREPL, "") < 0){
118 		err[0] = 0;
119 		errstr(err);
120 		if(strstr(err, "hungup") || strstr(err, "timed out")){
121 			remove(srv);
122 			if(try == 1)
123 				goto Again;
124 		}
125 		fprint(2, "srv %s: mount failed: %s\n", dest, err);
126 		exits("mount");
127 	}
128 	exits(0);
129 }
130 
131 void
132 post(char *srv, int fd)
133 {
134 	int f;
135 	char buf[128];
136 
137 	fprint(2, "post...\n");
138 	f = create(srv, OWRITE, 0666);
139 	if(f < 0){
140 		sprint(buf, "create(%s)", srv);
141 		error(buf);
142 	}
143 	sprint(buf, "%d", fd);
144 	if(write(f, buf, strlen(buf)) != strlen(buf))
145 		error("write");
146 }
147 
148 int
149 cyclone(void)
150 {
151 	int fd;
152 
153 	fd = open("#H/hotrod", ORDWR);
154 	if(fd < 0)
155 		error("opening #H/hotrod");
156 	return fd;
157 }
158 
159 void
160 error(char *s)
161 {
162 	fprint(2, "srv %s: %s: %r\n", dest, s);
163 	exits("srv: error");
164 }
165