|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)cico.c 5.3 (Berkeley) 10/3/83"; ! 3: #endif ! 4: ! 5: #include "uucp.h" ! 6: #include <signal.h> ! 7: #include <setjmp.h> ! 8: #include <sys/types.h> ! 9: #ifdef SYSIII ! 10: #include <termio.h> ! 11: #endif ! 12: #ifndef SYSIII ! 13: #include <sgtty.h> ! 14: #endif ! 15: ! 16: ! 17: #ifdef UNET ! 18: #include <UNET/unetio.h> ! 19: #include <UNET/tcp.h> ! 20: static struct uiocstate ust; ! 21: #endif ! 22: ! 23: jmp_buf Sjbuf; ! 24: /* call fail text */ ! 25: char *Stattext[] = { ! 26: "", ! 27: "BAD SYSTEM", ! 28: "WRONG TIME", ! 29: "SYSTEM LOCKED", ! 30: "NO DEVICE", ! 31: "DIAL FAILED", ! 32: "LOGIN FAILED", ! 33: "BAD SEQUENCE" ! 34: }; ! 35: ! 36: int Role = 0; ! 37: /* call fail codes */ ! 38: int Stattype[] = {0, 0, 0, 0, ! 39: SS_NODEVICE, SS_FAIL, SS_FAIL, SS_BADSEQ ! 40: }; ! 41: ! 42: ! 43: int Errorrate = 0; ! 44: #ifdef SYSIII ! 45: struct termio Savettyb; ! 46: #endif ! 47: #ifndef SYSIII ! 48: struct sgttyb Savettyb; ! 49: #endif ! 50: ! 51: /******* ! 52: * cico - this program is used to place a call to a ! 53: * remote machine, login, and copy files between the two machines. ! 54: */ ! 55: ! 56: main(argc, argv) ! 57: register char *argv[]; ! 58: { ! 59: register int ret; ! 60: int seq; ! 61: int onesys = 0; ! 62: char wkpre[NAMESIZE], file[NAMESIZE]; ! 63: char msg[BUFSIZ], *q; ! 64: register char *p; ! 65: extern onintr(), timeout(), setdebug(); ! 66: extern intrEXIT(); ! 67: extern char *pskip(); ! 68: char rflags[30]; ! 69: char *ttyn; ! 70: int orig_uid = getuid(); ! 71: ! 72: strcpy(Progname, "uucico"); ! 73: uucpname(Myname); ! 74: ! 75: /* Try to run as uucp -- rti!trt */ ! 76: setgid(getegid()); ! 77: setuid(geteuid()); ! 78: ! 79: signal(SIGILL, intrEXIT); ! 80: signal(SIGTRAP, intrEXIT); ! 81: signal(SIGIOT, intrEXIT); ! 82: signal(SIGEMT, intrEXIT); ! 83: signal(SIGFPE, intrEXIT); ! 84: signal(SIGBUS, intrEXIT); ! 85: signal(SIGSEGV, intrEXIT); ! 86: signal(SIGSYS, intrEXIT); ! 87: signal(SIGINT, onintr); ! 88: signal(SIGHUP, onintr); ! 89: signal(SIGQUIT, onintr); ! 90: signal(SIGTERM, onintr); ! 91: signal(SIGPIPE, onintr); /* 4.1a tcp-ip stupidity */ ! 92: signal(SIGFPE, setdebug); ! 93: ret = guinfo(getuid(), User, msg); ! 94: strcpy(Loginuser, User); ! 95: ASSERT(ret == 0, "BAD UID ", "", ret); ! 96: ! 97: rflags[0] = '\0'; ! 98: umask(WFMASK); ! 99: strcpy(Rmtname, Myname); ! 100: Ifn = Ofn = -1; ! 101: while(argc>1 && argv[1][0] == '-'){ ! 102: switch(argv[1][1]){ ! 103: case 'd': ! 104: Spool = &argv[1][2]; ! 105: break; ! 106: #ifdef PROTODEBUG ! 107: case 'E': ! 108: Errorrate = atoi(&argv[1][2]); ! 109: if (Errorrate <= 0) ! 110: Errorrate = 100; ! 111: break; ! 112: case 'g': ! 113: Pkdrvon = 1; ! 114: break; ! 115: case 'G': ! 116: Pkdrvon = 1; ! 117: strcat(rflags, " -g "); ! 118: break; ! 119: #endif ! 120: case 'r': ! 121: Role = atoi(&argv[1][2]); ! 122: break; ! 123: case 's': ! 124: sprintf(Rmtname, "%.7s", &argv[1][2]); ! 125: if (Rmtname[0] != '\0') ! 126: onesys = 1; ! 127: break; ! 128: case 'x': ! 129: chkdebug(orig_uid); ! 130: Debug = atoi(&argv[1][2]); ! 131: if (Debug <= 0) ! 132: Debug = 1; ! 133: strcat(rflags, argv[1]); ! 134: logent("ENABLED", "DEBUG"); ! 135: break; ! 136: default: ! 137: printf("unknown flag %s\n", argv[1]); ! 138: break; ! 139: } ! 140: --argc; argv++; ! 141: } ! 142: ! 143: subchdir(Spool); ! 144: strcpy(Wrkdir, Spool); ! 145: ! 146: #ifdef UNET ! 147: /* ! 148: * Determine if we are on UNET ! 149: */ ! 150: ret = ioctl(0, UIOCSTATE, &ust); ! 151: if (ret == 0) { ! 152: Unet = 1; ! 153: DEBUG(4, "UNET connection -- ioctl-s disabled\n", ""); ! 154: } ! 155: #endif ! 156: if (Role == SLAVE) { ! 157: /* initial handshake */ ! 158: onesys = 1; ! 159: if (!Unet) { ! 160: #ifdef SYSIII ! 161: ret = ioctl(0, TCGETA, &Savettyb); ! 162: Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7; ! 163: Savettyb.c_oflag |= OPOST; ! 164: Savettyb.c_lflag |= (ISIG|ICANON|ECHO); ! 165: #endif ! 166: #ifndef SYSIII ! 167: ret = ioctl(0, TIOCGETP, &Savettyb); ! 168: Savettyb.sg_flags |= ECHO; ! 169: Savettyb.sg_flags &= ~RAW; ! 170: #endif ! 171: } ! 172: Ifn = 0; ! 173: Ofn = 1; ! 174: fixmode(Ifn); ! 175: fclose(stderr); ! 176: fopen(RMTDEBUG, "w"); ! 177: omsg('S', "here", Ofn); ! 178: signal(SIGALRM, timeout); ! 179: alarm(MAXMSGTIME); ! 180: if (setjmp(Sjbuf)) { ! 181: /* timed out */ ! 182: if (!Unet) { ! 183: #ifdef SYSIII ! 184: ret = ioctl(0, TCSETA, &Savettyb); ! 185: #endif ! 186: #ifndef SYSIII ! 187: ret = ioctl(0, TIOCSETP, &Savettyb); ! 188: #endif ! 189: } ! 190: exit(0); ! 191: } ! 192: for (;;) { ! 193: ret = imsg(msg, Ifn); ! 194: if (ret != 0) { ! 195: alarm(0); ! 196: if (!Unet) { ! 197: #ifdef SYSIII ! 198: ret = ioctl(0, TCSETA, &Savettyb); ! 199: #endif ! 200: #ifndef SYSIII ! 201: ret = ioctl(0, TIOCSETP, &Savettyb); ! 202: #endif ! 203: } ! 204: exit(0); ! 205: } ! 206: if (msg[0] == 'S') ! 207: break; ! 208: } ! 209: alarm(0); ! 210: q = &msg[1]; ! 211: p = pskip(q); ! 212: sprintf(Rmtname, "%.7s", q); ! 213: DEBUG(4, "sys-%s\n", Rmtname); ! 214: if (mlock(Rmtname)) { ! 215: omsg('R', "LCK", Ofn); ! 216: cleanup(0); ! 217: } ! 218: else if (callback(Loginuser)) { ! 219: signal(SIGINT, SIG_IGN); ! 220: signal(SIGHUP, SIG_IGN); ! 221: omsg('R', "CB", Ofn); ! 222: logent("CALLBACK", "REQUIRED"); ! 223: /* set up for call back */ ! 224: systat(Rmtname, SS_CALLBACK, "CALL BACK"); ! 225: gename(CMDPRE, Rmtname, 'C', file); ! 226: close(creat(subfile(file), 0666)); ! 227: xuucico(Rmtname); ! 228: cleanup(0); ! 229: } ! 230: seq = 0; ! 231: while (*p == '-') { ! 232: q = pskip(p); ! 233: switch(*(++p)) { ! 234: case 'g': ! 235: Pkdrvon = 1; ! 236: break; ! 237: case 'x': ! 238: Debug = atoi(++p); ! 239: if (Debug <= 0) ! 240: Debug = 1; ! 241: break; ! 242: case 'Q': ! 243: seq = atoi(++p); ! 244: break; ! 245: default: ! 246: break; ! 247: } ! 248: p = q; ! 249: } ! 250: if (callok(Rmtname) == SS_BADSEQ) { ! 251: logent("BADSEQ", "PREVIOUS"); ! 252: omsg('R', "BADSEQ", Ofn); ! 253: cleanup(0); ! 254: } ! 255: if ((ret = gnxseq(Rmtname)) == seq) { ! 256: omsg('R', "OK", Ofn); ! 257: cmtseq(); ! 258: } ! 259: else { ! 260: systat(Rmtname, Stattype[7], Stattext[7]); ! 261: logent("BAD SEQ", "HANDSHAKE FAILED"); ! 262: ulkseq(); ! 263: omsg('R', "BADSEQ", Ofn); ! 264: cleanup(0); ! 265: } ! 266: ttyn = ttyname(Ifn); ! 267: if (ttyn != NULL) ! 268: chmod(ttyn, 0600); ! 269: } ! 270: loop: ! 271: if (!onesys) { ! 272: ret = gnsys(Rmtname, Spool, CMDPRE); ! 273: if (ret == FAIL) ! 274: cleanup(100); ! 275: if (ret == 0) ! 276: cleanup(0); ! 277: } ! 278: else if (Role == MASTER && callok(Rmtname) != 0) { ! 279: logent("SYSTEM STATUS", "CAN NOT CALL"); ! 280: cleanup(0); ! 281: } ! 282: ! 283: sprintf(wkpre, "%c.%.7s", CMDPRE, Rmtname); ! 284: ! 285: if (Role == MASTER) { ! 286: /* master part */ ! 287: signal(SIGINT, SIG_IGN); ! 288: signal(SIGHUP, SIG_IGN); ! 289: signal(SIGQUIT, SIG_IGN); ! 290: if (!iswrk(file, "chk", Spool, wkpre) && !onesys) { ! 291: logent(Rmtname, "NO WORK"); ! 292: goto next; ! 293: } ! 294: if (Ifn != -1 && Role == MASTER) { ! 295: write(Ofn, EOTMSG, strlen(EOTMSG)); ! 296: clsacu(); ! 297: close(Ofn); ! 298: close(Ifn); ! 299: Ifn = Ofn = -1; ! 300: rmlock(CNULL); ! 301: sleep(3); ! 302: } ! 303: sprintf(msg, "call to %s ", Rmtname); ! 304: if (mlock(Rmtname) != 0) { ! 305: logent(msg, "LOCKED"); ! 306: goto next; ! 307: } ! 308: Ofn = Ifn = conn(Rmtname); ! 309: if (Ofn < 0) { ! 310: logent(msg, "FAILED"); ! 311: systat(Rmtname, Stattype[-Ofn], ! 312: Stattext[-Ofn]); ! 313: goto next; ! 314: } ! 315: else { ! 316: logent(msg, "SUCCEEDED"); ! 317: } ! 318: ! 319: if (setjmp(Sjbuf)) ! 320: goto next; ! 321: signal(SIGALRM, timeout); ! 322: alarm(2 * MAXMSGTIME); ! 323: for (;;) { ! 324: ret = imsg(msg, Ifn); ! 325: if (ret != 0) { ! 326: alarm(0); ! 327: logent("imsg 1", "FAILED"); ! 328: goto next; ! 329: } ! 330: if (msg[0] == 'S') ! 331: break; ! 332: } ! 333: alarm(MAXMSGTIME); ! 334: seq = gnxseq(Rmtname); ! 335: sprintf(msg, "%.7s -Q%d %s", Myname, seq, rflags); ! 336: omsg('S', msg, Ofn); ! 337: for (;;) { ! 338: ret = imsg(msg, Ifn); ! 339: DEBUG(4, "msg-%s\n", msg); ! 340: if (ret != 0) { ! 341: alarm(0); ! 342: ulkseq(); ! 343: logent("imsg 2", "FAILED"); ! 344: goto next; ! 345: } ! 346: if (msg[0] == 'R') ! 347: break; ! 348: } ! 349: alarm(0); ! 350: if (msg[1] == 'B') { ! 351: /* bad sequence */ ! 352: logent("BAD SEQ", "HANDSHAKE FAILED"); ! 353: systat(Rmtname, Stattype[7], Stattext[7]); ! 354: ulkseq(); ! 355: goto next; ! 356: } ! 357: if (strcmp(&msg[1], "OK") != SAME) { ! 358: logent(&msg[1], "HANDSHAKE FAILED"); ! 359: ulkseq(); ! 360: goto next; ! 361: } ! 362: cmtseq(); ! 363: } ! 364: DEBUG(1, " Rmtname %s, ", Rmtname); ! 365: DEBUG(1, "Role %s, ", Role ? "MASTER" : "SLAVE"); ! 366: DEBUG(1, "Ifn - %d, ", Ifn); ! 367: DEBUG(1, "Loginuser - %s\n", Loginuser); ! 368: ! 369: alarm(MAXMSGTIME); ! 370: if (setjmp(Sjbuf)) ! 371: goto Failure; ! 372: ret = startup(Role); ! 373: alarm(0); ! 374: if (ret != SUCCESS) { ! 375: Failure: ! 376: logent("startup", "FAILED"); ! 377: systat(Rmtname, SS_FAIL, "STARTUP"); ! 378: goto next; ! 379: } ! 380: else { ! 381: logent("startup", "OK"); ! 382: systat(Rmtname, SS_INPROGRESS, "TALKING"); ! 383: ret = cntrl(Role, wkpre); ! 384: DEBUG(1, "cntrl - %d\n", ret); ! 385: signal(SIGINT, SIG_IGN); ! 386: signal(SIGHUP, SIG_IGN); ! 387: signal(SIGALRM, timeout); ! 388: if (ret == 0) { ! 389: logent("conversation complete", "OK"); ! 390: rmstat(Rmtname); ! 391: ! 392: } ! 393: else { ! 394: logent("conversation complete", "FAILED"); ! 395: systat(Rmtname, SS_FAIL, "CONVERSATION"); ! 396: } ! 397: alarm(MAXMSGTIME); ! 398: omsg('O', "OOOOO", Ofn); ! 399: DEBUG(4, "send OO %d,", ret); ! 400: if (!setjmp(Sjbuf)) { ! 401: for (;;) { ! 402: omsg('O', "OOOOO", Ofn); ! 403: ret = imsg(msg, Ifn); ! 404: if (ret != 0) ! 405: break; ! 406: if (msg[0] == 'O') ! 407: break; ! 408: } ! 409: } ! 410: alarm(0); ! 411: clsacu(); /* rti!trt: is this needed? */ ! 412: } ! 413: next: ! 414: if (!onesys) { ! 415: goto loop; ! 416: } ! 417: cleanup(0); ! 418: } ! 419: ! 420: #ifndef SYSIII ! 421: struct sgttyb Hupvec; ! 422: #endif ! 423: ! 424: /*** ! 425: * cleanup(code) cleanup and exit with "code" status ! 426: * int code; ! 427: */ ! 428: ! 429: cleanup(code) ! 430: register int code; ! 431: { ! 432: register int ret; ! 433: register char *ttyn; ! 434: ! 435: signal(SIGINT, SIG_IGN); ! 436: signal(SIGHUP, SIG_IGN); ! 437: rmlock(CNULL); ! 438: clsacu(); ! 439: logcls(); ! 440: if (Role == SLAVE) { ! 441: if (!Unet) { ! 442: #ifdef SYSIII ! 443: Savettyb.c_cflag |= HUPCL; ! 444: ret = ioctl(0, TCSETA, &Savettyb); ! 445: #endif ! 446: #ifndef SYSIII ! 447: /* rti!trt: use more robust hang up sequence */ ! 448: ret = ioctl(0, TIOCHPCL, STBNULL); ! 449: ret = ioctl(0, TIOCGETP, &Hupvec); ! 450: Hupvec.sg_ispeed = B0; ! 451: Hupvec.sg_ospeed = B0; ! 452: ret = ioctl(0, TIOCSETP, &Hupvec); ! 453: sleep(2); ! 454: ret = ioctl(0, TIOCSETP, &Savettyb); ! 455: #endif ! 456: DEBUG(4, "ret ioctl - %d\n", ret); ! 457: } ! 458: ttyn = ttyname(Ifn); ! 459: if (ttyn != NULL) ! 460: chmod(ttyn, 0600); ! 461: } ! 462: if (Ofn != -1) { ! 463: if (Role == MASTER) ! 464: write(Ofn, EOTMSG, strlen(EOTMSG)); ! 465: close(Ifn); ! 466: close(Ofn); ! 467: } ! 468: DEBUG(1, "exit code %d\n", code); ! 469: if (code == 0) ! 470: xuuxqt(); ! 471: exit(code); ! 472: } ! 473: ! 474: /*** ! 475: * onintr(inter) interrupt - remove locks and exit ! 476: */ ! 477: ! 478: onintr(inter) ! 479: register int inter; ! 480: { ! 481: char str[30]; ! 482: signal(inter, SIG_IGN); ! 483: sprintf(str, "SIGNAL %d", inter); ! 484: logent(str, "CAUGHT"); ! 485: systat(Rmtname, SS_FAIL, str); ! 486: cleanup(inter); ! 487: } ! 488: ! 489: /* changed to single version of intrEXIT. Is this okay? rti!trt */ ! 490: intrEXIT(signo) ! 491: int signo; ! 492: { ! 493: #ifdef SIGIO ! 494: /* if using 4.2 signal mechanism, must unblock all signal handlers */ ! 495: sigsetmask(0); ! 496: #endif ! 497: signal(signo, SIG_DFL); ! 498: setgid(getgid()); ! 499: setuid(getuid()); ! 500: abort(); ! 501: } ! 502: /* ! 503: * Catch a special signal ! 504: * (SIGFPE, ugh), and toggle debugging between 0 and 30. ! 505: * Handy for looking in on long running uucicos. ! 506: */ ! 507: setdebug() ! 508: { ! 509: if (Debug < 30) ! 510: Debug = 30; ! 511: else ! 512: Debug = 0; ! 513: } ! 514: ! 515: ! 516: /*** ! 517: * fixmode(tty) fix kill/echo/raw on line ! 518: * ! 519: * return codes: none ! 520: */ ! 521: ! 522: fixmode(tty) ! 523: register int tty; ! 524: { ! 525: #ifdef SYSIII ! 526: struct termio ttbuf; ! 527: #endif ! 528: #ifndef SYSIII ! 529: struct sgttyb ttbuf; ! 530: #endif ! 531: register int ret; ! 532: ! 533: if (Unet) ! 534: return; ! 535: #ifdef SYSIII ! 536: ioctl(tty, TCGETA, &ttbuf); ! 537: ttbuf.c_iflag = ttbuf.c_oflag = ttbuf.c_lflag = (ushort)0; ! 538: ttbuf.c_cflag &= (CBAUD); ! 539: ttbuf.c_cflag |= (CS8|CREAD); ! 540: ttbuf.c_cc[VMIN] = 6; ! 541: ttbuf.c_cc[VTIME] = 1; ! 542: ret = ioctl(tty, TCSETA, &ttbuf); ! 543: #endif ! 544: #ifndef SYSIII ! 545: ioctl(tty, TIOCGETP, &ttbuf); ! 546: ttbuf.sg_flags = (ANYP | RAW); ! 547: ret = ioctl(tty, TIOCSETP, &ttbuf); ! 548: #endif ! 549: ASSERT(ret >= 0, "STTY FAILED", "", ret); ! 550: #ifndef SYSIII ! 551: ioctl(tty, TIOCEXCL, STBNULL); ! 552: #endif ! 553: } ! 554: ! 555: ! 556: /*** ! 557: * timeout() catch SIGALRM routine ! 558: */ ! 559: ! 560: timeout() ! 561: { ! 562: logent(Rmtname, "TIMEOUT"); ! 563: systat(Rmtname, SS_FAIL, "TIMEOUT"); ! 564: longjmp(Sjbuf, 1); ! 565: } ! 566: ! 567: static char * ! 568: pskip(p) ! 569: register char *p; ! 570: { ! 571: while( *p && *p != ' ' ) ! 572: ++p; ! 573: if( *p ) *p++ = 0; ! 574: return(p); ! 575: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.