2 2277c5d7 2004-03-21 devnull * cpu.c - Make a connection to a cpu server
4 2277c5d7 2004-03-21 devnull * Invoked by listen as 'cpu -R | -N service net netdir'
5 2277c5d7 2004-03-21 devnull * by users as 'cpu [-h system] [-c cmd args ...]'
8 2277c5d7 2004-03-21 devnull #include <u.h>
9 2277c5d7 2004-03-21 devnull #include <libc.h>
10 2277c5d7 2004-03-21 devnull #include <bio.h>
11 2277c5d7 2004-03-21 devnull #include <auth.h>
12 2277c5d7 2004-03-21 devnull #include <fcall.h>
13 2277c5d7 2004-03-21 devnull #include <libsec.h>
15 2277c5d7 2004-03-21 devnull #define Maxfdata 8192
17 2277c5d7 2004-03-21 devnull void remoteside(int);
18 2277c5d7 2004-03-21 devnull void fatal(int, char*, ...);
19 2277c5d7 2004-03-21 devnull void lclnoteproc(int);
20 2277c5d7 2004-03-21 devnull void rmtnoteproc(void);
21 2277c5d7 2004-03-21 devnull void catcher(void*, char*);
22 2277c5d7 2004-03-21 devnull void usage(void);
23 2277c5d7 2004-03-21 devnull void writestr(int, char*, char*, int);
24 2277c5d7 2004-03-21 devnull int readstr(int, char*, int);
25 2277c5d7 2004-03-21 devnull char *rexcall(int*, char*, char*);
26 2277c5d7 2004-03-21 devnull int setamalg(char*);
28 2277c5d7 2004-03-21 devnull int notechan;
29 2277c5d7 2004-03-21 devnull char system[32];
30 2277c5d7 2004-03-21 devnull int cflag;
31 2277c5d7 2004-03-21 devnull int hflag;
33 2277c5d7 2004-03-21 devnull char *user;
35 2277c5d7 2004-03-21 devnull char *srvname = "ncpu";
36 2277c5d7 2004-03-21 devnull char *exportfs = "/bin/exportfs";
37 2277c5d7 2004-03-21 devnull char *ealgs = "rc4_256 sha1";
39 2277c5d7 2004-03-21 devnull /* message size for exportfs; may be larger so we can do big graphics in CPU window */
40 2277c5d7 2004-03-21 devnull int msgsize = 8192+IOHDRSZ;
42 2277c5d7 2004-03-21 devnull /* authentication mechanisms */
43 2277c5d7 2004-03-21 devnull static int netkeyauth(int);
44 2277c5d7 2004-03-21 devnull static int netkeysrvauth(int, char*);
45 2277c5d7 2004-03-21 devnull static int p9auth(int);
46 2277c5d7 2004-03-21 devnull static int srvp9auth(int, char*);
47 2277c5d7 2004-03-21 devnull static int noauth(int);
48 2277c5d7 2004-03-21 devnull static int srvnoauth(int, char*);
50 2277c5d7 2004-03-21 devnull typedef struct AuthMethod AuthMethod;
51 2277c5d7 2004-03-21 devnull struct AuthMethod {
52 2277c5d7 2004-03-21 devnull char *name; /* name of method */
53 2277c5d7 2004-03-21 devnull int (*cf)(int); /* client side authentication */
54 2277c5d7 2004-03-21 devnull int (*sf)(int, char*); /* server side authentication */
55 2277c5d7 2004-03-21 devnull } authmethod[] =
57 2277c5d7 2004-03-21 devnull { "p9", p9auth, srvp9auth,},
58 2277c5d7 2004-03-21 devnull { "netkey", netkeyauth, netkeysrvauth,},
59 2277c5d7 2004-03-21 devnull // { "none", noauth, srvnoauth,},
60 2277c5d7 2004-03-21 devnull { nil, nil}
62 2277c5d7 2004-03-21 devnull AuthMethod *am = authmethod; /* default is p9 */
64 2277c5d7 2004-03-21 devnull char *p9authproto = "p9any";
66 2277c5d7 2004-03-21 devnull int setam(char*);
69 2277c5d7 2004-03-21 devnull usage(void)
71 2277c5d7 2004-03-21 devnull fprint(2, "usage: cpu [-h system] [-a authmethod] [-e 'crypt hash'] [-c cmd args ...]\n");
72 2277c5d7 2004-03-21 devnull exits("usage");
77 2277c5d7 2004-03-21 devnull main(int argc, char **argv)
79 2277c5d7 2004-03-21 devnull char dat[128], buf[128], cmd[128], *p, *err;
80 2277c5d7 2004-03-21 devnull int fd, ms, kms, data;
82 2277c5d7 2004-03-21 devnull /* see if we should use a larger message size */
83 2277c5d7 2004-03-21 devnull fd = open("/dev/draw", OREAD);
84 2277c5d7 2004-03-21 devnull if(fd > 0){
85 2277c5d7 2004-03-21 devnull ms = iounit(fd);
86 2277c5d7 2004-03-21 devnull if(ms != 0 && ms < ms+IOHDRSZ)
87 2277c5d7 2004-03-21 devnull msgsize = ms+IOHDRSZ;
88 2277c5d7 2004-03-21 devnull close(fd);
90 2277c5d7 2004-03-21 devnull kms = kiounit();
91 2277c5d7 2004-03-21 devnull if(msgsize > kms-IOHDRSZ-100) /* 100 for network packets, etc. */
92 2277c5d7 2004-03-21 devnull msgsize = kms-IOHDRSZ-100;
94 2277c5d7 2004-03-21 devnull user = getuser();
95 2277c5d7 2004-03-21 devnull if(user == nil)
96 2277c5d7 2004-03-21 devnull fatal(1, "can't read user name");
97 2277c5d7 2004-03-21 devnull ARGBEGIN{
98 2277c5d7 2004-03-21 devnull case 'a':
99 2277c5d7 2004-03-21 devnull p = EARGF(usage());
100 2277c5d7 2004-03-21 devnull if(setam(p) < 0)
101 2277c5d7 2004-03-21 devnull fatal(0, "unknown auth method %s", p);
103 2277c5d7 2004-03-21 devnull case 'e':
104 2277c5d7 2004-03-21 devnull ealgs = EARGF(usage());
105 2277c5d7 2004-03-21 devnull if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
106 2277c5d7 2004-03-21 devnull ealgs = nil;
108 2277c5d7 2004-03-21 devnull case 'd':
111 2277c5d7 2004-03-21 devnull case 'f':
112 2277c5d7 2004-03-21 devnull /* ignored but accepted for compatibility */
114 2277c5d7 2004-03-21 devnull case 'O':
115 2277c5d7 2004-03-21 devnull p9authproto = "p9sk2";
116 2277c5d7 2004-03-21 devnull remoteside(1); /* From listen */
118 2277c5d7 2004-03-21 devnull case 'R': /* From listen */
119 2277c5d7 2004-03-21 devnull remoteside(0);
121 2277c5d7 2004-03-21 devnull case 'h':
122 2277c5d7 2004-03-21 devnull hflag++;
123 2277c5d7 2004-03-21 devnull p = EARGF(usage());
124 2277c5d7 2004-03-21 devnull strcpy(system, p);
126 2277c5d7 2004-03-21 devnull case 'c':
127 2277c5d7 2004-03-21 devnull cflag++;
128 2277c5d7 2004-03-21 devnull cmd[0] = '!';
129 2277c5d7 2004-03-21 devnull cmd[1] = '\0';
130 2277c5d7 2004-03-21 devnull while(p = ARGF()) {
131 2277c5d7 2004-03-21 devnull strcat(cmd, " ");
132 2277c5d7 2004-03-21 devnull strcat(cmd, p);
135 2277c5d7 2004-03-21 devnull case 'o':
136 2277c5d7 2004-03-21 devnull p9authproto = "p9sk2";
137 2277c5d7 2004-03-21 devnull srvname = "cpu";
139 2277c5d7 2004-03-21 devnull case 'u':
140 2277c5d7 2004-03-21 devnull user = EARGF(usage());
142 2277c5d7 2004-03-21 devnull default:
143 2277c5d7 2004-03-21 devnull usage();
144 2277c5d7 2004-03-21 devnull }ARGEND;
147 2277c5d7 2004-03-21 devnull if(argc != 0)
148 2277c5d7 2004-03-21 devnull usage();
150 2277c5d7 2004-03-21 devnull if(hflag == 0) {
151 2277c5d7 2004-03-21 devnull p = getenv("cpu");
152 2277c5d7 2004-03-21 devnull if(p == 0)
153 2277c5d7 2004-03-21 devnull fatal(0, "set $cpu");
154 2277c5d7 2004-03-21 devnull strcpy(system, p);
157 2277c5d7 2004-03-21 devnull if(err = rexcall(&data, system, srvname))
158 2277c5d7 2004-03-21 devnull fatal(1, "%s: %s", err, system);
160 2277c5d7 2004-03-21 devnull /* Tell the remote side the command to execute and where our working directory is */
161 2277c5d7 2004-03-21 devnull if(cflag)
162 2277c5d7 2004-03-21 devnull writestr(data, cmd, "command", 0);
163 2277c5d7 2004-03-21 devnull if(getwd(dat, sizeof(dat)) == 0)
164 2277c5d7 2004-03-21 devnull writestr(data, "NO", "dir", 0);
166 2277c5d7 2004-03-21 devnull writestr(data, dat, "dir", 0);
168 2277c5d7 2004-03-21 devnull /* start up a process to pass along notes */
169 2277c5d7 2004-03-21 devnull lclnoteproc(data);
172 2277c5d7 2004-03-21 devnull * Wait for the other end to execute and start our file service
173 2277c5d7 2004-03-21 devnull * of /mnt/term
175 2277c5d7 2004-03-21 devnull if(readstr(data, buf, sizeof(buf)) < 0)
176 2277c5d7 2004-03-21 devnull fatal(1, "waiting for FS");
177 2277c5d7 2004-03-21 devnull if(strncmp("FS", buf, 2) != 0) {
178 2277c5d7 2004-03-21 devnull print("remote cpu: %s", buf);
179 2277c5d7 2004-03-21 devnull exits(buf);
182 2277c5d7 2004-03-21 devnull /* Begin serving the gnot namespace */
183 2277c5d7 2004-03-21 devnull close(0);
184 2277c5d7 2004-03-21 devnull dup(data, 0);
185 2277c5d7 2004-03-21 devnull close(data);
186 2277c5d7 2004-03-21 devnull sprint(buf, "%d", msgsize);
188 2277c5d7 2004-03-21 devnull execl(exportfs, exportfs, "-dm", buf, 0);
190 2277c5d7 2004-03-21 devnull execl(exportfs, exportfs, "-m", buf, 0);
191 2277c5d7 2004-03-21 devnull fatal(1, "starting exportfs");
195 2277c5d7 2004-03-21 devnull fatal(int syserr, char *fmt, ...)
197 2277c5d7 2004-03-21 devnull char buf[ERRMAX];
198 2277c5d7 2004-03-21 devnull va_list arg;
200 2277c5d7 2004-03-21 devnull va_start(arg, fmt);
201 2277c5d7 2004-03-21 devnull doprint(buf, buf+sizeof(buf), fmt, arg);
202 2277c5d7 2004-03-21 devnull va_end(arg);
203 2277c5d7 2004-03-21 devnull if(syserr)
204 2277c5d7 2004-03-21 devnull fprint(2, "cpu: %s: %r\n", buf);
206 2277c5d7 2004-03-21 devnull fprint(2, "cpu: %s\n", buf);
207 2277c5d7 2004-03-21 devnull exits(buf);
210 2277c5d7 2004-03-21 devnull char *negstr = "negotiating authentication method";
212 2277c5d7 2004-03-21 devnull char bug[256];
215 2277c5d7 2004-03-21 devnull old9p(int fd)
217 2277c5d7 2004-03-21 devnull int p[2];
219 2277c5d7 2004-03-21 devnull if(pipe(p) < 0)
220 2277c5d7 2004-03-21 devnull fatal(1, "pipe");
222 2277c5d7 2004-03-21 devnull switch(rfork(RFPROC|RFFDG|RFNAMEG)) {
223 2277c5d7 2004-03-21 devnull case -1:
224 2277c5d7 2004-03-21 devnull fatal(1, "rfork srvold9p");
226 2277c5d7 2004-03-21 devnull if(fd != 1){
227 2277c5d7 2004-03-21 devnull dup(fd, 1);
228 2277c5d7 2004-03-21 devnull close(fd);
230 2277c5d7 2004-03-21 devnull if(p[0] != 0){
231 2277c5d7 2004-03-21 devnull dup(p[0], 0);
232 2277c5d7 2004-03-21 devnull close(p[0]);
234 2277c5d7 2004-03-21 devnull close(p[1]);
236 2277c5d7 2004-03-21 devnull fd = open("/sys/log/cpu", OWRITE);
237 2277c5d7 2004-03-21 devnull if(fd != 2){
238 2277c5d7 2004-03-21 devnull dup(fd, 2);
239 2277c5d7 2004-03-21 devnull close(fd);
241 2277c5d7 2004-03-21 devnull execl("/bin/srvold9p", "srvold9p", "-ds", 0);
243 2277c5d7 2004-03-21 devnull execl("/bin/srvold9p", "srvold9p", "-s", 0);
244 2277c5d7 2004-03-21 devnull fatal(1, "exec srvold9p");
245 2277c5d7 2004-03-21 devnull default:
246 2277c5d7 2004-03-21 devnull close(fd);
247 2277c5d7 2004-03-21 devnull close(p[0]);
249 2277c5d7 2004-03-21 devnull return p[1];
252 2277c5d7 2004-03-21 devnull /* Invoked with stdin, stdout and stderr connected to the network connection */
254 2277c5d7 2004-03-21 devnull remoteside(int old)
256 2277c5d7 2004-03-21 devnull char user[128], home[128], buf[128], xdir[128], cmd[128];
257 2277c5d7 2004-03-21 devnull int i, n, fd, badchdir, gotcmd;
261 2277c5d7 2004-03-21 devnull /* negotiate authentication mechanism */
262 2277c5d7 2004-03-21 devnull n = readstr(fd, cmd, sizeof(cmd));
263 2277c5d7 2004-03-21 devnull if(n < 0)
264 2277c5d7 2004-03-21 devnull fatal(1, "authenticating");
265 2277c5d7 2004-03-21 devnull if(setamalg(cmd) < 0){
266 2277c5d7 2004-03-21 devnull writestr(fd, "unsupported auth method", nil, 0);
267 2277c5d7 2004-03-21 devnull fatal(1, "bad auth method %s", cmd);
269 2277c5d7 2004-03-21 devnull writestr(fd, "", "", 1);
271 2277c5d7 2004-03-21 devnull fd = (*am->sf)(fd, user);
272 2277c5d7 2004-03-21 devnull if(fd < 0)
273 2277c5d7 2004-03-21 devnull fatal(1, "srvauth");
275 2277c5d7 2004-03-21 devnull /* Set environment values for the user */
276 2277c5d7 2004-03-21 devnull putenv("user", user);
277 2277c5d7 2004-03-21 devnull sprint(home, "/usr/%s", user);
278 2277c5d7 2004-03-21 devnull putenv("home", home);
280 2277c5d7 2004-03-21 devnull /* Now collect invoking cpu's current directory or possibly a command */
281 2277c5d7 2004-03-21 devnull gotcmd = 0;
282 2277c5d7 2004-03-21 devnull if(readstr(fd, xdir, sizeof(xdir)) < 0)
283 2277c5d7 2004-03-21 devnull fatal(1, "dir/cmd");
284 2277c5d7 2004-03-21 devnull if(xdir[0] == '!') {
285 2277c5d7 2004-03-21 devnull strcpy(cmd, &xdir[1]);
286 2277c5d7 2004-03-21 devnull gotcmd = 1;
287 2277c5d7 2004-03-21 devnull if(readstr(fd, xdir, sizeof(xdir)) < 0)
288 2277c5d7 2004-03-21 devnull fatal(1, "dir");
291 2277c5d7 2004-03-21 devnull /* Establish the new process at the current working directory of the
292 2277c5d7 2004-03-21 devnull * gnot */
293 2277c5d7 2004-03-21 devnull badchdir = 0;
294 2277c5d7 2004-03-21 devnull if(strcmp(xdir, "NO") == 0)
295 2277c5d7 2004-03-21 devnull chdir(home);
296 2277c5d7 2004-03-21 devnull else if(chdir(xdir) < 0) {
297 2277c5d7 2004-03-21 devnull badchdir = 1;
298 2277c5d7 2004-03-21 devnull chdir(home);
301 2277c5d7 2004-03-21 devnull /* Start the gnot serving its namespace */
302 2277c5d7 2004-03-21 devnull writestr(fd, "FS", "FS", 0);
303 2277c5d7 2004-03-21 devnull writestr(fd, "/", "exportfs dir", 0);
305 2277c5d7 2004-03-21 devnull n = read(fd, buf, sizeof(buf));
306 2277c5d7 2004-03-21 devnull if(n != 2 || buf[0] != 'O' || buf[1] != 'K')
307 2277c5d7 2004-03-21 devnull exits("remote tree");
310 2277c5d7 2004-03-21 devnull fd = old9p(fd);
312 2277c5d7 2004-03-21 devnull /* make sure buffers are big by doing fversion explicitly; pick a huge number; other side will trim */
313 2277c5d7 2004-03-21 devnull strcpy(buf, VERSION9P);
314 2277c5d7 2004-03-21 devnull if(fversion(fd, 64*1024, buf, sizeof buf) < 0)
315 2277c5d7 2004-03-21 devnull exits("fversion failed");
316 2277c5d7 2004-03-21 devnull if(mount(fd, -1, "/mnt/term", MCREATE|MREPL, "") < 0)
317 2277c5d7 2004-03-21 devnull exits("mount failed");
319 2277c5d7 2004-03-21 devnull close(fd);
321 2277c5d7 2004-03-21 devnull /* the remote noteproc uses the mount so it must follow it */
322 2277c5d7 2004-03-21 devnull rmtnoteproc();
324 2277c5d7 2004-03-21 devnull for(i = 0; i < 3; i++)
325 2277c5d7 2004-03-21 devnull close(i);
327 2277c5d7 2004-03-21 devnull if(open("/mnt/term/dev/cons", OREAD) != 0)
328 2277c5d7 2004-03-21 devnull exits("open stdin");
329 2277c5d7 2004-03-21 devnull if(open("/mnt/term/dev/cons", OWRITE) != 1)
330 2277c5d7 2004-03-21 devnull exits("open stdout");
331 2277c5d7 2004-03-21 devnull dup(1, 2);
333 2277c5d7 2004-03-21 devnull if(badchdir)
334 2277c5d7 2004-03-21 devnull print("cpu: failed to chdir to '%s'\n", xdir);
336 2277c5d7 2004-03-21 devnull if(gotcmd)
337 2277c5d7 2004-03-21 devnull execl("/bin/rc", "rc", "-lc", cmd, 0);
339 2277c5d7 2004-03-21 devnull execl("/bin/rc", "rc", "-li", 0);
340 2277c5d7 2004-03-21 devnull fatal(1, "exec shell");
344 2277c5d7 2004-03-21 devnull rexcall(int *fd, char *host, char *service)
346 2277c5d7 2004-03-21 devnull char *na;
347 2277c5d7 2004-03-21 devnull char dir[128];
348 2277c5d7 2004-03-21 devnull char err[ERRMAX];
349 2277c5d7 2004-03-21 devnull char msg[128];
352 2277c5d7 2004-03-21 devnull na = netmkaddr(host, 0, service);
353 2277c5d7 2004-03-21 devnull if((*fd = dial(na, 0, dir, 0)) < 0)
354 2277c5d7 2004-03-21 devnull return "can't dial";
356 2277c5d7 2004-03-21 devnull /* negotiate authentication mechanism */
357 2277c5d7 2004-03-21 devnull if(ealgs != nil)
358 2277c5d7 2004-03-21 devnull snprint(msg, sizeof(msg), "%s %s", am->name, ealgs);
360 2277c5d7 2004-03-21 devnull snprint(msg, sizeof(msg), "%s", am->name);
361 2277c5d7 2004-03-21 devnull writestr(*fd, msg, negstr, 0);
362 2277c5d7 2004-03-21 devnull n = readstr(*fd, err, sizeof err);
363 2277c5d7 2004-03-21 devnull if(n < 0)
364 2277c5d7 2004-03-21 devnull return negstr;
365 2277c5d7 2004-03-21 devnull if(*err){
366 2277c5d7 2004-03-21 devnull werrstr(err);
367 2277c5d7 2004-03-21 devnull return negstr;
370 2277c5d7 2004-03-21 devnull /* authenticate */
371 2277c5d7 2004-03-21 devnull *fd = (*am->cf)(*fd);
372 2277c5d7 2004-03-21 devnull if(*fd < 0)
373 2277c5d7 2004-03-21 devnull return "can't authenticate";
374 2277c5d7 2004-03-21 devnull return 0;
378 2277c5d7 2004-03-21 devnull writestr(int fd, char *str, char *thing, int ignore)
380 2277c5d7 2004-03-21 devnull int l, n;
382 2277c5d7 2004-03-21 devnull l = strlen(str);
383 2277c5d7 2004-03-21 devnull n = write(fd, str, l+1);
384 2277c5d7 2004-03-21 devnull if(!ignore && n < 0)
385 2277c5d7 2004-03-21 devnull fatal(1, "writing network: %s", thing);
389 2277c5d7 2004-03-21 devnull readstr(int fd, char *str, int len)
393 2277c5d7 2004-03-21 devnull while(len) {
394 2277c5d7 2004-03-21 devnull n = read(fd, str, 1);
395 2277c5d7 2004-03-21 devnull if(n < 0)
396 2277c5d7 2004-03-21 devnull return -1;
397 2277c5d7 2004-03-21 devnull if(*str == '\0')
398 2277c5d7 2004-03-21 devnull return 0;
402 2277c5d7 2004-03-21 devnull return -1;
405 2277c5d7 2004-03-21 devnull static int
406 2277c5d7 2004-03-21 devnull readln(char *buf, int n)
408 2277c5d7 2004-03-21 devnull char *p = buf;
411 2277c5d7 2004-03-21 devnull while(n > 0){
412 2277c5d7 2004-03-21 devnull if(read(0, p, 1) != 1)
414 2277c5d7 2004-03-21 devnull if(*p == '\n' || *p == '\r'){
416 2277c5d7 2004-03-21 devnull return p-buf;
421 2277c5d7 2004-03-21 devnull return p-buf;
425 2277c5d7 2004-03-21 devnull * user level challenge/response
427 2277c5d7 2004-03-21 devnull static int
428 2277c5d7 2004-03-21 devnull netkeyauth(int fd)
430 2277c5d7 2004-03-21 devnull char chall[32];
431 2277c5d7 2004-03-21 devnull char resp[32];
433 2277c5d7 2004-03-21 devnull strcpy(chall, getuser());
434 2277c5d7 2004-03-21 devnull print("user[%s]: ", chall);
435 2277c5d7 2004-03-21 devnull if(readln(resp, sizeof(resp)) < 0)
436 2277c5d7 2004-03-21 devnull return -1;
437 2277c5d7 2004-03-21 devnull if(*resp != 0)
438 2277c5d7 2004-03-21 devnull strcpy(chall, resp);
439 2277c5d7 2004-03-21 devnull writestr(fd, chall, "challenge/response", 1);
441 2277c5d7 2004-03-21 devnull for(;;){
442 2277c5d7 2004-03-21 devnull if(readstr(fd, chall, sizeof chall) < 0)
444 2277c5d7 2004-03-21 devnull if(*chall == 0)
445 2277c5d7 2004-03-21 devnull return fd;
446 2277c5d7 2004-03-21 devnull print("challenge: %s\nresponse: ", chall);
447 2277c5d7 2004-03-21 devnull if(readln(resp, sizeof(resp)) < 0)
449 2277c5d7 2004-03-21 devnull writestr(fd, resp, "challenge/response", 1);
451 2277c5d7 2004-03-21 devnull return -1;
454 2277c5d7 2004-03-21 devnull static int
455 2277c5d7 2004-03-21 devnull netkeysrvauth(int fd, char *user)
457 2277c5d7 2004-03-21 devnull char response[32];
458 2277c5d7 2004-03-21 devnull Chalstate *ch;
459 2277c5d7 2004-03-21 devnull int tries;
460 2277c5d7 2004-03-21 devnull AuthInfo *ai;
462 2277c5d7 2004-03-21 devnull if(readstr(fd, user, 32) < 0)
463 2277c5d7 2004-03-21 devnull return -1;
465 2277c5d7 2004-03-21 devnull ai = nil;
466 2277c5d7 2004-03-21 devnull ch = nil;
467 2277c5d7 2004-03-21 devnull for(tries = 0; tries < 10; tries++){
468 2277c5d7 2004-03-21 devnull if((ch = auth_challenge("p9cr", user, nil)) == nil)
469 2277c5d7 2004-03-21 devnull return -1;
470 2277c5d7 2004-03-21 devnull writestr(fd, ch->chal, "challenge", 1);
471 2277c5d7 2004-03-21 devnull if(readstr(fd, response, sizeof response) < 0)
472 2277c5d7 2004-03-21 devnull return -1;
473 2277c5d7 2004-03-21 devnull ch->resp = response;
474 2277c5d7 2004-03-21 devnull ch->nresp = strlen(response);
475 2277c5d7 2004-03-21 devnull if((ai = auth_response(ch)) != nil)
478 2277c5d7 2004-03-21 devnull auth_freechal(ch);
479 2277c5d7 2004-03-21 devnull if(ai == nil)
480 2277c5d7 2004-03-21 devnull return -1;
481 2277c5d7 2004-03-21 devnull writestr(fd, "", "challenge", 1);
482 2277c5d7 2004-03-21 devnull if(auth_chuid(ai, 0) < 0)
483 2277c5d7 2004-03-21 devnull fatal(1, "newns");
484 2277c5d7 2004-03-21 devnull auth_freeAI(ai);
485 2277c5d7 2004-03-21 devnull return fd;
488 2277c5d7 2004-03-21 devnull static void
489 2277c5d7 2004-03-21 devnull mksecret(char *t, uchar *f)
491 2277c5d7 2004-03-21 devnull sprint(t, "%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
492 2277c5d7 2004-03-21 devnull f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9]);
496 2277c5d7 2004-03-21 devnull * plan9 authentication followed by rc4 encryption
498 2277c5d7 2004-03-21 devnull static int
499 2277c5d7 2004-03-21 devnull p9auth(int fd)
501 2277c5d7 2004-03-21 devnull uchar key[16];
502 2277c5d7 2004-03-21 devnull uchar digest[SHA1dlen];
503 2277c5d7 2004-03-21 devnull char fromclientsecret[21];
504 2277c5d7 2004-03-21 devnull char fromserversecret[21];
506 2277c5d7 2004-03-21 devnull AuthInfo *ai;
508 2277c5d7 2004-03-21 devnull ai = auth_proxy(fd, auth_getkey, "proto=%q user=%q role=client", p9authproto, user);
509 2277c5d7 2004-03-21 devnull if(ai == nil)
510 2277c5d7 2004-03-21 devnull return -1;
511 2277c5d7 2004-03-21 devnull memmove(key+4, ai->secret, ai->nsecret);
512 2277c5d7 2004-03-21 devnull if(ealgs == nil)
513 2277c5d7 2004-03-21 devnull return fd;
515 2277c5d7 2004-03-21 devnull /* exchange random numbers */
516 2277c5d7 2004-03-21 devnull srand(truerand());
517 2277c5d7 2004-03-21 devnull for(i = 0; i < 4; i++)
518 2277c5d7 2004-03-21 devnull key[i] = rand();
519 2277c5d7 2004-03-21 devnull if(write(fd, key, 4) != 4)
520 2277c5d7 2004-03-21 devnull return -1;
521 2277c5d7 2004-03-21 devnull if(readn(fd, key+12, 4) != 4)
522 2277c5d7 2004-03-21 devnull return -1;
524 2277c5d7 2004-03-21 devnull /* scramble into two secrets */
525 2277c5d7 2004-03-21 devnull sha1(key, sizeof(key), digest, nil);
526 2277c5d7 2004-03-21 devnull mksecret(fromclientsecret, digest);
527 2277c5d7 2004-03-21 devnull mksecret(fromserversecret, digest+10);
529 2277c5d7 2004-03-21 devnull /* set up encryption */
530 2277c5d7 2004-03-21 devnull i = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
531 2277c5d7 2004-03-21 devnull if(i < 0)
532 2277c5d7 2004-03-21 devnull werrstr("can't establish ssl connection: %r");
533 2277c5d7 2004-03-21 devnull return i;
536 2277c5d7 2004-03-21 devnull static int
537 2277c5d7 2004-03-21 devnull noauth(int fd)
539 2277c5d7 2004-03-21 devnull ealgs = nil;
540 2277c5d7 2004-03-21 devnull return fd;
543 2277c5d7 2004-03-21 devnull static int
544 2277c5d7 2004-03-21 devnull srvnoauth(int fd, char *user)
546 2277c5d7 2004-03-21 devnull strcpy(user, getuser());
547 2277c5d7 2004-03-21 devnull ealgs = nil;
548 2277c5d7 2004-03-21 devnull return fd;
552 2277c5d7 2004-03-21 devnull loghex(uchar *p, int n)
554 2277c5d7 2004-03-21 devnull char buf[100];
557 2277c5d7 2004-03-21 devnull for(i = 0; i < n; i++)
558 2277c5d7 2004-03-21 devnull sprint(buf+2*i, "%2.2ux", p[i]);
559 2277c5d7 2004-03-21 devnull syslog(0, "cpu", buf);
562 2277c5d7 2004-03-21 devnull static int
563 2277c5d7 2004-03-21 devnull srvp9auth(int fd, char *user)
565 2277c5d7 2004-03-21 devnull uchar key[16];
566 2277c5d7 2004-03-21 devnull uchar digest[SHA1dlen];
567 2277c5d7 2004-03-21 devnull char fromclientsecret[21];
568 2277c5d7 2004-03-21 devnull char fromserversecret[21];
570 2277c5d7 2004-03-21 devnull AuthInfo *ai;
572 2277c5d7 2004-03-21 devnull ai = auth_proxy(0, nil, "proto=%q role=server", p9authproto);
573 2277c5d7 2004-03-21 devnull if(ai == nil)
574 2277c5d7 2004-03-21 devnull return -1;
575 2277c5d7 2004-03-21 devnull if(auth_chuid(ai, nil) < 0)
576 2277c5d7 2004-03-21 devnull return -1;
577 2277c5d7 2004-03-21 devnull strcpy(user, ai->cuid);
578 2277c5d7 2004-03-21 devnull memmove(key+4, ai->secret, ai->nsecret);
580 2277c5d7 2004-03-21 devnull if(ealgs == nil)
581 2277c5d7 2004-03-21 devnull return fd;
583 2277c5d7 2004-03-21 devnull /* exchange random numbers */
584 2277c5d7 2004-03-21 devnull srand(truerand());
585 2277c5d7 2004-03-21 devnull for(i = 0; i < 4; i++)
586 2277c5d7 2004-03-21 devnull key[i+12] = rand();
587 2277c5d7 2004-03-21 devnull if(readn(fd, key, 4) != 4)
588 2277c5d7 2004-03-21 devnull return -1;
589 2277c5d7 2004-03-21 devnull if(write(fd, key+12, 4) != 4)
590 2277c5d7 2004-03-21 devnull return -1;
592 2277c5d7 2004-03-21 devnull /* scramble into two secrets */
593 2277c5d7 2004-03-21 devnull sha1(key, sizeof(key), digest, nil);
594 2277c5d7 2004-03-21 devnull mksecret(fromclientsecret, digest);
595 2277c5d7 2004-03-21 devnull mksecret(fromserversecret, digest+10);
597 2277c5d7 2004-03-21 devnull /* set up encryption */
598 2277c5d7 2004-03-21 devnull i = pushssl(fd, ealgs, fromserversecret, fromclientsecret, nil);
599 2277c5d7 2004-03-21 devnull if(i < 0)
600 2277c5d7 2004-03-21 devnull werrstr("can't establish ssl connection: %r");
601 2277c5d7 2004-03-21 devnull return i;
605 2277c5d7 2004-03-21 devnull * set authentication mechanism
608 2277c5d7 2004-03-21 devnull setam(char *name)
610 2277c5d7 2004-03-21 devnull for(am = authmethod; am->name != nil; am++)
611 2277c5d7 2004-03-21 devnull if(strcmp(am->name, name) == 0)
612 2277c5d7 2004-03-21 devnull return 0;
613 2277c5d7 2004-03-21 devnull am = authmethod;
614 2277c5d7 2004-03-21 devnull return -1;
618 2277c5d7 2004-03-21 devnull * set authentication mechanism and encryption/hash algs
621 2277c5d7 2004-03-21 devnull setamalg(char *s)
623 2277c5d7 2004-03-21 devnull ealgs = strchr(s, ' ');
624 2277c5d7 2004-03-21 devnull if(ealgs != nil)
625 2277c5d7 2004-03-21 devnull *ealgs++ = 0;
626 2277c5d7 2004-03-21 devnull return setam(s);
629 2277c5d7 2004-03-21 devnull char *rmtnotefile = "/mnt/term/dev/cpunote";
632 2277c5d7 2004-03-21 devnull * loop reading /mnt/term/dev/note looking for notes.
633 2277c5d7 2004-03-21 devnull * The child returns to start the shell.
636 2277c5d7 2004-03-21 devnull rmtnoteproc(void)
638 2277c5d7 2004-03-21 devnull int n, fd, pid, notepid;
639 2277c5d7 2004-03-21 devnull char buf[256];
641 2277c5d7 2004-03-21 devnull /* new proc returns to start shell */
642 2277c5d7 2004-03-21 devnull pid = rfork(RFPROC|RFFDG|RFNOTEG|RFNAMEG|RFMEM);
643 2277c5d7 2004-03-21 devnull switch(pid){
644 2277c5d7 2004-03-21 devnull case -1:
645 2277c5d7 2004-03-21 devnull syslog(0, "cpu", "cpu -R: can't start noteproc: %r");
651 2277c5d7 2004-03-21 devnull /* new proc reads notes from other side and posts them to shell */
652 2277c5d7 2004-03-21 devnull switch(notepid = rfork(RFPROC|RFFDG|RFMEM)){
653 2277c5d7 2004-03-21 devnull case -1:
654 2277c5d7 2004-03-21 devnull syslog(0, "cpu", "cpu -R: can't start wait proc: %r");
655 2277c5d7 2004-03-21 devnull _exits(0);
657 2277c5d7 2004-03-21 devnull fd = open(rmtnotefile, OREAD);
658 2277c5d7 2004-03-21 devnull if(fd < 0){
659 2277c5d7 2004-03-21 devnull syslog(0, "cpu", "cpu -R: can't open %s", rmtnotefile);
660 2277c5d7 2004-03-21 devnull _exits(0);
663 2277c5d7 2004-03-21 devnull for(;;){
664 2277c5d7 2004-03-21 devnull n = read(fd, buf, sizeof(buf)-1);
665 2277c5d7 2004-03-21 devnull if(n <= 0){
666 2277c5d7 2004-03-21 devnull postnote(PNGROUP, pid, "hangup");
667 2277c5d7 2004-03-21 devnull _exits(0);
669 2277c5d7 2004-03-21 devnull buf[n] = 0;
670 2277c5d7 2004-03-21 devnull postnote(PNGROUP, pid, buf);
675 2277c5d7 2004-03-21 devnull /* original proc waits for shell proc to die and kills note proc */
676 2277c5d7 2004-03-21 devnull for(;;){
677 2277c5d7 2004-03-21 devnull n = waitpid();
678 2277c5d7 2004-03-21 devnull if(n < 0 || n == pid)
681 2277c5d7 2004-03-21 devnull postnote(PNPROC, notepid, "kill");
682 2277c5d7 2004-03-21 devnull _exits(0);
688 2277c5d7 2004-03-21 devnull Qcpunote,
690 2277c5d7 2004-03-21 devnull Nfid = 32,
693 2277c5d7 2004-03-21 devnull struct {
694 2277c5d7 2004-03-21 devnull char *name;
695 2277c5d7 2004-03-21 devnull Qid qid;
696 2277c5d7 2004-03-21 devnull ulong perm;
697 2277c5d7 2004-03-21 devnull } fstab[] =
699 2277c5d7 2004-03-21 devnull [Qdir] { ".", {Qdir, 0, QTDIR}, DMDIR|0555 },
700 2277c5d7 2004-03-21 devnull [Qcpunote] { "cpunote", {Qcpunote, 0}, 0444 },
703 2277c5d7 2004-03-21 devnull typedef struct Note Note;
704 2277c5d7 2004-03-21 devnull struct Note
706 2277c5d7 2004-03-21 devnull Note *next;
707 2277c5d7 2004-03-21 devnull char msg[ERRMAX];
710 2277c5d7 2004-03-21 devnull typedef struct Request Request;
711 2277c5d7 2004-03-21 devnull struct Request
713 2277c5d7 2004-03-21 devnull Request *next;
714 2277c5d7 2004-03-21 devnull Fcall f;
717 2277c5d7 2004-03-21 devnull typedef struct Fid Fid;
718 2277c5d7 2004-03-21 devnull struct Fid
720 2277c5d7 2004-03-21 devnull int fid;
721 2277c5d7 2004-03-21 devnull int file;
723 2277c5d7 2004-03-21 devnull Fid fids[Nfid];
725 2277c5d7 2004-03-21 devnull struct {
727 2277c5d7 2004-03-21 devnull Note *nfirst, *nlast;
728 2277c5d7 2004-03-21 devnull Request *rfirst, *rlast;
732 2277c5d7 2004-03-21 devnull fsreply(int fd, Fcall *f)
734 2277c5d7 2004-03-21 devnull uchar buf[IOHDRSZ+Maxfdata];
738 2277c5d7 2004-03-21 devnull fprint(2, "<-%F\n", f);
739 2277c5d7 2004-03-21 devnull n = convS2M(f, buf, sizeof buf);
740 2277c5d7 2004-03-21 devnull if(n > 0){
741 2277c5d7 2004-03-21 devnull if(write(fd, buf, n) != n){
742 2277c5d7 2004-03-21 devnull close(fd);
743 2277c5d7 2004-03-21 devnull return -1;
746 2277c5d7 2004-03-21 devnull return 0;
749 2277c5d7 2004-03-21 devnull /* match a note read request with a note, reply to the request */
751 2277c5d7 2004-03-21 devnull kick(int fd)
753 2277c5d7 2004-03-21 devnull Request *rp;
754 2277c5d7 2004-03-21 devnull Note *np;
757 2277c5d7 2004-03-21 devnull for(;;){
758 2277c5d7 2004-03-21 devnull lock(&nfs);
759 2277c5d7 2004-03-21 devnull rp = nfs.rfirst;
760 2277c5d7 2004-03-21 devnull np = nfs.nfirst;
761 2277c5d7 2004-03-21 devnull if(rp == nil || np == nil){
762 2277c5d7 2004-03-21 devnull unlock(&nfs);
765 2277c5d7 2004-03-21 devnull nfs.rfirst = rp->next;
766 2277c5d7 2004-03-21 devnull nfs.nfirst = np->next;
767 2277c5d7 2004-03-21 devnull unlock(&nfs);
769 2277c5d7 2004-03-21 devnull rp->f.type = Rread;
770 2277c5d7 2004-03-21 devnull rp->f.count = strlen(np->msg);
771 2277c5d7 2004-03-21 devnull rp->f.data = np->msg;
772 2277c5d7 2004-03-21 devnull rv = fsreply(fd, &rp->f);
773 2277c5d7 2004-03-21 devnull free(rp);
774 2277c5d7 2004-03-21 devnull free(np);
775 2277c5d7 2004-03-21 devnull if(rv < 0)
776 2277c5d7 2004-03-21 devnull return -1;
778 2277c5d7 2004-03-21 devnull return 0;
782 2277c5d7 2004-03-21 devnull flushreq(int tag)
784 2277c5d7 2004-03-21 devnull Request **l, *rp;
786 2277c5d7 2004-03-21 devnull lock(&nfs);
787 2277c5d7 2004-03-21 devnull for(l = &nfs.rfirst; *l != nil; l = &(*l)->next){
788 2277c5d7 2004-03-21 devnull rp = *l;
789 2277c5d7 2004-03-21 devnull if(rp->f.tag == tag){
790 2277c5d7 2004-03-21 devnull *l = rp->next;
791 2277c5d7 2004-03-21 devnull unlock(&nfs);
792 2277c5d7 2004-03-21 devnull free(rp);
796 2277c5d7 2004-03-21 devnull unlock(&nfs);
800 2277c5d7 2004-03-21 devnull getfid(int fid)
802 2277c5d7 2004-03-21 devnull int i, freefid;
804 2277c5d7 2004-03-21 devnull freefid = -1;
805 2277c5d7 2004-03-21 devnull for(i = 0; i < Nfid; i++){
806 2277c5d7 2004-03-21 devnull if(freefid < 0 && fids[i].file < 0)
807 2277c5d7 2004-03-21 devnull freefid = i;
808 2277c5d7 2004-03-21 devnull if(fids[i].fid == fid)
809 2277c5d7 2004-03-21 devnull return &fids[i];
811 2277c5d7 2004-03-21 devnull if(freefid >= 0){
812 2277c5d7 2004-03-21 devnull fids[freefid].fid = fid;
813 2277c5d7 2004-03-21 devnull return &fids[freefid];
815 2277c5d7 2004-03-21 devnull return nil;
819 2277c5d7 2004-03-21 devnull fsstat(int fd, Fid *fid, Fcall *f)
822 2277c5d7 2004-03-21 devnull uchar statbuf[256];
824 2277c5d7 2004-03-21 devnull memset(&d, 0, sizeof(d));
825 2277c5d7 2004-03-21 devnull d.name = fstab[fid->file].name;
826 2277c5d7 2004-03-21 devnull d.uid = user;
827 2277c5d7 2004-03-21 devnull d.gid = user;
828 2277c5d7 2004-03-21 devnull d.muid = user;
829 2277c5d7 2004-03-21 devnull d.qid = fstab[fid->file].qid;
830 2277c5d7 2004-03-21 devnull d.mode = fstab[fid->file].perm;
831 2277c5d7 2004-03-21 devnull d.atime = d.mtime = time(0);
832 2277c5d7 2004-03-21 devnull f->stat = statbuf;
833 2277c5d7 2004-03-21 devnull f->nstat = convD2M(&d, statbuf, sizeof statbuf);
834 2277c5d7 2004-03-21 devnull return fsreply(fd, f);
838 2277c5d7 2004-03-21 devnull fsread(int fd, Fid *fid, Fcall *f)
841 2277c5d7 2004-03-21 devnull uchar buf[256];
842 2277c5d7 2004-03-21 devnull Request *rp;
844 2277c5d7 2004-03-21 devnull switch(fid->file){
845 2277c5d7 2004-03-21 devnull default:
846 2277c5d7 2004-03-21 devnull return -1;
847 2277c5d7 2004-03-21 devnull case Qdir:
848 2277c5d7 2004-03-21 devnull if(f->offset == 0 && f->count >0){
849 2277c5d7 2004-03-21 devnull memset(&d, 0, sizeof(d));
850 2277c5d7 2004-03-21 devnull d.name = fstab[Qcpunote].name;
851 2277c5d7 2004-03-21 devnull d.uid = user;
852 2277c5d7 2004-03-21 devnull d.gid = user;
853 2277c5d7 2004-03-21 devnull d.muid = user;
854 2277c5d7 2004-03-21 devnull d.qid = fstab[Qcpunote].qid;
855 2277c5d7 2004-03-21 devnull d.mode = fstab[Qcpunote].perm;
856 2277c5d7 2004-03-21 devnull d.atime = d.mtime = time(0);
857 2277c5d7 2004-03-21 devnull f->count = convD2M(&d, buf, sizeof buf);
858 2277c5d7 2004-03-21 devnull f->data = (char*)buf;
860 2277c5d7 2004-03-21 devnull f->count = 0;
861 2277c5d7 2004-03-21 devnull return fsreply(fd, f);
862 2277c5d7 2004-03-21 devnull case Qcpunote:
863 2277c5d7 2004-03-21 devnull rp = mallocz(sizeof(*rp), 1);
864 2277c5d7 2004-03-21 devnull if(rp == nil)
865 2277c5d7 2004-03-21 devnull return -1;
866 2277c5d7 2004-03-21 devnull rp->f = *f;
867 2277c5d7 2004-03-21 devnull lock(&nfs);
868 2277c5d7 2004-03-21 devnull if(nfs.rfirst == nil)
869 2277c5d7 2004-03-21 devnull nfs.rfirst = rp;
871 2277c5d7 2004-03-21 devnull nfs.rlast->next = rp;
872 2277c5d7 2004-03-21 devnull nfs.rlast = rp;
873 2277c5d7 2004-03-21 devnull unlock(&nfs);
874 2277c5d7 2004-03-21 devnull return kick(fd);;
878 2277c5d7 2004-03-21 devnull char Eperm[] = "permission denied";
879 2277c5d7 2004-03-21 devnull char Enofile[] = "out of files";
880 2277c5d7 2004-03-21 devnull char Enotdir[] = "not a directory";
883 2277c5d7 2004-03-21 devnull notefs(int fd)
885 2277c5d7 2004-03-21 devnull uchar buf[IOHDRSZ+Maxfdata];
886 2277c5d7 2004-03-21 devnull int i, j, n;
887 2277c5d7 2004-03-21 devnull char err[ERRMAX];
888 2277c5d7 2004-03-21 devnull Fcall f;
889 2277c5d7 2004-03-21 devnull Fid *fid, *nfid;
890 2277c5d7 2004-03-21 devnull int doreply;
892 2277c5d7 2004-03-21 devnull rfork(RFNOTEG);
893 2277c5d7 2004-03-21 devnull fmtinstall('F', fcallconv);
895 2277c5d7 2004-03-21 devnull for(n = 0; n < Nfid; n++)
896 2277c5d7 2004-03-21 devnull fids[n].file = -1;
898 2277c5d7 2004-03-21 devnull for(;;){
899 2277c5d7 2004-03-21 devnull n = read9pmsg(fd, buf, sizeof(buf));
900 2277c5d7 2004-03-21 devnull if(n <= 0){
902 2277c5d7 2004-03-21 devnull fprint(2, "read9pmsg(%d) returns %d: %r\n", fd, n);
905 2277c5d7 2004-03-21 devnull if(convM2S(buf, n, &f) < 0)
908 2277c5d7 2004-03-21 devnull fprint(2, "->%F\n", &f);
909 2277c5d7 2004-03-21 devnull doreply = 1;
910 2277c5d7 2004-03-21 devnull fid = getfid(f.fid);
911 2277c5d7 2004-03-21 devnull if(fid == nil){
913 2277c5d7 2004-03-21 devnull f.type = Rerror;
914 2277c5d7 2004-03-21 devnull f.ename = Enofile;
915 2277c5d7 2004-03-21 devnull fsreply(fd, &f);
916 2277c5d7 2004-03-21 devnull continue;
918 2277c5d7 2004-03-21 devnull switch(f.type++){
919 2277c5d7 2004-03-21 devnull default:
920 2277c5d7 2004-03-21 devnull f.type = Rerror;
921 2277c5d7 2004-03-21 devnull f.ename = "unknown type";
923 2277c5d7 2004-03-21 devnull case Tflush:
924 2277c5d7 2004-03-21 devnull flushreq(f.oldtag);
926 2277c5d7 2004-03-21 devnull case Tversion:
927 2277c5d7 2004-03-21 devnull if(f.msize > IOHDRSZ+Maxfdata)
928 2277c5d7 2004-03-21 devnull f.msize = IOHDRSZ+Maxfdata;
930 2277c5d7 2004-03-21 devnull case Tauth:
931 2277c5d7 2004-03-21 devnull f.type = Rerror;
932 2277c5d7 2004-03-21 devnull f.ename = "cpu: authentication not required";
934 2277c5d7 2004-03-21 devnull case Tattach:
935 2277c5d7 2004-03-21 devnull f.qid = fstab[Qdir].qid;
936 2277c5d7 2004-03-21 devnull fid->file = Qdir;
938 2277c5d7 2004-03-21 devnull case Twalk:
939 2277c5d7 2004-03-21 devnull nfid = nil;
940 2277c5d7 2004-03-21 devnull if(f.newfid != f.fid){
941 2277c5d7 2004-03-21 devnull nfid = getfid(f.newfid);
942 2277c5d7 2004-03-21 devnull if(nfid == nil)
943 2277c5d7 2004-03-21 devnull goto nofids;
944 2277c5d7 2004-03-21 devnull nfid->file = fid->file;
945 2277c5d7 2004-03-21 devnull fid = nfid;
948 2277c5d7 2004-03-21 devnull f.ename = nil;
949 2277c5d7 2004-03-21 devnull for(i=0; i<f.nwname; i++){
950 2277c5d7 2004-03-21 devnull if(i > MAXWELEM){
951 2277c5d7 2004-03-21 devnull f.type = Rerror;
952 2277c5d7 2004-03-21 devnull f.ename = "too many name elements";
955 2277c5d7 2004-03-21 devnull if(fid->file != Qdir){
956 2277c5d7 2004-03-21 devnull f.type = Rerror;
957 2277c5d7 2004-03-21 devnull f.ename = Enotdir;
960 2277c5d7 2004-03-21 devnull if(strcmp(f.wname[i], "cpunote") == 0){
961 2277c5d7 2004-03-21 devnull fid->file = Qcpunote;
962 2277c5d7 2004-03-21 devnull f.wqid[i] = fstab[Qcpunote].qid;
963 2277c5d7 2004-03-21 devnull continue;
965 2277c5d7 2004-03-21 devnull f.type = Rerror;
966 2277c5d7 2004-03-21 devnull f.ename = err;
967 2277c5d7 2004-03-21 devnull strcpy(err, "cpu: file \"");
968 2277c5d7 2004-03-21 devnull for(j=0; j<=i; j++){
969 2277c5d7 2004-03-21 devnull if(strlen(err)+1+strlen(f.wname[j])+32 > sizeof err)
971 2277c5d7 2004-03-21 devnull if(j != 0)
972 2277c5d7 2004-03-21 devnull strcat(err, "/");
973 2277c5d7 2004-03-21 devnull strcat(err, f.wname[j]);
975 2277c5d7 2004-03-21 devnull strcat(err, "\" does not exist");
978 2277c5d7 2004-03-21 devnull if(nfid != nil && (f.ename != nil || i < f.nwname))
979 2277c5d7 2004-03-21 devnull nfid ->file = -1;
980 2277c5d7 2004-03-21 devnull if(f.type != Rerror)
981 2277c5d7 2004-03-21 devnull f.nwqid = i;
983 2277c5d7 2004-03-21 devnull case Topen:
984 2277c5d7 2004-03-21 devnull if(f.mode != OREAD){
985 2277c5d7 2004-03-21 devnull f.type = Rerror;
986 2277c5d7 2004-03-21 devnull f.ename = Eperm;
988 2277c5d7 2004-03-21 devnull f.qid = fstab[fid->file].qid;
990 2277c5d7 2004-03-21 devnull case Tcreate:
991 2277c5d7 2004-03-21 devnull f.type = Rerror;
992 2277c5d7 2004-03-21 devnull f.ename = Eperm;
994 2277c5d7 2004-03-21 devnull case Tread:
995 2277c5d7 2004-03-21 devnull if(fsread(fd, fid, &f) < 0)
996 2277c5d7 2004-03-21 devnull goto err;
997 2277c5d7 2004-03-21 devnull doreply = 0;
999 2277c5d7 2004-03-21 devnull case Twrite:
1000 2277c5d7 2004-03-21 devnull f.type = Rerror;
1001 2277c5d7 2004-03-21 devnull f.ename = Eperm;
1003 2277c5d7 2004-03-21 devnull case Tclunk:
1004 2277c5d7 2004-03-21 devnull fid->file = -1;
1006 2277c5d7 2004-03-21 devnull case Tremove:
1007 2277c5d7 2004-03-21 devnull f.type = Rerror;
1008 2277c5d7 2004-03-21 devnull f.ename = Eperm;
1010 2277c5d7 2004-03-21 devnull case Tstat:
1011 2277c5d7 2004-03-21 devnull if(fsstat(fd, fid, &f) < 0)
1012 2277c5d7 2004-03-21 devnull goto err;
1013 2277c5d7 2004-03-21 devnull doreply = 0;
1015 2277c5d7 2004-03-21 devnull case Twstat:
1016 2277c5d7 2004-03-21 devnull f.type = Rerror;
1017 2277c5d7 2004-03-21 devnull f.ename = Eperm;
1020 2277c5d7 2004-03-21 devnull if(doreply)
1021 2277c5d7 2004-03-21 devnull if(fsreply(fd, &f) < 0)
1025 2277c5d7 2004-03-21 devnull if(dbg)
1026 2277c5d7 2004-03-21 devnull fprint(2, "notefs exiting: %r\n");
1027 2277c5d7 2004-03-21 devnull close(fd);
1030 2277c5d7 2004-03-21 devnull char notebuf[ERRMAX];
1033 2277c5d7 2004-03-21 devnull catcher(void*, char *text)
1037 2277c5d7 2004-03-21 devnull n = strlen(text);
1038 2277c5d7 2004-03-21 devnull if(n >= sizeof(notebuf))
1039 2277c5d7 2004-03-21 devnull n = sizeof(notebuf)-1;
1040 2277c5d7 2004-03-21 devnull memmove(notebuf, text, n);
1041 2277c5d7 2004-03-21 devnull notebuf[n] = '\0';
1042 2277c5d7 2004-03-21 devnull noted(NCONT);
1046 2277c5d7 2004-03-21 devnull * mount in /dev a note file for the remote side to read.
1049 2277c5d7 2004-03-21 devnull lclnoteproc(int netfd)
1051 2277c5d7 2004-03-21 devnull int exportfspid;
1052 2277c5d7 2004-03-21 devnull Waitmsg *w;
1053 2277c5d7 2004-03-21 devnull Note *np;
1054 2277c5d7 2004-03-21 devnull int pfd[2];
1056 2277c5d7 2004-03-21 devnull if(pipe(pfd) < 0){
1057 2277c5d7 2004-03-21 devnull fprint(2, "cpu: can't start note proc: pipe: %r\n");
1058 2277c5d7 2004-03-21 devnull return;
1061 2277c5d7 2004-03-21 devnull /* new proc mounts and returns to start exportfs */
1062 2277c5d7 2004-03-21 devnull switch(exportfspid = rfork(RFPROC|RFNAMEG|RFFDG|RFMEM)){
1063 2277c5d7 2004-03-21 devnull case -1:
1064 2277c5d7 2004-03-21 devnull fprint(2, "cpu: can't start note proc: rfork: %r\n");
1065 2277c5d7 2004-03-21 devnull return;
1066 2277c5d7 2004-03-21 devnull case 0:
1067 2277c5d7 2004-03-21 devnull close(pfd[0]);
1068 2277c5d7 2004-03-21 devnull if(mount(pfd[1], -1, "/dev", MBEFORE, "") < 0)
1069 2277c5d7 2004-03-21 devnull fprint(2, "cpu: can't mount note proc: %r\n");
1070 2277c5d7 2004-03-21 devnull close(pfd[1]);
1071 2277c5d7 2004-03-21 devnull return;
1074 2277c5d7 2004-03-21 devnull close(netfd);
1075 2277c5d7 2004-03-21 devnull close(pfd[1]);
1077 2277c5d7 2004-03-21 devnull /* new proc listens for note file system rpc's */
1078 2277c5d7 2004-03-21 devnull switch(rfork(RFPROC|RFNAMEG|RFMEM)){
1079 2277c5d7 2004-03-21 devnull case -1:
1080 2277c5d7 2004-03-21 devnull fprint(2, "cpu: can't start note proc: rfork1: %r\n");
1081 2277c5d7 2004-03-21 devnull _exits(0);
1082 2277c5d7 2004-03-21 devnull case 0:
1083 2277c5d7 2004-03-21 devnull notefs(pfd[0]);
1084 2277c5d7 2004-03-21 devnull _exits(0);
1087 2277c5d7 2004-03-21 devnull /* original proc waits for notes */
1088 2277c5d7 2004-03-21 devnull notify(catcher);
1089 2277c5d7 2004-03-21 devnull w = nil;
1090 2277c5d7 2004-03-21 devnull for(;;) {
1091 2277c5d7 2004-03-21 devnull *notebuf = 0;
1092 2277c5d7 2004-03-21 devnull free(w);
1093 2277c5d7 2004-03-21 devnull w = wait();
1094 2277c5d7 2004-03-21 devnull if(w == nil) {
1095 2277c5d7 2004-03-21 devnull if(*notebuf == 0)
1097 2277c5d7 2004-03-21 devnull np = mallocz(sizeof(Note), 1);
1098 2277c5d7 2004-03-21 devnull if(np != nil){
1099 2277c5d7 2004-03-21 devnull strcpy(np->msg, notebuf);
1100 2277c5d7 2004-03-21 devnull lock(&nfs);
1101 2277c5d7 2004-03-21 devnull if(nfs.nfirst == nil)
1102 2277c5d7 2004-03-21 devnull nfs.nfirst = np;
1104 2277c5d7 2004-03-21 devnull nfs.nlast->next = np;
1105 2277c5d7 2004-03-21 devnull nfs.nlast = np;
1106 2277c5d7 2004-03-21 devnull unlock(&nfs);
1107 2277c5d7 2004-03-21 devnull kick(pfd[0]);
1109 2277c5d7 2004-03-21 devnull unlock(&nfs);
1110 2277c5d7 2004-03-21 devnull } else if(w->pid == exportfspid)
1114 2277c5d7 2004-03-21 devnull if(w == nil)
1115 2277c5d7 2004-03-21 devnull exits(nil);
1116 2277c5d7 2004-03-21 devnull exits(w->msg);