home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / INTERNET / UPC2S1.ZIP / CHECKTIM.C < prev    next >
C/C++ Source or Header  |  1993-09-20  |  14KB  |  337 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    c h e c k t i m . c                                             */
  3. /*                                                                    */
  4. /*    Time of day validation routine for UUPC/extended                */
  5. /*--------------------------------------------------------------------*/
  6.  
  7. /*--------------------------------------------------------------------*/
  8. /*       Changes Copyright (c) 1989-1993 by Kendra Electronic         */
  9. /*       Wonderworks.                                                 */
  10. /*                                                                    */
  11. /*       All rights reserved except those explicitly granted by       */
  12. /*       the UUPC/extended license agreement.                         */
  13. /*--------------------------------------------------------------------*/
  14.  
  15. /*--------------------------------------------------------------------*/
  16. /*                          RCS Information                           */
  17. /*--------------------------------------------------------------------*/
  18.  
  19. /*
  20.  *    $Id: checktim.c 1.2 1993/09/20 04:46:34 ahd Exp $
  21.  *
  22.  *    Revision history:
  23.  *    $Log: checktim.c $
  24.  * Revision 1.2  1993/09/20  04:46:34  ahd
  25.  * OS/2 2.x support (BC++ 1.0 support)
  26.  * TCP/IP support from Dave Watt
  27.  * 't' protocol support
  28.  *
  29.  */
  30.  
  31. /*--------------------------------------------------------------------*/
  32. /*                        System include files                        */
  33. /*--------------------------------------------------------------------*/
  34.  
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include <stdlib.h>
  38. #include <time.h>
  39.  
  40. /*--------------------------------------------------------------------*/
  41. /*                    UUPC/extended include files                     */
  42. /*--------------------------------------------------------------------*/
  43.  
  44. #include "lib.h"
  45. #include "checktim.h"
  46.  
  47. /*--------------------------------------------------------------------*/
  48. /*                          Global variables                          */
  49. /*--------------------------------------------------------------------*/
  50.  
  51. currentfile();
  52.  
  53. /*--------------------------------------------------------------------*/
  54. /*                          Local functions                           */
  55. /*--------------------------------------------------------------------*/
  56.  
  57. static char checkone( char *input, size_t hhmm, int weekday );
  58.  
  59. /*--------------------------------------------------------------------*/
  60. /*   The following day values are based on the fact the               */
  61. /*   localtime() call returns the day of the week as a value zero     */
  62. /*   (0) through six (6), which is converted into the bit number      */
  63. /*   and then AND'ed against the date mask.                           */
  64. /*--------------------------------------------------------------------*/
  65.  
  66. #define SUN 0x80
  67. #define MON 0x40
  68. #define TUE 0x20
  69. #define WED 0x10
  70. #define THU 0x08
  71. #define FRI 0x04
  72. #define SAT 0x02
  73. #define NEVER 0x00
  74. #define WEEKEND (SAT | SUN)
  75. #define WEEKDAY (MON | TUE | WED | THU | FRI)
  76. #define ANY (WEEKEND | WEEKDAY)
  77.  
  78. /*--------------------------------------------------------------------*/
  79. /*   Table of values for schedules.  Based on values given for        */
  80. /*   legal schedule keywords in "Managing uucp and Usenet" by         */
  81. /*   O'Reilly & Associates.  Multiple entries for a single keyword    */
  82. /*   are processed in logical OR fashion, just as multiple entries    */
  83. /*   for the same host in L.sys are treated in a logical OR           */
  84. /*   fashion.                                                         */
  85. /*                                                                    */
  86. /*   Timing windows are adjusted five minutes away from higher        */
  87. /*   telephone rates in an attempt to avoid massive charges           */
  88. /*   because of inaccurate PC clocks and the fact that a telephone    */
  89. /*   call generally requires more than one minute if the system is    */
  90. /*   trying to do useful work.                                        */
  91. /*                                                                    */
  92. /*   Does not support multiple keywords in one token                  */
  93. /*   (TuFr0800-0805), but allows multiple tokens                      */
  94. /*   (Tu0800-805,Fr0800-0805) on one line.                            */
  95. /*                                                                    */
  96. /*   The NonPeak keyword has been corrected to the current (May       */
  97. /*   1989) NonPeak hours for Telenet's PC-Pursuit.  However, keep     */
  98. /*   in mind the PC-Pursuit customer agreement specifies that you     */
  99. /*   can't use PC-Pursuit to network multiple PC's, so thou shalt     */
  100. /*   not use PC-Pursuit from a central mail server.  *sigh*           */
  101. /*                                                                    */
  102. /*   I also have Reach-Out America from ATT, for which night rates    */
  103. /*   begin at 10:00 pm.  It is duly added to the table.               */
  104. /*--------------------------------------------------------------------*/
  105.  
  106. static struct Table {
  107.    char *keyword;
  108.    int wdays;
  109.    unsigned int start;
  110.    unsigned int end;
  111.  
  112. } table[] = {
  113.    { "Any",     ANY,         0, 2400},
  114.    { "Wk",      WEEKDAY,     0, 2400},
  115.    { "Su",      SUN,         0, 2400},
  116.    { "Mo",      MON,         0, 2400},
  117.    { "Tu",      TUE,         0, 2400},
  118.    { "We",      WED,         0, 2400},
  119.    { "Th",      THU,         0, 2400},
  120.    { "Fr",      FRI,         0, 2400},
  121.    { "Sa",      SAT,         0, 2400},
  122.    { "Evening", WEEKDAY,  1705,  755},
  123.    { "Evening", WEEKEND,     0, 2400},
  124.    { "Night",   WEEKDAY,  2305,  755},
  125.    { "Night",   SAT,         0, 2400},
  126.    { "Night",   SUN,      2305, 1655},
  127.    { "NonPeak", WEEKDAY,  1805,  655}, /* Subject to change at TELENET's whim */
  128.    { "NonPeak", WEEKEND,     0, 2400},
  129.    { "ROA",     WEEKDAY,  2205,  755}, /* Reach Out America (sm) (AT&T)       */
  130.    { "ROA",     SAT,         0, 2400}, /* Reach Out America (sm) (AT&T)       */
  131.    { "ROA",     SUN,      2205, 1655}, /* Reach Out America (sm) (AT&T)       */
  132.    { "Never",   NEVER,       0, 2400},
  133.    {  nil(char) }
  134. }; /* table */
  135.  
  136. /*--------------------------------------------------------------------*/
  137. /*    c h e c k t i m e                                               */
  138. /*                                                                    */
  139. /*    Validate a time of day field; returns lowest grade              */
  140. /*--------------------------------------------------------------------*/
  141.  
  142. char checktime(const char *xtime)
  143. {
  144.  
  145.    struct tm *tm_now;
  146.    time_t secs_now;
  147.    size_t hhmm;
  148.    char  buf[BUFSIZ];
  149.    char  *token;
  150.    char  *nexttoken;
  151.    char  bestgrade = '\0';    /* No grade found yet                  */
  152.    int   weekday;
  153.  
  154.    strcpy(buf,xtime);         /* Copy time to local buffer we can alter */
  155.    time(&secs_now);
  156.    tm_now = localtime(&secs_now);
  157.                                        /* Create structure with time    */
  158.    weekday = SUN >> tm_now->tm_wday;   /* Get day of week as single bit */
  159.    hhmm = tm_now->tm_hour*100 + tm_now->tm_min;
  160.    nexttoken = buf;           /* First pass, look at start of buffer    */
  161.  
  162.    while ((bestgrade < ALL_GRADES) &&
  163.           ((token = strtok(nexttoken,",")) != NULL))
  164.    {
  165.       char grade = checkone( token, hhmm, weekday);
  166.  
  167.       if ( bestgrade < grade )
  168.             bestgrade = grade;
  169.  
  170.       nexttoken = NULL;       /* Continue parsing same string           */
  171.  
  172.    } /* while (!(dial) && ((token = strtok(nexttoken,",")) != NULL) ) */
  173.  
  174. /*--------------------------------------------------------------------*/
  175. /*            Report our results and return to the caller             */
  176. /*--------------------------------------------------------------------*/
  177.  
  178.    return (bestgrade);
  179.  
  180. } /*checktime*/
  181.  
  182. /*--------------------------------------------------------------------*/
  183. /*    c h e c k o n e                                                 */
  184. /*                                                                    */
  185. /*    Process one time field for checktime                            */
  186. /*--------------------------------------------------------------------*/
  187.  
  188. static char checkone( char *input, size_t hhmm, int weekday )
  189. {
  190.    char  tdays[20];           /* String version of user tokens       */
  191.    char  tstart[20];
  192.    char  tend[20];
  193.    size_t istart;
  194.    size_t iend;
  195.    struct Table *tptr;
  196.    boolean dial = FALSE;      /* Assume we cannot dial               */
  197.    char  found = 0;           /* Did not yet find current keyword    */
  198.    char grade = ALL_GRADES;   /* Default grade if none specified     */
  199.  
  200.    char *slash = strchr( input, '/' );
  201.  
  202. /*--------------------------------------------------------------------*/
  203. /*     Parse a day/time combination from the L.SYS file         *     */
  204. /*--------------------------------------------------------------------*/
  205.  
  206.    strcpy(tstart,"0000");  /* Set default times to all day           */
  207.    strcpy(tend,"2400");
  208.  
  209. /*--------------------------------------------------------------------*/
  210. /*                      Determine the call grade                      */
  211. /*--------------------------------------------------------------------*/
  212.  
  213.    if ( slash != NULL )
  214.    {
  215.  
  216.       if (strlen( slash ) != 2)
  217.       {
  218.          printmsg(0,"Invalid call grade in field: %s", input );
  219.          panic();
  220.       }
  221.  
  222.       *slash++ = '\0';     /* Terminate original string              */
  223.       grade = *slash;      /* Save the grade the user wanted         */
  224.  
  225.    } /* if ( slash != NULL ) */
  226.  
  227. /*--------------------------------------------------------------------*/
  228. /*         Get the period and time limits the user specified          */
  229. /*--------------------------------------------------------------------*/
  230.  
  231.     sscanf(input,
  232.            "%[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]"
  233.            "%[0123456789]-%[0123456789]", tdays, tstart, tend);
  234.  
  235. /*--------------------------------------------------------------------*/
  236. /*          Verify the lengths of the fields the user specified       */
  237. /*--------------------------------------------------------------------*/
  238.  
  239.    if (strlen(tstart) >= sizeof tstart)
  240.    {
  241.       printf( "%d character buffer overflow \"%s\"\n",
  242.                sizeof tstart , tstart );
  243.       panic();
  244.    }
  245.  
  246.    if (strlen(tend) >= sizeof tend)
  247.    {
  248.       printf( "%d character buffer overflow \"%s\"\n",
  249.                sizeof tend , tend );
  250.       panic();
  251.    }
  252.  
  253.    if (strlen(tdays) >= sizeof tdays)
  254.    {
  255.       printf( "%d character buffer overflow \"%s\"\n",
  256.                sizeof tdays, tdays );
  257.       panic();
  258.    }
  259.  
  260.    printmsg(8,"checkone: %s broken into \"%s\" from \"%s\" to \"%s\""
  261.               " with grade %c",
  262.             input,tdays,tstart,tend,grade );
  263.  
  264.    istart = atoi(tstart);  /* Convert start/end times to binary          */
  265.    iend  = atoi(tend);
  266.  
  267. /*--------------------------------------------------------------------*/
  268. /*    Handle case of midnight specified in such a way that the        */
  269. /*    time wraps through the daylight hours; we'll take the           */
  270. /*    conservative approach that the user really meant to start at    */
  271. /*    midnight.                                                       */
  272. /*--------------------------------------------------------------------*/
  273.  
  274.    if ((istart > iend) && (istart == 2400))
  275.       istart = 0000;
  276.  
  277. /*--------------------------------------------------------------------*/
  278. /*                  Search for the requested keyword                  */
  279. /*--------------------------------------------------------------------*/
  280.  
  281.    for (tptr = table, found = FALSE;
  282.          (tptr->keyword != nil(char)) && !dial; tptr++)
  283.    {
  284.  
  285. /*--------------------------------------------------------------------*/
  286. /*      We found the keyword, see if today qualifies for dialing      */
  287. /*--------------------------------------------------------------------*/
  288.  
  289.       if (equal(tptr->keyword,tdays))
  290.       {
  291.          found = TRUE;     /* Win or Lose, keyword is valid          */
  292.          if (weekday & tptr->wdays)    /* Can we dial out today?     */
  293.          {                             /* Yes --> Check the time     */
  294.  
  295. /*--------------------------------------------------------------------*/
  296. /*    This entry allows us to dial out today; now determine if the    */
  297. /*    time slot in the table allows dialing.                          */
  298. /*--------------------------------------------------------------------*/
  299.  
  300.             if (tptr->start > tptr->end)  /* span midnight?          */
  301.                dial = (tptr->start <= hhmm) || (tptr->end >= hhmm);
  302.             else
  303.                dial = (tptr->start <= hhmm) && (tptr->end >= hhmm);
  304.  
  305. /*--------------------------------------------------------------------*/
  306. /*    Now do a logical AND of that time with the time the user        */
  307. /*    specified in L.sys for this particular system.                  */
  308. /*--------------------------------------------------------------------*/
  309.  
  310.             if (istart > iend)            /* span midnight?          */
  311.                dial = ((istart <= hhmm) || (iend >= hhmm)) && dial;
  312.             else if (istart == iend)
  313.                dial = (istart == hhmm) && dial;
  314.             else
  315.                dial = (istart <= hhmm) && (iend >= hhmm) && dial;
  316.          } /* if */
  317.       } /* if */
  318.    } /* for */
  319.  
  320.    if (!found)
  321.       printmsg(0,"checkone: keyword \"%s\" not found",input);
  322.  
  323.    printmsg(3,"checkone: call window \"%s\" %s",
  324.          input,
  325.          dial ? "open" :"closed");
  326.  
  327. /*--------------------------------------------------------------------*/
  328. /*                Return success or failure to caller                 */
  329. /*--------------------------------------------------------------------*/
  330.  
  331.    if ( dial )
  332.       return grade;
  333.    else
  334.       return '\0';
  335.  
  336. } /* checkone */
  337.