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

Defined functions

alarmtr defined in line 34; used 17 times
bld_partab defined in line 630; used 5 times
clsacu defined in line 143; used 1 times
  • in line 99
conn defined in line 65; never used
expect defined in line 432; used 12 times
exphone defined in line 160; used 1 times
fdig defined in line 846; used 4 times
finds defined in line 236; used 1 times
  • in line 82
fixline defined in line 373; used 11 times
genbrk defined in line 655; used 2 times
getnextfd defined in line 483; used 11 times
getto defined in line 116; used 1 times
  • in line 84
ifadate defined in line 762; used 1 times
ifdate defined in line 730; used 1 times
lastc defined in line 830; never used
login defined in line 273; used 1 times
  • in line 97
notin defined in line 704; used 1 times
p_chwrite defined in line 616; used 10 times
rddev defined in line 208; used 3 times
sendthem defined in line 495; used 2 times
snccmp defined in line 864; used 6 times

Defined variables

Dcf defined in line 63; used 5 times
next_fd defined in line 29; used 14 times
par_tab defined in line 27; used 6 times
sccsid defined in line 1; never used
spds defined in line 314; used 1 times

Defined struct's

sg_spds defined in line 314; used 2 times
  • in line 382(2)

Defined macros

BSPEED defined in line 647; used 1 times
MAXC defined in line 17; used 3 times
MR defined in line 419; used 2 times
P_EVEN defined in line 25; used 3 times
P_ODD defined in line 26; used 2 times
P_ONE defined in line 24; used 2 times
P_ZERO defined in line 23; used 1 times
Last modified: 1983-07-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1513
Valid CSS Valid XHTML 1.0 Strict