|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)conn.c 5.3 (Berkeley) 8/13/83"; ! 3: #endif ! 4: ! 5: #include "uucp.h" ! 6: #include <signal.h> ! 7: #include <setjmp.h> ! 8: #include <ctype.h> ! 9: #include <sys/types.h> ! 10: #include <sys/time.h> ! 11: #include <errno.h> ! 12: #ifdef SYSIII ! 13: #include <termio.h> ! 14: #include <fcntl.h> ! 15: #endif ! 16: #ifndef SYSIII ! 17: #include <sgtty.h> ! 18: #endif ! 19: ! 20: #define MAXC 1000 ! 21: ! 22: extern jmp_buf Sjbuf; ! 23: extern int errno; ! 24: ! 25: /* Parity control during login procedure */ ! 26: #define P_ZERO 0 ! 27: #define P_ONE 1 ! 28: #define P_EVEN 2 ! 29: #define P_ODD 3 ! 30: char par_tab[128]; /* must be power of two */ ! 31: ! 32: int next_fd = -1; /* predicted fd to close interrupted opens */ ! 33: /* rti!trt, courtesy unc!smb */ ! 34: /*** ! 35: * alarmtr() - catch alarm routine for "expect". ! 36: */ ! 37: alarmtr() ! 38: { ! 39: signal(SIGALRM, alarmtr); ! 40: if (next_fd >= 0) { ! 41: if (close(next_fd)) ! 42: logent("FAIL", "ACU LINE CLOSE"); ! 43: next_fd = -1; ! 44: } ! 45: longjmp(Sjbuf, 1); ! 46: } ! 47: ! 48: /******* ! 49: * conn(system) ! 50: * char *system; ! 51: * ! 52: * conn - place a telephone call to system and ! 53: * login, etc. ! 54: * ! 55: * return codes: ! 56: * CF_SYSTEM: don't know system ! 57: * CF_TIME: wrong time to call ! 58: * CF_DIAL: call failed ! 59: * CF_NODEV: no devices available to place call ! 60: * CF_LOGIN: login/password dialog failed ! 61: * ! 62: * >0 - file no. - connect ok ! 63: * ! 64: */ ! 65: ! 66: int Dcf = -1; ! 67: ! 68: conn(system) ! 69: char *system; ! 70: { ! 71: int ret, nf; ! 72: register int fn, fnd; ! 73: char info[MAXC], *flds[MAXC/10]; ! 74: register FILE *fsys; ! 75: int fcode = 0; ! 76: ! 77: nf = 0; ! 78: fnd = 0; ! 79: ! 80: ! 81: fsys = fopen(SYSFILE, "r"); ! 82: ASSERT(fsys != NULL, "CAN'T OPEN", SYSFILE, 0); ! 83: ! 84: DEBUG(4, "finds %s\n", "called"); ! 85: while((nf = finds(fsys, system, info, flds)) > 0) { ! 86: DEBUG(4, "getto %s\n", "called"); ! 87: if ((fn = getto(flds)) > 0) { ! 88: fnd = 1; ! 89: Dcf = fn; ! 90: break; ! 91: } ! 92: fcode = (fn == FAIL ? CF_DIAL : fn); ! 93: } ! 94: fclose(fsys); ! 95: ! 96: if (nf <= 0) ! 97: return(fcode ? fcode : nf); ! 98: ! 99: DEBUG(4, "login %s\n", "called"); ! 100: ret = login(nf, flds, fn); ! 101: if (ret < 0) { ! 102: clsacu(); ! 103: return(CF_LOGIN); ! 104: } ! 105: /* rti!trt: avoid passing file to children */ ! 106: fioclex(fn); ! 107: return(fn); ! 108: } ! 109: ! 110: /*** ! 111: * getto(flds) connect to remote machine ! 112: * char *flds[]; ! 113: * ! 114: * return codes: ! 115: * >0 - file number - ok ! 116: * FAIL - failed ! 117: */ ! 118: ! 119: getto(flds) ! 120: register char *flds[]; ! 121: { ! 122: register struct condev *cd; ! 123: int nulldev(), diropn(); ! 124: ! 125: DEBUG(4, "call: no. %s ", flds[F_PHONE]); ! 126: DEBUG(4, "for sys %s\n", flds[F_NAME]); ! 127: ! 128: CU_end = nulldev; ! 129: for (cd = condevs; cd->CU_meth != NULL; cd++) { ! 130: if (snccmp(cd->CU_meth, flds[F_LINE]) == SAME) { ! 131: DEBUG(4, "Using %s to call\n", cd->CU_meth); ! 132: return((*(cd->CU_gen))(flds)); ! 133: } ! 134: } ! 135: logent(flds[F_LINE], "getto: Can't find, using DIR"); ! 136: return(diropn(flds)); /* search failed, so use direct */ ! 137: } ! 138: ! 139: /*** ! 140: * clsacu() close call unit ! 141: * ! 142: * return codes: none ! 143: */ ! 144: ! 145: int (*CU_end)() = nulldev; ! 146: clsacu() ! 147: { ! 148: (*(CU_end))(Dcf); ! 149: if (close(Dcf) == 0) { ! 150: DEBUG(4, "fd %d NOT CLOSED by CU_clos\n", Dcf); ! 151: logent("clsacu", "NOT CLOSED by CU_clos"); ! 152: } ! 153: Dcf = -1; ! 154: CU_end = nulldev; ! 155: } ! 156: ! 157: /*** ! 158: * exphone - expand phone number for given prefix and number ! 159: * ! 160: * return code - none ! 161: */ ! 162: ! 163: exphone(in, out) ! 164: register char *in, *out; ! 165: { ! 166: FILE *fn; ! 167: char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH]; ! 168: char buf[BUFSIZ]; ! 169: register char *s1; ! 170: ! 171: if (!isalpha(*in)) { ! 172: strcpy(out, in); ! 173: return; ! 174: } ! 175: ! 176: s1=pre; ! 177: while (isalpha(*in)) ! 178: *s1++ = *in++; ! 179: *s1 = '\0'; ! 180: s1 = npart; ! 181: while (*in != '\0') ! 182: *s1++ = *in++; ! 183: *s1 = '\0'; ! 184: ! 185: tpre[0] = '\0'; ! 186: if ((fn = fopen(DIALFILE, "r")) == NULL) ! 187: DEBUG(2, "CAN'T OPEN %s\n", DIALFILE); ! 188: else { ! 189: while (cfgets(buf, BUFSIZ, fn)) { ! 190: sscanf(buf, "%s%s", p, tpre); ! 191: if (strcmp(p, pre) == SAME) ! 192: goto found; ! 193: tpre[0] = '\0'; ! 194: } ! 195: DEBUG(2, "CAN'T FIND dialcodes prefix '%s'\n", pre); ! 196: found:; ! 197: fclose(fn); ! 198: } ! 199: ! 200: strcpy(out, tpre); ! 201: strcat(out, npart); ! 202: return; ! 203: } ! 204: ! 205: /*** ! 206: * rddev - read and decode a line from device file ! 207: * ! 208: * return code - FAIL at end-of file; 0 otherwise ! 209: */ ! 210: ! 211: rddev(fp, dev) ! 212: register struct Devices *dev; ! 213: FILE *fp; ! 214: { ! 215: char *fdig(); ! 216: char buf[BUFSIZ]; ! 217: int na; ! 218: ! 219: if (!cfgets(buf, BUFSIZ, fp)) ! 220: return(FAIL); ! 221: ! 222: na = sscanf(buf, "%s%s%s%s%s", dev->D_type, dev->D_line, ! 223: dev->D_calldev, dev->D_class, dev->D_brand); ! 224: ASSERT(na >= 4, "BAD DEVICE ENTRY", buf, 0); ! 225: if (na != 5) dev->D_brand[0] = '\0'; ! 226: dev->D_speed = atoi(fdig(dev->D_class)); ! 227: return(0); ! 228: } ! 229: ! 230: /*** ! 231: * finds(fsys, sysnam, info, flds) set system attribute vector ! 232: * ! 233: * return codes: ! 234: * >0 - number of arguments in vector - succeeded ! 235: * CF_SYSTEM - system name not found ! 236: * CF_TIME - wrong time to call ! 237: */ ! 238: ! 239: finds(fsys, sysnam, info, flds) ! 240: char *sysnam, info[], *flds[]; ! 241: FILE *fsys; ! 242: { ! 243: char sysn[8]; ! 244: int na; ! 245: int fcode = 0; ! 246: ! 247: /* format of fields ! 248: * 0 name; ! 249: * 1 time ! 250: * 2 acu/hardwired ! 251: * 3 speed ! 252: * etc ! 253: */ ! 254: while (cfgets(info, MAXC, fsys) != NULL) { ! 255: na = getargs(info, flds); ! 256: sprintf(sysn, "%.7s", flds[F_NAME]); ! 257: if (strcmp(sysnam, sysn) != SAME) ! 258: continue; ! 259: if (ifdate(flds[F_TIME])) ! 260: /* found a good entry */ ! 261: return(na); ! 262: DEBUG(2, "Wrong time ('%s') to call\n", flds[F_TIME]); ! 263: fcode = CF_TIME; ! 264: } ! 265: return(fcode ? fcode : CF_SYSTEM); ! 266: } ! 267: ! 268: /*** ! 269: * login(nf, flds, dcr) do login conversation ! 270: * char *flds[]; ! 271: * int nf; ! 272: * ! 273: * return codes: 0 | FAIL ! 274: */ ! 275: ! 276: login(nf, flds, fn) ! 277: register char *flds[]; ! 278: int nf, fn; ! 279: { ! 280: register char *want, *altern; ! 281: extern char *index(); ! 282: int k, ok; ! 283: ! 284: ASSERT(nf > 4, "TOO FEW LOG FIELDS", "", nf); ! 285: for (k = F_LOGIN; k < nf; k += 2) { ! 286: want = flds[k]; ! 287: ok = FAIL; ! 288: while (ok != 0) { ! 289: altern = index(want, '-'); ! 290: if (altern != NULL) ! 291: *altern++ = '\0'; ! 292: DEBUG(4, "wanted %s ", want); ! 293: ok = expect(want, fn); ! 294: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 295: if (ok == 0) ! 296: break; ! 297: if (altern == NULL) { ! 298: logent("LOGIN", "FAILED"); ! 299: /* close *not* needed here. rti!trt */ ! 300: return(FAIL); ! 301: } ! 302: want = index(altern, '-'); ! 303: if (want != NULL) ! 304: *want++ = '\0'; ! 305: sendthem(altern, fn); ! 306: } ! 307: sleep(2); ! 308: if (k+1 < nf) ! 309: sendthem(flds[k+1], fn); ! 310: } ! 311: return(0); ! 312: } ! 313: ! 314: ! 315: /* rti!trt: conditional table generation to support odd speeds */ ! 316: /* Suggested in n44a.139 by n44!dan (Dan Ts'o) */ ! 317: struct sg_spds {int sp_val, sp_name;} spds[] = { ! 318: #ifdef B50 ! 319: { 50, B50}, ! 320: #endif ! 321: #ifdef B75 ! 322: { 75, B75}, ! 323: #endif ! 324: #ifdef B110 ! 325: { 110, B110}, ! 326: #endif ! 327: #ifdef B150 ! 328: { 150, B150}, ! 329: #endif ! 330: #ifdef B200 ! 331: { 200, B200}, ! 332: #endif ! 333: #ifdef B300 ! 334: { 300, B300}, ! 335: #endif ! 336: #ifdef B600 ! 337: {600, B600}, ! 338: #endif ! 339: #ifdef B1200 ! 340: {1200, B1200}, ! 341: #endif ! 342: #ifdef B1800 ! 343: {1800, B1800}, ! 344: #endif ! 345: #ifdef B2000 ! 346: {2000, B2000}, ! 347: #endif ! 348: #ifdef B2400 ! 349: {2400, B2400}, ! 350: #endif ! 351: #ifdef B3600 ! 352: {3600, B3600}, ! 353: #endif ! 354: #ifdef B4800 ! 355: {4800, B4800}, ! 356: #endif ! 357: #ifdef B7200 ! 358: {7200, B7200}, ! 359: #endif ! 360: #ifdef B9600 ! 361: {9600, B9600}, ! 362: #endif ! 363: #ifdef B19200 ! 364: {19200,B19200}, ! 365: #endif ! 366: {0, 0} ! 367: }; ! 368: ! 369: /*** ! 370: * fixline(tty, spwant) set speed/echo/mode... ! 371: * int tty, spwant; ! 372: * ! 373: * return codes: none ! 374: */ ! 375: ! 376: fixline(tty, spwant) ! 377: int tty, spwant; ! 378: { ! 379: #ifdef SYSIII ! 380: struct termio ttbuf; ! 381: #endif ! 382: #ifndef SYSIII ! 383: struct sgttyb ttbuf; ! 384: #endif ! 385: register struct sg_spds *ps; ! 386: int speed = -1; ! 387: int ret; ! 388: ! 389: for (ps = spds; ps->sp_val; ps++) ! 390: if (ps->sp_val == spwant) ! 391: speed = ps->sp_name; ! 392: ASSERT(speed >= 0, "BAD SPEED", "", speed); ! 393: #ifdef SYSIII ! 394: ioctl(tty, TCGETA, &ttbuf); ! 395: /* ttbuf.sg_flags = (ANYP|RAW); ! 396: ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; */ ! 397: ttbuf.c_iflag = (ushort)0; ! 398: ttbuf.c_oflag = (ushort)0; ! 399: ttbuf.c_cflag = (speed|CS8|HUPCL|CREAD); ! 400: ttbuf.c_lflag = (ushort)0; ! 401: ttbuf.c_cc[VMIN] = 6; ! 402: ttbuf.c_cc[VTIME] = 1; ! 403: ret = ioctl(tty, TCSETA, &ttbuf); ! 404: #endif ! 405: #ifndef SYSIII ! 406: ioctl(tty, TIOCGETP, &ttbuf); ! 407: ttbuf.sg_flags = (ANYP|RAW); ! 408: ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed; ! 409: ret = ioctl(tty, TIOCSETP, &ttbuf); ! 410: #endif ! 411: ASSERT(ret >= 0, "RETURN FROM STTY", "", ret); ! 412: #ifndef SYSIII ! 413: ioctl(tty, TIOCHPCL, STBNULL); ! 414: ioctl(tty, TIOCEXCL, STBNULL); ! 415: #endif ! 416: return; ! 417: } ! 418: ! 419: ! 420: /* Bill Shannon recommends MR 2000, but that takes too much space on PDPs */ ! 421: /* Actually, the 'expect' algorithm should be rewritten. */ ! 422: #define MR 1000 ! 423: ! 424: ! 425: /*** ! 426: * expect(str, fn) look for expected string ! 427: * char *str; ! 428: * ! 429: * return codes: ! 430: * 0 - found ! 431: * FAIL - lost line or too many characters read ! 432: * some character - timed out ! 433: */ ! 434: ! 435: expect(str, fn) ! 436: register char *str; ! 437: int fn; ! 438: { ! 439: char rdvec[MR]; ! 440: register char *rp = rdvec; ! 441: int kr; ! 442: char nextch; ! 443: ! 444: if (strcmp(str, "\"\"") == SAME) ! 445: return(0); ! 446: *rp = 0; ! 447: if (setjmp(Sjbuf)) { ! 448: return(FAIL); ! 449: } ! 450: signal(SIGALRM, alarmtr); ! 451: /* change MAXCHARTIME to MAXMSGTIME, outside while loop -- brl-bmd!dpk */ ! 452: alarm(MAXMSGTIME); ! 453: while (notin(str, rdvec)) { ! 454: kr = read(fn, &nextch, 1); ! 455: if (kr <= 0) { ! 456: alarm(0); ! 457: DEBUG(4, "lost line kr - %d\n, ", kr); ! 458: logent("LOGIN", "LOST LINE"); ! 459: return(FAIL); ! 460: } ! 461: { ! 462: int c; ! 463: c = nextch & 0177; ! 464: DEBUG(4, c >= 040 ? "%c" : "\\%03o", c); ! 465: } ! 466: if ((*rp = nextch & 0177) != '\0') ! 467: rp++; ! 468: /* Check rdvec before null termination -- cmcl2!salkind */ ! 469: if (rp >= rdvec + MR) { ! 470: alarm(0); ! 471: return(FAIL); ! 472: } ! 473: *rp = '\0'; ! 474: } ! 475: alarm(0); ! 476: return(0); ! 477: } ! 478: ! 479: ! 480: /* ! 481: * Determine next file descriptor that would be allocated. ! 482: * This permits later closing of a file whose open was interrupted. ! 483: * It is a UNIX kernel problem, but it has to be handled. ! 484: * unc!smb (Steve Bellovin) probably first discovered it. ! 485: */ ! 486: getnextfd() ! 487: { ! 488: close(next_fd = open("/", 0)); ! 489: } ! 490: ! 491: /*** ! 492: * sendthem(str, fn) send line of login sequence ! 493: * char *str; ! 494: * ! 495: * return codes: none ! 496: */ ! 497: ! 498: sendthem(str, fn) ! 499: register char *str; ! 500: int fn; ! 501: { ! 502: register char *strptr; ! 503: int i, n, cr = 1; ! 504: static int p_init = 0; ! 505: ! 506: /* Note: debugging authorized only for privileged users */ ! 507: DEBUG(5, "send %s\n", str); ! 508: ! 509: if (!p_init) { ! 510: p_init++; ! 511: bld_partab(P_EVEN); ! 512: } ! 513: ! 514: if (prefix("BREAK", str)) { ! 515: sscanf(&str[5], "%1d", &i); ! 516: if (i <= 0 || i > 10) ! 517: i = 3; ! 518: /* send break */ ! 519: genbrk(fn, i); ! 520: return; ! 521: } ! 522: ! 523: if (prefix("PAUSE", str)) { ! 524: sscanf(&str[5], "%1d", &i); ! 525: if (i <= 0 || i > 10) ! 526: i = 3; ! 527: /* pause for a while */ ! 528: sleep((unsigned)i); ! 529: return; ! 530: } ! 531: ! 532: if (strcmp(str, "EOT") == SAME) { ! 533: p_chwrite(fn, '\04'); ! 534: return; ! 535: } ! 536: ! 537: /* LF, CR, and "" courtesy unc!smb */ ! 538: /* Send a '\n' */ ! 539: if (strcmp(str, "LF") == SAME) ! 540: str = "\\n\\c"; ! 541: ! 542: /* Send a '\r' */ ! 543: if (strcmp(str, "CR") == SAME) ! 544: str = "\\r\\c"; ! 545: ! 546: /* Set parity as needed */ ! 547: if (strcmp(str, "P_ZERO") == SAME) { ! 548: bld_partab(P_ZERO); ! 549: return; ! 550: } ! 551: if (strcmp(str, "P_ONE") == SAME) { ! 552: bld_partab(P_ONE); ! 553: return; ! 554: } ! 555: if (strcmp(str, "P_EVEN") == SAME) { ! 556: bld_partab(P_EVEN); ! 557: return; ! 558: } ! 559: if (strcmp(str, "P_ODD") == SAME) { ! 560: bld_partab(P_ODD); ! 561: return; ! 562: } ! 563: ! 564: /* If "", just send '\r' */ ! 565: if (strcmp(str, "\"\"") != SAME) ! 566: for (strptr = str; *strptr; strptr++) { ! 567: if (*strptr == '\\') switch(*++strptr) { ! 568: case 's': ! 569: DEBUG(5, "BLANK\n", ""); ! 570: *strptr = ' '; ! 571: break; ! 572: case 'd': ! 573: DEBUG(5, "DELAY\n", ""); ! 574: sleep(1); ! 575: continue; ! 576: case 'r': ! 577: DEBUG(5, "RETURN\n", ""); ! 578: *strptr = '\r'; ! 579: break; ! 580: case 'b': ! 581: if (isdigit(*(strptr+1))) { ! 582: i = (*++strptr - '0'); ! 583: if (i <= 0 || i > 10) ! 584: i = 3; ! 585: } else ! 586: i = 3; ! 587: /* send break */ ! 588: genbrk(fn, i); ! 589: continue; ! 590: case 'c': ! 591: if (*(strptr+1) == '\0') { ! 592: DEBUG(5, "NO CR\n", ""); ! 593: cr = 0; ! 594: continue; ! 595: } ! 596: DEBUG(5, "NO CR - MIDDLE IGNORED\n", ""); ! 597: continue; ! 598: default: ! 599: if (isdigit(strptr[1])) { ! 600: i = 0; ! 601: n = 0; ! 602: while (isdigit(strptr[1]) && ++n <= 3) ! 603: i = i*8 + (*++strptr - '0'); ! 604: p_chwrite(fn, i); ! 605: continue; ! 606: } ! 607: DEBUG(5, "BACKSLASH\n", ""); ! 608: strptr--; ! 609: } ! 610: p_chwrite(fn, *strptr); ! 611: } ! 612: ! 613: /* '\n' changed to '\r'--a better default. rti!trt */ ! 614: if (cr) ! 615: p_chwrite(fn, '\r'); ! 616: return; ! 617: } ! 618: ! 619: p_chwrite(fd, c) ! 620: int fd; ! 621: int c; ! 622: { ! 623: char t[2]; ! 624: ! 625: t[0] = par_tab[c&0177]; ! 626: t[1] = '\0'; ! 627: ASSERT(write(fd, t, 1) == 1, "BAD WRITE", "", t[0]); ! 628: } ! 629: ! 630: /* ! 631: * generate parity table for use by p_chwrite. ! 632: */ ! 633: bld_partab(type) ! 634: int type; ! 635: { ! 636: register int i, j, n; ! 637: ! 638: for (i = 0; i < sizeof(par_tab); i++) { ! 639: n = 0; ! 640: for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j) ! 641: n++; ! 642: par_tab[i] = i; ! 643: if (type == P_ONE ! 644: || (type == P_EVEN && (n&01) != 0) ! 645: || (type == P_ODD && (n&01) == 0)) ! 646: par_tab[i] |= sizeof(par_tab); ! 647: } ! 648: } ! 649: ! 650: #define BSPEED B150 ! 651: ! 652: /*** ! 653: * genbrk send a break ! 654: * ! 655: * return codes; none ! 656: */ ! 657: ! 658: genbrk(fn, bnulls) ! 659: register int fn, bnulls; ! 660: { ! 661: register int ret; ! 662: #ifdef SYSIII ! 663: ret = ioctl(fn, TCSBRK, STBNULL); ! 664: DEBUG(5, "break ioctl ret %d\n", ret); ! 665: #endif ! 666: #ifndef SYSIII ! 667: #ifdef TIOCSBRK ! 668: ret = ioctl(fn, TIOCSBRK, STBNULL); ! 669: DEBUG(5, "break ioctl ret %d\n", ret); ! 670: #ifdef TIOCCBRK ! 671: ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", bnulls); ! 672: ASSERT(ret > 0, "BAD WRITE genbrk", "", ret); ! 673: sleep(1); ! 674: ret = ioctl(fn, TIOCCBRK, STBNULL); ! 675: DEBUG(5, "break ioctl ret %d\n", ret); ! 676: #endif ! 677: DEBUG(4, "ioctl 1 second break\n", STBNULL); ! 678: #else ! 679: struct sgttyb ttbuf; ! 680: register int sospeed; ! 681: ! 682: ret = ioctl(fn, TIOCGETP, &ttbuf); ! 683: sospeed = ttbuf.sg_ospeed; ! 684: ttbuf.sg_ospeed = BSPEED; ! 685: ret = ioctl(fn, TIOCSETP, &ttbuf); ! 686: ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", bnulls); ! 687: ASSERT(ret > 0, "BAD WRITE genbrk", "", ret); ! 688: ttbuf.sg_ospeed = sospeed; ! 689: ret = ioctl(fn, TIOCSETP, &ttbuf); ! 690: ret = write(fn, "@", 1); ! 691: ASSERT(ret > 0, "BAD WRITE genbrk", "", ret); ! 692: DEBUG(4, "sent BREAK nulls - %d\n", bnulls); ! 693: #endif ! 694: #endif ! 695: } ! 696: ! 697: ! 698: /*** ! 699: * notin(sh, lg) check for occurrence of substring "sh" ! 700: * char *sh, *lg; ! 701: * ! 702: * return codes: ! 703: * 0 - found the string ! 704: * 1 - not in the string ! 705: */ ! 706: ! 707: notin(sh, lg) ! 708: register char *sh, *lg; ! 709: { ! 710: while (*lg != '\0') { ! 711: /* Dave Martingale: permit wild cards in 'expect' */ ! 712: if (wprefix(sh, lg)) ! 713: return(0); ! 714: else ! 715: lg++; ! 716: } ! 717: return(1); ! 718: } ! 719: ! 720: ! 721: /******* ! 722: * ifdate(s) ! 723: * char *s; ! 724: * ! 725: * ittvax!swatt ! 726: * Allow multiple date specifications separated by '|'. ! 727: * Calls ifadate, formerly "ifdate". ! 728: * ! 729: * return codes: ! 730: * see ifadate ! 731: */ ! 732: ! 733: ifdate(s) ! 734: char *s; ! 735: { ! 736: register char *p; ! 737: register int ret; ! 738: ! 739: for (p = s; p && (*p == '|' ? *++p : *p); p = index(p, '|')) ! 740: if (ret = ifadate(p)) ! 741: return(ret); ! 742: return(0); ! 743: } ! 744: ! 745: ! 746: /******* ! 747: * ifadate(s) ! 748: * char *s; ! 749: * ! 750: * ifadate - this routine will check a string (s) ! 751: * like "MoTu0800-1730" to see if the present ! 752: * time is within the given limits. ! 753: * SIDE EFFECT - Retrytime is set ! 754: * ! 755: * String alternatives: ! 756: * Wk - Mo thru Fr ! 757: * zero or one time means all day ! 758: * Any - any day ! 759: * ! 760: * return codes: ! 761: * 0 - not within limits ! 762: * 1 - within limits ! 763: */ ! 764: ! 765: ifadate(s) ! 766: char *s; ! 767: { ! 768: static char *days[]={ ! 769: "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0 ! 770: }; ! 771: time_t clock; ! 772: int rtime; ! 773: int i, tl, th, tn, flag, dayok=0; ! 774: struct tm *localtime(); ! 775: struct tm *tp; ! 776: char *index(); ! 777: char *p; ! 778: ! 779: /* pick up retry time for failures */ ! 780: /* global variable Retrytime is set here */ ! 781: if ((p = index(s, ',')) == NULL) { ! 782: Retrytime = RETRYTIME; ! 783: } ! 784: else { ! 785: i = sscanf(p+1, "%d", &rtime); ! 786: if (i < 1 || rtime < 5) ! 787: rtime = 5; ! 788: Retrytime = rtime * 60; ! 789: } ! 790: ! 791: time(&clock); ! 792: tp = localtime(&clock); ! 793: while (isalpha(*s)) { ! 794: for (i = 0; days[i]; i++) { ! 795: if (prefix(days[i], s)) ! 796: if (tp->tm_wday == i) ! 797: dayok = 1; ! 798: } ! 799: ! 800: if (prefix("Wk", s)) ! 801: if (tp->tm_wday >= 1 && tp->tm_wday <= 5) ! 802: dayok = 1; ! 803: if (prefix("Any", s)) ! 804: dayok = 1; ! 805: s++; ! 806: } ! 807: ! 808: if (dayok == 0) ! 809: return(0); ! 810: i = sscanf(s, "%d-%d", &tl, &th); ! 811: tn = tp->tm_hour * 100 + tp->tm_min; ! 812: if (i < 2) ! 813: return(1); ! 814: if (th < tl) ! 815: flag = 0; /* set up for crossover 2400 test */ ! 816: else ! 817: flag = 1; ! 818: if ((tn >= tl && tn <= th) ! 819: || (tn >= th && tn <= tl)) /* test for crossover 2400 */ ! 820: return(flag); ! 821: else ! 822: return(!flag); ! 823: } ! 824: ! 825: ! 826: /*** ! 827: * char * ! 828: * lastc(s) return pointer to last character ! 829: * char *s; ! 830: * ! 831: */ ! 832: ! 833: char * ! 834: lastc(s) ! 835: register char *s; ! 836: { ! 837: while (*s != '\0') s++; ! 838: return(s); ! 839: } ! 840: ! 841: ! 842: /*** ! 843: * char * ! 844: * fdig(cp) find first digit in string ! 845: * ! 846: * return - pointer to first digit in string or end of string ! 847: */ ! 848: ! 849: char * ! 850: fdig(cp) ! 851: register char *cp; ! 852: { ! 853: register char *c; ! 854: ! 855: for (c = cp; *c; c++) ! 856: if (*c >= '0' && *c <= '9') ! 857: break; ! 858: return(c); ! 859: } ! 860: ! 861: ! 862: /* ! 863: * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0 ! 864: * Strings are compared as if they contain all capital letters. ! 865: */ ! 866: ! 867: snccmp(s1, s2) ! 868: register char *s1, *s2; ! 869: { ! 870: char c1, c2; ! 871: ! 872: if (islower(*s1)) c1 = toupper(*s1); ! 873: else c1 = *s1; ! 874: if (islower(*s2)) c2 = toupper(*s2); ! 875: else c2 = *s2; ! 876: ! 877: while (c1 == c2) { ! 878: if (*s1++=='\0') ! 879: return(0); ! 880: s2++; ! 881: if (islower(*s1)) c1 = toupper(*s1); ! 882: else c1 = *s1; ! 883: if (islower(*s2)) c2 = toupper(*s2); ! 884: else c2 = *s2; ! 885: } ! 886: return(c1 - c2); ! 887: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.