1: #include "uucp.h" 2: #include "uucpdefs.h" 3: #include <signal.h> 4: #include <sgtty.h> 5: #include <setjmp.h> 6: 7: jmp_buf Sjbuf; 8: /* call fail text */ 9: char *Stattext[] = { 10: "", 11: "BAD SYSTEM", 12: "WRONG TIME", 13: "SYSTEM LOCKED", 14: "NO DEVICE", 15: "DIAL FAILED", 16: "LOGIN FAILED", 17: "BAD SEQUENCE" 18: }; 19: 20: int Role = 0; 21: 22: /* call fail codes */ 23: int Stattype[] = {0, 0, 0, 0, 24: SS_NODEVICE, SS_FAIL, SS_FAIL, SS_BADSEQ 25: }; 26: 27: 28: int Errorrate = 0; 29: struct sgttyb Savettyb; 30: 31: /******* 32: * cico - this program is used to place a call to a 33: * remote machine, login, and copy files between the two machines. 34: */ 35: 36: main(argc, argv) 37: char *argv[]; 38: { 39: int ret, seq; 40: int onesys = 0; 41: char wkpre[NAMESIZE], file[NAMESIZE]; 42: char msg[BUFSIZ], *p, *q; 43: extern onintr(), timeout(); 44: extern intrINT(); 45: extern intrHUP(); 46: extern intrQUIT(); 47: extern intrTERM(); 48: extern intrEXIT(); 49: extern char *pskip(); 50: char rflags[30]; 51: char *ttyn; 52: char *ttyname(); 53: 54: signal(SIGILL, intrEXIT); 55: signal(SIGTRAP, intrEXIT); 56: signal(SIGIOT, intrEXIT); 57: signal(SIGEMT, intrEXIT); 58: signal(SIGFPE, intrEXIT); 59: signal(SIGBUS, intrEXIT); 60: signal(SIGSEGV, intrEXIT); 61: signal(SIGSYS, intrEXIT); 62: signal(SIGINT, intrINT); 63: signal(SIGHUP, intrHUP); 64: signal(SIGQUIT, intrQUIT); 65: signal(SIGTERM, intrTERM); 66: ret = guinfo(getuid(), User, msg); 67: strcpy(Loginuser, User); 68: ASSERT(ret == 0, "BAD UID ret %d", ret); 69: 70: rflags[0] = '\0'; 71: strcpy(Rmtname, MYNAME); 72: Ifn = Ofn = -1; 73: while(argc>1 && argv[1][0] == '-'){ 74: switch(argv[1][1]){ 75: case 'd': 76: Spool = &argv[1][2]; 77: break; 78: /* 79: * case 'E': 80: * Errorrate = atoi(&argv[1][2]); 81: * if (Errorrate <= 0) 82: * Errorrate = 100; 83: * break; 84: * case 'g': 85: * Pkdrvon = 1; 86: * break; 87: * case 'G': 88: * Pkdrvon = 1; 89: * strcat(rflags, " -g "); 90: * break; 91: */ 92: case 'r': 93: Role = atoi(&argv[1][2]); 94: break; 95: case 's': 96: sprintf(Rmtname, "%.7s", &argv[1][2]); 97: if (Rmtname[0] != '\0') 98: onesys = 1; 99: break; 100: case 'x': 101: Debug = atoi(&argv[1][2]); 102: if (Debug <= 0) 103: Debug = 1; 104: strcat(rflags, argv[1]); 105: break; 106: default: 107: printf("unknown flag %s\n", argv[1]); 108: break; 109: } 110: --argc; argv++; 111: } 112: 113: chdir(Spool); 114: strcpy(Wrkdir, Spool); 115: 116: if (Role == SLAVE) { 117: /* initial handshake */ 118: onesys = 1; 119: ret = ioctl(0, TIOCGETP, &Savettyb); 120: Savettyb.sg_flags |= ECHO; 121: Savettyb.sg_flags &= ~RAW; 122: Ifn = 0; 123: Ofn = 1; 124: fixmode(Ifn); 125: fclose(stderr); 126: fopen(RMTDEBUG, "w"); 127: chmod(RMTDEBUG, 0666); 128: omsg('S', "here", Ofn); 129: signal(SIGALRM, timeout); 130: alarm(MAXMSGTIME); 131: if (setjmp(Sjbuf)) { 132: /* timed out */ 133: ret = ioctl(0, TIOCSETP, &Savettyb); 134: exit(0); 135: } 136: for (;;) { 137: ret = imsg(msg, Ifn); 138: if (ret != 0) { 139: alarm(0); 140: ret = ioctl(0, TIOCSETP, &Savettyb); 141: exit(0); 142: } 143: if (msg[0] == 'S') 144: break; 145: } 146: alarm(0); 147: DEBUG(4, "msg-%s,", msg); 148: q = &msg[1]; 149: p = pskip(q); 150: sprintf(Rmtname, "%.7s", q); 151: DEBUG(4, "sys-%s\n", Rmtname); 152: if (mlock(Rmtname)) { 153: omsg('R', "LCK", Ofn); 154: cleanup(0); 155: } 156: else if (callback(Loginuser)) { 157: signal(SIGINT, SIG_IGN); 158: signal(SIGHUP, SIG_IGN); 159: omsg('R', "CB", Ofn); 160: DEBUG(4, "CALLBACK Role %d\n", Role); 161: logent("CALLBACK", "REQUIRED"); 162: /* set up for call back */ 163: systat(Rmtname, SS_CALLBACK, "CALL BACK"); 164: gename(CMDPRE, Rmtname, 'C', file); 165: close(creat(file, 0666)); 166: chmod(file, 0666); 167: xuucico(Rmtname); 168: cleanup(0); 169: } 170: seq = 0; 171: while (*p == '-') { 172: q = pskip(p); 173: switch(*(++p)) { 174: case 'g': 175: Pkdrvon = 1; 176: break; 177: case 'x': 178: Debug = atoi(++p); 179: if (Debug <= 0) 180: Debug = 1; 181: break; 182: case 'Q': 183: seq = atoi(++p); 184: break; 185: default: 186: break; 187: } 188: p = q; 189: } 190: if (callok(Rmtname) == SS_BADSEQ) { 191: logent("BADSEQ", "PREVIOUS"); 192: omsg('R', "BADSEQ", Ofn); 193: cleanup(0); 194: } 195: if ((ret = gnxseq(Rmtname)) == seq) { 196: omsg('R', "OK", Ofn); 197: cmtseq(); 198: } 199: else { 200: systat(Rmtname, Stattype[7], Stattext[7]); 201: logent("BAD SEQ", "HANDSHAKE FAILED"); 202: ulkseq(); 203: omsg('R', "BADSEQ", Ofn); 204: cleanup(0); 205: } 206: } 207: loop: 208: if (!onesys) { 209: ret = gnsys(Rmtname, Spool, CMDPRE); 210: if (ret == FAIL) 211: cleanup(100); 212: if (ret == 0) 213: cleanup(0); 214: } 215: else if (Role == MASTER && callok(Rmtname) != 0) { 216: logent("SYSTEM STATUS", "CAN NOT CALL"); 217: cleanup(0); 218: } 219: 220: sprintf(wkpre, "%c.%.7s", CMDPRE, Rmtname); 221: 222: if (Role == MASTER) { 223: /* master part */ 224: signal(SIGINT, SIG_IGN); 225: signal(SIGHUP, SIG_IGN); 226: signal(SIGQUIT, SIG_IGN); 227: if (!iswrk(file, "chk", Spool, wkpre) && !onesys) { 228: logent(Rmtname, "NO WORK"); 229: cleanup(0); 230: } 231: if (Ifn != -1 && Role == MASTER) { 232: write(Ofn, EOTMSG, strlen(EOTMSG)); 233: close(Ofn); 234: close(Ifn); 235: Ifn = Ofn = -1; 236: rmlock(NULL); 237: clsacu(); 238: sleep(3); 239: } 240: sprintf(msg, "call to %s ", Rmtname); 241: if (mlock(Rmtname) != 0) { 242: logent(msg, "LOCKED"); 243: goto next; 244: } 245: Ofn = Ifn = conn(Rmtname); 246: if (Ofn < 0) { 247: logent(msg, "FAILED"); 248: systat(Rmtname, Stattype[-Ofn], 249: Stattext[-Ofn]); 250: goto next; 251: } 252: else { 253: logent(msg, "SUCCEEDED"); 254: } 255: 256: if (setjmp(Sjbuf)) 257: goto next; 258: signal(SIGALRM, timeout); 259: alarm(2 * MAXMSGTIME); 260: for (;;) { 261: ret = imsg(msg, Ifn); 262: if (ret != 0) { 263: alarm(0); 264: goto next; 265: } 266: if (msg[0] == 'S') 267: break; 268: } 269: alarm(MAXMSGTIME); 270: seq = gnxseq(Rmtname); 271: sprintf(msg, "%.7s -Q%d %s", Myname, seq, rflags); 272: omsg('S', msg, Ofn); 273: for (;;) { 274: ret = imsg(msg, Ifn); 275: DEBUG(4, "msg-%s\n", msg); 276: if (ret != 0) { 277: alarm(0); 278: ulkseq(); 279: goto next; 280: } 281: if (msg[0] == 'R') 282: break; 283: } 284: alarm(0); 285: if (msg[1] == 'B') { 286: /* bad sequence */ 287: logent("BAD SEQ", "HANDSHAKE FAILED"); 288: systat(Rmtname, Stattype[7], Stattext[7]); 289: ulkseq(); 290: goto next; 291: } 292: if (strcmp(&msg[1], "OK") != SAME) { 293: logent(&msg[1], "HANDSHAKE FAILED"); 294: ulkseq(); 295: goto next; 296: } 297: cmtseq(); 298: } 299: ttyn = ttyname(Ifn); 300: if (ttyn != NULL) 301: chmod(ttyn, 0600); 302: DEBUG(1, " Rmtname %s, ", Rmtname); 303: DEBUG(1, "my Role %s, ", Role ? "MASTER" : "SLAVE"); 304: DEBUG(1, "Spool - %s\n", Spool); 305: DEBUG(1, "Ifn - %d, ", Ifn); 306: DEBUG(1, "Ofn - %d, ", Ofn); 307: DEBUG(1, "Loginuser - %s\n", Loginuser); 308: 309: ret = startup(Role); 310: if (ret != SUCCESS) { 311: logent("startup", "FAILED"); 312: systat(Rmtname, SS_FAIL, "STARTUP"); 313: goto next; 314: } 315: else { 316: systat(Rmtname, SS_INPROGRESS, "TALKING"); 317: ret = cntrl(Role, wkpre); 318: DEBUG(1, "ret from cntrl - %d\n", ret); 319: signal(SIGINT, SIG_IGN); 320: signal(SIGHUP, SIG_IGN); 321: signal(SIGALRM, timeout); 322: if (ret == 0) 323: rmstat(Rmtname); 324: 325: else 326: systat(Rmtname, SS_FAIL, "CONVERSATION"); 327: alarm(MAXMSGTIME); 328: omsg('O', "OOOOO", Ofn); 329: DEBUG(4, "send OO %d,", ret); 330: if (!setjmp(Sjbuf)) { 331: for (;;) { 332: omsg('O', "OOOOO", Ofn); 333: ret = imsg(msg, Ifn); 334: if (ret != 0) 335: break; 336: if (msg[0] == 'O') 337: break; 338: } 339: } 340: alarm(0); 341: } 342: next: 343: if (!onesys) { 344: goto loop; 345: } 346: cleanup(0); 347: } 348: 349: 350: int Hupvec[] = {0, 0, 1}; 351: 352: /*** 353: * cleanup(code) cleanup and exit with "code" status 354: * int code; 355: */ 356: 357: cleanup(code) 358: int code; 359: { 360: int ret; 361: 362: signal(SIGINT, SIG_IGN); 363: signal(SIGHUP, SIG_IGN); 364: rmlock(NULL); 365: clsacu(); 366: logcls(); 367: if (Role == SLAVE) { 368: ret = ioctl(0, TIOCSETP, &Savettyb); 369: DEBUG(4, "\nIfn - %d, ", Ifn); 370: DEBUG(4, "ret ioctl - %d\n", ret); 371: DEBUG(4, "tty.flags %o,", Savettyb.sg_flags); 372: DEBUG(4, "tty.ispeed %d, ", Savettyb.sg_ispeed); 373: DEBUG(4, "tty.ospeed %d, ", Savettyb.sg_ospeed); 374: ret = ioctl(0, TIOCSETP, Hupvec); 375: DEBUG(4, "ret ioctl - %d\n", ret); 376: } 377: if (Ofn != -1) { 378: if (Role == MASTER) 379: write(Ofn, EOTMSG, strlen(EOTMSG)); 380: close(Ifn); 381: close(Ofn); 382: } 383: DEBUG(1, "exit code %d\n", code); 384: if (code == 0) 385: xuuxqt(); 386: exit(code); 387: } 388: 389: /*** 390: * onintr(inter) interrupt - remove locks and exit 391: */ 392: 393: onintr(inter) 394: int inter; 395: { 396: char str[30]; 397: signal(inter, SIG_IGN); 398: sprintf(str, "SIGNAL %d", inter); 399: logent(str, "CAUGHT"); 400: cleanup(inter); 401: } 402: 403: intrINT() { onintr(SIGINT);} 404: intrHUP() { onintr(SIGHUP);} 405: intrQUIT() { onintr(SIGQUIT);} 406: intrTERM() { onintr(SIGTERM);} 407: intrEXIT() {_exit(77);} 408: 409: /*** 410: * fixmode(tty) fix kill/echo/raw on line 411: * 412: * return codes: none 413: */ 414: 415: fixmode(tty) 416: int tty; 417: { 418: struct sgttyb ttbuf; 419: int ret; 420: 421: ioctl(tty, TIOCGETP, &ttbuf); 422: ttbuf.sg_flags |= (ANYP | RAW); 423: ttbuf.sg_flags &= ~(ECHO | ALLDELAY); 424: ret = ioctl(tty, TIOCSETP, &ttbuf); 425: ASSERT(ret >= 0, "RETURN FROM STTY %d", ret); 426: ioctl(tty, TIOCEXCL, 0); 427: return; 428: } 429: 430: 431: /*** 432: * timeout() catch SIGALRM routine 433: */ 434: 435: timeout() 436: { 437: longjmp(Sjbuf, 1); 438: } 439: 440: static char * 441: pskip(p) 442: register char *p; 443: { 444: while( *p && *p != ' ' ) 445: ++p; 446: if( *p ) *p++ = 0; 447: return(p); 448: }