|
|
1.1 ! root 1: /* %W% ! 2: ! 3: * uucp file transfer program: ! 4: * to place a call to a remote machine, login, and ! 5: * copy files between the two machines. ! 6: ! 7: */ ! 8: #include "uucp.h" ! 9: VERSION(%W%); ! 10: ! 11: #ifndef V7 ! 12: #include <sys/sysmacros.h> ! 13: #endif ! 14: ! 15: jmp_buf Sjbuf; ! 16: extern int Errorrate; ! 17: char uuxqtarg[MAXBASENAME] = {'\0'}; ! 18: ! 19: #define USAGE "[-xNUM] [-r[0|1]] -sSYSTEM" ! 20: ! 21: extern void closedem(); ! 22: ! 23: main(argc, argv, envp) ! 24: char *argv[]; ! 25: char **envp; ! 26: { ! 27: extern onintr(), timeout(); ! 28: extern intrEXIT(); ! 29: extern char *pskip(); ! 30: int ret, seq, exitcode; ! 31: char file[NAMESIZE]; ! 32: char msg[BUFSIZ], *p, *q; ! 33: char xflag[6]; /* -xN N is single digit */ ! 34: char *ttyn; ! 35: char cb[128]; ! 36: time_t ts, tconv; ! 37: #ifndef V7 ! 38: long minulimit, dummy; ! 39: #endif V7 ! 40: ! 41: Uid = getuid(); ! 42: Euid = geteuid(); /* this should be UUCPUID */ ! 43: if (Uid == 0) ! 44: setuid(UUCPUID); /* fails in ATTSV, but so what? */ ! 45: Env = envp; ! 46: Role = SLAVE; ! 47: strcpy(Logfile, LOGCICO); ! 48: *Rmtname = NULLCHAR; ! 49: ! 50: closedem(); ! 51: time(&Nstat.t_qtime); ! 52: tconv = Nstat.t_start = Nstat.t_qtime; ! 53: strcpy(Progname, "uucico"); ! 54: Pchar = 'C'; ! 55: (void) signal(SIGILL, intrEXIT); ! 56: (void) signal(SIGTRAP, intrEXIT); ! 57: (void) signal(SIGIOT, intrEXIT); ! 58: (void) signal(SIGEMT, intrEXIT); ! 59: (void) signal(SIGFPE, intrEXIT); ! 60: (void) signal(SIGBUS, intrEXIT); ! 61: (void) signal(SIGSEGV, intrEXIT); ! 62: (void) signal(SIGSYS, intrEXIT); ! 63: (void) signal(SIGPIPE, SIG_IGN); ! 64: (void) signal(SIGINT, onintr); ! 65: (void) signal(SIGHUP, onintr); ! 66: (void) signal(SIGQUIT, onintr); ! 67: (void) signal(SIGTERM, onintr); ! 68: #ifdef ATTSV ! 69: (void) signal(SIGUSR1, SIG_IGN); ! 70: (void) signal(SIGUSR2, SIG_IGN); ! 71: #endif ! 72: ret = guinfo(Euid, User); ! 73: ASSERT(ret == 0, "BAD UID ", "", ret); ! 74: strncpy(Uucp, User, NAMESIZE); ! 75: ! 76: setuucp(User); ! 77: ret = guinfo(Uid, Loginuser); ! 78: ASSERT(ret == 0, "BAD LOGIN_UID ", "", ret); ! 79: ! 80: *xflag = NULLCHAR; ! 81: Ifn = Ofn = -1; ! 82: while ((ret = getopt(argc, argv, "d:r:s:x:")) != EOF) { ! 83: switch (ret) { ! 84: case 'd': ! 85: Spool = optarg; ! 86: break; ! 87: case 'r': ! 88: Role = atoi(optarg); ! 89: break; ! 90: case 's': ! 91: /* avoid 2 searches of the systems file ! 92: if (versys(optarg, 0)) { ! 93: DEBUG(4, "%s not in Systems file\n", optarg); ! 94: cleanup(101); ! 95: } ! 96: */ ! 97: strncpy(Rmtname, optarg, MAXBASENAME); ! 98: Rmtname[MAXBASENAME] = '\0'; ! 99: /* set args for possible xuuxqt call */ ! 100: strcpy(uuxqtarg, Rmtname); ! 101: break; ! 102: case 'x': ! 103: Debug = atoi(optarg); ! 104: if (Debug <= 0) ! 105: Debug = 1; ! 106: if (Debug > 9) ! 107: Debug = 9; ! 108: (void) sprintf(xflag, "-x%d", Debug); ! 109: break; ! 110: default: ! 111: (void) fprintf(stderr, "\tusage: %s %s\n", ! 112: Progname, USAGE); ! 113: exit(1); ! 114: } ! 115: } ! 116: ! 117: if (Role == MASTER) { ! 118: if (*Rmtname == NULLCHAR) { ! 119: DEBUG(5, "No -s specified\n" , ""); ! 120: cleanup(101); ! 121: } ! 122: /* get Myname - it depends on who I'm calling--Rmtname */ ! 123: (void) mchFind(Rmtname); ! 124: myName(Myname); ! 125: if (EQUALSN(Rmtname, Myname, SYSNSIZE)) { ! 126: DEBUG(5, "This system specified: -sMyname: %s, ", Myname); ! 127: cleanup(101); ! 128: } ! 129: } ! 130: ! 131: ASSERT(chdir(Spool) == 0, Ct_CHDIR, Spool, errno); ! 132: strcpy(Wrkdir, Spool); ! 133: ! 134: if (Role == SLAVE) { ! 135: ! 136: /* ! 137: * initial handshake ! 138: */ ! 139: ret = savline(); ! 140: Ifn = 0; ! 141: Ofn = 1; ! 142: fixline(Ifn, 0, D_ACU); ! 143: freopen(RMTDEBUG, "a", stderr); ! 144: setbuf(stderr, (char *)NULL); ! 145: /* get MyName - use logFind to check PERMISSIONS file */ ! 146: (void) logFind(Loginuser, ""); ! 147: myName(Myname); ! 148: ! 149: DEBUG(4,"cico.c: Myname - %s\n",Myname); ! 150: DEBUG(4,"cico.c: Loginuser - %s\n",Loginuser); ! 151: Nstat.t_scall = times(&Nstat.t_tga); ! 152: (void) sprintf(msg, "here=%s", Myname); ! 153: omsg('S', msg, Ofn); ! 154: (void) signal(SIGALRM, timeout); ! 155: (void) alarm(2 * MAXMSGTIME); /* give slow machines a second chance */ ! 156: if (setjmp(Sjbuf)) { ! 157: ! 158: /* ! 159: * timed out ! 160: */ ! 161: ret = restline(); ! 162: rmlock(CNULL); ! 163: exit(0); ! 164: } ! 165: for (;;) { ! 166: ret = imsg(msg, Ifn); ! 167: if (ret != 0) { ! 168: (void) alarm(0); ! 169: ret = restline(); ! 170: rmlock(CNULL); ! 171: exit(0); ! 172: } ! 173: if (msg[0] == 'S') ! 174: break; ! 175: } ! 176: Nstat.t_ecall = times(&Nstat.t_tga); ! 177: (void) alarm(0); ! 178: q = &msg[1]; ! 179: p = pskip(q); ! 180: strncpy(Rmtname, q, MAXBASENAME); ! 181: Rmtname[MAXBASENAME] = '\0'; ! 182: ! 183: seq = 0; ! 184: while (*p == '-') { ! 185: q = pskip(p); ! 186: switch(*(++p)) { ! 187: case 'x': ! 188: Debug = atoi(++p); ! 189: if (Debug <= 0) ! 190: Debug = 1; ! 191: break; ! 192: case 'Q': ! 193: seq = atoi(++p); ! 194: break; ! 195: default: ! 196: break; ! 197: } ! 198: p = q; ! 199: } ! 200: DEBUG(4, "sys-%s\n", Rmtname); ! 201: ! 202: #ifdef NOSTRANGERS ! 203: /* here's the place to look the remote system up in the Systems file. ! 204: * If the command NOSTRANGERS is executable and ! 205: /* If they're not in my file then hang up */ ! 206: if ( (access(NOSTRANGERS, 1) == 0) && versys(Rmtname, 1)) { ! 207: char unkcmd[64]; ! 208: register char *p; ! 209: ! 210: omsg('R', "You are unknown to me", Ofn); ! 211: for (p = Rmtname; *p; p++) ! 212: if (*p == '\'') ! 213: *p = ' '; /* cheap hack. who cares. */ ! 214: (void) sprintf(unkcmd, "%s '%s'", NOSTRANGERS, Rmtname); ! 215: system(unkcmd); ! 216: cleanup(101); ! 217: } ! 218: #endif NOSTRANGERS ! 219: ! 220: if (mlock(Rmtname)) { ! 221: omsg('R', "LCK", Ofn); ! 222: cleanup(101); ! 223: } ! 224: ! 225: /* validate login using PERMISSIONS file */ ! 226: if (logFind(Loginuser, Rmtname) == FAIL) { ! 227: Uerror = SS_BAD_LOG_MCH; ! 228: logent(UERRORTEXT, "FAILED"); ! 229: systat(Rmtname, SS_BAD_LOG_MCH, UERRORTEXT, ! 230: Retrytime); ! 231: omsg('R', "LOGIN", Ofn); ! 232: cleanup(101); ! 233: } ! 234: ! 235: ret = callBack(); ! 236: DEBUG(4,"return from callcheck: %s",ret ? "TRUE" : "FALSE"); ! 237: if (ret==TRUE) { ! 238: (void) signal(SIGINT, SIG_IGN); ! 239: (void) signal(SIGHUP, SIG_IGN); ! 240: omsg('R', "CB", Ofn); ! 241: logent("CALLBACK", "REQUIRED"); ! 242: ! 243: /* ! 244: * set up for call back ! 245: */ ! 246: systat(Rmtname, SS_CALLBACK, "CALL BACK", Retrytime); ! 247: gename(CMDPRE, Rmtname, 'C', file); ! 248: (void) close(creat(file, CFILEMODE)); ! 249: xuucico(Rmtname); ! 250: cleanup(101); ! 251: } ! 252: ! 253: if (callok(Rmtname) == SS_SEQBAD) { ! 254: Uerror = SS_SEQBAD; ! 255: logent(UERRORTEXT, "PREVIOUS"); ! 256: omsg('R', "BADSEQ", Ofn); ! 257: cleanup(101); ! 258: } ! 259: ! 260: if ((ret = gnxseq(Rmtname)) == seq) { ! 261: omsg('R', "OK", Ofn); ! 262: cmtseq(); ! 263: } else { ! 264: Uerror = SS_SEQBAD; ! 265: systat(Rmtname, SS_SEQBAD, UERRORTEXT, Retrytime); ! 266: logent(UERRORTEXT, "HANDSHAKE FAILED"); ! 267: ulkseq(); ! 268: omsg('R', "BADSEQ", Ofn); ! 269: cleanup(101); ! 270: } ! 271: if ((ttyn = ttyname(Ifn)) != NULL) ! 272: strcpy(Dc, BASENAME(ttyn, '/')); ! 273: else ! 274: strcpy(Dc, "notty"); ! 275: /* set args for possible xuuxqt call */ ! 276: strcpy(uuxqtarg, Rmtname); ! 277: } ! 278: ! 279: strcpy(User, Uucp); ! 280: /* ! 281: * Ensure reasonable ulimit (MINULIMIT) ! 282: */ ! 283: ! 284: #ifndef V7 ! 285: minulimit = ulimit(1,dummy); ! 286: ASSERT(minulimit >= MINULIMIT, "ULIMIT TOO SMALL", ! 287: Loginuser, minulimit); ! 288: #endif ! 289: if (Role == MASTER && callok(Rmtname) != 0) { ! 290: logent("SYSTEM STATUS", "CAN NOT CALL"); ! 291: cleanup(101); ! 292: } ! 293: ! 294: chremdir(Rmtname); ! 295: ! 296: (void) strcpy(Wrkdir, RemSpool); ! 297: if (Role == MASTER) { ! 298: ! 299: /* ! 300: * master part ! 301: */ ! 302: (void) signal(SIGINT, SIG_IGN); ! 303: (void) signal(SIGHUP, SIG_IGN); ! 304: (void) signal(SIGQUIT, SIG_IGN); ! 305: if (Ifn != -1 && Role == MASTER) { ! 306: (void) write(Ofn, EOTMSG, strlen(EOTMSG)); ! 307: (void) close(Ofn); ! 308: (void) close(Ifn); ! 309: Ifn = Ofn = -1; ! 310: rmlock(CNULL); ! 311: sleep(3); ! 312: } ! 313: (void) sprintf(msg, "call to %s ", Rmtname); ! 314: if (mlock(Rmtname) != 0) { ! 315: logent(msg, "LOCKED"); ! 316: CDEBUG(1, "Currently Talking With %s\n", ! 317: Rmtname); ! 318: cleanup(100); ! 319: } ! 320: Nstat.t_scall = times(&Nstat.t_tga); ! 321: Ofn = Ifn = conn(Rmtname); ! 322: Nstat.t_ecall = times(&Nstat.t_tga); ! 323: if (Ofn < 0) { ! 324: delock(Rmtname); ! 325: logent(UERRORTEXT, "CONN FAILED"); ! 326: systat(Rmtname, Uerror, UERRORTEXT, Retrytime); ! 327: cleanup(101); ! 328: } else { ! 329: logent(msg, "SUCCEEDED"); ! 330: ttyn = ttyname(Ifn); ! 331: } ! 332: ! 333: if (setjmp(Sjbuf)) { ! 334: delock(Rmtname); ! 335: Uerror = SS_LOGIN_FAILED; ! 336: logent(Rmtname, UERRORTEXT); ! 337: systat(Rmtname, SS_LOGIN_FAILED, ! 338: UERRORTEXT, Retrytime); ! 339: DEBUG(4, "%s - failed\n", UERRORTEXT); ! 340: cleanup(101); ! 341: } ! 342: (void) signal(SIGALRM, timeout); ! 343: /* give slow guys lots of time to thrash */ ! 344: (void) alarm(3 * MAXMSGTIME); ! 345: for (;;) { ! 346: ret = imsg(msg, Ifn); ! 347: if (ret != 0) { ! 348: continue; /* try again */ ! 349: } ! 350: if (msg[0] == 'S') ! 351: break; ! 352: } ! 353: (void) alarm(0); ! 354: if(EQUALSN("here=", &msg[1], 5)){ ! 355: /* ! 356: /* this is a problem. We'd like to compare with an ! 357: * untruncated Rmtname but we fear incompatability. ! 358: * So we'll look at most 6 chars (at most). ! 359: */ ! 360: if(!EQUALSN(&msg[6], Rmtname, (strlen(Rmtname)< 7 ? ! 361: strlen(Rmtname) : 6))){ ! 362: delock(Rmtname); ! 363: Uerror = SS_WRONG_MCH; ! 364: logent(&msg[6], UERRORTEXT); ! 365: systat(Rmtname, SS_WRONG_MCH, UERRORTEXT, ! 366: Retrytime); ! 367: DEBUG(4, "%s - failed\n", UERRORTEXT); ! 368: cleanup(101); ! 369: } ! 370: } ! 371: CDEBUG(1,"Login Successful: System=%s\n",&msg[6]); ! 372: seq = gnxseq(Rmtname); ! 373: (void) sprintf(msg, "%s -Q%d %s", Myname, seq, xflag); ! 374: omsg('S', msg, Ofn); ! 375: (void) alarm(2 * MAXMSGTIME); /* give slow guys some thrash time */ ! 376: for (;;) { ! 377: ret = imsg(msg, Ifn); ! 378: DEBUG(3, "msg-%s\n", msg); ! 379: if (ret != 0) { ! 380: (void) alarm(0); ! 381: delock(Rmtname); ! 382: ulkseq(); ! 383: cleanup(101); ! 384: } ! 385: if (msg[0] == 'R') ! 386: break; ! 387: } ! 388: (void) alarm(0); ! 389: ! 390: /* check for rejects from remote */ ! 391: Uerror = 0; ! 392: if (EQUALS(&msg[1], "LCK")) ! 393: Uerror = SS_RLOCKED; ! 394: else if (EQUALS(&msg[1], "LOGIN")) ! 395: Uerror = SS_RLOGIN; ! 396: else if (EQUALS(&msg[1], "CB")) ! 397: Uerror = SS_CALLBACK; ! 398: else if (EQUALS(&msg[1], "You are unknown to me")) ! 399: Uerror = SS_RUNKNOWN; ! 400: else if (EQUALS(&msg[1], "BADSEQ")) ! 401: Uerror = SS_SEQBAD; ! 402: else if (!EQUALS(&msg[1], "OK")) ! 403: Uerror = SS_UNKNOWN_RESPONSE; ! 404: if (Uerror) { ! 405: delock(Rmtname); ! 406: systat(Rmtname, Uerror, UERRORTEXT, Retrytime); ! 407: logent(UERRORTEXT, "HANDSHAKE FAILED"); ! 408: CDEBUG(1, "HANDSHAKE FAILED: %s\n", UERRORTEXT); ! 409: ulkseq(); ! 410: cleanup(101); ! 411: } ! 412: cmtseq(); ! 413: } ! 414: DEBUG(4, " Rmtname %s, ", Rmtname); ! 415: DEBUG(4, "Role %s, ", Role ? "MASTER" : "SLAVE"); ! 416: DEBUG(4, "Ifn - %d, ", Ifn); ! 417: DEBUG(4, "Loginuser - %s\n", Loginuser); ! 418: ! 419: /* alarm/setjmp added here due to experience with uucico ! 420: * hanging for hours in imsg(). ! 421: */ ! 422: if (setjmp(Sjbuf)) { ! 423: delock(Rmtname); ! 424: logent("startup", "TIMEOUT"); ! 425: DEBUG(4, "%s - timeout\n", "startup"); ! 426: cleanup(101); ! 427: } ! 428: (void) alarm(MAXSTART); ! 429: ret = startup(Role); ! 430: (void) alarm(0); ! 431: ! 432: if (ret != SUCCESS) { ! 433: delock(Rmtname); ! 434: logent("startup", "FAILED"); ! 435: Uerror = SS_STARTUP; ! 436: CDEBUG(1, "%s\n", UERRORTEXT); ! 437: systat(Rmtname, Uerror, UERRORTEXT, Retrytime); ! 438: exitcode = 101; ! 439: } else { ! 440: logent("startup", "OK"); ! 441: systat(Rmtname, SS_INPROGRESS, UTEXT(SS_INPROGRESS),Retrytime); ! 442: Nstat.t_sftp = times(&Nstat.t_tga); ! 443: ! 444: exitcode = cntrl(Role); ! 445: Nstat.t_eftp = times(&Nstat.t_tga); ! 446: DEBUG(4, "cntrl - %d\n", exitcode); ! 447: (void) signal(SIGINT, SIG_IGN); ! 448: (void) signal(SIGHUP, SIG_IGN); ! 449: (void) signal(SIGALRM, timeout); ! 450: ! 451: if (exitcode == 0) { ! 452: (void) time(&ts); ! 453: (void) sprintf(cb, "conversation complete %s %ld", ! 454: Dc, ts - tconv); ! 455: logent(cb, "OK"); ! 456: systat(Rmtname, SS_OK, UTEXT(SS_OK), Retrytime); ! 457: ! 458: } else { ! 459: logent("conversation complete", "FAILED"); ! 460: systat(Rmtname, SS_CONVERSATION, ! 461: UTEXT(SS_CONVERSATION), 0); ! 462: } ! 463: (void) alarm(2 * MAXMSGTIME); /* give slow guys some thrash time */ ! 464: omsg('O', "OOOOO", Ofn); ! 465: CDEBUG(4, "send OO %d,", ret); ! 466: if (!setjmp(Sjbuf)) { ! 467: for (;;) { ! 468: omsg('O', "OOOOO", Ofn); ! 469: ret = imsg(msg, Ifn); ! 470: if (ret != 0) ! 471: break; ! 472: if (msg[0] == 'O') ! 473: break; ! 474: } ! 475: } ! 476: (void) alarm(0); ! 477: } ! 478: cleanup(exitcode); ! 479: } ! 480: ! 481: /* ! 482: * clean and exit with "code" status ! 483: */ ! 484: cleanup(code) ! 485: register int code; ! 486: { ! 487: int ret; ! 488: ! 489: (void) signal(SIGINT, SIG_IGN); ! 490: (void) signal(SIGHUP, SIG_IGN); ! 491: rmlock(CNULL); ! 492: closedem(); ! 493: if (Role == SLAVE) { ! 494: ret = restline(); ! 495: DEBUG(4, "ret restline - %d\n", ret); ! 496: sethup(0); ! 497: } ! 498: if (Ofn != -1) { ! 499: if (Role == MASTER) ! 500: (void) write(Ofn, EOTMSG, strlen(EOTMSG)); ! 501: (void) close(Ifn); ! 502: (void) close(Ofn); ! 503: } ! 504: DEBUG(4, "exit code %d\n", code); ! 505: CDEBUG(1, "Conversation Complete: Status %s\n\n", ! 506: code ? "FAILED" : "SUCCEEDED"); ! 507: ! 508: cleanTM(); ! 509: if (code == 0) ! 510: xuuxqt(uuxqtarg); ! 511: exit(code); ! 512: } ! 513: ! 514: short TM_cnt = 0; ! 515: char TM_name[MAXNAMESIZE]; ! 516: ! 517: cleanTM() ! 518: { ! 519: register int i; ! 520: char tm_name[MAXNAMESIZE]; ! 521: ! 522: DEBUG(7,"TM_cnt: %d\n",TM_cnt); ! 523: for(i=0; i < TM_cnt; i++) { ! 524: (void) sprintf(tm_name, "%s.%3.3d", TM_name, i); ! 525: DEBUG(7, "tm_name: %s\n", tm_name); ! 526: unlink(tm_name); ! 527: } ! 528: } ! 529: ! 530: TMname(file, pnum) ! 531: char *file; ! 532: { ! 533: ! 534: (void) sprintf(file, "%s/TM.%.5d.%.3d", RemSpool, pnum, TM_cnt); ! 535: if (TM_cnt == 0) ! 536: (void) sprintf(TM_name, "%s/TM.%.5d", RemSpool, pnum); ! 537: DEBUG(7, "TMname(%s)\n", file); ! 538: TM_cnt++; ! 539: } ! 540: ! 541: /* ! 542: * intrrupt - remove locks and exit ! 543: */ ! 544: onintr(inter) ! 545: register int inter; ! 546: { ! 547: char str[30]; ! 548: /* I'm putting a test for zero here because I saw it happen ! 549: * and don't know how or why, but it seemed to then loop ! 550: * here for ever? ! 551: */ ! 552: if (inter == 0) ! 553: exit(99); ! 554: (void) signal(inter, SIG_IGN); ! 555: (void) sprintf(str, "SIGNAL %d", inter); ! 556: logent(str, "CAUGHT"); ! 557: cleanup(inter); ! 558: } ! 559: ! 560: /*ARGSUSED*/ ! 561: intrEXIT(inter) ! 562: { ! 563: char cb[10]; ! 564: extern int errno; ! 565: ! 566: (void) sprintf(cb, "%d", errno); ! 567: logent("INTREXIT", cb); ! 568: (void) signal(SIGIOT, SIG_DFL); ! 569: (void) signal(SIGILL, SIG_DFL); ! 570: rmlock(CNULL); ! 571: closedem(); ! 572: (void) setuid(Uid); ! 573: abort(); ! 574: } ! 575: ! 576: /* ! 577: * catch SIGALRM routine ! 578: */ ! 579: timeout() ! 580: { ! 581: longjmp(Sjbuf, 1); ! 582: } ! 583: ! 584: static char * ! 585: pskip(p) ! 586: register char *p; ! 587: { ! 588: while( *p && *p != ' ' ) ! 589: ++p; ! 590: if( *p ) *p++ = 0; ! 591: return(p); ! 592: } ! 593: ! 594: void ! 595: closedem() ! 596: { ! 597: register i; ! 598: ! 599: for(i=3;i<_NFILE;i++) ! 600: (void) close(i); ! 601: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.