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