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