|
|
1.1 ! root 1: /* @(#)conn.c 1.16 ! 2: */ ! 3: #include "uucp.h" ! 4: VERSION(@(#)conn.c 1.16); ! 5: ! 6: static char _ProtoStr[20] = ""; /* protocol string from Systems file entry */ ! 7: extern jmp_buf Sjbuf; ! 8: ! 9: int alarmtr(); ! 10: static void getProto(); ! 11: /* static getto(), finds(); PUT this back after altconn is included */ ! 12: extern getto(); ! 13: static finds(); ! 14: ! 15: static notin(), ifdate(), classmatch(); ! 16: ! 17: extern struct caller caller[]; ! 18: ! 19: /* Needed for cu for force which line will be used */ ! 20: #ifdef STANDALONE ! 21: extern char *Myline; ! 22: #endif STANDALONE ! 23: ! 24: /* ! 25: * conn - place a telephone call to system and login, etc. ! 26: * ! 27: * return codes: ! 28: * FAIL - connection failed ! 29: * >0 - file no. - connect ok ! 30: * When a failure occurs, Uerror is set. ! 31: */ ! 32: ! 33: conn(system) ! 34: char *system; ! 35: { ! 36: int nf, fn = FAIL; ! 37: char *flds[F_MAX+1]; ! 38: FILE *fsys; ! 39: int (*oalrm)(); ! 40: #ifdef MANYSYS ! 41: #define SYSCLOSE pclose ! 42: FILE *sysopen(); ! 43: #else ! 44: #define SYSCLOSE fclose ! 45: #endif ! 46: ! 47: CDEBUG(4, "conn(%s)\n", system); ! 48: #ifndef MANYSYS ! 49: fsys = fopen(SYSFILE, "r"); ! 50: #else ! 51: fsys = sysopen(system); ! 52: #endif ! 53: ASSERT(fsys != NULL, Ct_OPEN, SYSFILE, errno); ! 54: Uerror = 0; ! 55: while ((nf = finds(fsys, system, flds, F_MAX)) > 0) { ! 56: fn = getto(flds); ! 57: CDEBUG(4, "getto ret %d\n", fn); ! 58: if (fn < 0) ! 59: continue; ! 60: #ifdef STANDALONE ! 61: SYSCLOSE(fsys); ! 62: return(fn); ! 63: #else ! 64: if (chat(nf - F_LOGIN, flds + F_LOGIN, fn,"","") == SUCCESS) { ! 65: SYSCLOSE(fsys); ! 66: return(fn); /* successful return */ ! 67: } ! 68: ! 69: /* login failed */ ! 70: DEBUG(6, "close caller (%d)\n", fn); ! 71: if (setjmp(Sjbuf) == 0) { ! 72: oalrm = signal(SIGALRM, alarmtr); ! 73: alarm(30); ! 74: close(fn); ! 75: } ! 76: alarm(0); ! 77: signal(SIGALRM, oalrm); ! 78: if (Dc[0] != NULLCHAR) { ! 79: DEBUG(6, "delock(%s)\n", Dc); ! 80: delock(Dc); ! 81: } ! 82: #endif ! 83: } ! 84: ! 85: /* finds or getto failed */ ! 86: SYSCLOSE(fsys); ! 87: CDEBUG(1, "Call Failed: %s\n", UERRORTEXT); ! 88: return(FAIL); ! 89: } ! 90: ! 91: /* ! 92: * getto - connect to remote machine ! 93: * ! 94: * return codes: ! 95: * >0 - file number - ok ! 96: * FAIL - failed ! 97: */ ! 98: ! 99: getto(flds) ! 100: char *flds[]; ! 101: { ! 102: FILE *dfp; ! 103: char *dev[D_MAX+2], devbuf[BUFSIZ]; ! 104: register int status; ! 105: register int dcf = -1; ! 106: int reread = 0; ! 107: int tries = 0; /* count of call attempts - for limit purposes */ ! 108: ! 109: CDEBUG(1, "Device Type %s wanted\n", flds[F_TYPE]); ! 110: dfp = fopen(DEVFILE, "r"); ! 111: ASSERT(dfp != NULL, Ct_OPEN, DEVFILE, errno); ! 112: Uerror = 0; ! 113: while (tries < TRYCALLS) { ! 114: if ((status=rddev(dfp, flds[F_TYPE], dev, devbuf, D_MAX)) == FAIL) { ! 115: if (tries == 0 || ++reread >= TRYCALLS) ! 116: break; ! 117: rewind(dfp); ! 118: continue; ! 119: } ! 120: /* check class, check (and possibly set) speed */ ! 121: if (classmatch(flds, dev) != SUCCESS) ! 122: continue; ! 123: if ((dcf = processdev(flds, dev)) >= 0) ! 124: break; ! 125: ! 126: switch(Uerror) { ! 127: case SS_CANT_ACCESS_DEVICE: ! 128: case SS_DEVICE_FAILED: ! 129: case SS_LOCKED_DEVICE: ! 130: break; ! 131: default: ! 132: tries++; ! 133: break; ! 134: } ! 135: } ! 136: (void) fclose(dfp); ! 137: if (status == FAIL && !Uerror) { ! 138: CDEBUG(1, "Requested Device Type Not Found\n", 0); ! 139: Uerror = SS_NO_DEVICE; ! 140: } ! 141: return(dcf); ! 142: } ! 143: ! 144: /* ! 145: * classmatch - process 'Any' in Devices and Systems and ! 146: * determine the correct speed, or match for == ! 147: */ ! 148: ! 149: static int ! 150: classmatch(flds, dev) ! 151: char *flds[], *dev[]; ! 152: { ! 153: /* check class, check (and possibly set) speed */ ! 154: if (EQUALS(flds[F_CLASS], "Any") ! 155: && EQUALS(dev[D_CLASS], "Any")) { ! 156: dev[D_CLASS] = flds[F_CLASS] = DEFAULT_BAUDRATE; ! 157: return(SUCCESS); ! 158: } else if (EQUALS(dev[F_CLASS], "Any")) { ! 159: dev[D_CLASS] = flds[F_CLASS]; ! 160: return(SUCCESS); ! 161: } else if (EQUALS(flds[F_CLASS], "Any")) { ! 162: flds[D_CLASS] = dev[F_CLASS]; ! 163: return(SUCCESS); ! 164: } else if (EQUALS(flds[F_CLASS], dev[D_CLASS])) ! 165: return(SUCCESS); ! 166: else ! 167: return(FAIL); ! 168: } ! 169: ! 170: ! 171: /*** ! 172: * rddev - find and unpack a line from device file for this caller type ! 173: * lines starting with whitespace of '#' are comments ! 174: * ! 175: * return codes: ! 176: * >0 - number of arguments in vector - succeeded ! 177: * FAIL - EOF ! 178: ***/ ! 179: ! 180: rddev(fp, type, dev, buf, devcount) ! 181: FILE *fp; ! 182: char *type; ! 183: char *dev[]; ! 184: char *buf; ! 185: { ! 186: int na; ! 187: ! 188: while (fgets(buf, BUFSIZ, fp) != NULL) { ! 189: if (buf[0] == ' ' || buf[0] == '\t' ! 190: || buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#') ! 191: continue; ! 192: na = getargs(buf, dev, devcount); ! 193: ASSERT(na >= D_CALLER, "BAD LINE", buf, na); ! 194: ! 195: /* For cu -- to force the requested line to be used */ ! 196: #ifdef STANDALONE ! 197: if ((Myline != NULL) && (!EQUALS(Myline, dev[D_LINE])) ) ! 198: continue; ! 199: #endif STANDALONE ! 200: ! 201: bsfix(dev); /* replace \X fields */ ! 202: if (EQUALS(dev[D_TYPE], type)) ! 203: return(na); ! 204: } ! 205: return(FAIL); ! 206: } ! 207: ! 208: ! 209: /* ! 210: * finds - set system attribute vector ! 211: * ! 212: * input: ! 213: * fsys - open Systems file descriptor ! 214: * sysnam - system name to find ! 215: * output: ! 216: * flds - attibute vector from Systems file ! 217: * fldcount - number of fields in flds ! 218: * return codes: ! 219: * >0 - number of arguments in vector - succeeded ! 220: * FAIL - failed ! 221: * Uerror set: ! 222: * 0 - found a line in Systems file ! 223: * SS_BADSYSTEM - no line found in Systems file ! 224: * SS_TIME_WRONG - wrong time to call ! 225: */ ! 226: ! 227: static ! 228: finds(fsys, sysnam, flds, fldcount) ! 229: char *sysnam, *flds[]; ! 230: FILE *fsys; ! 231: { ! 232: static char info[BUFSIZ]; ! 233: int na; ! 234: ! 235: /* format of fields ! 236: * 0 name; ! 237: * 1 time ! 238: * 2 acu/hardwired ! 239: * 3 speed ! 240: * etc ! 241: */ ! 242: while (fgets(info, BUFSIZ, fsys) != NULL) { ! 243: if (info[0] == '#') ! 244: continue; ! 245: na = getargs(info, flds, fldcount); ! 246: bsfix(flds); /* replace \X fields */ ! 247: if ( !EQUALSN(sysnam, flds[F_NAME], SYSNSIZE)) ! 248: continue; ! 249: #ifndef STANDALONE ! 250: if (ifdate(flds[F_TIME])) { ! 251: /* found a good entry */ ! 252: getProto(flds[F_TYPE]); ! 253: Uerror = 0; ! 254: return(na); /* FOUND OK LINE */ ! 255: } ! 256: CDEBUG(1, "Wrong Time To Call: %s\n", flds[F_TIME]); ! 257: Uerror = SS_TIME_WRONG; ! 258: #else ! 259: Uerror = 0; ! 260: return(na); /* FOUND OK LINE */ ! 261: #endif ! 262: } ! 263: if (!Uerror) ! 264: Uerror = SS_BADSYSTEM; ! 265: return(FAIL); ! 266: } ! 267: ! 268: /* ! 269: * getProto - get the protocol letters from the input string. ! 270: * input: ! 271: * str - string from Systems file (flds[F_TYPE])--the , ! 272: * delimits the protocol string ! 273: * e.g. ACU,g or DK,d ! 274: * output: ! 275: * str - the , (if present) will be replaced with NULLCHAR ! 276: * global ProtoStr will be modified ! 277: * return: none ! 278: */ ! 279: ! 280: static ! 281: void ! 282: getProto(str) ! 283: char *str; ! 284: { ! 285: register char *p; ! 286: if ( (p=strchr(str, ',')) != NULL) { ! 287: *p = NULLCHAR; ! 288: (void) strcpy(_ProtoStr, p+1); ! 289: DEBUG(7, "ProtoStr = %s\n", _ProtoStr); ! 290: } ! 291: else ! 292: *_ProtoStr = NULLCHAR; ! 293: } ! 294: ! 295: /* ! 296: * check for a specified protocol selection string ! 297: * return: ! 298: * protocol string pointer ! 299: * NULL if none specified for LOGNAME ! 300: */ ! 301: char * ! 302: protoString() ! 303: { ! 304: return(_ProtoStr[0] == NULLCHAR ? NULL : _ProtoStr); ! 305: } ! 306: ! 307: static int _Echoflag; ! 308: static int _Slowflag; ! 309: /* ! 310: * chat - do conversation ! 311: * input: ! 312: * flds - fields from Systems file ! 313: * nf - number of fields in flds array ! 314: * dcr - write file number ! 315: * phstr1 - phone number to replace \D ! 316: * phstr2 - phone number to replace \T ! 317: * ! 318: * return codes: 0 | FAIL ! 319: */ ! 320: ! 321: chat(nf, flds, fn, phstr1, phstr2) ! 322: char *flds[], *phstr1, *phstr2; ! 323: int nf, fn; ! 324: { ! 325: char *want, *altern; ! 326: extern char *strchr(); ! 327: int k, ok; ! 328: ! 329: _Echoflag = 0; ! 330: _Slowflag = 0; ! 331: for (k = 0; k < nf; k += 2) { ! 332: want = flds[k]; ! 333: ok = FAIL; ! 334: while (ok != 0) { ! 335: altern = strchr(want, '-'); ! 336: if (altern != NULL) ! 337: *altern++ = NULLCHAR; ! 338: ok = expect(want, fn); ! 339: if (ok == 0) ! 340: break; ! 341: if (altern == NULL) { ! 342: Uerror = SS_LOGIN_FAILED; ! 343: logent(UERRORTEXT, "FAILED"); ! 344: return(FAIL); ! 345: } ! 346: want = strchr(altern, '-'); ! 347: if (want != NULL) ! 348: *want++ = NULLCHAR; ! 349: sendthem(altern, fn, phstr1, phstr2); ! 350: } ! 351: sleep(2); ! 352: if (flds[k+1]) ! 353: sendthem(flds[k+1], fn, phstr1, phstr2); ! 354: } ! 355: return(0); ! 356: } ! 357: ! 358: /*** ! 359: * expect(str, fn) look for expected string ! 360: * char *str; ! 361: * ! 362: * return codes: ! 363: * 0 - found ! 364: * FAIL - lost line or too many characters read ! 365: * some character - timed out ! 366: * ! 367: * There are many delicacies here. ! 368: * -- keep the system calls in the inner loop to a minimum; ! 369: * else a garrulous system might time out while we're reading ! 370: * its chatter. ! 371: * -- because systems may be garrulous but correct, the alarm ! 372: * must be reset whenever a character arrives; time out only ! 373: * if nothing has come for a while. But putting the alarm inside ! 374: * the inner loop slows it down too much; so put it outside, ! 375: * and don't time out if anything arrives. But that might let ! 376: * the far side time out in some pathological cases, so wait ! 377: * a shorter time if some character have already arrived. ! 378: * -- reading several characters at a time might be a mistake; ! 379: * we might consume something beyond the string we expect, ! 380: * discard it here, but need it later. Too bad for now. ! 381: */ ! 382: ! 383: #define MR 2000 /* max chars before we give up */ ! 384: #define NNEXT 4 /* chars to read at a time */ ! 385: ! 386: expect(str, fn) ! 387: char *str; ! 388: int fn; ! 389: { ! 390: static char rdvec[MR]; ! 391: register char *rp = rdvec; ! 392: register int kr, c; ! 393: char nextch[NNEXT]; ! 394: char dbuf[NNEXT*2 + 1]; ! 395: register char *dp, *cp; ! 396: int nread; ! 397: extern errno; ! 398: ! 399: CDEBUG(4, "expect: (", 0); ! 400: for (c=0; kr=str[c]; c++) ! 401: if (kr < 040) { ! 402: CDEBUG(4, "^%c", kr | 0100); ! 403: } else { ! 404: CDEBUG(4, "%c", kr); ! 405: } ! 406: CDEBUG(4, ")\n", 0); ! 407: ! 408: if (EQUALS(str, "\"\"")) { ! 409: CDEBUG(4, "got it\n", 0); ! 410: return(0); ! 411: } ! 412: nread = 0; ! 413: if (setjmp(Sjbuf) && nread == 0) { ! 414: return(FAIL); ! 415: } ! 416: (void) signal(SIGALRM, alarmtr); ! 417: if (nread) ! 418: alarm(MAXEXPECTTIME/2); /* cheap hack */ ! 419: else ! 420: alarm(MAXEXPECTTIME); ! 421: nread = 0; ! 422: do { ! 423: errno = 0; ! 424: kr = read(fn, nextch, NNEXT); ! 425: if (kr <= 0) { ! 426: alarm(0); ! 427: CDEBUG(4, "lost line errno - %d\n", errno); ! 428: logent("LOGIN", "LOST LINE"); ! 429: return(FAIL); ! 430: } ! 431: if (rp + kr >= rdvec + MR) { ! 432: CDEBUG(4, "\ntoo much junk\n", 0); ! 433: alarm(0); ! 434: return(FAIL); ! 435: } ! 436: nread += kr; ! 437: for (dp = dbuf, cp = nextch; --kr >= 0; ) { ! 438: if ((c = *cp++ & 0177) == 0) ! 439: continue; ! 440: *rp++ = c; ! 441: if (c >= 040) ! 442: *dp++ = c; ! 443: else { ! 444: *dp++ = '^'; ! 445: *dp++ = c+0100; ! 446: } ! 447: } ! 448: *dp = 0; ! 449: CDEBUG(4, "%s", dbuf); ! 450: *rp = NULLCHAR; ! 451: } while (notin(str, rdvec)); ! 452: alarm(0); ! 453: CDEBUG(4, "got it\n", 0); ! 454: return(0); ! 455: } ! 456: ! 457: ! 458: /*** ! 459: * alarmtr() - catch alarm routine for "expect". ! 460: */ ! 461: ! 462: alarmtr() ! 463: { ! 464: CDEBUG(6, "timed out\n", 0); ! 465: longjmp(Sjbuf, 1); ! 466: } ! 467: ! 468: ! 469: /*** ! 470: * sendthem(str, fn, phstr1, phstr2) send line of chat sequence ! 471: * char *str, *phstr; ! 472: * ! 473: * return codes: none ! 474: */ ! 475: ! 476: sendthem(str, fn, phstr1, phstr2) ! 477: char *str, *phstr1, *phstr2; ! 478: int fn; ! 479: { ! 480: int sendcr = 1; ! 481: register char *sptr, *pptr; ! 482: ! 483: if (PREFIX("BREAK", str)) { ! 484: /* send break */ ! 485: CDEBUG(5, "BREAK\n", 0); ! 486: genbrk(fn); ! 487: return; ! 488: } ! 489: ! 490: if (EQUALS(str, "EOT")) { ! 491: CDEBUG(5, "EOT\n", 0); ! 492: (void) write(fn, EOTMSG, strlen(EOTMSG)); ! 493: return; ! 494: } ! 495: ! 496: if (EQUALS(str, "\"\"")) { ! 497: CDEBUG(5, "\"\"\n", 0); ! 498: str += 2; ! 499: } ! 500: ! 501: CDEBUG(5, "sendthem (", ""); ! 502: if (setjmp(Sjbuf)) /* Timer so echo check doesn't last forever */ ! 503: goto err; ! 504: (void) signal(SIGALRM, alarmtr); ! 505: alarm(MAXEXPECTTIME); ! 506: for (sptr = str; *sptr; sptr++) { ! 507: if (*sptr == '\\') ! 508: switch(*++sptr) { ! 509: case 'D': ! 510: for (pptr=phstr1; *pptr; pptr++) ! 511: if (wrchar(fn, pptr)) ! 512: goto err; ! 513: continue; ! 514: case 'T': ! 515: for (pptr=phstr2; *pptr; pptr++) ! 516: if (wrchar(fn, pptr)) ! 517: goto err; ! 518: continue; ! 519: case 'N': ! 520: *sptr = 0; ! 521: break; ! 522: case 'd': ! 523: CDEBUG(5, "DELAY\n", 0); ! 524: sleep(2); ! 525: continue; ! 526: case 'c': ! 527: if (*(sptr+1) == NULLCHAR) { ! 528: CDEBUG(5, "<NO CR>", 0); ! 529: sendcr = 0; ! 530: continue; ! 531: } ! 532: CDEBUG(5, "<NO CR - MIDDLE IGNORED>\n", 0); ! 533: continue; ! 534: case 's': ! 535: *sptr = ' '; ! 536: break; ! 537: case 'p': ! 538: CDEBUG(5, "PAUSE\n", 0); ! 539: nap(HZ/4); /* approximately 1/4 second */ ! 540: continue; ! 541: case 'E': ! 542: CDEBUG(5, "ECHO CHECK ON\n", 0); ! 543: _Echoflag = 1; ! 544: continue; ! 545: case 'e': ! 546: CDEBUG(5, "ECHO CHECK OFF\n", 0); ! 547: _Echoflag = 0; ! 548: continue; ! 549: case 'K': ! 550: CDEBUG(5, "BREAK\n", 0); ! 551: genbrk(fn); ! 552: continue; ! 553: case 'W': ! 554: _Slowflag = 1; ! 555: continue; ! 556: case 'w': ! 557: _Slowflag = 0; ! 558: continue; ! 559: case '\\': ! 560: /* backslash escapes itself */ ! 561: break; ! 562: default: ! 563: /* send the backslash */ ! 564: --sptr; ! 565: break; ! 566: } ! 567: if (wrchar(fn, sptr)) ! 568: goto err; ! 569: } ! 570: ! 571: if (sendcr) { ! 572: CDEBUG(5, "^M", 0); ! 573: (void) write(fn, "\r", 1); ! 574: } ! 575: err: ! 576: alarm(0); ! 577: CDEBUG(5, ")\n", 0); ! 578: return; ! 579: } ! 580: ! 581: wrchar(fn, sptr) ! 582: register int fn; ! 583: register char *sptr; ! 584: { ! 585: if (GRPCHK(getgid())) /* protect Systems file */ ! 586: { ! 587: CDEBUG(5, "%s", *sptr < 040 ? "^" : ""); ! 588: CDEBUG(5, "%c", *sptr < 040 ? *sptr | 0100 : *sptr); ! 589: } ! 590: if ((write(fn, sptr, 1)) != 1) ! 591: return(FAIL); ! 592: if (_Echoflag) { ! 593: char chr; ! 594: while(1) { /* Should set a timer here */ ! 595: if (read(fn, &chr, 1) != 1) ! 596: return(FAIL); ! 597: chr &= 0177; ! 598: CDEBUG(4, "%s", chr < 040 ? "^" : ""); ! 599: CDEBUG(4, "%c", chr < 040 ? chr | 0100 : chr); ! 600: if (chr == ((*sptr) & 0177)) ! 601: break; ! 602: } ! 603: ! 604: } ! 605: if (_Slowflag) ! 606: sleep(1); ! 607: return(SUCCESS); ! 608: } ! 609: ! 610: ! 611: /*** ! 612: * notin(sh, lg) check for occurrence of substring "sh" ! 613: * char *sh, *lg; ! 614: * ! 615: * return codes: ! 616: * 0 - found the string ! 617: * 1 - not in the string ! 618: */ ! 619: ! 620: static ! 621: notin(sh, lg) ! 622: register char *sh, *lg; ! 623: { ! 624: while (*lg != NULLCHAR) { ! 625: if (PREFIX(sh, lg)) ! 626: return(0); ! 627: else ! 628: lg++; ! 629: } ! 630: return(1); ! 631: } ! 632: ! 633: ! 634: /******* ! 635: * ifdate(s) ! 636: * char *s; ! 637: * ! 638: * ifdate - this routine will check a string (s) ! 639: * like "MoTu0800-1730" to see if the present ! 640: * time is within the given limits. ! 641: * SIDE EFFECT - Retrytime is set to number following ";" ! 642: * ! 643: * String alternatives: ! 644: * Wk - Mo thru Fr ! 645: * zero or one time means all day ! 646: * Any - any day ! 647: * ! 648: * return codes: ! 649: * 0 - not within limits ! 650: * 1 - within limits ! 651: */ ! 652: ! 653: static ! 654: ifdate(s) ! 655: char *s; ! 656: { ! 657: static char *days[] = { ! 658: "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0 ! 659: }; ! 660: time_t clock; ! 661: int t__now; ! 662: char *p, *strrchr(), *strchr(); ! 663: struct tm *tp; ! 664: ! 665: time(&clock); ! 666: tp = localtime(&clock); ! 667: t__now = tp->tm_hour * 100 + tp->tm_min; /* "navy" time */ ! 668: ! 669: /* ! 670: * pick up retry time for failures ! 671: * global variable Retrytime is set here ! 672: */ ! 673: if ((p = strrchr(s, ';')) != NULL) ! 674: if (isdigit(p[1])) { ! 675: if (sscanf(p+1, "%d", &Retrytime) < 1) ! 676: Retrytime = 5; /* 5 minutes is error default */ ! 677: Retrytime *= 60; ! 678: *p = NULLCHAR; ! 679: } ! 680: ! 681: while (*s) { ! 682: int i, dayok; ! 683: ! 684: for (dayok = 0; (!dayok) && isalpha(*s); s++) { ! 685: if (PREFIX("Any", s)) ! 686: dayok = 1; ! 687: else if (PREFIX("Wk", s)) { ! 688: if (tp->tm_wday >= 1 && tp->tm_wday <= 5) ! 689: dayok = 1; ! 690: } else ! 691: for (i = 0; days[i]; i++) ! 692: if (PREFIX(days[i], s)) ! 693: if (tp->tm_wday == i) ! 694: dayok = 1; ! 695: } ! 696: ! 697: if (dayok) { ! 698: int t__low, t__high; ! 699: ! 700: while (isalpha(*s)) /* flush remaining day stuff */ ! 701: s++; ! 702: ! 703: if ((sscanf(s, "%d-%d", &t__low, &t__high) < 2) ! 704: || (t__low == t__high)) ! 705: return(1); ! 706: ! 707: /* 0000 crossover? */ ! 708: if (t__low < t__high) { ! 709: if (t__low <= t__now && t__now <= t__high) ! 710: return(1); ! 711: } else if (t__low <= t__now || t__now <= t__high) ! 712: return(1); ! 713: ! 714: /* aim at next time slot */ ! 715: if ((s = strchr(s, ',')) == NULL) ! 716: break; ! 717: } ! 718: s++; ! 719: } ! 720: return(0); ! 721: } ! 722: ! 723: /*** ! 724: * char * ! 725: * fdig(cp) find first digit in string ! 726: * ! 727: * return - pointer to first digit in string or end of string ! 728: */ ! 729: ! 730: char * ! 731: fdig(cp) ! 732: char *cp; ! 733: { ! 734: char *c; ! 735: ! 736: for (c = cp; *c; c++) ! 737: if (*c >= '0' && *c <= '9') ! 738: break; ! 739: return(c); ! 740: } ! 741: ! 742: ! 743: #ifdef FASTTIMER ! 744: /* Sleep in increments of 60ths of second. */ ! 745: nap (time) ! 746: register int time; ! 747: { ! 748: static int fd; ! 749: ! 750: if (fd == 0) ! 751: fd = open (FASTTIMER, 0); ! 752: ! 753: read (fd, 0, time); ! 754: } ! 755: ! 756: #endif FASTTIMER ! 757: ! 758: #ifdef BSD4_2 ! 759: ! 760: /* nap(n) -- sleep for 'n' ticks of 1/60th sec each. */ ! 761: /* This version, by Mark Horton, uses the select system call */ ! 762: ! 763: ! 764: nap(n) ! 765: unsigned n; ! 766: { ! 767: struct timeval tv; ! 768: int rc; ! 769: ! 770: if (n==0) ! 771: return; ! 772: tv.tv_sec = n/60; ! 773: tv.tv_usec = ((n%60)*1000000L)/60; ! 774: rc = select(32, 0, 0, 0, &tv); ! 775: } ! 776: ! 777: #endif ! 778: ! 779: #ifdef NONAP ! 780: ! 781: /* nap(n) where n is ticks ! 782: * ! 783: * loop using n/HZ part of a second ! 784: * if n represents more than 1 second, then ! 785: * use sleep(time) where time is the equivalent ! 786: * seconds rounded off to full seconds ! 787: * NOTE - this is a rough approximation and chews up ! 788: * processor resource! ! 789: */ ! 790: ! 791: nap(n) ! 792: unsigned n; ! 793: { ! 794: struct tms tbuf; ! 795: long endtime; ! 796: int i; ! 797: ! 798: if (n > HZ) { ! 799: /* > second, use sleep, rounding time */ ! 800: sleep( (int) (((n)+HZ/2)/HZ) ); ! 801: return; ! 802: } ! 803: ! 804: /* use timing loop for < 1 second */ ! 805: endtime = times(&tbuf) + 3*n/4; /* use 3/4 because of scheduler! */ ! 806: while (times(&tbuf) < endtime) { ! 807: for (i=0; i<1000; i++, i*i) ! 808: ; ! 809: } ! 810: return; ! 811: } ! 812: ! 813: ! 814: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.