Blame


1 6e527fbc 2005-02-13 devnull /*
2 6e527fbc 2005-02-13 devnull * cpu.c - Make a connection to a cpu server
3 6e527fbc 2005-02-13 devnull *
4 6e527fbc 2005-02-13 devnull * Invoked by listen as 'cpu -R | -N service net netdir'
5 6e527fbc 2005-02-13 devnull * by users as 'cpu [-h system] [-c cmd args ...]'
6 6e527fbc 2005-02-13 devnull */
7 6e527fbc 2005-02-13 devnull
8 6e527fbc 2005-02-13 devnull #include <u.h>
9 6e527fbc 2005-02-13 devnull #include <libc.h>
10 6e527fbc 2005-02-13 devnull #include <bio.h>
11 6e527fbc 2005-02-13 devnull #include <auth.h>
12 6e527fbc 2005-02-13 devnull #include <fcall.h>
13 6e527fbc 2005-02-13 devnull #include <libsec.h>
14 6e527fbc 2005-02-13 devnull
15 6e527fbc 2005-02-13 devnull #define Maxfdata 8192
16 6e527fbc 2005-02-13 devnull
17 6e527fbc 2005-02-13 devnull void remoteside(int);
18 6e527fbc 2005-02-13 devnull void fatal(int, char*, ...);
19 6e527fbc 2005-02-13 devnull void lclnoteproc(int);
20 6e527fbc 2005-02-13 devnull void rmtnoteproc(void);
21 6e527fbc 2005-02-13 devnull void catcher(void*, char*);
22 6e527fbc 2005-02-13 devnull void usage(void);
23 6e527fbc 2005-02-13 devnull void writestr(int, char*, char*, int);
24 6e527fbc 2005-02-13 devnull int readstr(int, char*, int);
25 6e527fbc 2005-02-13 devnull char *rexcall(int*, char*, char*);
26 6e527fbc 2005-02-13 devnull int setamalg(char*);
27 6e527fbc 2005-02-13 devnull
28 6e527fbc 2005-02-13 devnull int notechan;
29 6e527fbc 2005-02-13 devnull char system[32];
30 6e527fbc 2005-02-13 devnull int cflag;
31 6e527fbc 2005-02-13 devnull int hflag;
32 6e527fbc 2005-02-13 devnull int dbg;
33 6e527fbc 2005-02-13 devnull char *user;
34 6e527fbc 2005-02-13 devnull
35 6e527fbc 2005-02-13 devnull char *srvname = "ncpu";
36 6e527fbc 2005-02-13 devnull char *exportfs = "/bin/exportfs";
37 6e527fbc 2005-02-13 devnull char *ealgs = "rc4_256 sha1";
38 6e527fbc 2005-02-13 devnull
39 6e527fbc 2005-02-13 devnull /* message size for exportfs; may be larger so we can do big graphics in CPU window */
40 6e527fbc 2005-02-13 devnull int msgsize = 8192+IOHDRSZ;
41 6e527fbc 2005-02-13 devnull
42 6e527fbc 2005-02-13 devnull /* authentication mechanisms */
43 6e527fbc 2005-02-13 devnull static int netkeyauth(int);
44 6e527fbc 2005-02-13 devnull static int netkeysrvauth(int, char*);
45 6e527fbc 2005-02-13 devnull static int p9auth(int);
46 6e527fbc 2005-02-13 devnull static int srvp9auth(int, char*);
47 6e527fbc 2005-02-13 devnull static int noauth(int);
48 6e527fbc 2005-02-13 devnull static int srvnoauth(int, char*);
49 6e527fbc 2005-02-13 devnull
50 6e527fbc 2005-02-13 devnull typedef struct AuthMethod AuthMethod;
51 6e527fbc 2005-02-13 devnull struct AuthMethod {
52 6e527fbc 2005-02-13 devnull char *name; /* name of method */
53 6e527fbc 2005-02-13 devnull int (*cf)(int); /* client side authentication */
54 6e527fbc 2005-02-13 devnull int (*sf)(int, char*); /* server side authentication */
55 6e527fbc 2005-02-13 devnull } authmethod[] =
56 6e527fbc 2005-02-13 devnull {
57 6e527fbc 2005-02-13 devnull { "p9", p9auth, srvp9auth,},
58 6e527fbc 2005-02-13 devnull { "netkey", netkeyauth, netkeysrvauth,},
59 6e527fbc 2005-02-13 devnull // { "none", noauth, srvnoauth,},
60 6e527fbc 2005-02-13 devnull { nil, nil}
61 6e527fbc 2005-02-13 devnull };
62 6e527fbc 2005-02-13 devnull AuthMethod *am = authmethod; /* default is p9 */
63 6e527fbc 2005-02-13 devnull
64 6e527fbc 2005-02-13 devnull char *p9authproto = "p9any";
65 6e527fbc 2005-02-13 devnull
66 6e527fbc 2005-02-13 devnull int setam(char*);
67 6e527fbc 2005-02-13 devnull
68 6e527fbc 2005-02-13 devnull void
69 6e527fbc 2005-02-13 devnull usage(void)
70 6e527fbc 2005-02-13 devnull {
71 6e527fbc 2005-02-13 devnull fprint(2, "usage: cpu [-h system] [-a authmethod] [-e 'crypt hash'] [-c cmd args ...]\n");
72 6e527fbc 2005-02-13 devnull exits("usage");
73 6e527fbc 2005-02-13 devnull }
74 6e527fbc 2005-02-13 devnull int fdd;
75 6e527fbc 2005-02-13 devnull
76 6e527fbc 2005-02-13 devnull void
77 6e527fbc 2005-02-13 devnull main(int argc, char **argv)
78 6e527fbc 2005-02-13 devnull {
79 6e527fbc 2005-02-13 devnull char dat[128], buf[128], cmd[128], *p, *err;
80 6e527fbc 2005-02-13 devnull int fd, ms, kms, data;
81 6e527fbc 2005-02-13 devnull
82 6e527fbc 2005-02-13 devnull /* see if we should use a larger message size */
83 6e527fbc 2005-02-13 devnull fd = open("/dev/draw", OREAD);
84 6e527fbc 2005-02-13 devnull if(fd > 0){
85 6e527fbc 2005-02-13 devnull ms = iounit(fd);
86 6e527fbc 2005-02-13 devnull if(ms != 0 && ms < ms+IOHDRSZ)
87 6e527fbc 2005-02-13 devnull msgsize = ms+IOHDRSZ;
88 6e527fbc 2005-02-13 devnull close(fd);
89 6e527fbc 2005-02-13 devnull }
90 6e527fbc 2005-02-13 devnull kms = kiounit();
91 6e527fbc 2005-02-13 devnull if(msgsize > kms-IOHDRSZ-100) /* 100 for network packets, etc. */
92 6e527fbc 2005-02-13 devnull msgsize = kms-IOHDRSZ-100;
93 6e527fbc 2005-02-13 devnull
94 6e527fbc 2005-02-13 devnull user = getuser();
95 6e527fbc 2005-02-13 devnull if(user == nil)
96 6e527fbc 2005-02-13 devnull fatal(1, "can't read user name");
97 6e527fbc 2005-02-13 devnull ARGBEGIN{
98 6e527fbc 2005-02-13 devnull case 'a':
99 6e527fbc 2005-02-13 devnull p = EARGF(usage());
100 6e527fbc 2005-02-13 devnull if(setam(p) < 0)
101 6e527fbc 2005-02-13 devnull fatal(0, "unknown auth method %s", p);
102 6e527fbc 2005-02-13 devnull break;
103 6e527fbc 2005-02-13 devnull case 'e':
104 6e527fbc 2005-02-13 devnull ealgs = EARGF(usage());
105 6e527fbc 2005-02-13 devnull if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
106 6e527fbc 2005-02-13 devnull ealgs = nil;
107 6e527fbc 2005-02-13 devnull break;
108 6e527fbc 2005-02-13 devnull case 'd':
109 6e527fbc 2005-02-13 devnull dbg++;
110 6e527fbc 2005-02-13 devnull break;
111 6e527fbc 2005-02-13 devnull case 'f':
112 6e527fbc 2005-02-13 devnull /* ignored but accepted for compatibility */
113 6e527fbc 2005-02-13 devnull break;
114 6e527fbc 2005-02-13 devnull case 'O':
115 6e527fbc 2005-02-13 devnull p9authproto = "p9sk2";
116 6e527fbc 2005-02-13 devnull remoteside(1); /* From listen */
117 6e527fbc 2005-02-13 devnull break;
118 6e527fbc 2005-02-13 devnull case 'R': /* From listen */
119 6e527fbc 2005-02-13 devnull remoteside(0);
120 6e527fbc 2005-02-13 devnull break;
121 6e527fbc 2005-02-13 devnull case 'h':
122 6e527fbc 2005-02-13 devnull hflag++;
123 6e527fbc 2005-02-13 devnull p = EARGF(usage());
124 6e527fbc 2005-02-13 devnull strcpy(system, p);
125 6e527fbc 2005-02-13 devnull break;
126 6e527fbc 2005-02-13 devnull case 'c':
127 6e527fbc 2005-02-13 devnull cflag++;
128 6e527fbc 2005-02-13 devnull cmd[0] = '!';
129 6e527fbc 2005-02-13 devnull cmd[1] = '\0';
130 6e527fbc 2005-02-13 devnull while(p = ARGF()) {
131 6e527fbc 2005-02-13 devnull strcat(cmd, " ");
132 6e527fbc 2005-02-13 devnull strcat(cmd, p);
133 6e527fbc 2005-02-13 devnull }
134 6e527fbc 2005-02-13 devnull break;
135 6e527fbc 2005-02-13 devnull case 'o':
136 6e527fbc 2005-02-13 devnull p9authproto = "p9sk2";
137 6e527fbc 2005-02-13 devnull srvname = "cpu";
138 6e527fbc 2005-02-13 devnull break;
139 6e527fbc 2005-02-13 devnull case 'u':
140 6e527fbc 2005-02-13 devnull user = EARGF(usage());
141 6e527fbc 2005-02-13 devnull break;
142 6e527fbc 2005-02-13 devnull default:
143 6e527fbc 2005-02-13 devnull usage();
144 6e527fbc 2005-02-13 devnull }ARGEND;
145 6e527fbc 2005-02-13 devnull
146 6e527fbc 2005-02-13 devnull
147 6e527fbc 2005-02-13 devnull if(argc != 0)
148 6e527fbc 2005-02-13 devnull usage();
149 6e527fbc 2005-02-13 devnull
150 6e527fbc 2005-02-13 devnull if(hflag == 0) {
151 6e527fbc 2005-02-13 devnull p = getenv("cpu");
152 6e527fbc 2005-02-13 devnull if(p == 0)
153 6e527fbc 2005-02-13 devnull fatal(0, "set $cpu");
154 6e527fbc 2005-02-13 devnull strcpy(system, p);
155 6e527fbc 2005-02-13 devnull }
156 6e527fbc 2005-02-13 devnull
157 6e527fbc 2005-02-13 devnull if(err = rexcall(&data, system, srvname))
158 6e527fbc 2005-02-13 devnull fatal(1, "%s: %s", err, system);
159 6e527fbc 2005-02-13 devnull
160 6e527fbc 2005-02-13 devnull /* Tell the remote side the command to execute and where our working directory is */
161 6e527fbc 2005-02-13 devnull if(cflag)
162 6e527fbc 2005-02-13 devnull writestr(data, cmd, "command", 0);
163 6e527fbc 2005-02-13 devnull if(getwd(dat, sizeof(dat)) == 0)
164 6e527fbc 2005-02-13 devnull writestr(data, "NO", "dir", 0);
165 6e527fbc 2005-02-13 devnull else
166 6e527fbc 2005-02-13 devnull writestr(data, dat, "dir", 0);
167 6e527fbc 2005-02-13 devnull
168 6e527fbc 2005-02-13 devnull /* start up a process to pass along notes */
169 6e527fbc 2005-02-13 devnull lclnoteproc(data);
170 6e527fbc 2005-02-13 devnull
171 6e527fbc 2005-02-13 devnull /*
172 6e527fbc 2005-02-13 devnull * Wait for the other end to execute and start our file service
173 6e527fbc 2005-02-13 devnull * of /mnt/term
174 6e527fbc 2005-02-13 devnull */
175 6e527fbc 2005-02-13 devnull if(readstr(data, buf, sizeof(buf)) < 0)
176 6e527fbc 2005-02-13 devnull fatal(1, "waiting for FS");
177 6e527fbc 2005-02-13 devnull if(strncmp("FS", buf, 2) != 0) {
178 6e527fbc 2005-02-13 devnull print("remote cpu: %s", buf);
179 6e527fbc 2005-02-13 devnull exits(buf);
180 6e527fbc 2005-02-13 devnull }
181 6e527fbc 2005-02-13 devnull
182 6e527fbc 2005-02-13 devnull /* Begin serving the gnot namespace */
183 6e527fbc 2005-02-13 devnull close(0);
184 6e527fbc 2005-02-13 devnull dup(data, 0);
185 6e527fbc 2005-02-13 devnull close(data);
186 6e527fbc 2005-02-13 devnull sprint(buf, "%d", msgsize);
187 6e527fbc 2005-02-13 devnull if(dbg)
188 6e527fbc 2005-02-13 devnull execl(exportfs, exportfs, "-dm", buf, 0);
189 6e527fbc 2005-02-13 devnull else
190 6e527fbc 2005-02-13 devnull execl(exportfs, exportfs, "-m", buf, 0);
191 6e527fbc 2005-02-13 devnull fatal(1, "starting exportfs");
192 6e527fbc 2005-02-13 devnull }
193 6e527fbc 2005-02-13 devnull
194 6e527fbc 2005-02-13 devnull void
195 6e527fbc 2005-02-13 devnull fatal(int syserr, char *fmt, ...)
196 6e527fbc 2005-02-13 devnull {
197 6e527fbc 2005-02-13 devnull char buf[ERRMAX];
198 6e527fbc 2005-02-13 devnull va_list arg;
199 6e527fbc 2005-02-13 devnull
200 6e527fbc 2005-02-13 devnull va_start(arg, fmt);
201 6e527fbc 2005-02-13 devnull doprint(buf, buf+sizeof(buf), fmt, arg);
202 6e527fbc 2005-02-13 devnull va_end(arg);
203 6e527fbc 2005-02-13 devnull if(syserr)
204 6e527fbc 2005-02-13 devnull fprint(2, "cpu: %s: %r\n", buf);
205 6e527fbc 2005-02-13 devnull else
206 6e527fbc 2005-02-13 devnull fprint(2, "cpu: %s\n", buf);
207 6e527fbc 2005-02-13 devnull exits(buf);
208 6e527fbc 2005-02-13 devnull }
209 6e527fbc 2005-02-13 devnull
210 6e527fbc 2005-02-13 devnull char *negstr = "negotiating authentication method";
211 6e527fbc 2005-02-13 devnull
212 6e527fbc 2005-02-13 devnull char bug[256];
213 6e527fbc 2005-02-13 devnull
214 6e527fbc 2005-02-13 devnull int
215 6e527fbc 2005-02-13 devnull old9p(int fd)
216 6e527fbc 2005-02-13 devnull {
217 6e527fbc 2005-02-13 devnull int p[2];
218 6e527fbc 2005-02-13 devnull
219 6e527fbc 2005-02-13 devnull if(pipe(p) < 0)
220 6e527fbc 2005-02-13 devnull fatal(1, "pipe");
221 6e527fbc 2005-02-13 devnull
222 6e527fbc 2005-02-13 devnull switch(rfork(RFPROC|RFFDG|RFNAMEG)) {
223 6e527fbc 2005-02-13 devnull case -1:
224 6e527fbc 2005-02-13 devnull fatal(1, "rfork srvold9p");
225 6e527fbc 2005-02-13 devnull case 0:
226 6e527fbc 2005-02-13 devnull if(fd != 1){
227 6e527fbc 2005-02-13 devnull dup(fd, 1);
228 6e527fbc 2005-02-13 devnull close(fd);
229 6e527fbc 2005-02-13 devnull }
230 6e527fbc 2005-02-13 devnull if(p[0] != 0){
231 6e527fbc 2005-02-13 devnull dup(p[0], 0);
232 6e527fbc 2005-02-13 devnull close(p[0]);
233 6e527fbc 2005-02-13 devnull }
234 6e527fbc 2005-02-13 devnull close(p[1]);
235 6e527fbc 2005-02-13 devnull if(0){
236 6e527fbc 2005-02-13 devnull fd = open("/sys/log/cpu", OWRITE);
237 6e527fbc 2005-02-13 devnull if(fd != 2){
238 6e527fbc 2005-02-13 devnull dup(fd, 2);
239 6e527fbc 2005-02-13 devnull close(fd);
240 6e527fbc 2005-02-13 devnull }
241 6e527fbc 2005-02-13 devnull execl("/bin/srvold9p", "srvold9p", "-ds", 0);
242 6e527fbc 2005-02-13 devnull } else
243 6e527fbc 2005-02-13 devnull execl("/bin/srvold9p", "srvold9p", "-s", 0);
244 6e527fbc 2005-02-13 devnull fatal(1, "exec srvold9p");
245 6e527fbc 2005-02-13 devnull default:
246 6e527fbc 2005-02-13 devnull close(fd);
247 6e527fbc 2005-02-13 devnull close(p[0]);
248 6e527fbc 2005-02-13 devnull }
249 6e527fbc 2005-02-13 devnull return p[1];
250 6e527fbc 2005-02-13 devnull }
251 6e527fbc 2005-02-13 devnull
252 6e527fbc 2005-02-13 devnull /* Invoked with stdin, stdout and stderr connected to the network connection */
253 6e527fbc 2005-02-13 devnull void
254 6e527fbc 2005-02-13 devnull remoteside(int old)
255 6e527fbc 2005-02-13 devnull {
256 6e527fbc 2005-02-13 devnull char user[128], home[128], buf[128], xdir[128], cmd[128];
257 6e527fbc 2005-02-13 devnull int i, n, fd, badchdir, gotcmd;
258 6e527fbc 2005-02-13 devnull
259 6e527fbc 2005-02-13 devnull fd = 0;
260 6e527fbc 2005-02-13 devnull
261 6e527fbc 2005-02-13 devnull /* negotiate authentication mechanism */
262 6e527fbc 2005-02-13 devnull n = readstr(fd, cmd, sizeof(cmd));
263 6e527fbc 2005-02-13 devnull if(n < 0)
264 6e527fbc 2005-02-13 devnull fatal(1, "authenticating");
265 6e527fbc 2005-02-13 devnull if(setamalg(cmd) < 0){
266 6e527fbc 2005-02-13 devnull writestr(fd, "unsupported auth method", nil, 0);
267 6e527fbc 2005-02-13 devnull fatal(1, "bad auth method %s", cmd);
268 6e527fbc 2005-02-13 devnull } else
269 6e527fbc 2005-02-13 devnull writestr(fd, "", "", 1);
270 6e527fbc 2005-02-13 devnull
271 6e527fbc 2005-02-13 devnull fd = (*am->sf)(fd, user);
272 6e527fbc 2005-02-13 devnull if(fd < 0)
273 6e527fbc 2005-02-13 devnull fatal(1, "srvauth");
274 6e527fbc 2005-02-13 devnull
275 6e527fbc 2005-02-13 devnull /* Set environment values for the user */
276 6e527fbc 2005-02-13 devnull putenv("user", user);
277 6e527fbc 2005-02-13 devnull sprint(home, "/usr/%s", user);
278 6e527fbc 2005-02-13 devnull putenv("home", home);
279 6e527fbc 2005-02-13 devnull
280 6e527fbc 2005-02-13 devnull /* Now collect invoking cpu's current directory or possibly a command */
281 6e527fbc 2005-02-13 devnull gotcmd = 0;
282 6e527fbc 2005-02-13 devnull if(readstr(fd, xdir, sizeof(xdir)) < 0)
283 6e527fbc 2005-02-13 devnull fatal(1, "dir/cmd");
284 6e527fbc 2005-02-13 devnull if(xdir[0] == '!') {
285 6e527fbc 2005-02-13 devnull strcpy(cmd, &xdir[1]);
286 6e527fbc 2005-02-13 devnull gotcmd = 1;
287 6e527fbc 2005-02-13 devnull if(readstr(fd, xdir, sizeof(xdir)) < 0)
288 6e527fbc 2005-02-13 devnull fatal(1, "dir");
289 6e527fbc 2005-02-13 devnull }
290 6e527fbc 2005-02-13 devnull
291 6e527fbc 2005-02-13 devnull /* Establish the new process at the current working directory of the
292 6e527fbc 2005-02-13 devnull * gnot */
293 6e527fbc 2005-02-13 devnull badchdir = 0;
294 6e527fbc 2005-02-13 devnull if(strcmp(xdir, "NO") == 0)
295 6e527fbc 2005-02-13 devnull chdir(home);
296 6e527fbc 2005-02-13 devnull else if(chdir(xdir) < 0) {
297 6e527fbc 2005-02-13 devnull badchdir = 1;
298 6e527fbc 2005-02-13 devnull chdir(home);
299 6e527fbc 2005-02-13 devnull }
300 6e527fbc 2005-02-13 devnull
301 6e527fbc 2005-02-13 devnull /* Start the gnot serving its namespace */
302 6e527fbc 2005-02-13 devnull writestr(fd, "FS", "FS", 0);
303 6e527fbc 2005-02-13 devnull writestr(fd, "/", "exportfs dir", 0);
304 6e527fbc 2005-02-13 devnull
305 6e527fbc 2005-02-13 devnull n = read(fd, buf, sizeof(buf));
306 6e527fbc 2005-02-13 devnull if(n != 2 || buf[0] != 'O' || buf[1] != 'K')
307 6e527fbc 2005-02-13 devnull exits("remote tree");
308 6e527fbc 2005-02-13 devnull
309 6e527fbc 2005-02-13 devnull if(old)
310 6e527fbc 2005-02-13 devnull fd = old9p(fd);
311 6e527fbc 2005-02-13 devnull
312 6e527fbc 2005-02-13 devnull /* make sure buffers are big by doing fversion explicitly; pick a huge number; other side will trim */
313 6e527fbc 2005-02-13 devnull strcpy(buf, VERSION9P);
314 6e527fbc 2005-02-13 devnull if(fversion(fd, 64*1024, buf, sizeof buf) < 0)
315 6e527fbc 2005-02-13 devnull exits("fversion failed");
316 6e527fbc 2005-02-13 devnull if(mount(fd, -1, "/mnt/term", MCREATE|MREPL, "") < 0)
317 6e527fbc 2005-02-13 devnull exits("mount failed");
318 6e527fbc 2005-02-13 devnull
319 6e527fbc 2005-02-13 devnull close(fd);
320 6e527fbc 2005-02-13 devnull
321 6e527fbc 2005-02-13 devnull /* the remote noteproc uses the mount so it must follow it */
322 6e527fbc 2005-02-13 devnull rmtnoteproc();
323 6e527fbc 2005-02-13 devnull
324 6e527fbc 2005-02-13 devnull for(i = 0; i < 3; i++)
325 6e527fbc 2005-02-13 devnull close(i);
326 6e527fbc 2005-02-13 devnull
327 6e527fbc 2005-02-13 devnull if(open("/mnt/term/dev/cons", OREAD) != 0)
328 6e527fbc 2005-02-13 devnull exits("open stdin");
329 6e527fbc 2005-02-13 devnull if(open("/mnt/term/dev/cons", OWRITE) != 1)
330 6e527fbc 2005-02-13 devnull exits("open stdout");
331 6e527fbc 2005-02-13 devnull dup(1, 2);
332 6e527fbc 2005-02-13 devnull
333 6e527fbc 2005-02-13 devnull if(badchdir)
334 6e527fbc 2005-02-13 devnull print("cpu: failed to chdir to '%s'\n", xdir);
335 6e527fbc 2005-02-13 devnull
336 6e527fbc 2005-02-13 devnull if(gotcmd)
337 6e527fbc 2005-02-13 devnull execl("/bin/rc", "rc", "-lc", cmd, 0);
338 6e527fbc 2005-02-13 devnull else
339 6e527fbc 2005-02-13 devnull execl("/bin/rc", "rc", "-li", 0);
340 6e527fbc 2005-02-13 devnull fatal(1, "exec shell");
341 6e527fbc 2005-02-13 devnull }
342 6e527fbc 2005-02-13 devnull
343 6e527fbc 2005-02-13 devnull char*
344 6e527fbc 2005-02-13 devnull rexcall(int *fd, char *host, char *service)
345 6e527fbc 2005-02-13 devnull {
346 6e527fbc 2005-02-13 devnull char *na;
347 6e527fbc 2005-02-13 devnull char dir[128];
348 6e527fbc 2005-02-13 devnull char err[ERRMAX];
349 6e527fbc 2005-02-13 devnull char msg[128];
350 6e527fbc 2005-02-13 devnull int n;
351 6e527fbc 2005-02-13 devnull
352 6e527fbc 2005-02-13 devnull na = netmkaddr(host, 0, service);
353 6e527fbc 2005-02-13 devnull if((*fd = dial(na, 0, dir, 0)) < 0)
354 6e527fbc 2005-02-13 devnull return "can't dial";
355 6e527fbc 2005-02-13 devnull
356 6e527fbc 2005-02-13 devnull /* negotiate authentication mechanism */
357 6e527fbc 2005-02-13 devnull if(ealgs != nil)
358 6e527fbc 2005-02-13 devnull snprint(msg, sizeof(msg), "%s %s", am->name, ealgs);
359 6e527fbc 2005-02-13 devnull else
360 6e527fbc 2005-02-13 devnull snprint(msg, sizeof(msg), "%s", am->name);
361 6e527fbc 2005-02-13 devnull writestr(*fd, msg, negstr, 0);
362 6e527fbc 2005-02-13 devnull n = readstr(*fd, err, sizeof err);
363 6e527fbc 2005-02-13 devnull if(n < 0)
364 6e527fbc 2005-02-13 devnull return negstr;
365 6e527fbc 2005-02-13 devnull if(*err){
366 6e527fbc 2005-02-13 devnull werrstr(err);
367 6e527fbc 2005-02-13 devnull return negstr;
368 6e527fbc 2005-02-13 devnull }
369 6e527fbc 2005-02-13 devnull
370 6e527fbc 2005-02-13 devnull /* authenticate */
371 6e527fbc 2005-02-13 devnull *fd = (*am->cf)(*fd);
372 6e527fbc 2005-02-13 devnull if(*fd < 0)
373 6e527fbc 2005-02-13 devnull return "can't authenticate";
374 6e527fbc 2005-02-13 devnull return 0;
375 6e527fbc 2005-02-13 devnull }
376 6e527fbc 2005-02-13 devnull
377 6e527fbc 2005-02-13 devnull void
378 6e527fbc 2005-02-13 devnull writestr(int fd, char *str, char *thing, int ignore)
379 6e527fbc 2005-02-13 devnull {
380 6e527fbc 2005-02-13 devnull int l, n;
381 6e527fbc 2005-02-13 devnull
382 6e527fbc 2005-02-13 devnull l = strlen(str);
383 6e527fbc 2005-02-13 devnull n = write(fd, str, l+1);
384 6e527fbc 2005-02-13 devnull if(!ignore && n < 0)
385 6e527fbc 2005-02-13 devnull fatal(1, "writing network: %s", thing);
386 6e527fbc 2005-02-13 devnull }
387 6e527fbc 2005-02-13 devnull
388 6e527fbc 2005-02-13 devnull int
389 6e527fbc 2005-02-13 devnull readstr(int fd, char *str, int len)
390 6e527fbc 2005-02-13 devnull {
391 6e527fbc 2005-02-13 devnull int n;
392 6e527fbc 2005-02-13 devnull
393 6e527fbc 2005-02-13 devnull while(len) {
394 6e527fbc 2005-02-13 devnull n = read(fd, str, 1);
395 6e527fbc 2005-02-13 devnull if(n < 0)
396 6e527fbc 2005-02-13 devnull return -1;
397 6e527fbc 2005-02-13 devnull if(*str == '\0')
398 6e527fbc 2005-02-13 devnull return 0;
399 6e527fbc 2005-02-13 devnull str++;
400 6e527fbc 2005-02-13 devnull len--;
401 6e527fbc 2005-02-13 devnull }
402 6e527fbc 2005-02-13 devnull return -1;
403 6e527fbc 2005-02-13 devnull }
404 6e527fbc 2005-02-13 devnull
405 6e527fbc 2005-02-13 devnull static int
406 6e527fbc 2005-02-13 devnull readln(char *buf, int n)
407 6e527fbc 2005-02-13 devnull {
408 6e527fbc 2005-02-13 devnull char *p = buf;
409 6e527fbc 2005-02-13 devnull
410 6e527fbc 2005-02-13 devnull n--;
411 6e527fbc 2005-02-13 devnull while(n > 0){
412 6e527fbc 2005-02-13 devnull if(read(0, p, 1) != 1)
413 6e527fbc 2005-02-13 devnull break;
414 6e527fbc 2005-02-13 devnull if(*p == '\n' || *p == '\r'){
415 6e527fbc 2005-02-13 devnull *p = 0;
416 6e527fbc 2005-02-13 devnull return p-buf;
417 6e527fbc 2005-02-13 devnull }
418 6e527fbc 2005-02-13 devnull p++;
419 6e527fbc 2005-02-13 devnull }
420 6e527fbc 2005-02-13 devnull *p = 0;
421 6e527fbc 2005-02-13 devnull return p-buf;
422 6e527fbc 2005-02-13 devnull }
423 6e527fbc 2005-02-13 devnull
424 6e527fbc 2005-02-13 devnull /*
425 6e527fbc 2005-02-13 devnull * user level challenge/response
426 6e527fbc 2005-02-13 devnull */
427 6e527fbc 2005-02-13 devnull static int
428 6e527fbc 2005-02-13 devnull netkeyauth(int fd)
429 6e527fbc 2005-02-13 devnull {
430 6e527fbc 2005-02-13 devnull char chall[32];
431 6e527fbc 2005-02-13 devnull char resp[32];
432 6e527fbc 2005-02-13 devnull
433 6e527fbc 2005-02-13 devnull strcpy(chall, getuser());
434 6e527fbc 2005-02-13 devnull print("user[%s]: ", chall);
435 6e527fbc 2005-02-13 devnull if(readln(resp, sizeof(resp)) < 0)
436 6e527fbc 2005-02-13 devnull return -1;
437 6e527fbc 2005-02-13 devnull if(*resp != 0)
438 6e527fbc 2005-02-13 devnull strcpy(chall, resp);
439 6e527fbc 2005-02-13 devnull writestr(fd, chall, "challenge/response", 1);
440 6e527fbc 2005-02-13 devnull
441 6e527fbc 2005-02-13 devnull for(;;){
442 6e527fbc 2005-02-13 devnull if(readstr(fd, chall, sizeof chall) < 0)
443 6e527fbc 2005-02-13 devnull break;
444 6e527fbc 2005-02-13 devnull if(*chall == 0)
445 6e527fbc 2005-02-13 devnull return fd;
446 6e527fbc 2005-02-13 devnull print("challenge: %s\nresponse: ", chall);
447 6e527fbc 2005-02-13 devnull if(readln(resp, sizeof(resp)) < 0)
448 6e527fbc 2005-02-13 devnull break;
449 6e527fbc 2005-02-13 devnull writestr(fd, resp, "challenge/response", 1);
450 6e527fbc 2005-02-13 devnull }
451 6e527fbc 2005-02-13 devnull return -1;
452 6e527fbc 2005-02-13 devnull }
453 6e527fbc 2005-02-13 devnull
454 6e527fbc 2005-02-13 devnull static int
455 6e527fbc 2005-02-13 devnull netkeysrvauth(int fd, char *user)
456 6e527fbc 2005-02-13 devnull {
457 6e527fbc 2005-02-13 devnull char response[32];
458 6e527fbc 2005-02-13 devnull Chalstate *ch;
459 6e527fbc 2005-02-13 devnull int tries;
460 6e527fbc 2005-02-13 devnull AuthInfo *ai;
461 6e527fbc 2005-02-13 devnull
462 6e527fbc 2005-02-13 devnull if(readstr(fd, user, 32) < 0)
463 6e527fbc 2005-02-13 devnull return -1;
464 6e527fbc 2005-02-13 devnull
465 6e527fbc 2005-02-13 devnull ai = nil;
466 6e527fbc 2005-02-13 devnull ch = nil;
467 6e527fbc 2005-02-13 devnull for(tries = 0; tries < 10; tries++){
468 6e527fbc 2005-02-13 devnull if((ch = auth_challenge("p9cr", user, nil)) == nil)
469 6e527fbc 2005-02-13 devnull return -1;
470 6e527fbc 2005-02-13 devnull writestr(fd, ch->chal, "challenge", 1);
471 6e527fbc 2005-02-13 devnull if(readstr(fd, response, sizeof response) < 0)
472 6e527fbc 2005-02-13 devnull return -1;
473 6e527fbc 2005-02-13 devnull ch->resp = response;
474 6e527fbc 2005-02-13 devnull ch->nresp = strlen(response);
475 6e527fbc 2005-02-13 devnull if((ai = auth_response(ch)) != nil)
476 6e527fbc 2005-02-13 devnull break;
477 6e527fbc 2005-02-13 devnull }
478 6e527fbc 2005-02-13 devnull auth_freechal(ch);
479 6e527fbc 2005-02-13 devnull if(ai == nil)
480 6e527fbc 2005-02-13 devnull return -1;
481 6e527fbc 2005-02-13 devnull writestr(fd, "", "challenge", 1);
482 6e527fbc 2005-02-13 devnull if(auth_chuid(ai, 0) < 0)
483 6e527fbc 2005-02-13 devnull fatal(1, "newns");
484 6e527fbc 2005-02-13 devnull auth_freeAI(ai);
485 6e527fbc 2005-02-13 devnull return fd;
486 6e527fbc 2005-02-13 devnull }
487 6e527fbc 2005-02-13 devnull
488 6e527fbc 2005-02-13 devnull static void
489 6e527fbc 2005-02-13 devnull mksecret(char *t, uchar *f)
490 6e527fbc 2005-02-13 devnull {
491 6e527fbc 2005-02-13 devnull sprint(t, "%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
492 6e527fbc 2005-02-13 devnull f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9]);
493 6e527fbc 2005-02-13 devnull }
494 6e527fbc 2005-02-13 devnull
495 6e527fbc 2005-02-13 devnull /*
496 6e527fbc 2005-02-13 devnull * plan9 authentication followed by rc4 encryption
497 6e527fbc 2005-02-13 devnull */
498 6e527fbc 2005-02-13 devnull static int
499 6e527fbc 2005-02-13 devnull p9auth(int fd)
500 6e527fbc 2005-02-13 devnull {
501 6e527fbc 2005-02-13 devnull uchar key[16];
502 6e527fbc 2005-02-13 devnull uchar digest[SHA1dlen];
503 6e527fbc 2005-02-13 devnull char fromclientsecret[21];
504 6e527fbc 2005-02-13 devnull char fromserversecret[21];
505 6e527fbc 2005-02-13 devnull int i;
506 6e527fbc 2005-02-13 devnull AuthInfo *ai;
507 6e527fbc 2005-02-13 devnull
508 6e527fbc 2005-02-13 devnull ai = auth_proxy(fd, auth_getkey, "proto=%q user=%q role=client", p9authproto, user);
509 6e527fbc 2005-02-13 devnull if(ai == nil)
510 6e527fbc 2005-02-13 devnull return -1;
511 6e527fbc 2005-02-13 devnull memmove(key+4, ai->secret, ai->nsecret);
512 6e527fbc 2005-02-13 devnull if(ealgs == nil)
513 6e527fbc 2005-02-13 devnull return fd;
514 6e527fbc 2005-02-13 devnull
515 6e527fbc 2005-02-13 devnull /* exchange random numbers */
516 6e527fbc 2005-02-13 devnull srand(truerand());
517 6e527fbc 2005-02-13 devnull for(i = 0; i < 4; i++)
518 6e527fbc 2005-02-13 devnull key[i] = rand();
519 6e527fbc 2005-02-13 devnull if(write(fd, key, 4) != 4)
520 6e527fbc 2005-02-13 devnull return -1;
521 6e527fbc 2005-02-13 devnull if(readn(fd, key+12, 4) != 4)
522 6e527fbc 2005-02-13 devnull return -1;
523 6e527fbc 2005-02-13 devnull
524 6e527fbc 2005-02-13 devnull /* scramble into two secrets */
525 6e527fbc 2005-02-13 devnull sha1(key, sizeof(key), digest, nil);
526 6e527fbc 2005-02-13 devnull mksecret(fromclientsecret, digest);
527 6e527fbc 2005-02-13 devnull mksecret(fromserversecret, digest+10);
528 6e527fbc 2005-02-13 devnull
529 6e527fbc 2005-02-13 devnull /* set up encryption */
530 6e527fbc 2005-02-13 devnull i = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
531 6e527fbc 2005-02-13 devnull if(i < 0)
532 6e527fbc 2005-02-13 devnull werrstr("can't establish ssl connection: %r");
533 6e527fbc 2005-02-13 devnull return i;
534 6e527fbc 2005-02-13 devnull }
535 6e527fbc 2005-02-13 devnull
536 6e527fbc 2005-02-13 devnull static int
537 6e527fbc 2005-02-13 devnull noauth(int fd)
538 6e527fbc 2005-02-13 devnull {
539 6e527fbc 2005-02-13 devnull ealgs = nil;
540 6e527fbc 2005-02-13 devnull return fd;
541 6e527fbc 2005-02-13 devnull }
542 6e527fbc 2005-02-13 devnull
543 6e527fbc 2005-02-13 devnull static int
544 6e527fbc 2005-02-13 devnull srvnoauth(int fd, char *user)
545 6e527fbc 2005-02-13 devnull {
546 6e527fbc 2005-02-13 devnull strcpy(user, getuser());
547 6e527fbc 2005-02-13 devnull ealgs = nil;
548 6e527fbc 2005-02-13 devnull return fd;
549 6e527fbc 2005-02-13 devnull }
550 6e527fbc 2005-02-13 devnull
551 6e527fbc 2005-02-13 devnull void
552 6e527fbc 2005-02-13 devnull loghex(uchar *p, int n)
553 6e527fbc 2005-02-13 devnull {
554 6e527fbc 2005-02-13 devnull char buf[100];
555 6e527fbc 2005-02-13 devnull int i;
556 6e527fbc 2005-02-13 devnull
557 6e527fbc 2005-02-13 devnull for(i = 0; i < n; i++)
558 6e527fbc 2005-02-13 devnull sprint(buf+2*i, "%2.2ux", p[i]);
559 6e527fbc 2005-02-13 devnull syslog(0, "cpu", buf);
560 6e527fbc 2005-02-13 devnull }
561 6e527fbc 2005-02-13 devnull
562 6e527fbc 2005-02-13 devnull static int
563 6e527fbc 2005-02-13 devnull srvp9auth(int fd, char *user)
564 6e527fbc 2005-02-13 devnull {
565 6e527fbc 2005-02-13 devnull uchar key[16];
566 6e527fbc 2005-02-13 devnull uchar digest[SHA1dlen];
567 6e527fbc 2005-02-13 devnull char fromclientsecret[21];
568 6e527fbc 2005-02-13 devnull char fromserversecret[21];
569 6e527fbc 2005-02-13 devnull int i;
570 6e527fbc 2005-02-13 devnull AuthInfo *ai;
571 6e527fbc 2005-02-13 devnull
572 6e527fbc 2005-02-13 devnull ai = auth_proxy(0, nil, "proto=%q role=server", p9authproto);
573 6e527fbc 2005-02-13 devnull if(ai == nil)
574 6e527fbc 2005-02-13 devnull return -1;
575 6e527fbc 2005-02-13 devnull if(auth_chuid(ai, nil) < 0)
576 6e527fbc 2005-02-13 devnull return -1;
577 6e527fbc 2005-02-13 devnull strcpy(user, ai->cuid);
578 6e527fbc 2005-02-13 devnull memmove(key+4, ai->secret, ai->nsecret);
579 6e527fbc 2005-02-13 devnull
580 6e527fbc 2005-02-13 devnull if(ealgs == nil)
581 6e527fbc 2005-02-13 devnull return fd;
582 6e527fbc 2005-02-13 devnull
583 6e527fbc 2005-02-13 devnull /* exchange random numbers */
584 6e527fbc 2005-02-13 devnull srand(truerand());
585 6e527fbc 2005-02-13 devnull for(i = 0; i < 4; i++)
586 6e527fbc 2005-02-13 devnull key[i+12] = rand();
587 6e527fbc 2005-02-13 devnull if(readn(fd, key, 4) != 4)
588 6e527fbc 2005-02-13 devnull return -1;
589 6e527fbc 2005-02-13 devnull if(write(fd, key+12, 4) != 4)
590 6e527fbc 2005-02-13 devnull return -1;
591 6e527fbc 2005-02-13 devnull
592 6e527fbc 2005-02-13 devnull /* scramble into two secrets */
593 6e527fbc 2005-02-13 devnull sha1(key, sizeof(key), digest, nil);
594 6e527fbc 2005-02-13 devnull mksecret(fromclientsecret, digest);
595 6e527fbc 2005-02-13 devnull mksecret(fromserversecret, digest+10);
596 6e527fbc 2005-02-13 devnull
597 6e527fbc 2005-02-13 devnull /* set up encryption */
598 6e527fbc 2005-02-13 devnull i = pushssl(fd, ealgs, fromserversecret, fromclientsecret, nil);
599 6e527fbc 2005-02-13 devnull if(i < 0)
600 6e527fbc 2005-02-13 devnull werrstr("can't establish ssl connection: %r");
601 6e527fbc 2005-02-13 devnull return i;
602 6e527fbc 2005-02-13 devnull }
603 6e527fbc 2005-02-13 devnull
604 6e527fbc 2005-02-13 devnull /*
605 6e527fbc 2005-02-13 devnull * set authentication mechanism
606 6e527fbc 2005-02-13 devnull */
607 6e527fbc 2005-02-13 devnull int
608 6e527fbc 2005-02-13 devnull setam(char *name)
609 6e527fbc 2005-02-13 devnull {
610 6e527fbc 2005-02-13 devnull for(am = authmethod; am->name != nil; am++)
611 6e527fbc 2005-02-13 devnull if(strcmp(am->name, name) == 0)
612 6e527fbc 2005-02-13 devnull return 0;
613 6e527fbc 2005-02-13 devnull am = authmethod;
614 6e527fbc 2005-02-13 devnull return -1;
615 6e527fbc 2005-02-13 devnull }
616 6e527fbc 2005-02-13 devnull
617 6e527fbc 2005-02-13 devnull /*
618 6e527fbc 2005-02-13 devnull * set authentication mechanism and encryption/hash algs
619 6e527fbc 2005-02-13 devnull */
620 6e527fbc 2005-02-13 devnull int
621 6e527fbc 2005-02-13 devnull setamalg(char *s)
622 6e527fbc 2005-02-13 devnull {
623 6e527fbc 2005-02-13 devnull ealgs = strchr(s, ' ');
624 6e527fbc 2005-02-13 devnull if(ealgs != nil)
625 6e527fbc 2005-02-13 devnull *ealgs++ = 0;
626 6e527fbc 2005-02-13 devnull return setam(s);
627 6e527fbc 2005-02-13 devnull }
628 6e527fbc 2005-02-13 devnull
629 6e527fbc 2005-02-13 devnull char *rmtnotefile = "/mnt/term/dev/cpunote";
630 6e527fbc 2005-02-13 devnull
631 6e527fbc 2005-02-13 devnull /*
632 6e527fbc 2005-02-13 devnull * loop reading /mnt/term/dev/note looking for notes.
633 6e527fbc 2005-02-13 devnull * The child returns to start the shell.
634 6e527fbc 2005-02-13 devnull */
635 6e527fbc 2005-02-13 devnull void
636 6e527fbc 2005-02-13 devnull rmtnoteproc(void)
637 6e527fbc 2005-02-13 devnull {
638 6e527fbc 2005-02-13 devnull int n, fd, pid, notepid;
639 6e527fbc 2005-02-13 devnull char buf[256];
640 6e527fbc 2005-02-13 devnull
641 6e527fbc 2005-02-13 devnull /* new proc returns to start shell */
642 6e527fbc 2005-02-13 devnull pid = rfork(RFPROC|RFFDG|RFNOTEG|RFNAMEG|RFMEM);
643 6e527fbc 2005-02-13 devnull switch(pid){
644 6e527fbc 2005-02-13 devnull case -1:
645 6e527fbc 2005-02-13 devnull syslog(0, "cpu", "cpu -R: can't start noteproc: %r");
646 6e527fbc 2005-02-13 devnull return;
647 6e527fbc 2005-02-13 devnull case 0:
648 6e527fbc 2005-02-13 devnull return;
649 6e527fbc 2005-02-13 devnull }
650 6e527fbc 2005-02-13 devnull
651 6e527fbc 2005-02-13 devnull /* new proc reads notes from other side and posts them to shell */
652 6e527fbc 2005-02-13 devnull switch(notepid = rfork(RFPROC|RFFDG|RFMEM)){
653 6e527fbc 2005-02-13 devnull case -1:
654 6e527fbc 2005-02-13 devnull syslog(0, "cpu", "cpu -R: can't start wait proc: %r");
655 6e527fbc 2005-02-13 devnull _exits(0);
656 6e527fbc 2005-02-13 devnull case 0:
657 6e527fbc 2005-02-13 devnull fd = open(rmtnotefile, OREAD);
658 6e527fbc 2005-02-13 devnull if(fd < 0){
659 6e527fbc 2005-02-13 devnull syslog(0, "cpu", "cpu -R: can't open %s", rmtnotefile);
660 6e527fbc 2005-02-13 devnull _exits(0);
661 6e527fbc 2005-02-13 devnull }
662 6e527fbc 2005-02-13 devnull
663 6e527fbc 2005-02-13 devnull for(;;){
664 6e527fbc 2005-02-13 devnull n = read(fd, buf, sizeof(buf)-1);
665 6e527fbc 2005-02-13 devnull if(n <= 0){
666 6e527fbc 2005-02-13 devnull postnote(PNGROUP, pid, "hangup");
667 6e527fbc 2005-02-13 devnull _exits(0);
668 6e527fbc 2005-02-13 devnull }
669 6e527fbc 2005-02-13 devnull buf[n] = 0;
670 6e527fbc 2005-02-13 devnull postnote(PNGROUP, pid, buf);
671 6e527fbc 2005-02-13 devnull }
672 6e527fbc 2005-02-13 devnull break;
673 6e527fbc 2005-02-13 devnull }
674 6e527fbc 2005-02-13 devnull
675 6e527fbc 2005-02-13 devnull /* original proc waits for shell proc to die and kills note proc */
676 6e527fbc 2005-02-13 devnull for(;;){
677 6e527fbc 2005-02-13 devnull n = waitpid();
678 6e527fbc 2005-02-13 devnull if(n < 0 || n == pid)
679 6e527fbc 2005-02-13 devnull break;
680 6e527fbc 2005-02-13 devnull }
681 6e527fbc 2005-02-13 devnull postnote(PNPROC, notepid, "kill");
682 6e527fbc 2005-02-13 devnull _exits(0);
683 6e527fbc 2005-02-13 devnull }
684 6e527fbc 2005-02-13 devnull
685 6e527fbc 2005-02-13 devnull enum
686 6e527fbc 2005-02-13 devnull {
687 6e527fbc 2005-02-13 devnull Qdir,
688 6e527fbc 2005-02-13 devnull Qcpunote,
689 6e527fbc 2005-02-13 devnull
690 6e527fbc 2005-02-13 devnull Nfid = 32,
691 6e527fbc 2005-02-13 devnull };
692 6e527fbc 2005-02-13 devnull
693 6e527fbc 2005-02-13 devnull struct {
694 6e527fbc 2005-02-13 devnull char *name;
695 6e527fbc 2005-02-13 devnull Qid qid;
696 6e527fbc 2005-02-13 devnull ulong perm;
697 6e527fbc 2005-02-13 devnull } fstab[] =
698 6e527fbc 2005-02-13 devnull {
699 6e527fbc 2005-02-13 devnull [Qdir] { ".", {Qdir, 0, QTDIR}, DMDIR|0555 },
700 6e527fbc 2005-02-13 devnull [Qcpunote] { "cpunote", {Qcpunote, 0}, 0444 },
701 6e527fbc 2005-02-13 devnull };
702 6e527fbc 2005-02-13 devnull
703 6e527fbc 2005-02-13 devnull typedef struct Note Note;
704 6e527fbc 2005-02-13 devnull struct Note
705 6e527fbc 2005-02-13 devnull {
706 6e527fbc 2005-02-13 devnull Note *next;
707 6e527fbc 2005-02-13 devnull char msg[ERRMAX];
708 6e527fbc 2005-02-13 devnull };
709 6e527fbc 2005-02-13 devnull
710 6e527fbc 2005-02-13 devnull typedef struct Request Request;
711 6e527fbc 2005-02-13 devnull struct Request
712 6e527fbc 2005-02-13 devnull {
713 6e527fbc 2005-02-13 devnull Request *next;
714 6e527fbc 2005-02-13 devnull Fcall f;
715 6e527fbc 2005-02-13 devnull };
716 6e527fbc 2005-02-13 devnull
717 6e527fbc 2005-02-13 devnull typedef struct Fid Fid;
718 6e527fbc 2005-02-13 devnull struct Fid
719 6e527fbc 2005-02-13 devnull {
720 6e527fbc 2005-02-13 devnull int fid;
721 6e527fbc 2005-02-13 devnull int file;
722 6e527fbc 2005-02-13 devnull };
723 6e527fbc 2005-02-13 devnull Fid fids[Nfid];
724 6e527fbc 2005-02-13 devnull
725 6e527fbc 2005-02-13 devnull struct {
726 6e527fbc 2005-02-13 devnull Lock;
727 6e527fbc 2005-02-13 devnull Note *nfirst, *nlast;
728 6e527fbc 2005-02-13 devnull Request *rfirst, *rlast;
729 6e527fbc 2005-02-13 devnull } nfs;
730 6e527fbc 2005-02-13 devnull
731 6e527fbc 2005-02-13 devnull int
732 6e527fbc 2005-02-13 devnull fsreply(int fd, Fcall *f)
733 6e527fbc 2005-02-13 devnull {
734 6e527fbc 2005-02-13 devnull uchar buf[IOHDRSZ+Maxfdata];
735 6e527fbc 2005-02-13 devnull int n;
736 6e527fbc 2005-02-13 devnull
737 6e527fbc 2005-02-13 devnull if(dbg)
738 6e527fbc 2005-02-13 devnull fprint(2, "<-%F\n", f);
739 6e527fbc 2005-02-13 devnull n = convS2M(f, buf, sizeof buf);
740 6e527fbc 2005-02-13 devnull if(n > 0){
741 6e527fbc 2005-02-13 devnull if(write(fd, buf, n) != n){
742 6e527fbc 2005-02-13 devnull close(fd);
743 6e527fbc 2005-02-13 devnull return -1;
744 6e527fbc 2005-02-13 devnull }
745 6e527fbc 2005-02-13 devnull }
746 6e527fbc 2005-02-13 devnull return 0;
747 6e527fbc 2005-02-13 devnull }
748 6e527fbc 2005-02-13 devnull
749 6e527fbc 2005-02-13 devnull /* match a note read request with a note, reply to the request */
750 6e527fbc 2005-02-13 devnull int
751 6e527fbc 2005-02-13 devnull kick(int fd)
752 6e527fbc 2005-02-13 devnull {
753 6e527fbc 2005-02-13 devnull Request *rp;
754 6e527fbc 2005-02-13 devnull Note *np;
755 6e527fbc 2005-02-13 devnull int rv;
756 6e527fbc 2005-02-13 devnull
757 6e527fbc 2005-02-13 devnull for(;;){
758 6e527fbc 2005-02-13 devnull lock(&nfs);
759 6e527fbc 2005-02-13 devnull rp = nfs.rfirst;
760 6e527fbc 2005-02-13 devnull np = nfs.nfirst;
761 6e527fbc 2005-02-13 devnull if(rp == nil || np == nil){
762 6e527fbc 2005-02-13 devnull unlock(&nfs);
763 6e527fbc 2005-02-13 devnull break;
764 6e527fbc 2005-02-13 devnull }
765 6e527fbc 2005-02-13 devnull nfs.rfirst = rp->next;
766 6e527fbc 2005-02-13 devnull nfs.nfirst = np->next;
767 6e527fbc 2005-02-13 devnull unlock(&nfs);
768 6e527fbc 2005-02-13 devnull
769 6e527fbc 2005-02-13 devnull rp->f.type = Rread;
770 6e527fbc 2005-02-13 devnull rp->f.count = strlen(np->msg);
771 6e527fbc 2005-02-13 devnull rp->f.data = np->msg;
772 6e527fbc 2005-02-13 devnull rv = fsreply(fd, &rp->f);
773 6e527fbc 2005-02-13 devnull free(rp);
774 6e527fbc 2005-02-13 devnull free(np);
775 6e527fbc 2005-02-13 devnull if(rv < 0)
776 6e527fbc 2005-02-13 devnull return -1;
777 6e527fbc 2005-02-13 devnull }
778 6e527fbc 2005-02-13 devnull return 0;
779 6e527fbc 2005-02-13 devnull }
780 6e527fbc 2005-02-13 devnull
781 6e527fbc 2005-02-13 devnull void
782 6e527fbc 2005-02-13 devnull flushreq(int tag)
783 6e527fbc 2005-02-13 devnull {
784 6e527fbc 2005-02-13 devnull Request **l, *rp;
785 6e527fbc 2005-02-13 devnull
786 6e527fbc 2005-02-13 devnull lock(&nfs);
787 6e527fbc 2005-02-13 devnull for(l = &nfs.rfirst; *l != nil; l = &(*l)->next){
788 6e527fbc 2005-02-13 devnull rp = *l;
789 6e527fbc 2005-02-13 devnull if(rp->f.tag == tag){
790 6e527fbc 2005-02-13 devnull *l = rp->next;
791 6e527fbc 2005-02-13 devnull unlock(&nfs);
792 6e527fbc 2005-02-13 devnull free(rp);
793 6e527fbc 2005-02-13 devnull return;
794 6e527fbc 2005-02-13 devnull }
795 6e527fbc 2005-02-13 devnull }
796 6e527fbc 2005-02-13 devnull unlock(&nfs);
797 6e527fbc 2005-02-13 devnull }
798 6e527fbc 2005-02-13 devnull
799 6e527fbc 2005-02-13 devnull Fid*
800 6e527fbc 2005-02-13 devnull getfid(int fid)
801 6e527fbc 2005-02-13 devnull {
802 6e527fbc 2005-02-13 devnull int i, freefid;
803 6e527fbc 2005-02-13 devnull
804 6e527fbc 2005-02-13 devnull freefid = -1;
805 6e527fbc 2005-02-13 devnull for(i = 0; i < Nfid; i++){
806 6e527fbc 2005-02-13 devnull if(freefid < 0 && fids[i].file < 0)
807 6e527fbc 2005-02-13 devnull freefid = i;
808 6e527fbc 2005-02-13 devnull if(fids[i].fid == fid)
809 6e527fbc 2005-02-13 devnull return &fids[i];
810 6e527fbc 2005-02-13 devnull }
811 6e527fbc 2005-02-13 devnull if(freefid >= 0){
812 6e527fbc 2005-02-13 devnull fids[freefid].fid = fid;
813 6e527fbc 2005-02-13 devnull return &fids[freefid];
814 6e527fbc 2005-02-13 devnull }
815 6e527fbc 2005-02-13 devnull return nil;
816 6e527fbc 2005-02-13 devnull }
817 6e527fbc 2005-02-13 devnull
818 6e527fbc 2005-02-13 devnull int
819 6e527fbc 2005-02-13 devnull fsstat(int fd, Fid *fid, Fcall *f)
820 6e527fbc 2005-02-13 devnull {
821 6e527fbc 2005-02-13 devnull Dir d;
822 6e527fbc 2005-02-13 devnull uchar statbuf[256];
823 6e527fbc 2005-02-13 devnull
824 6e527fbc 2005-02-13 devnull memset(&d, 0, sizeof(d));
825 6e527fbc 2005-02-13 devnull d.name = fstab[fid->file].name;
826 6e527fbc 2005-02-13 devnull d.uid = user;
827 6e527fbc 2005-02-13 devnull d.gid = user;
828 6e527fbc 2005-02-13 devnull d.muid = user;
829 6e527fbc 2005-02-13 devnull d.qid = fstab[fid->file].qid;
830 6e527fbc 2005-02-13 devnull d.mode = fstab[fid->file].perm;
831 6e527fbc 2005-02-13 devnull d.atime = d.mtime = time(0);
832 6e527fbc 2005-02-13 devnull f->stat = statbuf;
833 6e527fbc 2005-02-13 devnull f->nstat = convD2M(&d, statbuf, sizeof statbuf);
834 6e527fbc 2005-02-13 devnull return fsreply(fd, f);
835 6e527fbc 2005-02-13 devnull }
836 6e527fbc 2005-02-13 devnull
837 6e527fbc 2005-02-13 devnull int
838 6e527fbc 2005-02-13 devnull fsread(int fd, Fid *fid, Fcall *f)
839 6e527fbc 2005-02-13 devnull {
840 6e527fbc 2005-02-13 devnull Dir d;
841 6e527fbc 2005-02-13 devnull uchar buf[256];
842 6e527fbc 2005-02-13 devnull Request *rp;
843 6e527fbc 2005-02-13 devnull
844 6e527fbc 2005-02-13 devnull switch(fid->file){
845 6e527fbc 2005-02-13 devnull default:
846 6e527fbc 2005-02-13 devnull return -1;
847 6e527fbc 2005-02-13 devnull case Qdir:
848 6e527fbc 2005-02-13 devnull if(f->offset == 0 && f->count >0){
849 6e527fbc 2005-02-13 devnull memset(&d, 0, sizeof(d));
850 6e527fbc 2005-02-13 devnull d.name = fstab[Qcpunote].name;
851 6e527fbc 2005-02-13 devnull d.uid = user;
852 6e527fbc 2005-02-13 devnull d.gid = user;
853 6e527fbc 2005-02-13 devnull d.muid = user;
854 6e527fbc 2005-02-13 devnull d.qid = fstab[Qcpunote].qid;
855 6e527fbc 2005-02-13 devnull d.mode = fstab[Qcpunote].perm;
856 6e527fbc 2005-02-13 devnull d.atime = d.mtime = time(0);
857 6e527fbc 2005-02-13 devnull f->count = convD2M(&d, buf, sizeof buf);
858 6e527fbc 2005-02-13 devnull f->data = (char*)buf;
859 6e527fbc 2005-02-13 devnull } else
860 6e527fbc 2005-02-13 devnull f->count = 0;
861 6e527fbc 2005-02-13 devnull return fsreply(fd, f);
862 6e527fbc 2005-02-13 devnull case Qcpunote:
863 6e527fbc 2005-02-13 devnull rp = mallocz(sizeof(*rp), 1);
864 6e527fbc 2005-02-13 devnull if(rp == nil)
865 6e527fbc 2005-02-13 devnull return -1;
866 6e527fbc 2005-02-13 devnull rp->f = *f;
867 6e527fbc 2005-02-13 devnull lock(&nfs);
868 6e527fbc 2005-02-13 devnull if(nfs.rfirst == nil)
869 6e527fbc 2005-02-13 devnull nfs.rfirst = rp;
870 6e527fbc 2005-02-13 devnull else
871 6e527fbc 2005-02-13 devnull nfs.rlast->next = rp;
872 6e527fbc 2005-02-13 devnull nfs.rlast = rp;
873 6e527fbc 2005-02-13 devnull unlock(&nfs);
874 6e527fbc 2005-02-13 devnull return kick(fd);;
875 6e527fbc 2005-02-13 devnull }
876 6e527fbc 2005-02-13 devnull }
877 6e527fbc 2005-02-13 devnull
878 6e527fbc 2005-02-13 devnull char Eperm[] = "permission denied";
879 6e527fbc 2005-02-13 devnull char Enofile[] = "out of files";
880 6e527fbc 2005-02-13 devnull char Enotdir[] = "not a directory";
881 6e527fbc 2005-02-13 devnull
882 6e527fbc 2005-02-13 devnull void
883 6e527fbc 2005-02-13 devnull notefs(int fd)
884 6e527fbc 2005-02-13 devnull {
885 6e527fbc 2005-02-13 devnull uchar buf[IOHDRSZ+Maxfdata];
886 6e527fbc 2005-02-13 devnull int i, j, n;
887 6e527fbc 2005-02-13 devnull char err[ERRMAX];
888 6e527fbc 2005-02-13 devnull Fcall f;
889 6e527fbc 2005-02-13 devnull Fid *fid, *nfid;
890 6e527fbc 2005-02-13 devnull int doreply;
891 6e527fbc 2005-02-13 devnull
892 6e527fbc 2005-02-13 devnull rfork(RFNOTEG);
893 6e527fbc 2005-02-13 devnull fmtinstall('F', fcallconv);
894 6e527fbc 2005-02-13 devnull
895 6e527fbc 2005-02-13 devnull for(n = 0; n < Nfid; n++)
896 6e527fbc 2005-02-13 devnull fids[n].file = -1;
897 6e527fbc 2005-02-13 devnull
898 6e527fbc 2005-02-13 devnull for(;;){
899 6e527fbc 2005-02-13 devnull n = read9pmsg(fd, buf, sizeof(buf));
900 6e527fbc 2005-02-13 devnull if(n <= 0){
901 6e527fbc 2005-02-13 devnull if(dbg)
902 6e527fbc 2005-02-13 devnull fprint(2, "read9pmsg(%d) returns %d: %r\n", fd, n);
903 6e527fbc 2005-02-13 devnull break;
904 6e527fbc 2005-02-13 devnull }
905 6e527fbc 2005-02-13 devnull if(convM2S(buf, n, &f) < 0)
906 6e527fbc 2005-02-13 devnull break;
907 6e527fbc 2005-02-13 devnull if(dbg)
908 6e527fbc 2005-02-13 devnull fprint(2, "->%F\n", &f);
909 6e527fbc 2005-02-13 devnull doreply = 1;
910 6e527fbc 2005-02-13 devnull fid = getfid(f.fid);
911 6e527fbc 2005-02-13 devnull if(fid == nil){
912 6e527fbc 2005-02-13 devnull nofids:
913 6e527fbc 2005-02-13 devnull f.type = Rerror;
914 6e527fbc 2005-02-13 devnull f.ename = Enofile;
915 6e527fbc 2005-02-13 devnull fsreply(fd, &f);
916 6e527fbc 2005-02-13 devnull continue;
917 6e527fbc 2005-02-13 devnull }
918 6e527fbc 2005-02-13 devnull switch(f.type++){
919 6e527fbc 2005-02-13 devnull default:
920 6e527fbc 2005-02-13 devnull f.type = Rerror;
921 6e527fbc 2005-02-13 devnull f.ename = "unknown type";
922 6e527fbc 2005-02-13 devnull break;
923 6e527fbc 2005-02-13 devnull case Tflush:
924 6e527fbc 2005-02-13 devnull flushreq(f.oldtag);
925 6e527fbc 2005-02-13 devnull break;
926 6e527fbc 2005-02-13 devnull case Tversion:
927 6e527fbc 2005-02-13 devnull if(f.msize > IOHDRSZ+Maxfdata)
928 6e527fbc 2005-02-13 devnull f.msize = IOHDRSZ+Maxfdata;
929 6e527fbc 2005-02-13 devnull break;
930 6e527fbc 2005-02-13 devnull case Tauth:
931 6e527fbc 2005-02-13 devnull f.type = Rerror;
932 6e527fbc 2005-02-13 devnull f.ename = "cpu: authentication not required";
933 6e527fbc 2005-02-13 devnull break;
934 6e527fbc 2005-02-13 devnull case Tattach:
935 6e527fbc 2005-02-13 devnull f.qid = fstab[Qdir].qid;
936 6e527fbc 2005-02-13 devnull fid->file = Qdir;
937 6e527fbc 2005-02-13 devnull break;
938 6e527fbc 2005-02-13 devnull case Twalk:
939 6e527fbc 2005-02-13 devnull nfid = nil;
940 6e527fbc 2005-02-13 devnull if(f.newfid != f.fid){
941 6e527fbc 2005-02-13 devnull nfid = getfid(f.newfid);
942 6e527fbc 2005-02-13 devnull if(nfid == nil)
943 6e527fbc 2005-02-13 devnull goto nofids;
944 6e527fbc 2005-02-13 devnull nfid->file = fid->file;
945 6e527fbc 2005-02-13 devnull fid = nfid;
946 6e527fbc 2005-02-13 devnull }
947 6e527fbc 2005-02-13 devnull
948 6e527fbc 2005-02-13 devnull f.ename = nil;
949 6e527fbc 2005-02-13 devnull for(i=0; i<f.nwname; i++){
950 6e527fbc 2005-02-13 devnull if(i > MAXWELEM){
951 6e527fbc 2005-02-13 devnull f.type = Rerror;
952 6e527fbc 2005-02-13 devnull f.ename = "too many name elements";
953 6e527fbc 2005-02-13 devnull break;
954 6e527fbc 2005-02-13 devnull }
955 6e527fbc 2005-02-13 devnull if(fid->file != Qdir){
956 6e527fbc 2005-02-13 devnull f.type = Rerror;
957 6e527fbc 2005-02-13 devnull f.ename = Enotdir;
958 6e527fbc 2005-02-13 devnull break;
959 6e527fbc 2005-02-13 devnull }
960 6e527fbc 2005-02-13 devnull if(strcmp(f.wname[i], "cpunote") == 0){
961 6e527fbc 2005-02-13 devnull fid->file = Qcpunote;
962 6e527fbc 2005-02-13 devnull f.wqid[i] = fstab[Qcpunote].qid;
963 6e527fbc 2005-02-13 devnull continue;
964 6e527fbc 2005-02-13 devnull }
965 6e527fbc 2005-02-13 devnull f.type = Rerror;
966 6e527fbc 2005-02-13 devnull f.ename = err;
967 6e527fbc 2005-02-13 devnull strcpy(err, "cpu: file \"");
968 6e527fbc 2005-02-13 devnull for(j=0; j<=i; j++){
969 6e527fbc 2005-02-13 devnull if(strlen(err)+1+strlen(f.wname[j])+32 > sizeof err)
970 6e527fbc 2005-02-13 devnull break;
971 6e527fbc 2005-02-13 devnull if(j != 0)
972 6e527fbc 2005-02-13 devnull strcat(err, "/");
973 6e527fbc 2005-02-13 devnull strcat(err, f.wname[j]);
974 6e527fbc 2005-02-13 devnull }
975 6e527fbc 2005-02-13 devnull strcat(err, "\" does not exist");
976 6e527fbc 2005-02-13 devnull break;
977 6e527fbc 2005-02-13 devnull }
978 6e527fbc 2005-02-13 devnull if(nfid != nil && (f.ename != nil || i < f.nwname))
979 6e527fbc 2005-02-13 devnull nfid ->file = -1;
980 6e527fbc 2005-02-13 devnull if(f.type != Rerror)
981 6e527fbc 2005-02-13 devnull f.nwqid = i;
982 6e527fbc 2005-02-13 devnull break;
983 6e527fbc 2005-02-13 devnull case Topen:
984 6e527fbc 2005-02-13 devnull if(f.mode != OREAD){
985 6e527fbc 2005-02-13 devnull f.type = Rerror;
986 6e527fbc 2005-02-13 devnull f.ename = Eperm;
987 6e527fbc 2005-02-13 devnull }
988 6e527fbc 2005-02-13 devnull f.qid = fstab[fid->file].qid;
989 6e527fbc 2005-02-13 devnull break;
990 6e527fbc 2005-02-13 devnull case Tcreate:
991 6e527fbc 2005-02-13 devnull f.type = Rerror;
992 6e527fbc 2005-02-13 devnull f.ename = Eperm;
993 6e527fbc 2005-02-13 devnull break;
994 6e527fbc 2005-02-13 devnull case Tread:
995 6e527fbc 2005-02-13 devnull if(fsread(fd, fid, &f) < 0)
996 6e527fbc 2005-02-13 devnull goto err;
997 6e527fbc 2005-02-13 devnull doreply = 0;
998 6e527fbc 2005-02-13 devnull break;
999 6e527fbc 2005-02-13 devnull case Twrite:
1000 6e527fbc 2005-02-13 devnull f.type = Rerror;
1001 6e527fbc 2005-02-13 devnull f.ename = Eperm;
1002 6e527fbc 2005-02-13 devnull break;
1003 6e527fbc 2005-02-13 devnull case Tclunk:
1004 6e527fbc 2005-02-13 devnull fid->file = -1;
1005 6e527fbc 2005-02-13 devnull break;
1006 6e527fbc 2005-02-13 devnull case Tremove:
1007 6e527fbc 2005-02-13 devnull f.type = Rerror;
1008 6e527fbc 2005-02-13 devnull f.ename = Eperm;
1009 6e527fbc 2005-02-13 devnull break;
1010 6e527fbc 2005-02-13 devnull case Tstat:
1011 6e527fbc 2005-02-13 devnull if(fsstat(fd, fid, &f) < 0)
1012 6e527fbc 2005-02-13 devnull goto err;
1013 6e527fbc 2005-02-13 devnull doreply = 0;
1014 6e527fbc 2005-02-13 devnull break;
1015 6e527fbc 2005-02-13 devnull case Twstat:
1016 6e527fbc 2005-02-13 devnull f.type = Rerror;
1017 6e527fbc 2005-02-13 devnull f.ename = Eperm;
1018 6e527fbc 2005-02-13 devnull break;
1019 6e527fbc 2005-02-13 devnull }
1020 6e527fbc 2005-02-13 devnull if(doreply)
1021 6e527fbc 2005-02-13 devnull if(fsreply(fd, &f) < 0)
1022 6e527fbc 2005-02-13 devnull break;
1023 6e527fbc 2005-02-13 devnull }
1024 6e527fbc 2005-02-13 devnull err:
1025 6e527fbc 2005-02-13 devnull if(dbg)
1026 6e527fbc 2005-02-13 devnull fprint(2, "notefs exiting: %r\n");
1027 6e527fbc 2005-02-13 devnull close(fd);
1028 6e527fbc 2005-02-13 devnull }
1029 6e527fbc 2005-02-13 devnull
1030 6e527fbc 2005-02-13 devnull char notebuf[ERRMAX];
1031 6e527fbc 2005-02-13 devnull
1032 6e527fbc 2005-02-13 devnull void
1033 6e527fbc 2005-02-13 devnull catcher(void*, char *text)
1034 6e527fbc 2005-02-13 devnull {
1035 6e527fbc 2005-02-13 devnull int n;
1036 6e527fbc 2005-02-13 devnull
1037 6e527fbc 2005-02-13 devnull n = strlen(text);
1038 6e527fbc 2005-02-13 devnull if(n >= sizeof(notebuf))
1039 6e527fbc 2005-02-13 devnull n = sizeof(notebuf)-1;
1040 6e527fbc 2005-02-13 devnull memmove(notebuf, text, n);
1041 6e527fbc 2005-02-13 devnull notebuf[n] = '\0';
1042 6e527fbc 2005-02-13 devnull noted(NCONT);
1043 6e527fbc 2005-02-13 devnull }
1044 6e527fbc 2005-02-13 devnull
1045 6e527fbc 2005-02-13 devnull /*
1046 6e527fbc 2005-02-13 devnull * mount in /dev a note file for the remote side to read.
1047 6e527fbc 2005-02-13 devnull */
1048 6e527fbc 2005-02-13 devnull void
1049 6e527fbc 2005-02-13 devnull lclnoteproc(int netfd)
1050 6e527fbc 2005-02-13 devnull {
1051 6e527fbc 2005-02-13 devnull int exportfspid;
1052 6e527fbc 2005-02-13 devnull Waitmsg *w;
1053 6e527fbc 2005-02-13 devnull Note *np;
1054 6e527fbc 2005-02-13 devnull int pfd[2];
1055 6e527fbc 2005-02-13 devnull
1056 6e527fbc 2005-02-13 devnull if(pipe(pfd) < 0){
1057 6e527fbc 2005-02-13 devnull fprint(2, "cpu: can't start note proc: pipe: %r\n");
1058 6e527fbc 2005-02-13 devnull return;
1059 6e527fbc 2005-02-13 devnull }
1060 6e527fbc 2005-02-13 devnull
1061 6e527fbc 2005-02-13 devnull /* new proc mounts and returns to start exportfs */
1062 6e527fbc 2005-02-13 devnull switch(exportfspid = rfork(RFPROC|RFNAMEG|RFFDG|RFMEM)){
1063 6e527fbc 2005-02-13 devnull case -1:
1064 6e527fbc 2005-02-13 devnull fprint(2, "cpu: can't start note proc: rfork: %r\n");
1065 6e527fbc 2005-02-13 devnull return;
1066 6e527fbc 2005-02-13 devnull case 0:
1067 6e527fbc 2005-02-13 devnull close(pfd[0]);
1068 6e527fbc 2005-02-13 devnull if(mount(pfd[1], -1, "/dev", MBEFORE, "") < 0)
1069 6e527fbc 2005-02-13 devnull fprint(2, "cpu: can't mount note proc: %r\n");
1070 6e527fbc 2005-02-13 devnull close(pfd[1]);
1071 6e527fbc 2005-02-13 devnull return;
1072 6e527fbc 2005-02-13 devnull }
1073 6e527fbc 2005-02-13 devnull
1074 6e527fbc 2005-02-13 devnull close(netfd);
1075 6e527fbc 2005-02-13 devnull close(pfd[1]);
1076 6e527fbc 2005-02-13 devnull
1077 6e527fbc 2005-02-13 devnull /* new proc listens for note file system rpc's */
1078 6e527fbc 2005-02-13 devnull switch(rfork(RFPROC|RFNAMEG|RFMEM)){
1079 6e527fbc 2005-02-13 devnull case -1:
1080 6e527fbc 2005-02-13 devnull fprint(2, "cpu: can't start note proc: rfork1: %r\n");
1081 6e527fbc 2005-02-13 devnull _exits(0);
1082 6e527fbc 2005-02-13 devnull case 0:
1083 6e527fbc 2005-02-13 devnull notefs(pfd[0]);
1084 6e527fbc 2005-02-13 devnull _exits(0);
1085 6e527fbc 2005-02-13 devnull }
1086 6e527fbc 2005-02-13 devnull
1087 6e527fbc 2005-02-13 devnull /* original proc waits for notes */
1088 6e527fbc 2005-02-13 devnull notify(catcher);
1089 6e527fbc 2005-02-13 devnull w = nil;
1090 6e527fbc 2005-02-13 devnull for(;;) {
1091 6e527fbc 2005-02-13 devnull *notebuf = 0;
1092 6e527fbc 2005-02-13 devnull free(w);
1093 6e527fbc 2005-02-13 devnull w = wait();
1094 6e527fbc 2005-02-13 devnull if(w == nil) {
1095 6e527fbc 2005-02-13 devnull if(*notebuf == 0)
1096 6e527fbc 2005-02-13 devnull break;
1097 6e527fbc 2005-02-13 devnull np = mallocz(sizeof(Note), 1);
1098 6e527fbc 2005-02-13 devnull if(np != nil){
1099 6e527fbc 2005-02-13 devnull strcpy(np->msg, notebuf);
1100 6e527fbc 2005-02-13 devnull lock(&nfs);
1101 6e527fbc 2005-02-13 devnull if(nfs.nfirst == nil)
1102 6e527fbc 2005-02-13 devnull nfs.nfirst = np;
1103 6e527fbc 2005-02-13 devnull else
1104 6e527fbc 2005-02-13 devnull nfs.nlast->next = np;
1105 6e527fbc 2005-02-13 devnull nfs.nlast = np;
1106 6e527fbc 2005-02-13 devnull unlock(&nfs);
1107 6e527fbc 2005-02-13 devnull kick(pfd[0]);
1108 6e527fbc 2005-02-13 devnull }
1109 6e527fbc 2005-02-13 devnull unlock(&nfs);
1110 6e527fbc 2005-02-13 devnull } else if(w->pid == exportfspid)
1111 6e527fbc 2005-02-13 devnull break;
1112 6e527fbc 2005-02-13 devnull }
1113 6e527fbc 2005-02-13 devnull
1114 6e527fbc 2005-02-13 devnull if(w == nil)
1115 6e527fbc 2005-02-13 devnull exits(nil);
1116 6e527fbc 2005-02-13 devnull exits(w->msg);
1117 6e527fbc 2005-02-13 devnull }