1: #ifndef lint
   2: static char sccsid[] = "@(#)conn.c	5.2 (Berkeley) 7/2/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: #ifndef DIALUP
 415:     ioctl(tty, TIOCEXCL, STBNULL);
 416: #endif
 417: #endif
 418:     return;
 419: }
 420: 
 421: 
 422: #define MR 2000
 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: }

Defined functions

alarmtr defined in line 37; used 17 times
bld_partab defined in line 633; used 5 times
clsacu defined in line 146; used 1 times
conn defined in line 68; never used
expect defined in line 435; used 13 times
exphone defined in line 163; used 1 times
fdig defined in line 849; used 4 times
finds defined in line 239; used 1 times
  • in line 85
fixline defined in line 376; used 11 times
genbrk defined in line 658; used 2 times
getnextfd defined in line 486; used 11 times
getto defined in line 119; used 1 times
  • in line 87
ifadate defined in line 765; used 1 times
ifdate defined in line 733; used 1 times
lastc defined in line 833; never used
login defined in line 276; used 1 times
notin defined in line 707; used 1 times
p_chwrite defined in line 619; used 10 times
rddev defined in line 211; used 3 times
sendthem defined in line 498; used 8 times
snccmp defined in line 867; used 6 times

Defined variables

Dcf defined in line 66; used 5 times
next_fd defined in line 32; used 14 times
par_tab defined in line 30; used 6 times
sccsid defined in line 2; never used
spds defined in line 317; used 1 times

Defined struct's

sg_spds defined in line 317; used 2 times
  • in line 385(2)

Defined macros

BSPEED defined in line 650; used 1 times
MAXC defined in line 20; used 3 times
MR defined in line 422; used 2 times
P_EVEN defined in line 28; used 3 times
P_ODD defined in line 29; used 2 times
P_ONE defined in line 27; used 2 times
P_ZERO defined in line 26; used 1 times
Last modified: 1983-10-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2061
Valid CSS Valid XHTML 1.0 Strict