|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)cico.c 5.14 (Berkeley) 4/14/86"; ! 3: #endif ! 4: ! 5: #include <signal.h> ! 6: #include "uucp.h" ! 7: #include <setjmp.h> ! 8: #ifdef USG ! 9: #include <termio.h> ! 10: #endif ! 11: #ifndef USG ! 12: #include <sgtty.h> ! 13: #endif ! 14: #ifdef BSDTCP ! 15: #include <netdb.h> ! 16: #include <netinet/in.h> ! 17: #include <sys/socket.h> ! 18: #endif BSDTCP ! 19: #include <sys/stat.h> ! 20: #include "uust.h" ! 21: #include "uusub.h" ! 22: ! 23: #if defined(VMS) && defined(BSDTCP) ! 24: #define NOGETPEER ! 25: #endif ! 26: ! 27: #ifdef BSD2_9 ! 28: #define NOGETPEER ! 29: #endif ! 30: ! 31: jmp_buf Sjbuf; ! 32: jmp_buf Pipebuf; ! 33: ! 34: /* call fail text */ ! 35: char *Stattext[] = { ! 36: "", ! 37: "BAD SYSTEM", ! 38: "WRONG TIME TO CALL", ! 39: "SYSTEM LOCKED", ! 40: "NO DEVICE", ! 41: "CALL FAILED", ! 42: "LOGIN FAILED", ! 43: "BAD SEQUENCE" ! 44: }; ! 45: ! 46: /* call fail codes */ ! 47: int Stattype[] = { ! 48: 0, ! 49: 0, ! 50: SS_WRONGTIME, ! 51: 0, ! 52: SS_NODEVICE, ! 53: SS_FAIL, ! 54: SS_FAIL, ! 55: SS_BADSEQ ! 56: }; ! 57: ! 58: /* Arguments to setdebug(): */ ! 59: #define DBG_TEMP 0 /* Create a temporary audit file */ ! 60: #define DBG_PERM 1 /* Create a permanent audit file */ ! 61: #define DBG_CLEAN 2 /* Cleanup, discard temp file */ ! 62: ! 63: int ReverseRole = 0; ! 64: int Role = SLAVE; ! 65: int onesys = 0; ! 66: int turntime = 30 * 60; /* 30 minutes expressed in seconds */ ! 67: char *ttyn = NULL; ! 68: extern int LocalOnly; ! 69: extern int errno; ! 70: extern char MaxGrade, DefMaxGrade; ! 71: extern char Myfullname[]; ! 72: ! 73: #ifdef USG ! 74: struct termio Savettyb; ! 75: #endif ! 76: #ifndef USG ! 77: struct sgttyb Savettyb; ! 78: #endif ! 79: ! 80: /* ! 81: * this program is used to place a call to a ! 82: * remote machine, login, and copy files between the two machines. ! 83: */ ! 84: main(argc, argv) ! 85: int argc; ! 86: register char *argv[]; ! 87: { ! 88: register int ret; ! 89: int seq; ! 90: char wkpre[NAMESIZE], file[NAMESIZE]; ! 91: char msg[MAXFULLNAME], *q; ! 92: register char *p; ! 93: extern onintr(), timeout(), dbg_signal(); ! 94: extern char *pskip(); ! 95: char rflags[MAXFULLNAME]; ! 96: #ifdef NOGETPEER ! 97: u_long Hostnumber = 0; ! 98: #endif NOGETPEER ! 99: ! 100: strcpy(Progname, "uucico"); ! 101: ! 102: #ifdef BSD4_2 ! 103: sigsetmask(0); /* in case we inherit blocked signals */ ! 104: #endif BSD4_2 ! 105: signal(SIGINT, onintr); ! 106: signal(SIGHUP, onintr); ! 107: signal(SIGQUIT, onintr); ! 108: signal(SIGTERM, onintr); ! 109: signal(SIGPIPE, onintr); /* 4.1a tcp-ip stupidity */ ! 110: signal(SIGFPE, dbg_signal); ! 111: ret = guinfo(getuid(), User, msg); ! 112: strcpy(Loginuser, User); ! 113: uucpname(Myname); ! 114: ASSERT(ret == 0, "BAD UID", CNULL, ret); ! 115: ! 116: setbuf (stderr, CNULL); ! 117: ! 118: rflags[0] = '\0'; ! 119: umask(WFMASK); ! 120: strcpy(Rmtname, Myname); ! 121: Ifn = Ofn = -1; ! 122: while(argc>1 && argv[1][0] == '-'){ ! 123: switch(argv[1][1]){ ! 124: case 'd': ! 125: Spool = &argv[1][2]; ! 126: break; ! 127: case 'g': ! 128: case 'p': ! 129: MaxGrade = DefMaxGrade = argv[1][2]; ! 130: break; ! 131: case 'r': ! 132: Role = atoi(&argv[1][2]); ! 133: break; ! 134: case 'R': ! 135: ReverseRole++; ! 136: Role = MASTER; ! 137: break; ! 138: case 's': ! 139: strncpy(Rmtname, &argv[1][2], MAXBASENAME); ! 140: Rmtname[MAXBASENAME] = '\0'; ! 141: if (Rmtname[0] != '\0') ! 142: onesys = 1; ! 143: break; ! 144: case 'x': ! 145: Debug = atoi(&argv[1][2]); ! 146: if (Debug <= 0) ! 147: Debug = 1; ! 148: strcat(rflags, argv[1]); ! 149: break; ! 150: case 't': ! 151: turntime = atoi(&argv[1][2])*60;/* minutes to seconds */ ! 152: break; ! 153: case 'L': /* local calls only */ ! 154: LocalOnly++; ! 155: break; ! 156: #ifdef NOGETPEER ! 157: case 'h': ! 158: Hostnumber = inet_addr(&argv[1][2]); ! 159: break; ! 160: #endif NOGETPEER ! 161: default: ! 162: printf("unknown flag %s (ignored)\n", argv[1]); ! 163: break; ! 164: } ! 165: --argc; argv++; ! 166: } ! 167: ! 168: while (argc > 1) { ! 169: fprintf(stderr, "unknown argument %s (ignored)\n", argv[1]); ! 170: --argc; argv++; ! 171: } ! 172: ! 173: if (Debug && Role == MASTER) ! 174: chkdebug(); ! 175: ! 176: /* Try to run as uucp */ ! 177: setgid(getegid()); ! 178: setuid(geteuid()); ! 179: #ifdef TIOCNOTTY ! 180: /* ! 181: * detach uucico from controlling terminal ! 182: * to defend against rlogind sending us a SIGKILL (!!!) ! 183: */ ! 184: if (Role == MASTER && (ret = open("/dev/tty", 2)) >= 0) { ! 185: ioctl(ret, TIOCNOTTY, STBNULL); ! 186: close(ret); ! 187: } ! 188: #endif TIOCNOTTY ! 189: #ifdef BSD4_2 ! 190: if (getpgrp(0) == 0) { /* We have no controlling terminal */ ! 191: setpgrp(0, getpid()); ! 192: } ! 193: #endif BSD4_2 ! 194: ! 195: ret = subchdir(Spool); ! 196: ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); ! 197: strcpy(Wrkdir, Spool); ! 198: ! 199: if (Debug) { ! 200: setdebug ((Role == SLAVE) ? DBG_TEMP : DBG_PERM); ! 201: if (Debug > 0) ! 202: logent ("Local Enabled", "DEBUG"); ! 203: } ! 204: ! 205: /* ! 206: * First time through: If we're the slave, do initial checking. ! 207: */ ! 208: if (Role == SLAVE) { ! 209: /* check for /etc/nologin */ ! 210: if (access(NOLOGIN, 0) == 0) { ! 211: logent(NOLOGIN, "UUCICO SHUTDOWN"); ! 212: if (Debug > 4) ! 213: logent("DEBUGGING", "continuing anyway"); ! 214: else ! 215: cleanup(1); ! 216: } ! 217: Ifn = 0; ! 218: Ofn = 1; ! 219: #ifdef TCPIP ! 220: /* ! 221: * Determine if we are on TCPIP ! 222: */ ! 223: if (isatty(Ifn) < 0) { ! 224: IsTcpIp = 1; ! 225: DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL); ! 226: } else ! 227: IsTcpIp = 0; ! 228: #endif TCPIP ! 229: /* initial handshake */ ! 230: onesys = 1; ! 231: if (!IsTcpIp) { ! 232: #ifdef USG ! 233: ret = ioctl(Ifn, TCGETA, &Savettyb); ! 234: Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7; ! 235: Savettyb.c_oflag |= OPOST; ! 236: Savettyb.c_lflag |= (ISIG|ICANON|ECHO); ! 237: #else !USG ! 238: ret = ioctl(Ifn, TIOCGETP, &Savettyb); ! 239: Savettyb.sg_flags |= ECHO; ! 240: Savettyb.sg_flags &= ~RAW; ! 241: #endif !USG ! 242: ttyn = ttyname(Ifn); ! 243: } ! 244: fixmode(Ifn); ! 245: ! 246: /* ! 247: * Initial Message -- tell them we're here, and who we are. ! 248: */ ! 249: sprintf(msg, "here=%s", Myfullname); ! 250: omsg('S', msg, Ofn); ! 251: signal(SIGALRM, timeout); ! 252: alarm(MAXMSGTIME); ! 253: if (setjmp(Sjbuf)) { ! 254: /* timed out */ ! 255: if (!IsTcpIp) { ! 256: #ifdef USG ! 257: ret = ioctl(Ifn, TCSETA, &Savettyb); ! 258: ! 259: #else !USG ! 260: ret = ioctl(Ifn, TIOCSETP, &Savettyb); ! 261: #endif !USG ! 262: } ! 263: cleanup(0); ! 264: } ! 265: for (;;) { ! 266: ret = imsg(msg, Ifn); ! 267: if (ret != SUCCESS) { ! 268: alarm(0); ! 269: if (!IsTcpIp) { ! 270: #ifdef USG ! 271: ret = ioctl(Ifn, TCSETA, &Savettyb); ! 272: #else !USG ! 273: ret = ioctl(Ifn, TIOCSETP, &Savettyb); ! 274: #endif !USG ! 275: } ! 276: cleanup(0); ! 277: } ! 278: if (msg[0] == 'S') ! 279: break; ! 280: } ! 281: alarm(0); ! 282: q = &msg[1]; ! 283: p = pskip(q); ! 284: strncpy(Rmtname, q, MAXBASENAME); ! 285: Rmtname[MAXBASENAME] = '\0'; ! 286: ! 287: /* ! 288: * Now that we know who they are, give the audit file the right ! 289: * name. ! 290: */ ! 291: setdebug (DBG_PERM); ! 292: DEBUG(4, "sys-%s\n", Rmtname); ! 293: /* The versys will also do an alias on the incoming name */ ! 294: if (versys(&Rmtname)) { ! 295: /* If we don't know them, we won't talk to them... */ ! 296: #ifdef NOSTRANGERS ! 297: logent(Rmtname, "UNKNOWN HOST"); ! 298: omsg('R', "You are unknown to me", Ofn); ! 299: cleanup(0); ! 300: #endif NOSTRANGERS ! 301: } ! 302: #ifdef BSDTCP ! 303: /* we must make sure they are really who they say they ! 304: * are. We compare the hostnumber with the number in the hosts ! 305: * table for the site they claim to be. ! 306: */ ! 307: if (IsTcpIp) { ! 308: struct hostent *hp; ! 309: char *cpnt, *inet_ntoa(); ! 310: int fromlen; ! 311: struct sockaddr_in from; ! 312: extern char PhoneNumber[]; ! 313: ! 314: #ifdef NOGETPEER ! 315: from.sin_addr.s_addr = Hostnumber; ! 316: from.sin_family = AF_INET; ! 317: #else !NOGETPEER ! 318: fromlen = sizeof(from); ! 319: if (getpeername(Ifn, &from, &fromlen) < 0) { ! 320: logent(Rmtname, "NOT A TCP CONNECTION"); ! 321: omsg('R', "NOT TCP", Ofn); ! 322: cleanup(0); ! 323: } ! 324: #endif !NOGETPEER ! 325: hp = gethostbyaddr(&from.sin_addr, ! 326: sizeof (struct in_addr), from.sin_family); ! 327: if (hp == NULL) { ! 328: /* security break or just old host table? */ ! 329: logent(Rmtname, "UNKNOWN IP-HOST Name ="); ! 330: cpnt = inet_ntoa(from.sin_addr), ! 331: logent(cpnt, "UNKNOWN IP-HOST Number ="); ! 332: sprintf(wkpre, "%s/%s isn't in my host table", ! 333: Rmtname, cpnt); ! 334: omsg('R' ,wkpre ,Ofn); ! 335: cleanup(0); ! 336: } ! 337: if (Debug > 99) ! 338: logent(Rmtname,"Request from IP-Host name ="); ! 339: /* ! 340: * The following is to determine if the name given us by ! 341: * the Remote uucico matches any of the names ! 342: * given its network number (remote machine) in our ! 343: * host table. ! 344: * We could check the aliases, but that won't work in ! 345: * all cases (like if you are running the domain ! 346: * server, where you don't get any aliases). The only ! 347: * reliable way I can think of that works in ALL cases ! 348: * is too look up the site in L.sys and see if the ! 349: * sitename matches what we would call him if we ! 350: * originated the call. ! 351: */ ! 352: /* PhoneNumber contains the official network name of the host we are checking. (set in versys.c) */ ! 353: if (sncncmp(PhoneNumber, hp->h_name, SYSNSIZE) == 0) { ! 354: if (Debug > 99) ! 355: logent(q,"Found in host Tables"); ! 356: } else { ! 357: logent(hp->h_name, "FORGED HOSTNAME"); ! 358: logent(inet_ntoa(from.sin_addr), "ORIGINATED AT"); ! 359: logent(PhoneNumber, "SHOULD BE"); ! 360: sprintf(wkpre, "You're not who you claim to be: %s != %s", hp->h_name, PhoneNumber); ! 361: omsg('R', wkpre, Ofn); ! 362: cleanup(0); ! 363: } ! 364: } ! 365: #endif BSDTCP ! 366: ! 367: if (mlock(Rmtname)) { ! 368: omsg('R', "LCK", Ofn); ! 369: cleanup(0); ! 370: } ! 371: else if (callback(Loginuser)) { ! 372: signal(SIGINT, SIG_IGN); ! 373: signal(SIGHUP, SIG_IGN); ! 374: omsg('R', "CB", Ofn); ! 375: logent("CALLBACK", "REQUIRED"); ! 376: /* set up for call back */ ! 377: systat(Rmtname, SS_CALLBACK, "CALLING BACK"); ! 378: gename(CMDPRE, Rmtname, 'C', file); ! 379: close(creat(subfile(file), 0666)); ! 380: xuucico(Rmtname); ! 381: cleanup(0); ! 382: } ! 383: seq = 0; ! 384: while (*p == '-') { ! 385: q = pskip(p); ! 386: switch(*(++p)) { ! 387: case 'x': ! 388: if (Debug == 0) { ! 389: Debug = atoi(++p); ! 390: if (Debug <= 0) ! 391: Debug = 1; ! 392: setdebug(DBG_PERM); ! 393: if (Debug > 0) ! 394: logent("Remote Enabled", "DEBUG"); ! 395: } else { ! 396: DEBUG(1, "Remote debug request ignored\n", ! 397: CNULL); ! 398: } ! 399: break; ! 400: case 'Q': ! 401: seq = atoi(++p); ! 402: break; ! 403: case 'p': ! 404: MaxGrade = DefMaxGrade = *++p; ! 405: DEBUG(4, "MaxGrade set to %c\n", MaxGrade); ! 406: break; ! 407: case 'v': ! 408: if (strncmp(p, "grade", 5) == 0) { ! 409: p += 6; ! 410: MaxGrade = DefMaxGrade = *p++; ! 411: DEBUG(4, "MaxGrade set to %c\n", MaxGrade); ! 412: } ! 413: break; ! 414: default: ! 415: break; ! 416: } ! 417: p = q; ! 418: } ! 419: if (callok(Rmtname) == SS_BADSEQ) { ! 420: logent("BADSEQ", "PREVIOUS"); ! 421: omsg('R', "BADSEQ", Ofn); ! 422: cleanup(0); ! 423: } ! 424: #ifdef GNXSEQ ! 425: if ((ret = gnxseq(Rmtname)) == seq) { ! 426: omsg('R', "OK", Ofn); ! 427: cmtseq(); ! 428: } else { ! 429: #else !GNXSEQ ! 430: if (seq == 0) ! 431: omsg('R', "OK", Ofn); ! 432: else { ! 433: #endif !GNXSEQ ! 434: systat(Rmtname, Stattype[7], Stattext[7]); ! 435: logent("BAD SEQ", "FAILED HANDSHAKE"); ! 436: #ifdef GNXSEQ ! 437: ulkseq(); ! 438: #endif GNXSEQ ! 439: omsg('R', "BADSEQ", Ofn); ! 440: cleanup(0); ! 441: } ! 442: if (ttyn != NULL) ! 443: chmod(ttyn, 0600); ! 444: } ! 445: ! 446: loop: ! 447: if(setjmp(Pipebuf)) { /* come here on SIGPIPE */ ! 448: clsacu(); ! 449: close(Ofn); ! 450: close(Ifn); ! 451: Ifn = Ofn = -1; ! 452: rmlock(CNULL); ! 453: sleep(3); ! 454: } ! 455: if (!onesys) { ! 456: ret = gnsys(Rmtname, Spool, CMDPRE); ! 457: setdebug(DBG_PERM); ! 458: if (ret == FAIL) ! 459: cleanup(100); ! 460: if (ret == SUCCESS) ! 461: cleanup(0); ! 462: } else if (Role == MASTER && callok(Rmtname) != 0) { ! 463: logent("SYSTEM STATUS", "CAN NOT CALL"); ! 464: cleanup(0); ! 465: } ! 466: ! 467: sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname); ! 468: ! 469: signal(SIGINT, SIG_IGN); ! 470: signal(SIGQUIT, SIG_IGN); ! 471: if (Role == MASTER) { ! 472: /* check for /etc/nologin */ ! 473: if (access(NOLOGIN, 0) == 0) { ! 474: logent(NOLOGIN, "UUCICO SHUTDOWN"); ! 475: if (Debug > 4) ! 476: logent("DEBUGGING", "continuing anyway"); ! 477: else ! 478: cleanup(1); ! 479: } ! 480: /* master part */ ! 481: signal(SIGHUP, SIG_IGN); ! 482: if (Ifn != -1 && Role == MASTER) { ! 483: write(Ofn, EOTMSG, strlen(EOTMSG)); ! 484: clsacu(); ! 485: close(Ofn); ! 486: close(Ifn); ! 487: Ifn = Ofn = -1; ! 488: rmlock(CNULL); ! 489: sleep(3); ! 490: } ! 491: sprintf(msg, "call to %s ", Rmtname); ! 492: if (mlock(Rmtname) != SUCCESS) { ! 493: logent(msg, "LOCKED"); ! 494: US_SST(us_s_lock); ! 495: goto next; ! 496: } ! 497: Ofn = Ifn = conn(Rmtname); ! 498: if (Ofn < 0) { ! 499: if (Ofn != CF_TIME) ! 500: logent(msg, _FAILED); ! 501: /* avoid excessive 'wrong time' info */ ! 502: if (Stattype[-Ofn] != SS_WRONGTIME){ ! 503: systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]); ! 504: US_SST(-Ofn); ! 505: UB_SST(-Ofn); ! 506: } ! 507: goto next; ! 508: } else { ! 509: logent(msg, "SUCCEEDED"); ! 510: US_SST(us_s_cok); ! 511: UB_SST(ub_ok); ! 512: } ! 513: #ifdef TCPIP ! 514: /* ! 515: * Determine if we are on TCPIP ! 516: */ ! 517: if (isatty(Ifn) == 0) { ! 518: IsTcpIp = 1; ! 519: DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL); ! 520: } else ! 521: IsTcpIp = 0; ! 522: #endif ! 523: ! 524: if (setjmp(Sjbuf)) ! 525: goto next; ! 526: signal(SIGALRM, timeout); ! 527: alarm(2 * MAXMSGTIME); ! 528: for (;;) { ! 529: ret = imsg(msg, Ifn); ! 530: if (ret != 0) { ! 531: alarm(0); ! 532: logent("imsg 1", _FAILED); ! 533: goto Failure; ! 534: } ! 535: if (msg[0] == 'S') ! 536: break; ! 537: } ! 538: alarm(MAXMSGTIME); ! 539: #ifdef GNXSEQ ! 540: seq = gnxseq(Rmtname); ! 541: #else !GNXSEQ ! 542: seq = 0; ! 543: #endif !GNXSEQ ! 544: if (MaxGrade != '\177') { ! 545: DEBUG(2, "Max Grade this transfer is %c\n", MaxGrade); ! 546: sprintf(msg, "%s -Q%d -p%c -vgrade=%c %s", ! 547: Myname, seq, MaxGrade, MaxGrade, rflags); ! 548: } else ! 549: sprintf(msg, "%s -Q%d %s", Myname, seq, rflags); ! 550: omsg('S', msg, Ofn); ! 551: for (;;) { ! 552: ret = imsg(msg, Ifn); ! 553: DEBUG(4, "msg-%s\n", msg); ! 554: if (ret != SUCCESS) { ! 555: alarm(0); ! 556: #ifdef GNXSEQ ! 557: ulkseq(); ! 558: #endif GNXSEQ ! 559: logent("imsg 2", _FAILED); ! 560: goto Failure; ! 561: } ! 562: if (msg[0] == 'R') ! 563: break; ! 564: } ! 565: alarm(0); ! 566: if (msg[1] == 'B') { ! 567: /* bad sequence */ ! 568: logent("BAD SEQ", "FAILED HANDSHAKE"); ! 569: US_SST(us_s_hand); ! 570: systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]); ! 571: #ifdef GNXSEQ ! 572: ulkseq(); ! 573: #endif GNXSEQ ! 574: goto next; ! 575: } ! 576: if (strcmp(&msg[1], "OK") != SAME) { ! 577: logent(&msg[1], "FAILED HANDSHAKE"); ! 578: US_SST(us_s_hand); ! 579: #ifdef GNXSEQ ! 580: ulkseq(); ! 581: #endif GNXSEQ ! 582: systat(Rmtname, SS_INPROGRESS, ! 583: strcmp(&msg[1], "CB") == SAME? ! 584: "AWAITING CALLBACK": "FAILED HANDSHAKE"); ! 585: goto next; ! 586: } ! 587: #ifdef GNXSEQ ! 588: cmtseq(); ! 589: #endif GNXSEQ ! 590: } ! 591: DEBUG(1, "Rmtname %s, ", Rmtname); ! 592: DEBUG(1, "Role %s, ", Role ? "MASTER" : "SLAVE"); ! 593: DEBUG(1, "Ifn - %d, ", Ifn); ! 594: DEBUG(1, "Loginuser - %s\n", Loginuser); ! 595: ! 596: ttyn = ttyname(Ifn); ! 597: ! 598: alarm(MAXMSGTIME); ! 599: if (ret=setjmp(Sjbuf)) ! 600: goto Failure; ! 601: ret = startup(Role); ! 602: alarm(0); ! 603: if (ret != SUCCESS) { ! 604: logent("startup", _FAILED); ! 605: Failure: ! 606: US_SST(us_s_start); ! 607: systat(Rmtname, SS_FAIL, ret > 0 ? "CONVERSATION FAILED" : ! 608: "STARTUP FAILED"); ! 609: goto next; ! 610: } else { ! 611: if (ttyn != NULL) { ! 612: char startupmsg[BUFSIZ]; ! 613: extern int linebaudrate; ! 614: sprintf(startupmsg, "startup %s %d baud", &ttyn[5], ! 615: linebaudrate); ! 616: logent(startupmsg, "OK"); ! 617: } else ! 618: logent("startup", "OK"); ! 619: US_SST(us_s_gress); ! 620: systat(Rmtname, SS_INPROGRESS, "TALKING"); ! 621: ret = cntrl(Role, wkpre); ! 622: DEBUG(1, "cntrl - %d\n", ret); ! 623: signal(SIGINT, SIG_IGN); ! 624: signal(SIGHUP, SIG_IGN); ! 625: signal(SIGALRM, timeout); ! 626: if (ret == SUCCESS) { ! 627: logent("conversation complete", "OK"); ! 628: US_SST(us_s_ok); ! 629: rmstat(Rmtname); ! 630: ! 631: } else { ! 632: logent("conversation complete", _FAILED); ! 633: US_SST(us_s_cf); ! 634: systat(Rmtname, SS_FAIL, "CONVERSATION FAILED"); ! 635: } ! 636: alarm(MAXMSGTIME); ! 637: DEBUG(4, "send OO %d,", ret); ! 638: if (!setjmp(Sjbuf)) { ! 639: for (;;) { ! 640: omsg('O', "OOOOO", Ofn); ! 641: ret = imsg(msg, Ifn); ! 642: if (ret != 0) ! 643: break; ! 644: if (msg[0] == 'O') ! 645: break; ! 646: } ! 647: } ! 648: alarm(0); ! 649: clsacu(); ! 650: rmlock(CNULL); ! 651: } ! 652: next: ! 653: if (!onesys) { ! 654: goto loop; ! 655: } ! 656: cleanup(0); ! 657: } ! 658: ! 659: #ifndef USG ! 660: struct sgttyb Hupvec; ! 661: #endif ! 662: ! 663: /* ! 664: * cleanup and exit with "code" status ! 665: */ ! 666: cleanup(code) ! 667: register int code; ! 668: { ! 669: signal(SIGINT, SIG_IGN); ! 670: signal(SIGHUP, SIG_IGN); ! 671: rmlock(CNULL); ! 672: sleep(5); /* Wait for any pending output */ ! 673: clsacu(); ! 674: logcls(); ! 675: if (Role == SLAVE) { ! 676: if (!IsTcpIp) { ! 677: #ifdef USG ! 678: Savettyb.c_cflag |= HUPCL; ! 679: (void) ioctl(0, TCSETA, &Savettyb); ! 680: #else !USG ! 681: (void) ioctl(0, TIOCHPCL, STBNULL); ! 682: #ifdef TIOCSDTR ! 683: (void) ioctl(0, TIOCCDTR, STBNULL); ! 684: sleep(2); ! 685: (void) ioctl(0, TIOCSDTR, STBNULL); ! 686: #else !TIOCSDTR ! 687: (void) ioctl(0, TIOCGETP, &Hupvec); ! 688: Hupvec.sg_ispeed = B0; ! 689: Hupvec.sg_ospeed = B0; ! 690: (void) ioctl(0, TIOCSETP, &Hupvec); ! 691: #endif !TIOCSDTR ! 692: sleep(2); ! 693: (void) ioctl(0, TIOCSETP, &Savettyb); ! 694: /* make *sure* exclusive access is off */ ! 695: (void) ioctl(0, TIOCNXCL, STBNULL); ! 696: #endif !USG ! 697: } ! 698: if (ttyn != NULL) ! 699: chmod(ttyn, 0600); ! 700: } ! 701: if (Ofn != -1) { ! 702: if (Role == MASTER) ! 703: write(Ofn, EOTMSG, strlen(EOTMSG)); ! 704: close(Ifn); ! 705: close(Ofn); ! 706: } ! 707: #ifdef DIALINOUT ! 708: /* reenable logins on dialout */ ! 709: reenable(); ! 710: #endif DIALINOUT ! 711: if (code == 0) ! 712: xuuxqt(); ! 713: else ! 714: DEBUG(1, "exit code %d\n", code); ! 715: setdebug (DBG_CLEAN); ! 716: exit(code); ! 717: } ! 718: ! 719: /* ! 720: * on interrupt - remove locks and exit ! 721: */ ! 722: ! 723: onintr(inter) ! 724: register int inter; ! 725: { ! 726: char str[30]; ! 727: signal(inter, SIG_IGN); ! 728: sprintf(str, "SIGNAL %d", inter); ! 729: logent(str, "CAUGHT"); ! 730: US_SST(us_s_intr); ! 731: if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) ! 732: systat(Rmtname, SS_FAIL, str); ! 733: if (inter == SIGPIPE && !onesys) ! 734: longjmp(Pipebuf, 1); ! 735: cleanup(inter); ! 736: } ! 737: ! 738: /* ! 739: * Catch a special signal ! 740: * (SIGFPE, ugh), and toggle debugging between 0 and 30. ! 741: * Handy for looking in on long running uucicos. ! 742: */ ! 743: dbg_signal() ! 744: { ! 745: Debug = (Debug == 0) ? 30 : 0; ! 746: setdebug(DBG_PERM); ! 747: if (Debug > 0) ! 748: logent("Signal Enabled", "DEBUG"); ! 749: } ! 750: ! 751: ! 752: /* ! 753: * Check debugging requests, and open RMTDEBUG audit file if necessary. If an ! 754: * audit file is needed, the parm argument indicates how to create the file: ! 755: * ! 756: * DBG_TEMP - Open a temporary file, with filename = RMTDEBUG/pid. ! 757: * DBG_PERM - Open a permanent audit file, filename = RMTDEBUG/Rmtname. ! 758: * If a temp file already exists, it is mv'ed to be permanent. ! 759: * DBG_CLEAN - Cleanup; unlink temp files. ! 760: * ! 761: * Restrictions - this code can only cope with one open debug file at a time. ! 762: * Each call creates a new file; if an old one of the same name exists it will ! 763: * be overwritten. ! 764: */ ! 765: setdebug(parm) ! 766: int parm; ! 767: { ! 768: char buf[BUFSIZ]; /* Buffer for building filenames */ ! 769: static char *temp = NULL; /* Ptr to temporary file name */ ! 770: static int auditopen = 0; /* Set to 1 when we open a file */ ! 771: struct stat stbuf; /* File status buffer */ ! 772: ! 773: /* ! 774: * If movement or cleanup of a temp file is indicated, we do it no ! 775: * matter what. ! 776: */ ! 777: if (temp != CNULL && parm == DBG_PERM) { ! 778: sprintf(buf, "%s/%s", RMTDEBUG, Rmtname); ! 779: unlink(buf); ! 780: if (link(temp, buf) != 0) { ! 781: Debug = 0; ! 782: assert("RMTDEBUG LINK FAIL", temp, errno); ! 783: cleanup(1); ! 784: } ! 785: parm = DBG_CLEAN; ! 786: } ! 787: if (parm == DBG_CLEAN) { ! 788: if (temp != CNULL) { ! 789: unlink(temp); ! 790: free(temp); ! 791: temp = CNULL; ! 792: } ! 793: return; ! 794: } ! 795: ! 796: if (Debug == 0) ! 797: return; /* Gotta be in debug to come here. */ ! 798: ! 799: /* ! 800: * If we haven't opened a file already, we can just return if it's ! 801: * alright to use the stderr we came in with. We can if: ! 802: * ! 803: * Role == MASTER, and Stderr is a regular file, a TTY or a pipe. ! 804: * ! 805: * Caution: Detecting when stderr is a pipe is tricky, because the 4.2 ! 806: * man page for fstat(2) disagrees with reality, and System V leaves it ! 807: * undefined, which means different implementations act differently. ! 808: */ ! 809: if (!auditopen && Role == MASTER) { ! 810: if (isatty(fileno(stderr))) ! 811: return; ! 812: else if (fstat(fileno(stderr), &stbuf) == 0) { ! 813: #ifdef USG ! 814: /* Is Regular File or Fifo */ ! 815: if ((stbuf.st_mode & 0060000) == 0) ! 816: return; ! 817: #else !USG ! 818: #ifdef BSD4_2 ! 819: /* Is Regular File */ ! 820: if ((stbuf.st_mode & S_IFMT) == S_IFREG || ! 821: stbuf.st_mode == 0) /* Is a pipe */ ! 822: return; ! 823: #else !BSD4_2 ! 824: /* Is Regular File or Pipe */ ! 825: if ((stbuf.st_mode & S_IFMT) == S_IFREG) ! 826: return; ! 827: #endif BSD4_2 ! 828: #endif USG ! 829: } ! 830: } ! 831: ! 832: /* ! 833: * We need RMTDEBUG directory to do auditing. If the file doesn't exist, ! 834: * then we forget about debugging; if it exists but has improper owner- ! 835: * ship or modes, we gripe about it in ERRLOG. ! 836: */ ! 837: if (stat(RMTDEBUG, &stbuf) != SUCCESS) { ! 838: Debug = 0; ! 839: return; ! 840: } ! 841: if ((geteuid() != stbuf.st_uid) || /* We must own it */ ! 842: ((stbuf.st_mode & 0170700) != 040700)) { /* Directory, rwx */ ! 843: Debug = 0; ! 844: assert("INVALID RMTDEBUG DIRECTORY:", RMTDEBUG, stbuf.st_mode); ! 845: return; ! 846: } ! 847: ! 848: if (parm == DBG_TEMP) { ! 849: sprintf(buf, "%s/%d", RMTDEBUG, getpid()); ! 850: temp = malloc(strlen (buf) + 1); ! 851: if (temp == CNULL) { ! 852: Debug = 0; ! 853: assert("RMTDEBUG MALLOC ERROR:", temp, errno); ! 854: cleanup(1); ! 855: } ! 856: strcpy(temp, buf); ! 857: } else ! 858: sprintf(buf, "%s/%s", RMTDEBUG, Rmtname); ! 859: ! 860: unlink(buf); ! 861: if (freopen(buf, "w", stderr) != stderr) { ! 862: Debug = 0; ! 863: assert("FAILED RMTDEBUG FILE OPEN:", buf, errno); ! 864: cleanup(1); ! 865: } ! 866: setbuf(stderr, CNULL); ! 867: auditopen = 1; ! 868: } ! 869: ! 870: /* ! 871: * catch SIGALRM routine ! 872: */ ! 873: timeout() ! 874: { ! 875: extern int HaveSentHup; ! 876: if (!HaveSentHup) { ! 877: logent(Rmtname, "TIMEOUT"); ! 878: if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) { ! 879: US_SST(us_s_tmot); ! 880: systat(Rmtname, SS_FAIL, "TIMEOUT"); ! 881: } ! 882: } ! 883: longjmp(Sjbuf, 1); ! 884: } ! 885: ! 886: static char * ! 887: pskip(p) ! 888: register char *p; ! 889: { ! 890: while(*p && *p != ' ') ! 891: ++p; ! 892: while(*p && *p == ' ') ! 893: *p++ = 0; ! 894: return p; ! 895: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.