|
|
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.