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