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