Annotation of researchv10no/cmd/uucp/conn.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.