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