home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / uucp / conn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-15  |  13.0 KB  |  729 lines

  1. #define CONN
  2. #include "uucp.h"
  3. #include <signal.h>
  4. #include <sgtty.h>
  5. #include <setjmp.h>
  6. #include <ctype.h>
  7. #include <sys/types.h>
  8. #include <time.h>
  9.  
  10.  
  11. #define F_NAME 0
  12. #define F_TIME 1
  13. #define F_LINE 2
  14. #define F_SPEED 3
  15. #define F_PHONE 4
  16. #define F_LOGIN 5
  17.  
  18. jmp_buf Sjbuf;
  19. #define INVOKE(a, r) ret = a; if (ret<0) return(r);
  20. /*******
  21.  *    conn(system)
  22.  *    char *system;
  23.  *
  24.  *    conn - place a telephone call to system and
  25.  *    login, etc.
  26.  *
  27.  *    return codes:
  28.  *        CF_SYSTEM: don't know system
  29.  *        CF_TIME: wrong time to call
  30.  *        CF_DIAL: call failed
  31.  *        CF_LOGIN: login/password dialog failed
  32.  *
  33.  *        >0  - file no.  -  connect ok
  34.  *
  35.  */
  36.  
  37. conn(system)
  38. char *system;
  39. {
  40.     int ret, nf;
  41.     int fn;
  42.     char *flds[50];
  43.     DEBUG(4, "gdial %s\n", "called");
  44.     INVOKE(gdial(), CF_DIAL)
  45.     DEBUG(4, "finds %s\n", "called");
  46.     INVOKE(nf = finds(system, flds), nf)
  47.     DEBUG(4, "getto %s\n", "called");
  48.     INVOKE(fn = getto(flds), CF_DIAL)
  49.     DEBUG(4, "login %s\n", "called");
  50.     INVOKE(login(nf, flds, fn), CF_LOGIN)
  51.     return(fn);
  52. }
  53.  
  54. /***
  55.  *    char *
  56.  *    lastc(s)    return pointer to last character
  57.  *    char *s;
  58.  *
  59.  */
  60.  
  61. char *
  62. lastc(s)
  63. char *s;
  64. {
  65.     while (*s != '\0') s++;
  66.     return(s);
  67. }
  68.  
  69. #define MAXDEV 10
  70. #define MAXDCH MAXDEV*20
  71. #define MAXCODE 30
  72. #define MAXCCH MAXCODE*20
  73.     /* This array tells us about possible acu's, etc. */
  74. struct Devices {
  75.     char *D_line;
  76.     char *D_acu;
  77.     int D_speed;
  78.     } Devs [MAXDEV];
  79.  
  80. char Devbuff[MAXDCH];
  81.  
  82. struct Codes {
  83.     char *C_locs;
  84.     char *C_prefix;
  85.     } Dialcodes [MAXCODE];
  86.  
  87. char Codebuff[MAXCCH];
  88. int Dcfull = 0;
  89.  
  90.  
  91. /***
  92.  *    gdial()        get device and dial info
  93.  *
  94.  *    return codes:  0  |  FAIL
  95.  */
  96.  
  97. gdial()
  98. {
  99.     char *flds[10], *lt;
  100.     char *lb = Devbuff;
  101.     char *lc = Codebuff;
  102.     FILE *fn;
  103.     int nr;
  104.     struct Devices *pd;
  105.     struct Codes *pc;
  106.     if (Dcfull) return(0);
  107.  
  108.     fn = fopen(Devfile, "r");
  109.     ASSERT(fn != NULL, "CAN'T OPEN %s", Devfile);
  110.     for (pd = Devs; fgets(lb, 200, fn); pd++) {
  111.         lt = lastc(lb);
  112.         nr = getargs(lb, flds);
  113.         ASSERT(nr == 3, "BAD LINE %s", lb);
  114.         pd->D_line = flds[0];
  115.         pd->D_acu = flds[1];
  116.         pd->D_speed = atoi(flds[2]);
  117.         lb = lt;
  118.         ASSERT(lb < Devbuff + MAXDCH, "TOO LONG %s", Devbuff);
  119.         ASSERT(pd < Devs + MAXDEV, "TOO MANY DEVICES %d", MAXCODE);
  120.     }
  121.     pd->D_line = NULL;
  122.     fclose(fn);
  123.     ASSERT(pd > Devs, "BAD FILE %s", Devfile);
  124.     /* Now dialcodes, same way */
  125.     fn = fopen(Dialfile, "r");
  126.     ASSERT(fn != NULL, "CAN'T OPEN %s", Dialfile);
  127.     for (pc = Dialcodes; fgets(lc, 200, fn); pc++) {
  128.         lt = lastc(lc);
  129.         nr = getargs(lc, flds);
  130.         if (nr == 1) flds[nr++] = "";
  131.         ASSERT(nr == 2, "BAD LINE %s", lc);
  132.         pc->C_locs = flds[0];
  133.         pc->C_prefix = flds[1];
  134.         lc = lt;
  135.         ASSERT(lc < Codebuff + MAXCCH, "TOO LONG %s", Codebuff);
  136.         ASSERT(pc < Dialcodes + MAXCODE, "MANY DEVICES %d", MAXCODE);
  137.     }
  138.     pc->C_locs = 0;
  139.     fclose(fn);
  140.     return(0);
  141. }
  142.  
  143.  
  144. /***
  145.  *    ckdev(type, speed, ndev)
  146.  *    char *type, *speed;
  147.  *    int ndev;
  148.  *
  149.  *    ckdev  -  return the device number in table Devs for
  150.  *    a device with proper attributes.
  151.  *
  152.  *    return codes: >= 0 (ok)  |  FAIL
  153.  */
  154.  
  155. ckdev(type, speed, ndev)
  156. char *type, *speed;
  157. int ndev;
  158. {
  159.     int sp, acu;
  160.     struct Devices *pd;
  161.  
  162.     sp = atoi(speed);
  163.     acu =(strcmp(type, "ACU") == SAME);
  164.     for (pd = &Devs[ndev]; pd->D_line != NULL; pd++) {
  165.         if (sp != pd->D_speed)
  166.             continue;
  167.         if (acu && (strcmp(pd->D_acu, "0") != SAME)
  168.             && !mlock(pd->D_line))
  169.             return(ndev = pd - Devs);
  170.         if (!acu && (strcmp(pd->D_line, type) == SAME)
  171.             && !mlock(type))
  172.             return(ndev = pd - Devs);
  173.     }
  174.     return(FAIL);
  175. }
  176.  
  177.  
  178. /***
  179.  *    getto(flds)        connect to remote machine
  180.  *    char *flds[];
  181.  *
  182.  *    return codes:
  183.  *        >0  -  file number - ok
  184.  *        FAIL  -  failed
  185.  */
  186.  
  187. getto(flds)
  188. char *flds[];
  189. {
  190.     DEBUG(F_PHONE, "call: no. %s ", flds[4]);
  191.     DEBUG(4, "for sys %s ", flds[F_NAME]);
  192.  
  193.     if (strcmp(flds[F_LINE], "ACU") == SAME)
  194.         return(call(flds));
  195.     else
  196.         return(direct(flds));
  197. }
  198.  
  199. /***
  200.  *    call(flds)        call remote machine
  201.  *    char *flds[];
  202.  *
  203.  *    "flds" contains the call information (name, date, type, speed,
  204.  *    phone no. ...
  205.  *    Ndev has the device no.
  206.  *
  207.  *    return codes:
  208.  *        >0  -  file number  -  ok
  209.  *        FAIL  -  failed
  210.  */
  211.  
  212. call(flds)
  213. char *flds[];
  214. {
  215.     char *pno, pref[20], phone[20];
  216.     char *s1, *s2;
  217.     int dcr;
  218.     struct Codes *pc;
  219.  
  220.     pno = flds[F_PHONE];
  221.     s1 = pref; s2 = pno;
  222.     while (isalpha(*s2))
  223.         *s1++ = *s2++;
  224.     *s1 = '\0';
  225.     for (pc = Dialcodes; pc->C_locs; pc++)
  226.         if (strcmp(pc->C_locs, pref) == SAME) {
  227.             s1 = pc->C_prefix;
  228.             break;
  229.         }
  230.     sprintf(phone, "%s%s", s1, s2);
  231.     DEBUG(4, "Dial %s\n", phone);
  232.     dcr = dialup(phone, flds);
  233.     DEBUG(4, "dcr returned as %d\n", dcr);
  234.     if (dcr == FAIL)
  235.         return(FAIL);
  236.     return(dcr);
  237.  
  238. }
  239.  
  240.     /*  file descriptor for call unit  */
  241. int Dnf = 0;
  242.  
  243. /***
  244.  *    dialup(ph, flds)    dial remote machine
  245.  *    char *ph;
  246.  *    char *flds[];
  247.  *
  248.  *    return codes:
  249.  *        file descriptor  -  succeeded
  250.  *        FAIL  -  failed
  251.  */
  252.  
  253. dialup(ph, flds)
  254. char *ph;
  255. char *flds[];
  256. {
  257.     char dcname[20], dnname[20], phone[20];
  258.     struct Devices *pd;
  259.     int nw, lt, pid, dcf, ndev;
  260.     extern int Error;
  261.     extern alarmtr();
  262.  
  263.     for (ndev = 0;;ndev++) {
  264.         ndev = ckdev(flds[F_LINE], flds[F_SPEED], ndev);
  265.         if (ndev < 0) {
  266.             logent("AVAILABLE DEVICE", "NO");
  267.             DEBUG(4, "NO AVAILABLE DEVICE %s\n", "");
  268.             return(FAIL);
  269.         }
  270.         pd = &Devs[ndev];
  271.         sprintf(dnname, "/dev/%s", pd->D_acu);
  272.         /*  open call unit  */
  273.         Dnf = open(dnname, 1);
  274.         if (Dnf >= 0)
  275.             break;
  276.         delock(pd->D_line);
  277.     }
  278.     sprintf(dcname, "/dev/%s", pd->D_line);
  279.     sprintf(phone, "%s%s", ph, ACULAST);
  280.     DEBUG(4, "dc - %s, ", dcname);
  281.     DEBUG(4, "acu - %s\n", dnname);
  282.     if (setjmp(Sjbuf)) {
  283.         DEBUG(1, "DN write %s\n", "timeout");
  284.         logent("DIALUP DN write", "TIMEOUT");
  285.         kill(pid, 9);
  286.         close(Dnf);
  287.         return(FAIL);
  288.     }
  289.     signal(SIGALRM, alarmtr);
  290.     alarm(30);
  291.     if ((pid = fork()) == 0) {
  292.         sleep(2);
  293.         fclose(stdin);
  294.         fclose(stdout);
  295.         nw = write(Dnf, phone, lt = strlen(phone));
  296.         if (nw != lt) {
  297.             DEBUG(1, "ACU write %s\n", "error");
  298.             logent("DIALUP ACU write", "FAILED");
  299.             exit(1);
  300.         }
  301.         DEBUG(4, "ACU write ok%s\n", "");
  302.         exit(0);
  303.     }
  304.     /*  open line - will return on carrier */
  305.     dcf = open(dcname, 2);
  306.     DEBUG(4, "dcf is %d\n", dcf);
  307.     if (dcf < 0) {
  308.         DEBUG(1, "Line open %s\n", "failed");
  309.         logent("DIALUP LINE open", "FAILED");
  310.         alarm(0);
  311.         return(FAIL);
  312.     }
  313.     ioctl(dcf, TIOCHPCL, 0);
  314.     nw = wait(<);
  315.     alarm(0);
  316.     fflush(stdout);
  317.     fixline(dcf, pd->D_speed);
  318.     DEBUG(4, "Forked %d ", pid);
  319.     DEBUG(4, "Wait got %d ", nw);
  320.     DEBUG(4, "Status %o\n", lt);
  321.     if (lt != 0) {
  322.         close(dcf);
  323.         return(FAIL);
  324.     }
  325.     return(dcf);
  326. }
  327.  
  328.  
  329. /***
  330.  *    clsacu()    close call unit
  331.  *
  332.  *    return codes:  none
  333.  */
  334.  
  335. clsacu()
  336. {
  337.     if (Dnf > 0) {
  338.         close(Dnf);
  339.         Dnf = 0;
  340.     }
  341.     return;
  342. }
  343.  
  344.  
  345. /***
  346.  *    direct(flds)    connect to hardware line
  347.  *    char *flds[];
  348.  *
  349.  *    return codes:
  350.  *        >0  -  file number  -  ok
  351.  *        FAIL  -  failed
  352.  */
  353.  
  354. direct(flds)
  355. char *flds[];
  356. {
  357.     int dcr, ndev;
  358.     char dcname[20];
  359.  
  360.     ndev = 0;
  361.     if ((ndev = ckdev(flds[F_LINE], flds[F_SPEED], ndev)) < 0) {
  362.         logent("DEVICE", "NOT AVAILABLE");
  363.         return(FAIL);
  364.     }
  365.     sprintf(dcname, "/dev/%s", Devs[ndev].D_line);
  366.     signal(SIGALRM, alarmtr);
  367.     alarm(10);
  368.     if (setjmp(Sjbuf))
  369.         return(FAIL);
  370.     dcr = open(dcname, 2); /* read/write */
  371.     alarm(0);
  372.     if (dcr < 0)
  373.         return(FAIL);
  374.     fflush(stdout);
  375.     fixline(dcr, Devs[ndev].D_speed);
  376.     return(dcr);
  377. }
  378.  
  379.  
  380.  
  381. #define MAXC 300
  382.  
  383. /***
  384.  *    finds(sysnam, flds)    set system attribute vector
  385.  *    char *sysnam, *flds[];
  386.  *
  387.  *    return codes:
  388.  *        >0  -  number of arguments in vector - succeeded
  389.  *        CF_SYSTEM  -  system name not found
  390.  *        CF_TIME  -  wrong time to call
  391.  */
  392.  
  393. finds(sysnam, flds)
  394. char *sysnam, *flds[];
  395. {
  396.     FILE *fsys;
  397.     static char info[MAXC];
  398.     char **fnp;
  399.     int na;
  400.     int fnd = 0;
  401.  
  402.     for (fnp = Sysfiles; *fnp != NULL && !fnd; fnp++) {
  403.         fsys = fopen(*fnp, "r");
  404.         if (fsys == NULL)
  405.             continue;
  406.         while (!fnd && (fgets(info, MAXC, fsys) != NULL)) {
  407.             na = getargs(info, flds);
  408.             if (prefix(sysnam, flds[F_NAME]))
  409.                 fnd = 1;
  410.         }
  411.         fclose(fsys);
  412.     }
  413.     if (fnd == 0)
  414.         return(CF_SYSTEM);
  415.     /* format of fields
  416.      *    0 name;
  417.      *    1 time
  418.      *    2 acu/hardwired
  419.      *    3 speed
  420.      *    etc
  421.      */
  422.     if (ifdate(flds[F_TIME]) == 0) {
  423.         DEBUG(1, "Wrong time to call %s\n", sysnam);
  424.         logent(sysnam, "WRONG TIME TO CALL");
  425.         return(CF_TIME);
  426.     }
  427.     return(na);
  428. }
  429.  
  430.  
  431. /***
  432.  *    login(nf, flds, dcr)        do log conversation
  433.  *    char *flds[];
  434.  *    int nf;
  435.  *
  436.  *    return codes:  0  |  FAIL
  437.  */
  438.  
  439. login(nf, flds, fn)
  440. char *flds[];
  441. int nf, fn;
  442. {
  443.     char *want, *altern;
  444.     extern char *index();
  445.     int k, ok;
  446.  
  447.     ASSERT(nf > 4, "TOO FEW LOG FIELDS %d", nf);
  448.     for (k = F_LOGIN; k < nf; k += 2) {
  449.         want = flds[k];
  450.         ok = FAIL;
  451.         while (ok != 0) {
  452.             altern = index(want, '-');
  453.             if (altern != NULL)
  454.                 *altern++ = '\0';
  455.             DEBUG(4, "wanted %s ", want);
  456.             ok = expect(want, fn);
  457.             DEBUG(4, "got %s\n", ok ? "?" : "that");
  458.             if (ok == 0)
  459.                 break;
  460.             if (altern == NULL) {
  461.                 logent("LOGIN", "FAILED");
  462.                 return(FAIL);
  463.             }
  464.             want = index(altern, '-');
  465.             if (want != NULL)
  466.                 *want++ = '\0';
  467.             sendthem(altern, fn);
  468.         }
  469.         sleep(2);
  470.         sendthem(flds[k+1], fn);
  471.     }
  472.     return(0);
  473. }
  474.  
  475.  
  476. struct sg_spds {int sp_val, sp_name;} spds[] = {
  477.     { 300,  B300},
  478.     {1200, B1200},
  479.     {4800, B4800},
  480.     {9600, B9600},
  481.     {0, 0} };
  482.  
  483. /***
  484.  *    fixline(tty, spwant)    set speed/echo/mode...
  485.  *    int tty, spwant;
  486.  *
  487.  *    return codes:  none
  488.  */
  489.  
  490. fixline(tty, spwant)
  491. int tty, spwant;
  492. {
  493.     struct sgttyb ttbuf;
  494.     struct sg_spds *ps;
  495.     int speed = -1;
  496.     int ret;
  497.  
  498.     for (ps = spds; ps->sp_val; ps++)
  499.         if (ps->sp_val == spwant)
  500.             speed = ps->sp_name;
  501.     ASSERT(speed >= 0, "BAD SPEED %d", speed);
  502.     ioctl(tty, TIOCGETP, &ttbuf);
  503.     ttbuf.sg_flags |=(ANYP|RAW);
  504.     ttbuf.sg_flags &= ~(ECHO|ALLDELAY);
  505.     ttbuf.sg_ispeed = ttbuf.sg_ospeed = speed;
  506.     DEBUG(4, "Speed: want %d ", spwant);
  507.     DEBUG(4, "use %o ", speed);
  508.     DEBUG(4, "ps %d\n", ps-spds);
  509.     ret = ioctl(tty, TIOCSETP, &ttbuf);
  510.     ASSERT(ret >= 0, "RETURN FROM STTY %d", ret);
  511.     ioctl(tty, TIOCHPCL, 0);
  512.     ioctl(tty, TIOCEXCL, 0);
  513.     return;
  514. }
  515.  
  516.  
  517. #define MR 300
  518.  
  519. int Error = 0;
  520.  
  521. /***
  522.  *    expect(str, fn)    look for expected string
  523.  *    char *str;
  524.  *
  525.  *    return codes:
  526.  *        0  -  found
  527.  *        FAIL  -  lost line or too many characters read
  528.  *        some character  -  timed out
  529.  */
  530.  
  531. expect(str, fn)
  532. char *str;
  533. int fn;
  534. {
  535.     static char rdvec[MR];
  536.     extern alarmtr();
  537.     char *rp = rdvec;
  538.     int nextch = 0, kr;
  539.  
  540.     if (strcmp(str, "\"\"") == SAME)
  541.         return(0);
  542.     *rp = 0;
  543.     if (setjmp(Sjbuf)) {
  544.         return(FAIL);
  545.     }
  546.     signal(SIGALRM, alarmtr);
  547.     while (notin(str, rdvec)) {
  548.         alarm(MAXCHARTIME);
  549.         kr = read(fn, &nextch, 1);
  550.         if (kr <= 0) {
  551.             DEBUG(4, "kr - %d\n", kr);
  552.             alarm(0);
  553.             DEBUG(4, "lost line kr - %d, ", kr);
  554.             DEBUG(4, "fn - %d\n", fn);
  555.             logent("LOGIN", "LOST LINE");
  556.             return(FAIL);
  557.         }
  558.         {
  559.         int c;
  560.         c = nextch & 0177;
  561.         DEBUG(4, "%c", c > 040 ? c : '_');
  562.         }
  563.         if ((*rp = nextch & 0177) != '\0')
  564.             rp++;
  565.         *rp = '\0';
  566.         if (rp >= rdvec + MR)
  567.             return(FAIL);
  568.     }
  569.     alarm(0);
  570.     return(0);
  571. }
  572.  
  573.  
  574. /***
  575.  *    alarmtr()  -  catch alarm routine for "expect".
  576.  */
  577.  
  578. alarmtr()
  579. {
  580.     longjmp(Sjbuf, 1);
  581. }
  582.  
  583.  
  584. /***
  585.  *    sendthem(str, fn)    send line of login sequence
  586.  *    char *str;
  587.  *
  588.  *    return codes:  none
  589.  */
  590.  
  591. sendthem(str, fn)
  592. char *str;
  593. int fn;
  594. {
  595.     int nw, ns;
  596.     int nulls;
  597.  
  598.     if (prefix("BREAK", str)) {
  599.         sscanf(&str[5], "%1d", &nulls);
  600.         if (nulls <= 0 || nulls > 10)
  601.             nulls = 3;
  602.         /* send break */
  603.         DEBUG(5, "%s,", str);
  604.         DEBUG(5, "%d\n", nulls);
  605.         genbrk(fn, Bspeed, nulls);
  606.         return;
  607.     }
  608.  
  609.     if (strcmp(str, "EOT") == SAME) {
  610.         write(fn, EOTMSG, strlen(EOTMSG));
  611.         return;
  612.     }
  613.     if (strcmp(str, "") != SAME) {
  614.         nw = write(fn, str, ns = strlen(str));
  615.         ASSERT(nw == ns, "BAD WRITE $s", str);
  616.     }
  617.     write(fn, "\n", 1);
  618.     return;
  619. }
  620.  
  621.  
  622. /***
  623.  *    genbrk(fn)    send equivalent to break
  624.  *
  625.  *    return codes;  none
  626.  */
  627.  
  628. genbrk(fn, bspeed, bnulls)
  629. int fn, bspeed, bnulls;
  630. {
  631.     struct sgttyb ttbuf;
  632.     int ret, sospeed;
  633.  
  634.     ret = ioctl(fn, TIOCGETP, &ttbuf);
  635.     DEBUG(5, "ioctl ret %d\n", ret);
  636.     sospeed = ttbuf.sg_ospeed;
  637.     ttbuf.sg_ospeed = bspeed;
  638.     ret = ioctl(fn, TIOCSETP, &ttbuf);
  639.     DEBUG(5, "ioctl ret %d\n", ret);
  640.     ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", bnulls);
  641.     ASSERT(ret > 0, "BAD WRITE genbrk %d", ret);
  642.     ttbuf.sg_ospeed = sospeed;
  643.     ret = ioctl(fn, TIOCSETP, &ttbuf);
  644.     ret = write(fn, "@", 1);
  645.     ASSERT(ret > 0, "BAD WRITE genbrk %d", ret);
  646.     DEBUG(4, "sent BREAK nulls - %d\n", bnulls);
  647.     return;
  648. }
  649.  
  650.  
  651. /***
  652.  *    notin(sh, lg)    check for occurrence of substring "sh"
  653.  *    char *sh, *lg;
  654.  *
  655.  *    return codes:
  656.  *        0  -  found the string
  657.  *        1  -  not in the string
  658.  */
  659.  
  660. notin(sh, lg)
  661. char *sh, *lg;
  662. {
  663.     while (*lg != '\0') {
  664.         if (prefix(sh, lg))
  665.             return(0);
  666.         else
  667.             lg++;
  668.     }
  669.     return(1);
  670. }
  671.  
  672.  
  673. /*******
  674.  *    ifdate(s)
  675.  *    char *s;
  676.  *
  677.  *    ifdate  -  this routine will check a string (s)
  678.  *    like "MoTu0800-1730" to see if the present
  679.  *    time is within the given limits.
  680.  *
  681.  *    String alternatives:
  682.  *        Wk - Mo thru Fr
  683.  *        zero or one time means all day
  684.  *        Any - any day
  685.  *
  686.  *    return codes:
  687.  *        0  -  not within limits
  688.  *        1  -  within limits
  689.  */
  690.  
  691. ifdate(s)
  692. char *s;
  693. {
  694.     static char *days[]={
  695.         "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0
  696.     };
  697.     long clock;
  698.     int i, tl, th, tn, dayok=0;
  699.     struct tm *localtime();
  700.     struct tm *tp;
  701.  
  702.     time(&clock);
  703.     tp = localtime(&clock);
  704.     while (isalpha(*s)) {
  705.         for (i = 0; days[i]; i++) {
  706.             if (prefix(days[i], s))
  707.                 if (tp->tm_wday == i)
  708.                     dayok = 1;
  709.         }
  710.  
  711.         if (prefix("Wk", s))
  712.             if (tp->tm_wday >= 1 && tp->tm_wday <= 5)
  713.                 dayok = 1;
  714.         if (prefix("Any", s))
  715.             dayok = 1;
  716.         s++;
  717.     }
  718.  
  719.     if (dayok == 0)
  720.         return(0);
  721.     i = sscanf(s, "%d-%d", &tl, &th);
  722.     tn = tp->tm_hour * 100 + tp->tm_min;
  723.     if (i < 2)
  724.         return(1);
  725.     if (tn >= tl && tn <= th)
  726.         return(1);
  727.     return(0);
  728. }
  729.