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