Blame


1 2277c5d7 2004-03-21 devnull /*
2 2277c5d7 2004-03-21 devnull * cpu.c - Make a connection to a cpu server
3 2277c5d7 2004-03-21 devnull *
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 ...]'
6 2277c5d7 2004-03-21 devnull */
7 2277c5d7 2004-03-21 devnull
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>
14 2277c5d7 2004-03-21 devnull
15 2277c5d7 2004-03-21 devnull #define Maxfdata 8192
16 2277c5d7 2004-03-21 devnull
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*);
27 2277c5d7 2004-03-21 devnull
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;
32 2277c5d7 2004-03-21 devnull int dbg;
33 2277c5d7 2004-03-21 devnull char *user;
34 2277c5d7 2004-03-21 devnull
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";
38 2277c5d7 2004-03-21 devnull
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;
41 2277c5d7 2004-03-21 devnull
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*);
49 2277c5d7 2004-03-21 devnull
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[] =
56 2277c5d7 2004-03-21 devnull {
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}
61 2277c5d7 2004-03-21 devnull };
62 2277c5d7 2004-03-21 devnull AuthMethod *am = authmethod; /* default is p9 */
63 2277c5d7 2004-03-21 devnull
64 2277c5d7 2004-03-21 devnull char *p9authproto = "p9any";
65 2277c5d7 2004-03-21 devnull
66 2277c5d7 2004-03-21 devnull int setam(char*);
67 2277c5d7 2004-03-21 devnull
68 2277c5d7 2004-03-21 devnull void
69 2277c5d7 2004-03-21 devnull usage(void)
70 2277c5d7 2004-03-21 devnull {
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");
73 2277c5d7 2004-03-21 devnull }
74 2277c5d7 2004-03-21 devnull int fdd;
75 2277c5d7 2004-03-21 devnull
76 2277c5d7 2004-03-21 devnull void
77 2277c5d7 2004-03-21 devnull main(int argc, char **argv)
78 2277c5d7 2004-03-21 devnull {
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;
81 2277c5d7 2004-03-21 devnull
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);
89 2277c5d7 2004-03-21 devnull }
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;
93 2277c5d7 2004-03-21 devnull
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);
102 2277c5d7 2004-03-21 devnull break;
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;
107 2277c5d7 2004-03-21 devnull break;
108 2277c5d7 2004-03-21 devnull case 'd':
109 2277c5d7 2004-03-21 devnull dbg++;
110 2277c5d7 2004-03-21 devnull break;
111 2277c5d7 2004-03-21 devnull case 'f':
112 2277c5d7 2004-03-21 devnull /* ignored but accepted for compatibility */
113 2277c5d7 2004-03-21 devnull break;
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 */
117 2277c5d7 2004-03-21 devnull break;
118 2277c5d7 2004-03-21 devnull case 'R': /* From listen */
119 2277c5d7 2004-03-21 devnull remoteside(0);
120 2277c5d7 2004-03-21 devnull break;
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);
125 2277c5d7 2004-03-21 devnull break;
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);
133 2277c5d7 2004-03-21 devnull }
134 2277c5d7 2004-03-21 devnull break;
135 2277c5d7 2004-03-21 devnull case 'o':
136 2277c5d7 2004-03-21 devnull p9authproto = "p9sk2";
137 2277c5d7 2004-03-21 devnull srvname = "cpu";
138 2277c5d7 2004-03-21 devnull break;
139 2277c5d7 2004-03-21 devnull case 'u':
140 2277c5d7 2004-03-21 devnull user = EARGF(usage());
141 2277c5d7 2004-03-21 devnull break;
142 2277c5d7 2004-03-21 devnull default:
143 2277c5d7 2004-03-21 devnull usage();
144 2277c5d7 2004-03-21 devnull }ARGEND;
145 2277c5d7 2004-03-21 devnull
146 2277c5d7 2004-03-21 devnull
147 2277c5d7 2004-03-21 devnull if(argc != 0)
148 2277c5d7 2004-03-21 devnull usage();
149 2277c5d7 2004-03-21 devnull
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);
155 2277c5d7 2004-03-21 devnull }
156 2277c5d7 2004-03-21 devnull
157 2277c5d7 2004-03-21 devnull if(err = rexcall(&data, system, srvname))
158 2277c5d7 2004-03-21 devnull fatal(1, "%s: %s", err, system);
159 2277c5d7 2004-03-21 devnull
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);
165 2277c5d7 2004-03-21 devnull else
166 2277c5d7 2004-03-21 devnull writestr(data, dat, "dir", 0);
167 2277c5d7 2004-03-21 devnull
168 2277c5d7 2004-03-21 devnull /* start up a process to pass along notes */
169 2277c5d7 2004-03-21 devnull lclnoteproc(data);
170 2277c5d7 2004-03-21 devnull
171 2277c5d7 2004-03-21 devnull /*
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
174 2277c5d7 2004-03-21 devnull */
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);
180 2277c5d7 2004-03-21 devnull }
181 2277c5d7 2004-03-21 devnull
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);
187 2277c5d7 2004-03-21 devnull if(dbg)
188 2277c5d7 2004-03-21 devnull execl(exportfs, exportfs, "-dm", buf, 0);
189 2277c5d7 2004-03-21 devnull else
190 2277c5d7 2004-03-21 devnull execl(exportfs, exportfs, "-m", buf, 0);
191 2277c5d7 2004-03-21 devnull fatal(1, "starting exportfs");
192 2277c5d7 2004-03-21 devnull }
193 2277c5d7 2004-03-21 devnull
194 2277c5d7 2004-03-21 devnull void
195 2277c5d7 2004-03-21 devnull fatal(int syserr, char *fmt, ...)
196 2277c5d7 2004-03-21 devnull {
197 2277c5d7 2004-03-21 devnull char buf[ERRMAX];
198 2277c5d7 2004-03-21 devnull va_list arg;
199 2277c5d7 2004-03-21 devnull
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);
205 2277c5d7 2004-03-21 devnull else
206 2277c5d7 2004-03-21 devnull fprint(2, "cpu: %s\n", buf);
207 2277c5d7 2004-03-21 devnull exits(buf);
208 2277c5d7 2004-03-21 devnull }
209 2277c5d7 2004-03-21 devnull
210 2277c5d7 2004-03-21 devnull char *negstr = "negotiating authentication method";
211 2277c5d7 2004-03-21 devnull
212 2277c5d7 2004-03-21 devnull char bug[256];
213 2277c5d7 2004-03-21 devnull
214 2277c5d7 2004-03-21 devnull int
215 2277c5d7 2004-03-21 devnull old9p(int fd)
216 2277c5d7 2004-03-21 devnull {
217 2277c5d7 2004-03-21 devnull int p[2];
218 2277c5d7 2004-03-21 devnull
219 2277c5d7 2004-03-21 devnull if(pipe(p) < 0)
220 2277c5d7 2004-03-21 devnull fatal(1, "pipe");
221 2277c5d7 2004-03-21 devnull
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");
225 2277c5d7 2004-03-21 devnull case 0:
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);
229 2277c5d7 2004-03-21 devnull }
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]);
233 2277c5d7 2004-03-21 devnull }
234 2277c5d7 2004-03-21 devnull close(p[1]);
235 2277c5d7 2004-03-21 devnull if(0){
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);
240 2277c5d7 2004-03-21 devnull }
241 2277c5d7 2004-03-21 devnull execl("/bin/srvold9p", "srvold9p", "-ds", 0);
242 2277c5d7 2004-03-21 devnull } else
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]);
248 2277c5d7 2004-03-21 devnull }
249 2277c5d7 2004-03-21 devnull return p[1];
250 2277c5d7 2004-03-21 devnull }
251 2277c5d7 2004-03-21 devnull
252 2277c5d7 2004-03-21 devnull /* Invoked with stdin, stdout and stderr connected to the network connection */
253 2277c5d7 2004-03-21 devnull void
254 2277c5d7 2004-03-21 devnull remoteside(int old)
255 2277c5d7 2004-03-21 devnull {
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;
258 2277c5d7 2004-03-21 devnull
259 2277c5d7 2004-03-21 devnull fd = 0;
260 2277c5d7 2004-03-21 devnull
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);
268 2277c5d7 2004-03-21 devnull } else
269 2277c5d7 2004-03-21 devnull writestr(fd, "", "", 1);
270 2277c5d7 2004-03-21 devnull
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");
274 2277c5d7 2004-03-21 devnull
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);
279 2277c5d7 2004-03-21 devnull
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");
289 2277c5d7 2004-03-21 devnull }
290 2277c5d7 2004-03-21 devnull
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);
299 2277c5d7 2004-03-21 devnull }
300 2277c5d7 2004-03-21 devnull
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);
304 2277c5d7 2004-03-21 devnull
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");
308 2277c5d7 2004-03-21 devnull
309 2277c5d7 2004-03-21 devnull if(old)
310 2277c5d7 2004-03-21 devnull fd = old9p(fd);
311 2277c5d7 2004-03-21 devnull
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");
318 2277c5d7 2004-03-21 devnull
319 2277c5d7 2004-03-21 devnull close(fd);
320 2277c5d7 2004-03-21 devnull
321 2277c5d7 2004-03-21 devnull /* the remote noteproc uses the mount so it must follow it */
322 2277c5d7 2004-03-21 devnull rmtnoteproc();
323 2277c5d7 2004-03-21 devnull
324 2277c5d7 2004-03-21 devnull for(i = 0; i < 3; i++)
325 2277c5d7 2004-03-21 devnull close(i);
326 2277c5d7 2004-03-21 devnull
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);
332 2277c5d7 2004-03-21 devnull
333 2277c5d7 2004-03-21 devnull if(badchdir)
334 2277c5d7 2004-03-21 devnull print("cpu: failed to chdir to '%s'\n", xdir);
335 2277c5d7 2004-03-21 devnull
336 2277c5d7 2004-03-21 devnull if(gotcmd)
337 2277c5d7 2004-03-21 devnull execl("/bin/rc", "rc", "-lc", cmd, 0);
338 2277c5d7 2004-03-21 devnull else
339 2277c5d7 2004-03-21 devnull execl("/bin/rc", "rc", "-li", 0);
340 2277c5d7 2004-03-21 devnull fatal(1, "exec shell");
341 2277c5d7 2004-03-21 devnull }
342 2277c5d7 2004-03-21 devnull
343 2277c5d7 2004-03-21 devnull char*
344 2277c5d7 2004-03-21 devnull rexcall(int *fd, char *host, char *service)
345 2277c5d7 2004-03-21 devnull {
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];
350 2277c5d7 2004-03-21 devnull int n;
351 2277c5d7 2004-03-21 devnull
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";
355 2277c5d7 2004-03-21 devnull
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);
359 2277c5d7 2004-03-21 devnull else
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;
368 2277c5d7 2004-03-21 devnull }
369 2277c5d7 2004-03-21 devnull
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;
375 2277c5d7 2004-03-21 devnull }
376 2277c5d7 2004-03-21 devnull
377 2277c5d7 2004-03-21 devnull void
378 2277c5d7 2004-03-21 devnull writestr(int fd, char *str, char *thing, int ignore)
379 2277c5d7 2004-03-21 devnull {
380 2277c5d7 2004-03-21 devnull int l, n;
381 2277c5d7 2004-03-21 devnull
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);
386 2277c5d7 2004-03-21 devnull }
387 2277c5d7 2004-03-21 devnull
388 2277c5d7 2004-03-21 devnull int
389 2277c5d7 2004-03-21 devnull readstr(int fd, char *str, int len)
390 2277c5d7 2004-03-21 devnull {
391 2277c5d7 2004-03-21 devnull int n;
392 2277c5d7 2004-03-21 devnull
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;
399 2277c5d7 2004-03-21 devnull str++;
400 2277c5d7 2004-03-21 devnull len--;
401 2277c5d7 2004-03-21 devnull }
402 2277c5d7 2004-03-21 devnull return -1;
403 2277c5d7 2004-03-21 devnull }
404 2277c5d7 2004-03-21 devnull
405 2277c5d7 2004-03-21 devnull static int
406 2277c5d7 2004-03-21 devnull readln(char *buf, int n)
407 2277c5d7 2004-03-21 devnull {
408 2277c5d7 2004-03-21 devnull char *p = buf;
409 2277c5d7 2004-03-21 devnull
410 2277c5d7 2004-03-21 devnull n--;
411 2277c5d7 2004-03-21 devnull while(n > 0){
412 2277c5d7 2004-03-21 devnull if(read(0, p, 1) != 1)
413 2277c5d7 2004-03-21 devnull break;
414 2277c5d7 2004-03-21 devnull if(*p == '\n' || *p == '\r'){
415 2277c5d7 2004-03-21 devnull *p = 0;
416 2277c5d7 2004-03-21 devnull return p-buf;
417 2277c5d7 2004-03-21 devnull }
418 2277c5d7 2004-03-21 devnull p++;
419 2277c5d7 2004-03-21 devnull }
420 2277c5d7 2004-03-21 devnull *p = 0;
421 2277c5d7 2004-03-21 devnull return p-buf;
422 2277c5d7 2004-03-21 devnull }
423 2277c5d7 2004-03-21 devnull
424 2277c5d7 2004-03-21 devnull /*
425 2277c5d7 2004-03-21 devnull * user level challenge/response
426 2277c5d7 2004-03-21 devnull */
427 2277c5d7 2004-03-21 devnull static int
428 2277c5d7 2004-03-21 devnull netkeyauth(int fd)
429 2277c5d7 2004-03-21 devnull {
430 2277c5d7 2004-03-21 devnull char chall[32];
431 2277c5d7 2004-03-21 devnull char resp[32];
432 2277c5d7 2004-03-21 devnull
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);
440 2277c5d7 2004-03-21 devnull
441 2277c5d7 2004-03-21 devnull for(;;){
442 2277c5d7 2004-03-21 devnull if(readstr(fd, chall, sizeof chall) < 0)
443 2277c5d7 2004-03-21 devnull break;
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)
448 2277c5d7 2004-03-21 devnull break;
449 2277c5d7 2004-03-21 devnull writestr(fd, resp, "challenge/response", 1);
450 2277c5d7 2004-03-21 devnull }
451 2277c5d7 2004-03-21 devnull return -1;
452 2277c5d7 2004-03-21 devnull }
453 2277c5d7 2004-03-21 devnull
454 2277c5d7 2004-03-21 devnull static int
455 2277c5d7 2004-03-21 devnull netkeysrvauth(int fd, char *user)
456 2277c5d7 2004-03-21 devnull {
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;
461 2277c5d7 2004-03-21 devnull
462 2277c5d7 2004-03-21 devnull if(readstr(fd, user, 32) < 0)
463 2277c5d7 2004-03-21 devnull return -1;
464 2277c5d7 2004-03-21 devnull
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)
476 2277c5d7 2004-03-21 devnull break;
477 2277c5d7 2004-03-21 devnull }
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;
486 2277c5d7 2004-03-21 devnull }
487 2277c5d7 2004-03-21 devnull
488 2277c5d7 2004-03-21 devnull static void
489 2277c5d7 2004-03-21 devnull mksecret(char *t, uchar *f)
490 2277c5d7 2004-03-21 devnull {
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]);
493 2277c5d7 2004-03-21 devnull }
494 2277c5d7 2004-03-21 devnull
495 2277c5d7 2004-03-21 devnull /*
496 2277c5d7 2004-03-21 devnull * plan9 authentication followed by rc4 encryption
497 2277c5d7 2004-03-21 devnull */
498 2277c5d7 2004-03-21 devnull static int
499 2277c5d7 2004-03-21 devnull p9auth(int fd)
500 2277c5d7 2004-03-21 devnull {
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];
505 2277c5d7 2004-03-21 devnull int i;
506 2277c5d7 2004-03-21 devnull AuthInfo *ai;
507 2277c5d7 2004-03-21 devnull
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;
514 2277c5d7 2004-03-21 devnull
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;
523 2277c5d7 2004-03-21 devnull
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);
528 2277c5d7 2004-03-21 devnull
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;
534 2277c5d7 2004-03-21 devnull }
535 2277c5d7 2004-03-21 devnull
536 2277c5d7 2004-03-21 devnull static int
537 2277c5d7 2004-03-21 devnull noauth(int fd)
538 2277c5d7 2004-03-21 devnull {
539 2277c5d7 2004-03-21 devnull ealgs = nil;
540 2277c5d7 2004-03-21 devnull return fd;
541 2277c5d7 2004-03-21 devnull }
542 2277c5d7 2004-03-21 devnull
543 2277c5d7 2004-03-21 devnull static int
544 2277c5d7 2004-03-21 devnull srvnoauth(int fd, char *user)
545 2277c5d7 2004-03-21 devnull {
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;
549 2277c5d7 2004-03-21 devnull }
550 2277c5d7 2004-03-21 devnull
551 2277c5d7 2004-03-21 devnull void
552 2277c5d7 2004-03-21 devnull loghex(uchar *p, int n)
553 2277c5d7 2004-03-21 devnull {
554 2277c5d7 2004-03-21 devnull char buf[100];
555 2277c5d7 2004-03-21 devnull int i;
556 2277c5d7 2004-03-21 devnull
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);
560 2277c5d7 2004-03-21 devnull }
561 2277c5d7 2004-03-21 devnull
562 2277c5d7 2004-03-21 devnull static int
563 2277c5d7 2004-03-21 devnull srvp9auth(int fd, char *user)
564 2277c5d7 2004-03-21 devnull {
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];
569 2277c5d7 2004-03-21 devnull int i;
570 2277c5d7 2004-03-21 devnull AuthInfo *ai;
571 2277c5d7 2004-03-21 devnull
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);
579 2277c5d7 2004-03-21 devnull
580 2277c5d7 2004-03-21 devnull if(ealgs == nil)
581 2277c5d7 2004-03-21 devnull return fd;
582 2277c5d7 2004-03-21 devnull
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;
591 2277c5d7 2004-03-21 devnull
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);
596 2277c5d7 2004-03-21 devnull
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;
602 2277c5d7 2004-03-21 devnull }
603 2277c5d7 2004-03-21 devnull
604 2277c5d7 2004-03-21 devnull /*
605 2277c5d7 2004-03-21 devnull * set authentication mechanism
606 2277c5d7 2004-03-21 devnull */
607 2277c5d7 2004-03-21 devnull int
608 2277c5d7 2004-03-21 devnull setam(char *name)
609 2277c5d7 2004-03-21 devnull {
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;
615 2277c5d7 2004-03-21 devnull }
616 2277c5d7 2004-03-21 devnull
617 2277c5d7 2004-03-21 devnull /*
618 2277c5d7 2004-03-21 devnull * set authentication mechanism and encryption/hash algs
619 2277c5d7 2004-03-21 devnull */
620 2277c5d7 2004-03-21 devnull int
621 2277c5d7 2004-03-21 devnull setamalg(char *s)
622 2277c5d7 2004-03-21 devnull {
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);
627 2277c5d7 2004-03-21 devnull }
628 2277c5d7 2004-03-21 devnull
629 2277c5d7 2004-03-21 devnull char *rmtnotefile = "/mnt/term/dev/cpunote";
630 2277c5d7 2004-03-21 devnull
631 2277c5d7 2004-03-21 devnull /*
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.
634 2277c5d7 2004-03-21 devnull */
635 2277c5d7 2004-03-21 devnull void
636 2277c5d7 2004-03-21 devnull rmtnoteproc(void)
637 2277c5d7 2004-03-21 devnull {
638 2277c5d7 2004-03-21 devnull int n, fd, pid, notepid;
639 2277c5d7 2004-03-21 devnull char buf[256];
640 2277c5d7 2004-03-21 devnull
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");
646 2277c5d7 2004-03-21 devnull return;
647 2277c5d7 2004-03-21 devnull case 0:
648 2277c5d7 2004-03-21 devnull return;
649 2277c5d7 2004-03-21 devnull }
650 2277c5d7 2004-03-21 devnull
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);
656 2277c5d7 2004-03-21 devnull case 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);
661 2277c5d7 2004-03-21 devnull }
662 2277c5d7 2004-03-21 devnull
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);
668 2277c5d7 2004-03-21 devnull }
669 2277c5d7 2004-03-21 devnull buf[n] = 0;
670 2277c5d7 2004-03-21 devnull postnote(PNGROUP, pid, buf);
671 2277c5d7 2004-03-21 devnull }
672 2277c5d7 2004-03-21 devnull break;
673 2277c5d7 2004-03-21 devnull }
674 2277c5d7 2004-03-21 devnull
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)
679 2277c5d7 2004-03-21 devnull break;
680 2277c5d7 2004-03-21 devnull }
681 2277c5d7 2004-03-21 devnull postnote(PNPROC, notepid, "kill");
682 2277c5d7 2004-03-21 devnull _exits(0);
683 2277c5d7 2004-03-21 devnull }
684 2277c5d7 2004-03-21 devnull
685 2277c5d7 2004-03-21 devnull enum
686 2277c5d7 2004-03-21 devnull {
687 2277c5d7 2004-03-21 devnull Qdir,
688 2277c5d7 2004-03-21 devnull Qcpunote,
689 2277c5d7 2004-03-21 devnull
690 2277c5d7 2004-03-21 devnull Nfid = 32,
691 2277c5d7 2004-03-21 devnull };
692 2277c5d7 2004-03-21 devnull
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[] =
698 2277c5d7 2004-03-21 devnull {
699 2277c5d7 2004-03-21 devnull [Qdir] { ".", {Qdir, 0, QTDIR}, DMDIR|0555 },
700 2277c5d7 2004-03-21 devnull [Qcpunote] { "cpunote", {Qcpunote, 0}, 0444 },
701 2277c5d7 2004-03-21 devnull };
702 2277c5d7 2004-03-21 devnull
703 2277c5d7 2004-03-21 devnull typedef struct Note Note;
704 2277c5d7 2004-03-21 devnull struct Note
705 2277c5d7 2004-03-21 devnull {
706 2277c5d7 2004-03-21 devnull Note *next;
707 2277c5d7 2004-03-21 devnull char msg[ERRMAX];
708 2277c5d7 2004-03-21 devnull };
709 2277c5d7 2004-03-21 devnull
710 2277c5d7 2004-03-21 devnull typedef struct Request Request;
711 2277c5d7 2004-03-21 devnull struct Request
712 2277c5d7 2004-03-21 devnull {
713 2277c5d7 2004-03-21 devnull Request *next;
714 2277c5d7 2004-03-21 devnull Fcall f;
715 2277c5d7 2004-03-21 devnull };
716 2277c5d7 2004-03-21 devnull
717 2277c5d7 2004-03-21 devnull typedef struct Fid Fid;
718 2277c5d7 2004-03-21 devnull struct Fid
719 2277c5d7 2004-03-21 devnull {
720 2277c5d7 2004-03-21 devnull int fid;
721 2277c5d7 2004-03-21 devnull int file;
722 2277c5d7 2004-03-21 devnull };
723 2277c5d7 2004-03-21 devnull Fid fids[Nfid];
724 2277c5d7 2004-03-21 devnull
725 2277c5d7 2004-03-21 devnull struct {
726 2277c5d7 2004-03-21 devnull Lock;
727 2277c5d7 2004-03-21 devnull Note *nfirst, *nlast;
728 2277c5d7 2004-03-21 devnull Request *rfirst, *rlast;
729 2277c5d7 2004-03-21 devnull } nfs;
730 2277c5d7 2004-03-21 devnull
731 2277c5d7 2004-03-21 devnull int
732 2277c5d7 2004-03-21 devnull fsreply(int fd, Fcall *f)
733 2277c5d7 2004-03-21 devnull {
734 2277c5d7 2004-03-21 devnull uchar buf[IOHDRSZ+Maxfdata];
735 2277c5d7 2004-03-21 devnull int n;
736 2277c5d7 2004-03-21 devnull
737 2277c5d7 2004-03-21 devnull if(dbg)
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;
744 2277c5d7 2004-03-21 devnull }
745 2277c5d7 2004-03-21 devnull }
746 2277c5d7 2004-03-21 devnull return 0;
747 2277c5d7 2004-03-21 devnull }
748 2277c5d7 2004-03-21 devnull
749 2277c5d7 2004-03-21 devnull /* match a note read request with a note, reply to the request */
750 2277c5d7 2004-03-21 devnull int
751 2277c5d7 2004-03-21 devnull kick(int fd)
752 2277c5d7 2004-03-21 devnull {
753 2277c5d7 2004-03-21 devnull Request *rp;
754 2277c5d7 2004-03-21 devnull Note *np;
755 2277c5d7 2004-03-21 devnull int rv;
756 2277c5d7 2004-03-21 devnull
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);
763 2277c5d7 2004-03-21 devnull break;
764 2277c5d7 2004-03-21 devnull }
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);
768 2277c5d7 2004-03-21 devnull
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;
777 2277c5d7 2004-03-21 devnull }
778 2277c5d7 2004-03-21 devnull return 0;
779 2277c5d7 2004-03-21 devnull }
780 2277c5d7 2004-03-21 devnull
781 2277c5d7 2004-03-21 devnull void
782 2277c5d7 2004-03-21 devnull flushreq(int tag)
783 2277c5d7 2004-03-21 devnull {
784 2277c5d7 2004-03-21 devnull Request **l, *rp;
785 2277c5d7 2004-03-21 devnull
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);
793 2277c5d7 2004-03-21 devnull return;
794 2277c5d7 2004-03-21 devnull }
795 2277c5d7 2004-03-21 devnull }
796 2277c5d7 2004-03-21 devnull unlock(&nfs);
797 2277c5d7 2004-03-21 devnull }
798 2277c5d7 2004-03-21 devnull
799 2277c5d7 2004-03-21 devnull Fid*
800 2277c5d7 2004-03-21 devnull getfid(int fid)
801 2277c5d7 2004-03-21 devnull {
802 2277c5d7 2004-03-21 devnull int i, freefid;
803 2277c5d7 2004-03-21 devnull
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];
810 2277c5d7 2004-03-21 devnull }
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];
814 2277c5d7 2004-03-21 devnull }
815 2277c5d7 2004-03-21 devnull return nil;
816 2277c5d7 2004-03-21 devnull }
817 2277c5d7 2004-03-21 devnull
818 2277c5d7 2004-03-21 devnull int
819 2277c5d7 2004-03-21 devnull fsstat(int fd, Fid *fid, Fcall *f)
820 2277c5d7 2004-03-21 devnull {
821 2277c5d7 2004-03-21 devnull Dir d;
822 2277c5d7 2004-03-21 devnull uchar statbuf[256];
823 2277c5d7 2004-03-21 devnull
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);
835 2277c5d7 2004-03-21 devnull }
836 2277c5d7 2004-03-21 devnull
837 2277c5d7 2004-03-21 devnull int
838 2277c5d7 2004-03-21 devnull fsread(int fd, Fid *fid, Fcall *f)
839 2277c5d7 2004-03-21 devnull {
840 2277c5d7 2004-03-21 devnull Dir d;
841 2277c5d7 2004-03-21 devnull uchar buf[256];
842 2277c5d7 2004-03-21 devnull Request *rp;
843 2277c5d7 2004-03-21 devnull
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;
859 2277c5d7 2004-03-21 devnull } else
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;
870 2277c5d7 2004-03-21 devnull else
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);;
875 2277c5d7 2004-03-21 devnull }
876 2277c5d7 2004-03-21 devnull }
877 2277c5d7 2004-03-21 devnull
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";
881 2277c5d7 2004-03-21 devnull
882 2277c5d7 2004-03-21 devnull void
883 2277c5d7 2004-03-21 devnull notefs(int fd)
884 2277c5d7 2004-03-21 devnull {
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;
891 2277c5d7 2004-03-21 devnull
892 2277c5d7 2004-03-21 devnull rfork(RFNOTEG);
893 2277c5d7 2004-03-21 devnull fmtinstall('F', fcallconv);
894 2277c5d7 2004-03-21 devnull
895 2277c5d7 2004-03-21 devnull for(n = 0; n < Nfid; n++)
896 2277c5d7 2004-03-21 devnull fids[n].file = -1;
897 2277c5d7 2004-03-21 devnull
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){
901 2277c5d7 2004-03-21 devnull if(dbg)
902 2277c5d7 2004-03-21 devnull fprint(2, "read9pmsg(%d) returns %d: %r\n", fd, n);
903 2277c5d7 2004-03-21 devnull break;
904 2277c5d7 2004-03-21 devnull }
905 2277c5d7 2004-03-21 devnull if(convM2S(buf, n, &f) < 0)
906 2277c5d7 2004-03-21 devnull break;
907 2277c5d7 2004-03-21 devnull if(dbg)
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){
912 2277c5d7 2004-03-21 devnull nofids:
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;
917 2277c5d7 2004-03-21 devnull }
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";
922 2277c5d7 2004-03-21 devnull break;
923 2277c5d7 2004-03-21 devnull case Tflush:
924 2277c5d7 2004-03-21 devnull flushreq(f.oldtag);
925 2277c5d7 2004-03-21 devnull break;
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;
929 2277c5d7 2004-03-21 devnull break;
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";
933 2277c5d7 2004-03-21 devnull break;
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;
937 2277c5d7 2004-03-21 devnull break;
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;
946 2277c5d7 2004-03-21 devnull }
947 2277c5d7 2004-03-21 devnull
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";
953 2277c5d7 2004-03-21 devnull break;
954 2277c5d7 2004-03-21 devnull }
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;
958 2277c5d7 2004-03-21 devnull break;
959 2277c5d7 2004-03-21 devnull }
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;
964 2277c5d7 2004-03-21 devnull }
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)
970 2277c5d7 2004-03-21 devnull break;
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]);
974 2277c5d7 2004-03-21 devnull }
975 2277c5d7 2004-03-21 devnull strcat(err, "\" does not exist");
976 2277c5d7 2004-03-21 devnull break;
977 2277c5d7 2004-03-21 devnull }
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;
982 2277c5d7 2004-03-21 devnull break;
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;
987 2277c5d7 2004-03-21 devnull }
988 2277c5d7 2004-03-21 devnull f.qid = fstab[fid->file].qid;
989 2277c5d7 2004-03-21 devnull break;
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;
993 2277c5d7 2004-03-21 devnull break;
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;
998 2277c5d7 2004-03-21 devnull break;
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;
1002 2277c5d7 2004-03-21 devnull break;
1003 2277c5d7 2004-03-21 devnull case Tclunk:
1004 2277c5d7 2004-03-21 devnull fid->file = -1;
1005 2277c5d7 2004-03-21 devnull break;
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;
1009 2277c5d7 2004-03-21 devnull break;
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;
1014 2277c5d7 2004-03-21 devnull break;
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;
1018 2277c5d7 2004-03-21 devnull break;
1019 2277c5d7 2004-03-21 devnull }
1020 2277c5d7 2004-03-21 devnull if(doreply)
1021 2277c5d7 2004-03-21 devnull if(fsreply(fd, &f) < 0)
1022 2277c5d7 2004-03-21 devnull break;
1023 2277c5d7 2004-03-21 devnull }
1024 2277c5d7 2004-03-21 devnull err:
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);
1028 2277c5d7 2004-03-21 devnull }
1029 2277c5d7 2004-03-21 devnull
1030 2277c5d7 2004-03-21 devnull char notebuf[ERRMAX];
1031 2277c5d7 2004-03-21 devnull
1032 2277c5d7 2004-03-21 devnull void
1033 2277c5d7 2004-03-21 devnull catcher(void*, char *text)
1034 2277c5d7 2004-03-21 devnull {
1035 2277c5d7 2004-03-21 devnull int n;
1036 2277c5d7 2004-03-21 devnull
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);
1043 2277c5d7 2004-03-21 devnull }
1044 2277c5d7 2004-03-21 devnull
1045 2277c5d7 2004-03-21 devnull /*
1046 2277c5d7 2004-03-21 devnull * mount in /dev a note file for the remote side to read.
1047 2277c5d7 2004-03-21 devnull */
1048 2277c5d7 2004-03-21 devnull void
1049 2277c5d7 2004-03-21 devnull lclnoteproc(int netfd)
1050 2277c5d7 2004-03-21 devnull {
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];
1055 2277c5d7 2004-03-21 devnull
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;
1059 2277c5d7 2004-03-21 devnull }
1060 2277c5d7 2004-03-21 devnull
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;
1072 2277c5d7 2004-03-21 devnull }
1073 2277c5d7 2004-03-21 devnull
1074 2277c5d7 2004-03-21 devnull close(netfd);
1075 2277c5d7 2004-03-21 devnull close(pfd[1]);
1076 2277c5d7 2004-03-21 devnull
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);
1085 2277c5d7 2004-03-21 devnull }
1086 2277c5d7 2004-03-21 devnull
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)
1096 2277c5d7 2004-03-21 devnull break;
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;
1103 2277c5d7 2004-03-21 devnull else
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]);
1108 2277c5d7 2004-03-21 devnull }
1109 2277c5d7 2004-03-21 devnull unlock(&nfs);
1110 2277c5d7 2004-03-21 devnull } else if(w->pid == exportfspid)
1111 2277c5d7 2004-03-21 devnull break;
1112 2277c5d7 2004-03-21 devnull }
1113 2277c5d7 2004-03-21 devnull
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);
1117 2277c5d7 2004-03-21 devnull }