|
|
1.1 ! root 1: /* /sccs/src/cmd/uucp/s.cntrl.c ! 2: cntrl.c 1.9 8/30/84 17:37:09 ! 3: */ ! 4: #include "uucp.h" ! 5: VERSION(@(#)cntrl.c 1.9); ! 6: ! 7: struct Proto { ! 8: char P_id; ! 9: int (*P_turnon)(); ! 10: int (*P_rdmsg)(); ! 11: int (*P_wrmsg)(); ! 12: int (*P_rddata)(); ! 13: int (*P_wrdata)(); ! 14: int (*P_turnoff)(); ! 15: }; ! 16: ! 17: #ifdef PROTO_G ! 18: extern int gturnon(), gturnoff(); ! 19: extern int errno; ! 20: extern int grdmsg(), grddata(); ! 21: extern int gwrmsg(), gwrdata(); ! 22: #endif ! 23: #ifdef PROTO_D ! 24: extern int dturnon(), dturnoff(); ! 25: extern int drdmsg(), drddata(); ! 26: extern int dwrmsg(), dwrdata(); ! 27: #endif ! 28: #ifdef PROTO_X ! 29: extern int xturnon(), xturnoff(); ! 30: extern int xrdmsg(), xrddata(); ! 31: extern int xwrmsg(), xwrdata(); ! 32: #endif ! 33: #ifdef PROTO_E ! 34: extern int eturnon(), eturnoff(); ! 35: extern int erdmsg(), erddata(); ! 36: extern int ewrmsg(), ewrdata(); ! 37: #endif ! 38: ! 39: extern int imsg(); ! 40: extern int omsg(); ! 41: ! 42: struct Proto Ptbl[]={ ! 43: #ifdef PROTO_G ! 44: 'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff, ! 45: #endif ! 46: #ifdef PROTO_E ! 47: 'e', eturnon, erdmsg, ewrmsg, erddata, ewrdata, eturnoff, ! 48: #endif ! 49: #ifdef PROTO_D ! 50: 'd', dturnon, drdmsg, dwrmsg, drddata, dwrdata, dturnoff, ! 51: #endif ! 52: #ifdef PROTO_X ! 53: 'x', xturnon, xrdmsg, xwrmsg, xrddata, xwrdata, xturnoff, ! 54: #endif ! 55: '\0' ! 56: }; ! 57: ! 58: int (*Rdmsg)()=imsg, (*Rddata)(); ! 59: int (*Wrmsg)()=omsg, (*Wrdata)(); ! 60: int (*Turnon)(), (*Turnoff)(); ! 61: ! 62: ! 63: #define YES "Y" ! 64: #define NO "N" ! 65: ! 66: /* ! 67: * failure messages ! 68: */ ! 69: #define EM_MAX 7 ! 70: #define EM_LOCACC "N1" /* local access to file denied */ ! 71: #define EM_RMTACC "N2" /* remote access to file/path denied */ ! 72: #define EM_BADUUCP "N3" /* a bad uucp command was generated */ ! 73: #define EM_NOTMP "N4" /* remote error - can't create temp */ ! 74: #define EM_RMTCP "N5" /* can't copy to remote directory - file in public */ ! 75: #define EM_LOCCP "N6" /* can't copy on local system */ ! 76: ! 77: char *Em_msg[] = { ! 78: "COPY FAILED (reason not given by remote)", ! 79: "local access to file denied", ! 80: "remote access to path/file denied", ! 81: "system error - bad uucp command generated", ! 82: "remote system can't create temp file", ! 83: "can't copy to file/directory - file left in PUBDIR/user/file", ! 84: "can't copy to file/directory - file left in PUBDIR/user/file", ! 85: "forwarding error" ! 86: }; ! 87: ! 88: ! 89: #define XUUCP 'X' /* execute uucp (string) */ ! 90: #define SLTPTCL 'P' /* select protocol (string) */ ! 91: #define USEPTCL 'U' /* use protocol (character) */ ! 92: #define RCVFILE 'R' /* receive file (string) */ ! 93: #define SNDFILE 'S' /* send file (string) */ ! 94: #define RQSTCMPT 'C' /* request complete (string - yes | no) */ ! 95: #define HUP 'H' /* ready to hangup (string - yes | no) */ ! 96: #define RESET 'X' /* reset line modes */ ! 97: ! 98: #define W_MAX 10 /* maximum number of C. files per line */ ! 99: #define W_TYPE wrkvec[0] ! 100: #define W_FILE1 wrkvec[1] ! 101: #define W_FILE2 wrkvec[2] ! 102: #define W_USER wrkvec[3] ! 103: #define W_OPTNS wrkvec[4] ! 104: #define W_DFILE wrkvec[5] ! 105: #define W_MODE wrkvec[6] ! 106: #define W_NUSER wrkvec[7] ! 107: #define W_SFILE wrkvec[8] ! 108: #define W_RFILE wrkvec[5] ! 109: #define W_XFILE wrkvec[5] ! 110: char *mf; ! 111: ! 112: #define RMESG(m, s) if (rmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);} ! 113: #define RAMESG(s) if (rmesg('\0', s) != 0) {(*Turnoff)(); return(FAIL);} ! 114: #define WMESG(m, s) if(wmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);} ! 115: ! 116: char Wfile[MAXFULLNAME] = {'\0'}; ! 117: char Dfile[MAXFULLNAME]; ! 118: ! 119: /* ! 120: * execute the conversation between the two machines ! 121: * after both programs are running. ! 122: * returns: ! 123: * SUCCESS -> ok ! 124: * FAIL -> failed ! 125: */ ! 126: char *wrkvec[W_MAX+1]; ! 127: int statfopt; ! 128: cntrl(role) ! 129: register int role; ! 130: { ! 131: FILE * fp; ! 132: struct stat stbuf; ! 133: extern (*Rdmsg)(), (*Wrmsg)(); ! 134: int filemode; ! 135: int status = 1; ! 136: int i, narg; ! 137: int mailopt, ntfyopt; ! 138: int ret; ! 139: char rqstr[BUFSIZ]; /* contains the current request message */ ! 140: char msg[BUFSIZ]; ! 141: char filename[MAXFULLNAME], wrktype; ! 142: static int pnum; ! 143: ! 144: pnum = getpid(); ! 145: Wfile[0] = '\0'; ! 146: top: ! 147: statfopt = 0; ! 148: *Jobid = '\0'; ! 149: DEBUG(4, "*** TOP *** - role=%d, ", role); ! 150: setline(RESET); ! 151: if (role == MASTER) { ! 152: ! 153: /* ! 154: * get work ! 155: */ ! 156: if ((narg = gtwvec(Wfile, wrkvec, W_MAX)) == 0) { ! 157: WMESG(HUP, ""); ! 158: RMESG(HUP, msg); ! 159: goto process; ! 160: } ! 161: DEBUG(7, "Wfile - %s,", Wfile); ! 162: strncpy(Jobid, BASENAME(Wfile, '/')+2, NAMESIZE); ! 163: Jobid[NAMESIZE-1] = '\0'; ! 164: DEBUG(7, "Jobid = %s\n", Jobid); ! 165: wrktype = W_TYPE[0]; ! 166: mailopt = strchr(W_OPTNS, 'm') != NULL; ! 167: #if NOTDEF /* unsafe */ ! 168: statfopt = strchr(W_OPTNS, 'o') != NULL; ! 169: #endif ! 170: ntfyopt = strchr(W_OPTNS, 'n') != NULL; ! 171: ! 172: strcpy(User, W_USER); ! 173: W_USER = Uucp; /* so what we send is short */ ! 174: msg[0] = '\0'; ! 175: for (i = 1; i < narg; i++) { ! 176: (void) strcat(msg, " "); ! 177: (void) strcat(msg, wrkvec[i]); ! 178: } ! 179: ! 180: /* ! 181: * We used to check for corrupt workfiles here (narg < 5), ! 182: * but we were doing it wrong, and besides, anlwrk.c is the ! 183: * appropriate place to do it. ! 184: */ ! 185: ! 186: if (wrktype == SNDFILE ) { ! 187: (void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Myname, ! 188: W_FILE1, Rmtname, W_FILE2, User); ! 189: logent(rqstr, "REQUEST"); ! 190: CDEBUG(1, "Request: %s\n", rqstr); ! 191: mf = W_SFILE; ! 192: (void) strcpy(filename, W_FILE1); ! 193: expfile(filename); ! 194: if ( !READSOME(filename) && !READSOME(W_DFILE)) { ! 195: ! 196: /* ! 197: * access denied ! 198: */ ! 199: logent("DENIED", "ACCESS"); ! 200: unlinkdf(W_DFILE); ! 201: lnotify(User, rqstr, "access denied"); ! 202: CDEBUG(1, "Failed: Access Denied\n", 0); ! 203: goto top; ! 204: } ! 205: ! 206: (void) strcpy(Dfile, W_DFILE); ! 207: fp = NULL; ! 208: fp = fopen(Dfile, "r"); ! 209: ASSERT(strlen(Dfile)>0, "Dfile==0", "", role); ! 210: if (fp == NULL && ! 211: (fp = fopen(filename, "r")) == NULL) { ! 212: ! 213: /* can not read data file */ ! 214: unlinkdf(Dfile); ! 215: lnotify(User, rqstr, "can't access"); ! 216: ! 217: (void) sprintf(msg, "CAN'T READ %s %d", ! 218: filename, errno); ! 219: logent(msg, "FAILED"); ! 220: CDEBUG(1, "Failed: Can't Read %s\n", filename); ! 221: goto top; ! 222: } ! 223: Seqn++; ! 224: setline(SNDFILE); ! 225: } ! 226: ! 227: if (wrktype == RCVFILE) { ! 228: (void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Rmtname, ! 229: W_FILE1, Myname, W_FILE2, User); ! 230: logent(rqstr, "REQUEST"); ! 231: CDEBUG(1, "Request: %s\n", rqstr); ! 232: mf = W_RFILE; ! 233: (void) strcpy(filename, W_FILE2); ! 234: expfile(filename); ! 235: if (chkperm(W_FILE1, filename, strchr(W_OPTNS, 'd'))) { ! 236: ! 237: /* access denied */ ! 238: logent("DENIED", "ACCESS"); ! 239: lnotify(User, rqstr, "access denied"); ! 240: CDEBUG(1, "Failed: Access Denied--File: $s\n", ! 241: filename); ! 242: goto top; ! 243: } ! 244: TMname(Dfile, pnum); /* get TM file name */ ! 245: ! 246: if ( ((fp = fopen(Dfile, "w")) == NULL) ! 247: || nospace(Dfile)) { ! 248: ! 249: /* can not create temp */ ! 250: logent("CAN'T CREATE TM", "FAILED"); ! 251: CDEBUG(1, "Failed: No Space!\n", 0); ! 252: unlinkdf(Dfile); ! 253: assert(Ct_CREATE, Dfile, nospace(Dfile), ! 254: sccsid, __FILE__, __LINE__); ! 255: cleanup(FAIL); ! 256: } ! 257: Seqn++; ! 258: chmod(Dfile, DFILEMODE); /* no peeking! */ ! 259: setline(RCVFILE); ! 260: } ! 261: sendmsg: ! 262: DEBUG(4, "wrktype - %c\n ", wrktype); ! 263: WMESG(wrktype, msg); ! 264: RMESG(wrktype, msg); ! 265: goto process; ! 266: } ! 267: ! 268: /* ! 269: * role is slave ! 270: */ ! 271: RAMESG(msg); ! 272: ! 273: process: ! 274: ! 275: /* ! 276: * touch all lock files ! 277: */ ! 278: ultouch(); ! 279: DEBUG(4, " PROCESS: msg - %s\n", msg); ! 280: switch (msg[0]) { ! 281: ! 282: case RQSTCMPT: ! 283: DEBUG(4, "%s\n", "RQSTCMPT:"); ! 284: if (msg[1] == 'N') { ! 285: i = atoi(&msg[2]); ! 286: if (i < 0 || i > EM_MAX) ! 287: i = 0; ! 288: logent(Em_msg[i], "REQUESTED"); ! 289: } ! 290: if (role == MASTER) ! 291: notify(mailopt, User, rqstr, Rmtname, &msg[1]); ! 292: goto top; ! 293: ! 294: case HUP: ! 295: DEBUG(4, "%s\n", "HUP:"); ! 296: if (msg[1] == 'Y') { ! 297: WMESG(HUP, YES); ! 298: (*Turnoff)(); ! 299: Rdmsg = imsg; ! 300: Wrmsg = omsg; ! 301: return(0); ! 302: } ! 303: ! 304: if (msg[1] == 'N') { ! 305: ASSERT(role == MASTER, Wr_ROLE, "", role); ! 306: role = SLAVE; ! 307: goto top; ! 308: } ! 309: ! 310: /* ! 311: * get work ! 312: */ ! 313: if ( (switchRole() == FALSE) || !iswrk(Wfile) ) { ! 314: DEBUG(5, "SLAVE-switchRole (%s)\n", ! 315: switchRole() ? "TRUE" : "FALSE"); ! 316: WMESG(HUP, YES); ! 317: RMESG(HUP, msg); ! 318: goto process; ! 319: } ! 320: ! 321: /* Note that Wfile is the first C. to process at top ! 322: * set above by iswrk() call ! 323: */ ! 324: WMESG(HUP, NO); ! 325: role = MASTER; ! 326: goto top; ! 327: ! 328: case XUUCP: ! 329: /* ! 330: * slave part ! 331: * No longer accepted ! 332: */ ! 333: ! 334: WMESG(XUUCP, NO); ! 335: goto top; ! 336: ! 337: case SNDFILE: ! 338: ! 339: /* ! 340: * MASTER section of SNDFILE ! 341: */ ! 342: DEBUG(4, "%s\n", "SNDFILE:"); ! 343: if (msg[1] == 'N') ! 344: { ! 345: i = atoi(&msg[2]); ! 346: if (i < 0 || i > EM_MAX) ! 347: i = 0; ! 348: logent(Em_msg[i], "REQUEST"); ! 349: notify(mailopt, User, rqstr, Rmtname, &msg[1]); ! 350: ASSERT(role == MASTER, Wr_ROLE, "", role); ! 351: (void) fclose(fp); ! 352: ASSERT(i != 4, Em_msg[4], Rmtname, i); /* EM_NOTMP */ ! 353: unlinkdf(W_DFILE); ! 354: goto top; ! 355: } ! 356: ! 357: if (msg[1] == 'Y') { ! 358: ! 359: /* ! 360: * send file ! 361: */ ! 362: ASSERT(role == MASTER, Wr_ROLE, "", role); ! 363: if (fstat(fileno(fp), &stbuf)) /* never fail but .. */ ! 364: stbuf.st_size = 0; /* for time loop calculation */ ! 365: ret = (*Wrdata)(fp, Ofn); ! 366: (void) fclose(fp); ! 367: if (ret != 0) { ! 368: (*Turnoff)(); ! 369: return(FAIL); ! 370: } ! 371: ! 372: /* loop depending on the size of the file */ ! 373: /* give an extra try for each megabyte */ ! 374: for (i = stbuf.st_size >> 10; i >= 0; --i) { ! 375: if ((ret = rmesg(RQSTCMPT, msg)) == 0) ! 376: break; /* got message */ ! 377: } ! 378: if (ret != 0) { ! 379: (*Turnoff)(); ! 380: return(FAIL); ! 381: } ! 382: unlinkdf(W_DFILE); ! 383: goto process; ! 384: } ! 385: ! 386: /* ! 387: * SLAVE section of SNDFILE ! 388: */ ! 389: ASSERT(role == SLAVE, Wr_ROLE, "", role); ! 390: ! 391: /* ! 392: * request to receive file ! 393: * check permissions ! 394: */ ! 395: i = getargs(msg, wrkvec, W_MAX); ! 396: ! 397: /* Check for bad request */ ! 398: if (i < 7) { ! 399: WMESG(SNDFILE, EM_BADUUCP); ! 400: logent("DENIED", "TOO FEW ARGS IN SLAVE SNDFILE"); ! 401: goto top; ! 402: } ! 403: ! 404: mf = W_SFILE; ! 405: (void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Rmtname, ! 406: W_FILE1, Myname, W_FILE2, W_USER); ! 407: logent(rqstr, "REMOTE REQUESTED"); ! 408: DEBUG(4, "msg - %s\n", msg); ! 409: CDEBUG(1, "Remote Requested: %s\n", rqstr); ! 410: (void) strcpy(filename, W_FILE2); ! 411: expfile(filename); ! 412: DEBUG(4, "SLAVE - filename: %s\n", filename); ! 413: if (chkpth(filename, CK_WRITE) ! 414: || chkperm(W_FILE1, filename, strchr(W_OPTNS, 'd'))) { ! 415: WMESG(SNDFILE, EM_RMTACC); ! 416: logent("DENIED", "PERMISSION"); ! 417: CDEBUG(1, "Failed: Access Denied\n", 0); ! 418: goto top; ! 419: } ! 420: strcpy(User, W_USER); ! 421: ! 422: DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname); ! 423: TMname(Dfile, pnum); /* get TM file name */ ! 424: ! 425: if ( ((fp = fopen(Dfile, "w")) == NULL) || nospace(Dfile) ) { ! 426: WMESG(SNDFILE, EM_NOTMP); ! 427: logent("CAN'T OPEN", "DENIED"); ! 428: CDEBUG(1, "Failed: Can't Create Temp File\n", 0); ! 429: unlinkdf(Dfile); ! 430: goto top; ! 431: } ! 432: Seqn++; ! 433: chmod(Dfile, DFILEMODE); /* no peeking! */ ! 434: WMESG(SNDFILE, YES); ! 435: ret = (*Rddata)(Ifn, fp); ! 436: (void) fclose(fp); ! 437: if (ret != 0) { ! 438: (*Turnoff)(); ! 439: logent("INPUT FAILURE", "IN SEND/SLAVE MODE"); ! 440: return(FAIL); ! 441: } ! 442: /* copy to user directory */ ! 443: ntfyopt = strchr(W_OPTNS, 'n') != NULL; ! 444: status = xmv(Dfile, filename); ! 445: WMESG(RQSTCMPT, status ? EM_RMTCP : YES); ! 446: if (status == 0) { ! 447: sscanf(W_MODE, "%o", &filemode); ! 448: if (filemode <= 0) ! 449: filemode = 0666; ! 450: if (PREFIX(RemSpool, filename)) ! 451: chmod(filename, 0600); ! 452: else ! 453: chmod(filename, (filemode|0666) & 0777); ! 454: arrived(ntfyopt, filename, W_NUSER, Rmtname, User); ! 455: } else { ! 456: logent("FAILED", "COPY"); ! 457: status = putinpub(filename, Dfile, ! 458: BASENAME(W_USER, '!')); ! 459: DEBUG(4, "->PUBDIR %d\n", status); ! 460: if (status == 0) ! 461: arrived(ntfyopt, filename, W_NUSER, ! 462: Rmtname, User); ! 463: } ! 464: goto top; ! 465: ! 466: case RCVFILE: ! 467: ! 468: /* ! 469: * MASTER section of RCVFULE ! 470: */ ! 471: DEBUG(4, "%s\n", "RCVFILE:"); ! 472: if (msg[1] == 'N') { ! 473: i = atoi(&msg[2]); ! 474: if (i < 0 || i > EM_MAX) ! 475: i = 0; ! 476: logent(Em_msg[i], "REQUEST"); ! 477: notify(mailopt, User, rqstr, Rmtname, &msg[1]); ! 478: ASSERT(role == MASTER, Wr_ROLE, "", role); ! 479: (void) fclose(fp); ! 480: unlinkdf(Dfile); ! 481: goto top; ! 482: } ! 483: ! 484: if (msg[1] == 'Y') { ! 485: ! 486: /* ! 487: * receive file ! 488: */ ! 489: ASSERT(role == MASTER, Wr_ROLE, "", role); ! 490: ret = (*Rddata)(Ifn, fp); ! 491: (void) fclose(fp); ! 492: if (ret != 0) { ! 493: (*Turnoff)(); ! 494: return(FAIL); ! 495: } ! 496: ! 497: status = xmv(Dfile, filename); ! 498: WMESG(RQSTCMPT, status ? EM_RMTCP : YES); ! 499: notify(mailopt, User, rqstr, Rmtname, ! 500: status ? EM_LOCCP : YES); ! 501: if (status == 0) { ! 502: sscanf(&msg[2], "%o", &filemode); ! 503: if (filemode <= 0) ! 504: filemode = 0666; ! 505: if (PREFIX(RemSpool, filename)) ! 506: chmod(filename, 0600); ! 507: else ! 508: chmod(filename, (filemode|0666) & 0777); ! 509: } else { ! 510: logent("FAILED", "COPY"); ! 511: putinpub(filename, Dfile, W_USER); ! 512: } ! 513: goto top; ! 514: } ! 515: ! 516: /* ! 517: * SLAVE section of RCVFILE ! 518: * (request to send file) ! 519: */ ! 520: ASSERT(role == SLAVE, Wr_ROLE, "", role); ! 521: ! 522: /* check permissions */ ! 523: i = getargs(msg, wrkvec, W_MAX); ! 524: ! 525: /* Check for bad request */ ! 526: if (i < 5) { ! 527: WMESG(RCVFILE, EM_BADUUCP); ! 528: logent("DENIED", "TOO FEW ARGS IN SLAVE RCVFILE"); ! 529: goto top; ! 530: } ! 531: ! 532: (void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Myname, ! 533: W_FILE1, Rmtname, W_FILE2, W_USER); ! 534: logent(rqstr, "REMOTE REQUESTED"); ! 535: CDEBUG(1, "Remote Requested: %s\n", rqstr); ! 536: mf = W_RFILE; ! 537: DEBUG(4, "msg - %s\n", msg); ! 538: DEBUG(4, "W_FILE1 - %s\n", W_FILE1); ! 539: (void) strcpy(filename, W_FILE1); ! 540: expfile(filename); ! 541: if (DIRECTORY(filename)) { ! 542: (void) strcat(filename, "/"); ! 543: (void) strcat(filename, BASENAME(W_FILE2, '/')); ! 544: } ! 545: strcpy(User, W_USER); ! 546: if (requestOK() == FALSE) { ! 547: WMESG(RCVFILE, EM_RMTACC); ! 548: logent("DENIED", "REQUESTING"); ! 549: CDEBUG(1, "Failed: Access Denied\n", 0); ! 550: goto top; ! 551: } ! 552: DEBUG(4, "requestOK for Loginuser - %s\n", Loginuser); ! 553: ! 554: if (chkpth(filename, CK_READ) || !READANY(filename)) { ! 555: WMESG(RCVFILE, EM_RMTACC); ! 556: logent("DENIED", "PERMISSION"); ! 557: CDEBUG(1, "Failed: Access Denied\n", 0); ! 558: goto top; ! 559: } ! 560: DEBUG(4, "chkpth ok Loginuser - %s\n", Loginuser); ! 561: ! 562: if ((fp = fopen(filename, "r")) == NULL) { ! 563: WMESG(RCVFILE, EM_RMTACC); ! 564: logent("CAN'T OPEN", "DENIED"); ! 565: CDEBUG(1, "Failed: Can't Open %s\n", filename); ! 566: goto top; ! 567: } ! 568: ! 569: /* ! 570: * ok to send file ! 571: */ ! 572: ! 573: ASSERT(fstat(fileno(fp), &stbuf) == 0, Ct_STAT, ! 574: filename, errno); ! 575: (void) sprintf(msg, "%s %o", YES, stbuf.st_mode & 0777); ! 576: WMESG(RCVFILE, msg); ! 577: Seqn++; ! 578: ret = (*Wrdata)(fp, Ofn); ! 579: (void) fclose(fp); ! 580: if (ret != 0) { ! 581: (*Turnoff)(); ! 582: return(FAIL); ! 583: } ! 584: ! 585: /* loop depending on the size of the file */ ! 586: /* give an extra try for each megabyte */ ! 587: /* stbuf set in fstat several lines back */ ! 588: for (i = stbuf.st_size >> 10; i >= 0; --i) { ! 589: if ((ret = rmesg(RQSTCMPT, msg)) == 0) ! 590: break; /* got message */ ! 591: } ! 592: if (ret != 0) { ! 593: (*Turnoff)(); ! 594: return(FAIL); ! 595: } ! 596: goto process; ! 597: } ! 598: (*Turnoff)(); ! 599: return(FAIL); ! 600: } ! 601: ! 602: ! 603: ! 604: /* ! 605: * read message ! 606: * returns: ! 607: * 0 -> success ! 608: * FAIL -> failure ! 609: */ ! 610: rmesg(c, msg) ! 611: char *msg, c; ! 612: { ! 613: char str[50]; ! 614: ! 615: DEBUG(4, "rmesg - '%c' ", c); ! 616: if ((*Rdmsg)(msg, Ifn) != 0) { ! 617: DEBUG(4, "got %s\n", "FAIL"); ! 618: (void) sprintf(str, "expected '%c' got FAIL", c); ! 619: logent(str, "BAD READ"); ! 620: return(FAIL); ! 621: } ! 622: if (c != '\0' && msg[0] != c) { ! 623: DEBUG(4, "got %s\n", msg); ! 624: (void) sprintf(str, "expected '%c' got %s", c, msg); ! 625: logent(str, "BAD READ"); ! 626: return(FAIL); ! 627: } ! 628: DEBUG(4, "got %s\n", msg); ! 629: return(0); ! 630: } ! 631: ! 632: ! 633: /* ! 634: * write a message ! 635: * returns: ! 636: * 0 -> ok ! 637: * FAIL -> ng ! 638: */ ! 639: wmesg(m, s) ! 640: char *s, m; ! 641: { ! 642: CDEBUG(4, "wmesg '%c'", m); ! 643: CDEBUG(4, "%s\n", s); ! 644: return((*Wrmsg)(m, s, Ofn)); ! 645: } ! 646: ! 647: ! 648: /* ! 649: * mail results of command ! 650: * return: ! 651: * none ! 652: */ ! 653: notify(mailopt, user, msgin, sys, msgcode) ! 654: char *user, *msgin, *sys; ! 655: register char *msgcode; ! 656: { ! 657: register int i; ! 658: char str[BUFSIZ]; ! 659: register char *msg; ! 660: ! 661: DEBUG(4,"mailopt %d, ", mailopt); ! 662: DEBUG(4,"statfopt %d\n", statfopt); ! 663: if (statfopt == 0 && mailopt == 0 && *msgcode == 'Y') ! 664: return; ! 665: if (*msgcode == 'Y') ! 666: msg = "copy succeeded"; ! 667: else { ! 668: i = atoi(msgcode + 1); ! 669: if (i < 1 || i > EM_MAX) ! 670: i = 0; ! 671: msg = Em_msg[i]; ! 672: } ! 673: if(statfopt){ ! 674: stmesg(msgin, msg); ! 675: return; ! 676: } ! 677: (void) sprintf(str, "REQUEST: %s\n(SYSTEM: %s) %s\n", ! 678: msgin, sys, msg); ! 679: mailst(user, str, "", ""); ! 680: return; ! 681: } ! 682: ! 683: /* ! 684: * local notify ! 685: * return: ! 686: * none ! 687: */ ! 688: lnotify(user, msgin, mesg) ! 689: char *user, *msgin, *mesg; ! 690: { ! 691: char mbuf[BUFSIZ]; ! 692: ! 693: if(statfopt){ ! 694: stmesg(msgin, mesg); ! 695: return; ! 696: } ! 697: (void) sprintf(mbuf, "REQUEST: %s\n(SYSTEM: %s) %s\n", ! 698: msgin, Myname, mesg); ! 699: mailst(user, mbuf, "", ""); ! 700: return; ! 701: } ! 702: static ! 703: stmesg(f, m) ! 704: char *f, *m; ! 705: { ! 706: FILE *Cf; ! 707: time_t clock; ! 708: long td, th, tm, ts; ! 709: ! 710: ASSERT(1, "stmesg called", "", 0); ! 711: #if NOTDEF ! 712: DEBUG(4,"STMES %s\n",mf); ! 713: if((Cf = fopen(mf, "a+")) == NULL){ ! 714: chmod(mf, 0666); ! 715: return; ! 716: } ! 717: (void) time(&clock); ! 718: (void) fprintf(Cf, "uucp job: %s (%s) ", Jobid, timeStamp()); ! 719: td = clock - Nstat.t_qtime; ! 720: ts = td%60; ! 721: td /= 60; ! 722: tm = td%60; ! 723: td /= 60; ! 724: th = td; ! 725: (void) fprintf(Cf, "(%ld:%ld:%ld)\n%s\n%s\n\n", th, tm, ts, f, m); ! 726: (void) fclose(Cf); ! 727: chmod(mf, 0666); ! 728: #endif ! 729: ! 730: } ! 731: ! 732: ! 733: /* ! 734: * converse with the remote machine, agree upon a ! 735: * protocol (if possible) and start the protocol. ! 736: * return: ! 737: * SUCCESS -> successful protocol selection ! 738: * FAIL -> can't find common or open failed ! 739: */ ! 740: startup(role) ! 741: register int role; ! 742: { ! 743: extern (*Rdmsg)(), (*Wrmsg)(); ! 744: extern imsg(), omsg(); ! 745: extern char *blptcl(), fptcl(), *protoString(); ! 746: char msg[BUFSIZ], str[BUFSIZ]; ! 747: ! 748: Rdmsg = imsg; ! 749: Wrmsg = omsg; ! 750: if (role == MASTER) { ! 751: RMESG(SLTPTCL, msg); ! 752: if ((str[0] = fptcl(&msg[1])) == NULL) { ! 753: ! 754: /* ! 755: * no protocol match ! 756: */ ! 757: WMESG(USEPTCL, NO); ! 758: return(FAIL); ! 759: } ! 760: str[1] = '\0'; ! 761: WMESG(USEPTCL, str); ! 762: if (stptcl(str) != 0) ! 763: return(FAIL); ! 764: return(SUCCESS); ! 765: } else { ! 766: WMESG(SLTPTCL, blptcl(str)); ! 767: RMESG(USEPTCL, msg); ! 768: if (msg[1] == 'N') { ! 769: return(FAIL); ! 770: } ! 771: ! 772: if (stptcl(&msg[1]) != 0) ! 773: return(FAIL); ! 774: return(SUCCESS); ! 775: } ! 776: } ! 777: ! 778: ! 779: /* ! 780: * choose a protocol from the input string (str) ! 781: * and return the found letter. ! 782: * Use the MASTER string for order of selection. ! 783: * If a preferred protocol was named, use that if possible. ! 784: * return: ! 785: * '\0' -> no acceptable protocol ! 786: * any character -> the chosen protocol ! 787: */ ! 788: char ! 789: fptcl(str) ! 790: register char *str; ! 791: { ! 792: char *l, list[20]; /* assume less than 20 protocols */ ! 793: ! 794: if ((l = protoString()) != NULL) ! 795: for (; *l; l++) ! 796: if (strchr(str, *l)) ! 797: return (*l); ! 798: blptcl(list); ! 799: for (l = list; *l != '\0'; l++) ! 800: if (strchr(str, *l) != NULL) ! 801: return(*l); ! 802: return('\0'); ! 803: } ! 804: ! 805: /* ! 806: * build a string of the letters of the available ! 807: * protocols and return the string (str). ! 808: * return: ! 809: * a pointer to string (str) ! 810: */ ! 811: char * ! 812: blptcl(str) ! 813: register char *str; ! 814: { ! 815: register struct Proto *p; ! 816: char *s; ! 817: ! 818: for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++) ! 819: ; ! 820: return(str); ! 821: } ! 822: ! 823: /* ! 824: * set up the six routines (Rdmg. Wrmsg, Rddata ! 825: * Wrdata, Turnon, Turnoff) for the desired protocol. ! 826: * returns: ! 827: * SUCCESS -> ok ! 828: * FAIL -> no find or failed to open ! 829: */ ! 830: stptcl(c) ! 831: register char *c; ! 832: { ! 833: register struct Proto *p; ! 834: ! 835: for (p = Ptbl; p->P_id != '\0'; p++) { ! 836: if (*c == p->P_id) { ! 837: ! 838: /* ! 839: * found protocol ! 840: * set routine ! 841: */ ! 842: Rdmsg = p->P_rdmsg; ! 843: Wrmsg = p->P_wrmsg; ! 844: Rddata = p->P_rddata; ! 845: Wrdata = p->P_wrdata; ! 846: Turnon = p->P_turnon; ! 847: Turnoff = p->P_turnoff; ! 848: if ((*Turnon)() != 0) ! 849: break; ! 850: CDEBUG(4, "Proto started %c\n", *c); ! 851: return(SUCCESS); ! 852: } ! 853: } ! 854: CDEBUG(4, "Proto start-fail %c\n", *c); ! 855: return(FAIL); ! 856: } ! 857: ! 858: /* ! 859: * put file in public place ! 860: * if successful, filename is modified ! 861: * returns: ! 862: * 0 -> success ! 863: * FAIL -> failure ! 864: */ ! 865: putinpub(file, tmp, user) ! 866: char *file, *user, *tmp; ! 867: { ! 868: int status; ! 869: char fullname[MAXFULLNAME]; ! 870: ! 871: (void) sprintf(fullname, "%s/%s/", Pubdir, user); ! 872: if (mkdirs(fullname) != 0) { ! 873: ! 874: /* ! 875: * can not make directories ! 876: */ ! 877: return(FAIL); ! 878: } ! 879: (void) strcat(fullname, BASENAME(file, '/')); ! 880: status = xmv(tmp, fullname); ! 881: if (status == 0) { ! 882: (void) strcpy(file, fullname); ! 883: (void) chmod(fullname,0666); ! 884: } ! 885: return(status); ! 886: } ! 887: ! 888: /* ! 889: * unlink D. file ! 890: * returns: ! 891: * none ! 892: */ ! 893: unlinkdf(file) ! 894: register char *file; ! 895: { ! 896: if (strlen(file) > 6) ! 897: (void) unlink(file); ! 898: return; ! 899: } ! 900: ! 901: /* ! 902: * notify receiver of arrived file ! 903: * returns: ! 904: * none ! 905: */ ! 906: arrived(opt, file, nuser, rmtsys, rmtuser) ! 907: char *file, *nuser, *rmtsys, *rmtuser; ! 908: { ! 909: char mbuf[200]; ! 910: ! 911: if (!opt) ! 912: return; ! 913: (void) sprintf(mbuf, "%s from %s!%s arrived\n", file, rmtsys, rmtuser); ! 914: mailst(nuser, mbuf, "", ""); ! 915: return; ! 916: } ! 917: ! 918: ! 919: /* ! 920: * Check to see if there is space for file ! 921: */ ! 922: ! 923: #define FREESPACE 50 /* Minimum freespace in blocks to permit transfer */ ! 924: #define FREENODES 5 /* Minimum number of inodes to permit transfer */ ! 925: ! 926: /*ARGSUSED*/ ! 927: static ! 928: nospace(name) ! 929: char *name; ! 930: #ifdef NOUSTAT ! 931: {return(FALSE);} ! 932: #else ! 933: { ! 934: struct stat statb; ! 935: struct ustat ustatb; ! 936: ! 937: if( stat(name, &statb) < 0 ) ! 938: return(TRUE); ! 939: #ifdef RT ! 940: if( (statb.st_mode|S_IFMT) == S_IFREG || ! 941: (statb.st_mode|S_IFMT) == S_IFEXT || ! 942: (statb.st_mode&S_IFMT) == S_IF1EXT ) ! 943: #else ! 944: if( (statb.st_mode&S_IFMT) == S_IFREG ) ! 945: #endif ! 946: { ! 947: if( ustat(statb.st_dev, &ustatb)<0 ) ! 948: return(TRUE); ! 949: if( ustatb.f_tfree < FREESPACE ) { ! 950: logent("FREESPACE IS LOW","REMOTE TRANSFER DENIED - "); ! 951: return(TRUE); ! 952: } ! 953: if( ustatb.f_tinode < FREENODES ) { ! 954: logent("TOO FEW INODES","REMOTE TRANSFER DENIED - "); ! 955: return(TRUE); ! 956: } ! 957: } ! 958: return(FALSE); ! 959: } ! 960: #endif ! 961: ! 962: #ifdef V7USTAT ! 963: ustat(dev, ustat) ! 964: int dev; ! 965: struct ustat *ustat; ! 966: { ! 967: FILE *dfp, *popen(); ! 968: struct fstab *fstab = NULL; ! 969: char *fval, buf[BUFSIZ]; ! 970: ! 971: sprintf(buf, "%s %d %d 2>&1", V7USTAT, major(dev), minor(dev)); ! 972: if ((dfp = popen(buf, "r")) == NULL) ! 973: return(-1); ! 974: fval = fgets(buf, sizeof(buf), dfp); ! 975: if (pclose(dfp) != 0 ! 976: || fval == NULL ! 977: || sscanf(buf, "%d %d", &ustat->f_tfree, &ustat->f_tinode) != 2) ! 978: return(-1); ! 979: return(0); ! 980: } ! 981: #endif V7USTAT
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.