Commit | Line | Data |
---|---|---|
48688564 SL |
1 | #ifndef lint |
2 | static char sccsid[] = "@(#)cntrl.c 5.1 (Berkeley) %G%"; | |
3 | #endif | |
4 | ||
5 | #include "uucp.h" | |
6 | #include <sys/types.h> | |
7 | #include <sys/stat.h> | |
8 | ||
9 | ||
10 | ||
11 | struct Proto { | |
12 | char P_id; | |
13 | int (*P_turnon)(); | |
14 | int (*P_rdmsg)(); | |
15 | int (*P_wrmsg)(); | |
16 | int (*P_rddata)(); | |
17 | int (*P_wrdata)(); | |
18 | int (*P_turnoff)(); | |
19 | }; | |
20 | ||
21 | ||
22 | extern int gturnon(), gturnoff(); | |
23 | extern int grdmsg(), grddata(); | |
24 | extern int gwrmsg(), gwrdata(); | |
25 | extern int imsg(), omsg(); | |
26 | ||
27 | struct Proto Ptbl[]={ | |
28 | 'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff, | |
29 | '\0' | |
30 | }; | |
31 | ||
32 | int (*Imsg)() = imsg, (*Omsg)() = omsg; /* avoid SEL compiler limitation */ | |
33 | ||
34 | int (*Rdmsg)()=imsg, (*Rddata)(); | |
35 | int (*Wrmsg)()=omsg, (*Wrdata)(); | |
36 | int (*Turnon)(), (*Turnoff)(); | |
37 | ||
38 | ||
39 | #define YES "Y" | |
40 | #define NO "N" | |
41 | ||
42 | /* failure messages */ | |
43 | #define EM_MAX 6 | |
44 | #define EM_LOCACC "N1" /* local access to file denied */ | |
45 | #define EM_RMTACC "N2" /* remote access to file/path denied */ | |
46 | #define EM_BADUUCP "N3" /* a bad uucp command was generated */ | |
47 | #define EM_NOTMP "N4" /* remote error - can't create temp */ | |
48 | #define EM_RMTCP "N5" /* can't copy to remote directory - file in public */ | |
49 | #define EM_LOCCP "N6" /* can't copy on local system */ | |
50 | ||
51 | char *Em_msg[] = { | |
52 | "COPY FAILED (reason not given by remote)", | |
53 | "local access to file denied", | |
54 | "remote access to path/file denied", | |
55 | "system error - bad uucp command generated", | |
56 | "remote system can't create temp file", | |
57 | "can't copy to file/directory - file left in PUBDIR/user/file", | |
58 | "can't copy to file/directory - file left in PUBDIR/user/file" | |
59 | }; | |
60 | ||
61 | /* */ | |
62 | ||
63 | ||
64 | #define XUUCP 'X' /* execute uucp (string) */ | |
65 | #define SLTPTCL 'P' /* select protocol (string) */ | |
66 | #define USEPTCL 'U' /* use protocol (character) */ | |
67 | #define RCVFILE 'R' /* receive file (string) */ | |
68 | #define SNDFILE 'S' /* send file (string) */ | |
69 | #define RQSTCMPT 'C' /* request complete (string - yes | no) */ | |
70 | #define HUP 'H' /* ready to hangup (string - yes | no) */ | |
71 | #define RESET 'X' /* reset line modes */ | |
72 | ||
73 | ||
74 | #define W_TYPE wrkvec[0] | |
75 | #define W_FILE1 wrkvec[1] | |
76 | #define W_FILE2 wrkvec[2] | |
77 | #define W_USER wrkvec[3] | |
78 | #define W_OPTNS wrkvec[4] | |
79 | #define W_DFILE wrkvec[5] | |
80 | #define W_MODE wrkvec[6] | |
81 | #define W_NUSER wrkvec[7] | |
82 | ||
83 | #define XFRRATE 350000L | |
84 | #define RMESG(m, s, n) if (rmesg(m, s, n) != 0) {(*Turnoff)(); return(FAIL);} else | |
85 | #define RAMESG(s, n) if (rmesg('\0', s, n) != 0) {(*Turnoff)(); return(FAIL);} else | |
86 | #define WMESG(m, s) if(wmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);} else | |
87 | ||
88 | char Wfile[MAXFULLNAME] = {'\0'}; | |
89 | char Dfile[MAXFULLNAME]; | |
90 | ||
91 | /* | |
92 | * To avoid a huge backlog of X. files, start uuxqt every so often. | |
93 | * To avoid a huge number of uuxqt zombies, | |
94 | * wait for one occasionally! | |
95 | */ | |
96 | static int nXfiles = 0; /* number of X files since last uuxqt start */ | |
97 | static int nXQTs = 0; /* number of uuxqts started */ | |
98 | ||
99 | /******* | |
100 | * cntrl(role, wkpre) | |
101 | * int role; | |
102 | * char *wkpre; | |
103 | * | |
104 | * cntrl - this routine will execute the conversation | |
105 | * between the two machines after both programs are | |
106 | * running. | |
107 | * | |
108 | * return codes | |
109 | * SUCCESS - ok | |
110 | * FAIL - failed | |
111 | */ | |
112 | ||
113 | cntrl(role, wkpre) | |
114 | int role; | |
115 | char *wkpre; | |
116 | { | |
117 | char msg[BUFSIZ], rqstr[BUFSIZ]; | |
118 | register FILE *fp; | |
119 | int filemode; | |
120 | struct stat stbuf; | |
121 | char filename[MAXFULLNAME], wrktype, *wrkvec[20]; | |
122 | extern (*Rdmsg)(), (*Wrmsg)(); | |
123 | extern char *index(), *lastpart(); | |
124 | int status = 1; | |
125 | register int i, narg; | |
126 | int mailopt, ntfyopt; | |
127 | int ret; | |
128 | static int pnum, tmpnum = 0; | |
129 | ||
130 | pnum = getpid(); | |
131 | /* | |
132 | * ima.247, John Levine, IECC, PO Box 349, Cambridge MA 02238; (617) 491-5450 | |
133 | * zap Wfile to prevent reuse of wrong C. file | |
134 | */ | |
135 | Wfile[0] = '\0'; | |
136 | top: | |
137 | for (i = 0; i < sizeof wrkvec / sizeof wrkvec[0]; i++) | |
138 | wrkvec[i] = 0; | |
139 | DEBUG(4, "*** TOP *** - role=%d, ", role); | |
140 | setline(RESET); | |
141 | if (role == MASTER) { | |
142 | /* get work */ | |
143 | if ((narg = gtwvec(Wfile, Spool, wkpre, wrkvec)) == 0) { | |
144 | WMESG(HUP, ""); | |
145 | RMESG(HUP, msg, 1); | |
146 | goto process; | |
147 | } | |
148 | wrktype = W_TYPE[0]; | |
149 | mailopt = index(W_OPTNS, 'm') != NULL; | |
150 | ntfyopt = index(W_OPTNS, 'n') != NULL; | |
151 | ||
152 | msg[0] = '\0'; | |
153 | for (i = 1; i < narg; i++) { | |
154 | strcat(msg, " "); | |
155 | strcat(msg, wrkvec[i]); | |
156 | } | |
157 | ||
158 | if (wrktype == XUUCP) { | |
159 | sprintf(rqstr, "X %s", msg); | |
160 | logent(rqstr, "REQUEST"); | |
161 | goto sendmsg; | |
162 | } | |
163 | ||
164 | ASSERT(narg > 4, "ARG COUNT<5", "", i); | |
165 | sprintf(User, "%.9s", W_USER); | |
166 | sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1, | |
167 | W_FILE2, W_USER); | |
168 | logent(rqstr, "REQUEST"); | |
169 | if (wrktype == SNDFILE ) { | |
170 | strcpy(filename, W_FILE1); | |
171 | i = expfile(filename); | |
172 | DEBUG(4, "expfile type - %d", i); | |
173 | if (i != 0 && chkpth(User, "", filename)) | |
174 | goto e_access; | |
175 | strcpy(Dfile, W_DFILE); | |
176 | fp = NULL; | |
177 | if (index(W_OPTNS, 'c') == NULL) { | |
178 | fp = fopen(subfile(Dfile), "r"); | |
179 | if (fp != NULL) | |
180 | i = 0; | |
181 | } | |
182 | if (fp == NULL && | |
183 | (fp = fopen(subfile(filename), "r")) == NULL) { | |
184 | /* can not read data file */ | |
185 | logent("CAN'T READ DATA", "FAILED"); | |
186 | unlinkdf(Dfile); | |
187 | lnotify(User, filename, "can't access"); | |
188 | goto top; | |
189 | } | |
190 | /* if file exists but is not generally readable... */ | |
191 | if (i != 0 && fstat(fileno(fp), &stbuf) == 0 | |
192 | && (stbuf.st_mode & ANYREAD) == 0) { | |
193 | e_access:; | |
194 | /* access denied */ | |
195 | fclose(fp); | |
196 | fp = NULL; | |
197 | logent("DENIED", "ACCESS"); | |
198 | unlinkdf(W_DFILE); | |
199 | lnotify(User, filename, "access denied"); | |
200 | goto top; | |
201 | } | |
202 | ||
203 | setline(SNDFILE); | |
204 | } | |
205 | ||
206 | if (wrktype == RCVFILE) { | |
207 | strcpy(filename, W_FILE2); | |
208 | expfile(filename); | |
209 | if (chkpth(User, "", filename) | |
210 | || chkperm(filename, index(W_OPTNS, 'd'))) { | |
211 | /* access denied */ | |
212 | logent("DENIED", "ACCESS"); | |
213 | lnotify(User, filename, "access denied"); | |
214 | goto top; | |
215 | } | |
216 | sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++); | |
217 | if ((fp = fopen(subfile(Dfile), "w")) == NULL) { | |
218 | /* can not create temp */ | |
219 | logent("CAN'T CREATE TM", "FAILED"); | |
220 | unlinkdf(Dfile); | |
221 | goto top; | |
222 | } | |
223 | setline(RCVFILE); | |
224 | } | |
225 | sendmsg: | |
226 | DEBUG(4, "wrktype - %c\n ", wrktype); | |
227 | WMESG(wrktype, msg); | |
228 | RMESG(wrktype, msg, 1); | |
229 | goto process; | |
230 | } | |
231 | ||
232 | /* role is slave */ | |
233 | RAMESG(msg, 1); | |
234 | goto process; | |
235 | ||
236 | process: | |
237 | /* rti!trt: ultouch is now done in gio.c (yes, kludge) | |
238 | * ultouch(); | |
239 | */ | |
240 | DEBUG(4, " PROCESS: msg - %s\n", msg); | |
241 | switch (msg[0]) { | |
242 | ||
243 | case RQSTCMPT: | |
244 | DEBUG(4, "%s\n", "RQSTCMPT:"); | |
245 | if (msg[1] == 'N') { | |
246 | i = atoi(&msg[2]); | |
247 | if (i<0 || i>EM_MAX) i=0; | |
248 | /* duke!rti: only note failed requests */ | |
249 | logent(msg, "REQUESTED"); | |
250 | } | |
251 | if (role == MASTER) { | |
252 | notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]); | |
253 | } | |
254 | goto top; | |
255 | ||
256 | case HUP: | |
257 | DEBUG(4, "%s\n", "HUP:"); | |
258 | if (msg[1] == 'Y') { | |
259 | WMESG(HUP, YES); | |
260 | (*Turnoff)(); | |
261 | Rdmsg = Imsg; | |
262 | Wrmsg = Omsg; | |
263 | return(0); | |
264 | } | |
265 | ||
266 | if (msg[1] == 'N') { | |
267 | ASSERT(role == MASTER, "WRONG ROLE", "", role); | |
268 | role = SLAVE; | |
269 | goto top; | |
270 | } | |
271 | ||
272 | /* get work */ | |
273 | if (!iswrk(Wfile, "chk", Spool, wkpre)) { | |
274 | WMESG(HUP, YES); | |
275 | RMESG(HUP, msg, 1); | |
276 | goto process; | |
277 | } | |
278 | ||
279 | WMESG(HUP, NO); | |
280 | role = MASTER; | |
281 | goto top; | |
282 | ||
283 | case XUUCP: | |
284 | if (role == MASTER) { | |
285 | goto top; | |
286 | } | |
287 | ||
288 | /* slave part */ | |
289 | i = getargs(msg, wrkvec); | |
290 | strcpy(filename, W_FILE1); | |
291 | if (index(filename, ';') != NULL | |
292 | || index(W_FILE2, ';') != NULL | |
293 | || i < 3) { | |
294 | WMESG(XUUCP, NO); | |
295 | goto top; | |
296 | } | |
297 | expfile(filename); | |
298 | if (chkpth("", Rmtname, filename)) { | |
299 | WMESG(XUUCP, NO); | |
300 | logent("XUUCP DENIED", filename); | |
301 | goto top; | |
302 | } | |
303 | sprintf(rqstr, "%s %s", filename, W_FILE2); | |
304 | xuucp(rqstr); | |
305 | WMESG(XUUCP, YES); | |
306 | goto top; | |
307 | ||
308 | case SNDFILE: | |
309 | /* MASTER section of SNDFILE */ | |
310 | ||
311 | DEBUG(4, "%s\n", "SNDFILE:"); | |
312 | if (msg[1] == 'N') { | |
313 | i = atoi(&msg[2]); | |
314 | if (i < 0 || i > EM_MAX) | |
315 | i = 0; | |
316 | logent(Em_msg[i], "REQUEST"); | |
317 | notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]); | |
318 | ASSERT(role == MASTER, "WRONG ROLE", "", role); | |
319 | fclose(fp); | |
320 | fp = NULL; | |
321 | if (msg[1] != '4') | |
322 | unlinkdf(W_DFILE); | |
323 | goto top; | |
324 | } | |
325 | ||
326 | if (msg[1] == 'Y') { | |
327 | /* send file */ | |
328 | ASSERT(role == MASTER, "WRONG ROLE", "", role); | |
329 | ret = fstat(fileno(fp), &stbuf); | |
330 | ASSERT(ret != -1, "STAT FAILED", filename, 0); | |
331 | i = 1 + (int)(stbuf.st_size / XFRRATE); | |
332 | ret = (*Wrdata)(fp, Ofn); | |
333 | fclose(fp); | |
334 | fp = NULL; | |
335 | if (ret != 0) { | |
336 | (*Turnoff)(); | |
337 | return(FAIL); | |
338 | } | |
339 | RMESG(RQSTCMPT, msg, i); | |
340 | /* put the unlink *after* the RMESG -- fortune!Dave-Yost */ | |
341 | unlinkdf(W_DFILE); | |
342 | goto process; | |
343 | } | |
344 | ||
345 | /* SLAVE section of SNDFILE */ | |
346 | ASSERT(role == SLAVE, "WRONG ROLE", "", role); | |
347 | ||
348 | /* request to receive file */ | |
349 | /* check permissions */ | |
350 | i = getargs(msg, wrkvec); | |
351 | ASSERT(i > 4, "ARG COUNT<5", "", i); | |
352 | sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1, | |
353 | W_FILE2, W_USER); | |
354 | logent(rqstr, "REQUESTED"); | |
355 | DEBUG(4, "msg - %s\n", msg); | |
356 | strcpy(filename, W_FILE2); | |
357 | /* Run uuxqt occasionally */ | |
358 | if (filename[0] == XQTPRE) { | |
359 | if (++nXfiles > 10) { | |
360 | nXfiles = 0; | |
361 | /* I sure hope the wait(II) does not hang. | |
362 | * One can never tell about UNIX variants. | |
363 | */ | |
364 | if (++nXQTs > 2) | |
365 | wait((int *)0); | |
366 | xuuxqt(); | |
367 | } | |
368 | } | |
369 | /* rti!trt: expand filename, i is set to 0 if this is | |
370 | * is a vanilla spool file, so no stat(II)s are needed */ | |
371 | i = expfile(filename); | |
372 | DEBUG(4, "expfile type - %d\n", i); | |
373 | if (i != 0) { | |
374 | if (chkpth("", Rmtname, filename) | |
375 | || chkperm(filename, index(W_OPTNS, 'd'))) { | |
376 | WMESG(SNDFILE, EM_RMTACC); | |
377 | logent("DENIED", "PERMISSION"); | |
378 | goto top; | |
379 | } | |
380 | if (isdir(filename)) { | |
381 | strcat(filename, "/"); | |
382 | strcat(filename, lastpart(W_FILE1)); | |
383 | } | |
384 | } | |
385 | sprintf(User, "%.9s", W_USER); | |
386 | ||
387 | DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname); | |
388 | sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++); | |
389 | if((fp = fopen(subfile(Dfile), "w")) == NULL) { | |
390 | WMESG(SNDFILE, EM_NOTMP); | |
391 | logent("CAN'T OPEN", "DENIED"); | |
392 | unlinkdf(Dfile); | |
393 | goto top; | |
394 | } | |
395 | ||
396 | WMESG(SNDFILE, YES); | |
397 | ret = (*Rddata)(Ifn, fp); | |
398 | /* ittvax!swatt: (try to) make sure IO successful */ | |
399 | fflush(fp); | |
400 | if (ferror(fp) || fclose(fp)) | |
401 | ret = FAIL; | |
402 | if (ret != 0) { | |
403 | (*Turnoff)(); | |
404 | return(FAIL); | |
405 | } | |
406 | /* copy to user directory */ | |
407 | ntfyopt = index(W_OPTNS, 'n') != NULL; | |
408 | status = xmv(Dfile, filename); | |
409 | WMESG(RQSTCMPT, status ? EM_RMTCP : YES); | |
410 | if (status == 0) { | |
411 | sscanf(W_MODE, "%o", &filemode); | |
412 | if (filemode <= 0) | |
413 | filemode = BASEMODE; | |
414 | chmod(subfile(filename), filemode | BASEMODE); | |
415 | arrived(ntfyopt, filename, W_NUSER, Rmtname, User); | |
416 | } | |
417 | else { | |
418 | logent("FAILED", "COPY"); | |
419 | status = putinpub(filename, Dfile, W_USER); | |
420 | DEBUG(4, "->PUBDIR %d\n", status); | |
421 | if (status == 0) | |
422 | arrived(ntfyopt, filename, W_NUSER, | |
423 | Rmtname, User); | |
424 | } | |
425 | ||
426 | goto top; | |
427 | ||
428 | case RCVFILE: | |
429 | /* MASTER section of RCVFILE */ | |
430 | ||
431 | DEBUG(4, "%s\n", "RCVFILE:"); | |
432 | if (msg[1] == 'N') { | |
433 | i = atoi(&msg[2]); | |
434 | if (i < 0 || i > EM_MAX) | |
435 | i = 0; | |
436 | logent(Em_msg[i], "REQUEST"); | |
437 | notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]); | |
438 | ASSERT(role == MASTER, "WRONG ROLE", "", role); | |
439 | fclose(fp); | |
440 | unlinkdf(Dfile); | |
441 | goto top; | |
442 | } | |
443 | ||
444 | if (msg[1] == 'Y') { | |
445 | /* receive file */ | |
446 | ASSERT(role == MASTER, "WRONG ROLE", "", role); | |
447 | ret = (*Rddata)(Ifn, fp); | |
448 | /* ittvax!swatt: (try to) make sure IO successful */ | |
449 | fflush(fp); | |
450 | if (ferror(fp) || fclose(fp)) | |
451 | ret = FAIL; | |
452 | if (ret != 0) { | |
453 | (*Turnoff)(); | |
454 | return(FAIL); | |
455 | } | |
456 | /* copy to user directory */ | |
457 | if (isdir(filename)) { | |
458 | strcat(filename, "/"); | |
459 | strcat(filename, lastpart(W_FILE1)); | |
460 | } | |
461 | status = xmv(Dfile, filename); | |
462 | WMESG(RQSTCMPT, status ? EM_RMTCP : YES); | |
463 | notify(mailopt, W_USER, filename, Rmtname, | |
464 | status ? EM_LOCCP : YES); | |
465 | if (status == 0) { | |
466 | sscanf(&msg[2], "%o", &filemode); | |
467 | if (filemode <= 0) | |
468 | filemode = BASEMODE; | |
469 | chmod(subfile(filename), filemode | BASEMODE); | |
470 | } | |
471 | else { | |
472 | logent("FAILED", "COPY"); | |
473 | putinpub(filename, Dfile, W_USER); | |
474 | } | |
475 | goto top; | |
476 | } | |
477 | ||
478 | /* SLAVE section of RCVFILE */ | |
479 | ASSERT(role == SLAVE, "WRONG ROLE", "", role); | |
480 | ||
481 | /* request to send file */ | |
482 | strcpy(rqstr, msg); | |
483 | logent(rqstr, "REQUESTED"); | |
484 | ||
485 | /* check permissions */ | |
486 | i = getargs(msg, wrkvec); | |
487 | ASSERT(i > 3, "ARG COUNT<4", "", i); | |
488 | DEBUG(4, "msg - %s\n", msg); | |
489 | DEBUG(4, "W_FILE1 - %s\n", W_FILE1); | |
490 | strcpy(filename, W_FILE1); | |
491 | expfile(filename); | |
492 | if (isdir(filename)) { | |
493 | strcat(filename, "/"); | |
494 | strcat(filename, lastpart(W_FILE2)); | |
495 | } | |
496 | sprintf(User, "%.9s", W_USER); | |
497 | if (chkpth("", Rmtname, filename) || anyread(filename)) { | |
498 | WMESG(RCVFILE, EM_RMTACC); | |
499 | logent("DENIED", "PERMISSION"); | |
500 | goto top; | |
501 | } | |
502 | DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname); | |
503 | ||
504 | if ((fp = fopen(subfile(filename), "r")) == NULL) { | |
505 | WMESG(RCVFILE, EM_RMTACC); | |
506 | logent("CAN'T OPEN", "DENIED"); | |
507 | goto top; | |
508 | } | |
509 | ||
510 | /* ok to send file */ | |
511 | ret = fstat(fileno(fp), &stbuf); | |
512 | ASSERT(ret != -1, "STAT FAILED", filename, 0); | |
513 | i = 1 + (int)(stbuf.st_size / XFRRATE); | |
514 | sprintf(msg, "%s %o", YES, stbuf.st_mode & 0777); | |
515 | WMESG(RCVFILE, msg); | |
516 | ret = (*Wrdata)(fp, Ofn); | |
517 | fclose(fp); | |
518 | if (ret != 0) { | |
519 | (*Turnoff)(); | |
520 | return(FAIL); | |
521 | } | |
522 | RMESG(RQSTCMPT, msg, i); | |
523 | goto process; | |
524 | } | |
525 | (*Turnoff)(); | |
526 | return(FAIL); | |
527 | } | |
528 | ||
529 | ||
530 | /*** | |
531 | * rmesg(c, msg, n) read message 'c' | |
532 | * try 'n' times | |
533 | * char *msg, c; | |
534 | * | |
535 | * return code: 0 | FAIL | |
536 | */ | |
537 | ||
538 | rmesg(c, msg, n) | |
539 | register char *msg, c; | |
540 | register int n; | |
541 | { | |
542 | char str[50]; | |
543 | ||
544 | DEBUG(4, "rmesg - '%c' ", c); | |
545 | if (n != 1) { | |
546 | sprintf(str, "%d", n); | |
547 | logent(str, "PATIENCE"); | |
548 | } | |
549 | while ((*Rdmsg)(msg, Ifn) != 0) { | |
550 | if (--n > 0) | |
551 | continue; | |
552 | DEBUG(4, "got %s\n", "FAIL"); | |
553 | sprintf(str, "expected '%c' got FAIL", c); | |
554 | logent(str, "BAD READ"); | |
555 | return(FAIL); | |
556 | } | |
557 | if (c != '\0' && msg[0] != c) { | |
558 | DEBUG(4, "got %s\n", msg); | |
559 | sprintf(str, "expected '%c' got %.25s", c, msg); | |
560 | logent(str, "BAD READ"); | |
561 | return(FAIL); | |
562 | } | |
563 | DEBUG(4, "got %.25s\n", msg); | |
564 | return(0); | |
565 | } | |
566 | ||
567 | ||
568 | /*** | |
569 | * wmesg(m, s) write a message (type m) | |
570 | * char *s, m; | |
571 | * | |
572 | * return codes: 0 - ok | FAIL - ng | |
573 | */ | |
574 | ||
575 | wmesg(m, s) | |
576 | register char *s, m; | |
577 | { | |
578 | DEBUG(4, "wmesg '%c'", m); | |
579 | DEBUG(4, "%.25s\n", s); | |
580 | return((*Wrmsg)(m, s, Ofn)); | |
581 | } | |
582 | ||
583 | ||
584 | /*** | |
585 | * notify mail results of command | |
586 | * | |
587 | * return codes: none | |
588 | */ | |
589 | ||
590 | notify(mailopt, user, file, sys, msgcode) | |
591 | char *user, *file, *sys, *msgcode; | |
592 | { | |
593 | char str[200]; | |
594 | int i; | |
595 | char *msg; | |
596 | ||
597 | if (!mailopt && *msgcode == 'Y') | |
598 | return; | |
599 | if (*msgcode == 'Y') | |
600 | msg = "copy succeeded"; | |
601 | else { | |
602 | i = atoi(msgcode + 1); | |
603 | if (i < 1 || i > EM_MAX) | |
604 | i = 0; | |
605 | msg = Em_msg[i]; | |
606 | } | |
607 | sprintf(str, "file %s, system %s\n%s\n", | |
608 | file, sys, msg); | |
609 | mailst(user, str, ""); | |
610 | return; | |
611 | } | |
612 | ||
613 | /*** | |
614 | * lnotify(user, file, mesg) - local notify | |
615 | * | |
616 | * return code - none | |
617 | */ | |
618 | ||
619 | lnotify(user, file, mesg) | |
620 | char *user, *file, *mesg; | |
621 | { | |
622 | char mbuf[200]; | |
623 | sprintf(mbuf, "file %s on %s\n%s\n", file, Myname, mesg); | |
624 | mailst(user, mbuf, ""); | |
625 | return; | |
626 | } | |
627 | ||
628 | ||
629 | /*** | |
630 | * startup(role) | |
631 | * int role; | |
632 | * | |
633 | * startup - this routine will converse with the remote | |
634 | * machine, agree upon a protocol (if possible) and start the | |
635 | * protocol. | |
636 | * | |
637 | * return codes: | |
638 | * SUCCESS - successful protocol selection | |
639 | * FAIL - can't find common or open failed | |
640 | */ | |
641 | ||
642 | startup(role) | |
643 | int role; | |
644 | { | |
645 | extern (*Rdmsg)(), (*Wrmsg)(); | |
646 | extern char *blptcl(), fptcl(); | |
647 | char msg[BUFSIZ], str[BUFSIZ]; | |
648 | ||
649 | Rdmsg = Imsg; | |
650 | Wrmsg = Omsg; | |
651 | if (role == MASTER) { | |
652 | RMESG(SLTPTCL, msg, 1); | |
653 | if ((str[0] = fptcl(&msg[1])) == NULL) { | |
654 | /* no protocol match */ | |
655 | WMESG(USEPTCL, NO); | |
656 | return(FAIL); | |
657 | } | |
658 | str[1] = '\0'; | |
659 | WMESG(USEPTCL, str); | |
660 | if (stptcl(str) != 0) | |
661 | return(FAIL); | |
662 | DEBUG(4, "protocol %s\n", str); | |
663 | return(SUCCESS); | |
664 | } | |
665 | else { | |
666 | WMESG(SLTPTCL, blptcl(str)); | |
667 | RMESG(USEPTCL, msg, 1); | |
668 | if (msg[1] == 'N') { | |
669 | return(FAIL); | |
670 | } | |
671 | ||
672 | if (stptcl(&msg[1]) != 0) | |
673 | return(FAIL); | |
674 | DEBUG(4, "Protocol %s\n", msg); | |
675 | return(SUCCESS); | |
676 | } | |
677 | } | |
678 | ||
679 | ||
680 | /******* | |
681 | * char | |
682 | * fptcl(str) | |
683 | * char *str; | |
684 | * | |
685 | * fptcl - this routine will choose a protocol from | |
686 | * the input string (str) and return the found letter. | |
687 | * | |
688 | * return codes: | |
689 | * '\0' - no acceptable protocol | |
690 | * any character - the chosen protocol | |
691 | */ | |
692 | ||
693 | char | |
694 | fptcl(str) | |
695 | register char *str; | |
696 | { | |
697 | register struct Proto *p; | |
698 | ||
699 | for (p = Ptbl; p->P_id != '\0'; p++) { | |
700 | if (index(str, p->P_id) != NULL) { | |
701 | return(p->P_id); | |
702 | } | |
703 | } | |
704 | ||
705 | return('\0'); | |
706 | } | |
707 | ||
708 | ||
709 | /*** | |
710 | * char * | |
711 | * blptcl(str) | |
712 | * char *str; | |
713 | * | |
714 | * blptcl - this will build a string of the | |
715 | * letters of the available protocols and return | |
716 | * the string (str). | |
717 | * | |
718 | * return: | |
719 | * a pointer to string (str) | |
720 | */ | |
721 | ||
722 | char * | |
723 | blptcl(str) | |
724 | register char *str; | |
725 | { | |
726 | register struct Proto *p; | |
727 | register char *s; | |
728 | ||
729 | for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++); | |
730 | return(str); | |
731 | } | |
732 | ||
733 | /*** | |
734 | * stptcl(c) | |
735 | * char *c; | |
736 | * | |
737 | * stptcl - this routine will set up the six routines | |
738 | * (Rdmsg, Wrmsg, Rddata, Wrdata, Turnon, Turnoff) for the | |
739 | * desired protocol. | |
740 | * | |
741 | * return codes: | |
742 | * SUCCESS - ok | |
743 | * FAIL - no find or failed to open | |
744 | * | |
745 | */ | |
746 | ||
747 | stptcl(c) | |
748 | register char *c; | |
749 | { | |
750 | register struct Proto *p; | |
751 | ||
752 | for (p = Ptbl; p->P_id != '\0'; p++) { | |
753 | if (*c == p->P_id) { | |
754 | /* found protocol - set routines */ | |
755 | Rdmsg = p->P_rdmsg; | |
756 | Wrmsg = p->P_wrmsg; | |
757 | Rddata = p->P_rddata; | |
758 | Wrdata = p->P_wrdata; | |
759 | Turnon = p->P_turnon; | |
760 | Turnoff = p->P_turnoff; | |
761 | if ((*Turnon)() != 0) | |
762 | return(FAIL); | |
763 | DEBUG(4, "Proto started %c\n", *c); | |
764 | return(SUCCESS); | |
765 | } | |
766 | } | |
767 | DEBUG(4, "Proto start-fail %c\n", *c); | |
768 | return(FAIL); | |
769 | } | |
770 | ||
771 | /*** | |
772 | * putinpub put file in public place | |
773 | * if successful, filename is modified | |
774 | * | |
775 | * return code 0 | FAIL | |
776 | */ | |
777 | ||
778 | putinpub(file, tmp, user) | |
779 | register char *file, *user, *tmp; | |
780 | { | |
781 | char fullname[MAXFULLNAME]; | |
782 | char *lastpart(); | |
783 | int status; | |
784 | ||
785 | sprintf(fullname, "%s/%s/", PUBDIR, user); | |
786 | if (mkdirs(fullname) != 0) { | |
787 | /* can not make directories */ | |
788 | return(FAIL); | |
789 | } | |
790 | strcat(fullname, lastpart(file)); | |
791 | status = xmv(tmp, fullname); | |
792 | if (status == 0) { | |
793 | strcpy(file, fullname); | |
794 | chmod(subfile(fullname), BASEMODE); | |
795 | } | |
796 | return(status); | |
797 | } | |
798 | ||
799 | /*** | |
800 | * unlinkdf(file) - unlink D. file | |
801 | * | |
802 | * return code - none | |
803 | */ | |
804 | ||
805 | unlinkdf(file) | |
806 | register char *file; | |
807 | { | |
808 | if (strlen(file) > 6) | |
809 | unlink(subfile(file)); | |
810 | return; | |
811 | } | |
812 | ||
813 | /*** | |
814 | * arrived - notify receiver of arrived file | |
815 | * | |
816 | * return code - none | |
817 | */ | |
818 | ||
819 | arrived(opt, file, nuser, rmtsys, rmtuser) | |
820 | char *file, *nuser, *rmtsys, *rmtuser; | |
821 | { | |
822 | char mbuf[200]; | |
823 | ||
824 | if (!opt) | |
825 | return; | |
826 | sprintf(mbuf, "%s from %s!%s arrived\n", file, rmtsys, rmtuser); | |
827 | mailst(nuser, mbuf, ""); | |
828 | return; | |
829 | } |