home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BSRC_250.LZH / SCHED.C < prev    next >
C/C++ Source or Header  |  1991-09-15  |  16KB  |  517 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*           This module was originally written by Bob Hartman              */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*                     BinkleyTerm Scheduler Routines                       */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.250.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  27. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  28. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  29. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  30. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /* You can contact Bit Bucket Software Co. at any one of the following      */
  34. /* addresses:                                                               */
  35. /*                                                                          */
  36. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  37. /* P.O. Box 460398                AlterNet 7:491/0                          */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                Internet f491.n343.z1.fidonet.org         */
  40. /*                                                                          */
  41. /* Please feel free to contact us at any time to share your comments about  */
  42. /* our software and/or licensing policies.                                  */
  43. /*                                                                          */
  44. /*--------------------------------------------------------------------------*/
  45.  
  46. /* Include this file before any other includes or defines! */
  47.  
  48. #include "includes.h"
  49.  
  50.  
  51. /**************************************************************************/
  52. /*** This MUST be exactly 16 total bytes including the terminating null ***/
  53. /*** or the routines read_sched() and write_sched() must be changed!!!! ***/
  54. /**************************************************************************/
  55. static char *BinkSched = PRDCT_SHRT "Schedule 08";      /* Version of scheduler   */
  56.  
  57.  
  58. void find_event ()
  59. {
  60.    time_t long_time;
  61.    struct tm *tm;
  62.    
  63.    int cur_day;
  64.    int our_time;
  65.    int i;
  66.    char cmds[150];
  67.  
  68.    BINK_EVENT evt;
  69.  
  70.    /* Get the current time into a structure */
  71.  
  72.    (void) time (&long_time);
  73.    tm = localtime (&long_time);
  74.  
  75.    cur_day = 1 << tm->tm_wday;
  76.  
  77.    our_time = (tm->tm_hour % 24) * 60 + (tm->tm_min % 60);
  78.  
  79.    cur_event = -1;
  80.  
  81.    if (tm->tm_mday != hist.which_day)
  82.       {
  83.       write_stats ();
  84.       (void) memset (&hist, 0, sizeof (HISTORY));
  85.       hist.which_day = tm->tm_mday;
  86.       if (un_attended && fullscreen)
  87.          {
  88.          do_today ();
  89.          sb_show ();
  90.          }
  91.       }
  92.  
  93.    /* Make the month 1-based instead of 0-based */
  94.    tm->tm_mon += 1;
  95.  
  96.    /* Go through the events from top to bottom */
  97.    for (i = 0; i < num_events; i++)
  98.       {
  99.       if (our_time >= e_ptrs[i].minute)
  100.          {
  101.          evt = e_ptrs[i];
  102.  
  103.          if ((cur_day & evt.days) &&
  104.              ((!evt.day) || (evt.day == (char)tm->tm_mday)) &&
  105.              ((!evt.month) || (evt.month == (char)tm->tm_mon)))
  106.             {
  107.             if (((our_time - evt.minute) < evt.length) ||
  108.             ((our_time == evt.minute) && (evt.length == 0)) ||
  109.             ((evt.behavior & MAT_FORCED) && (evt.last_ran != (char)tm->tm_mday)))
  110.                {
  111.                /* Are we not supposed to force old events */
  112.                if (((our_time - evt.minute) > evt.length) && (noforce))
  113.                   {
  114.                   e_ptrs[i].last_ran = (char) tm->tm_mday;
  115.                   continue;
  116.                   }
  117.  
  118.                if (evt.last_ran != (char) tm->tm_mday)
  119.                   {
  120.                   cur_event = i;
  121.                   do_ready (MSG_TXT(M_READY_WAITING));
  122.                   status_line (MSG_TXT(M_STARTING_EVENT), i + 1);
  123.  
  124.                   if (!blank_on_key)
  125.                      screen_blank = 0;
  126.  
  127.                   more_mail = 1;
  128.  
  129.                   /* Mark that this one is running */
  130.                   e_ptrs[i].last_ran = (char) tm->tm_mday;
  131.  
  132.                   /*
  133.                    * Mark that we have not yet skipped it. After all, it just
  134.                    * started! 
  135.                    */
  136.                   e_ptrs[i].behavior &= ~MAT_SKIP;
  137.  
  138.                   /* Write out the schedule */
  139.                   write_sched ();
  140.  
  141.                   /* If we are supposed to exit, then do it */
  142.                   if (evt.errlevel[0])
  143.                      {
  144.                      status_line (MSG_TXT(M_EVENT_EXIT), evt.errlevel[0]);
  145.  
  146.                      screen_blank = 0;
  147.                      errl_exit (evt.errlevel[0]);
  148.                      }
  149.                   else if (packer != NULL)
  150.                      {
  151.                      if (!blank_on_key)
  152.                         screen_blank = 0;
  153.                      status_line (MSG_TXT(M_CLEAN_PACK));
  154.                      mdm_init (modem_busy);
  155.                      exit_DTR ();
  156.                      screen_clear ();
  157.                      vfossil_cursor (1);
  158.                      if (cleanup != NULL)
  159.                         {
  160.                         (void) strcpy (cmds, cleanup);
  161.                         if (i >= 0)
  162.                            (void) strcat (cmds, evt.cmd);
  163.                         b_spawn (cmds);
  164.                         }
  165.                      (void) strcpy (cmds, packer);
  166.                      if (i >= 0)
  167.                         (void) strcat (cmds, evt.cmd);
  168.                      b_spawn (cmds);
  169.                      if (fullscreen)
  170.                         {
  171.                         screen_clear ();
  172.                         sb_dirty ();
  173.                         opening_banner ();
  174.                         mailer_banner ();
  175.                         }
  176.                      RAISE_DTR ();
  177.                      mdm_init (modem_init);
  178.                      status_line (MSG_TXT(M_AFTER_CLEAN_PACK));
  179.                      waitfor_line = timerset ((unsigned int)6000);
  180.                      }
  181.  
  182.                   cur_event = i;
  183.                   max_connects = evt.with_connect;
  184.                   max_noconnects = evt.no_connect;
  185.                   set_up_outbound ();
  186.                   }
  187.                else
  188.                   {
  189.                   /* Don't do events that have been exited already */
  190.                   if (evt.behavior & MAT_SKIP)
  191.                      continue;
  192.                   }
  193.  
  194.                cur_event = i;
  195.  
  196.                if (evt.behavior & MAT_NOREQ)
  197.                   {
  198.                   matrix_mask &= ~TAKE_REQ;
  199.                   no_requests = 1;
  200.                   }
  201.                else
  202.                   {
  203.                   matrix_mask |= TAKE_REQ;
  204.                   no_requests = 0;
  205.                   }
  206.  
  207.                if (evt.behavior & MAT_NOOUTREQ)
  208.                   {
  209.                   requests_ok = 0;
  210.                   }
  211.                else
  212.                   {
  213.                   requests_ok = 1;
  214.                   }
  215.  
  216.                max_connects = evt.with_connect;
  217.                max_noconnects = evt.no_connect;
  218.  
  219.                break;
  220.                }
  221.             }
  222.          }
  223.       }
  224. }
  225.  
  226. void read_sched ()
  227. {
  228.    char temp1[80], temp2[80];
  229.    struct stat buffer1, buffer2;
  230.  
  231.     HFILE stream;
  232.     USHORT got;
  233.  
  234.    (void) strcpy (temp1, BINKpath);
  235.    (void) strcpy (temp2, BINKpath);
  236.    (void) strcat (temp1, PRDCT_PRFX ".Scd");
  237.    (void) strcat (temp2, PRDCT_PRFX ".Evt");
  238.  
  239.    if (stat (temp1, &buffer1) == -1)
  240.       {
  241.       return;
  242.       }
  243.  
  244.    if (stat (temp2, &buffer2) == -1)
  245.       {
  246.       (void) strcpy (temp2, BINKpath);
  247.       (void) strcat (temp2, config_name);
  248.       if (stat (temp2, &buffer2) == -1)
  249.          {
  250.          return;
  251.          }
  252.       }
  253.  
  254.    if ((buffer1.st_atime < buffer2.st_atime) ||
  255.        (buffer1.st_size < sizeof (BINK_EVENT)))
  256.       {
  257.       return;
  258.       }
  259.  
  260.   if ((stream = open (temp1, O_RDONLY|O_BINARY)) == -1)
  261.       {
  262.       return;
  263.       }
  264.  
  265.    temp1[0] = '\0';
  266.    (void) read (stream, temp1, 16);
  267.    if (strcmp (temp1, BinkSched) != 0)
  268.       {
  269.       (void) close (stream);
  270.       return;
  271.       }
  272.  
  273.    (void) read (stream,  (char *) &hist, (int) sizeof (HISTORY));
  274.  
  275.    (void) _dos_read (stream, (char far *)e_ptrs, 
  276.            (unsigned int) (buffer1.st_size - 16 - sizeof (HISTORY)), &got);
  277.  
  278.    got_sched = 1;
  279.  
  280.    num_events = (int) ((buffer1.st_size - 16 - sizeof (HISTORY)) / sizeof (BINK_EVENT));
  281.  
  282.    (void) close (stream);
  283.    return;
  284. }
  285.  
  286. void write_sched ()
  287. {
  288.    char temp1[80], temp2[80];
  289.    int i;
  290.    struct stat buffer1;
  291.    struct utimbuf times;
  292.    long t;
  293.  
  294.    HFILE stream;
  295.    USHORT got;
  296.  
  297.    /* Get the current time */
  298.    t = time (NULL);
  299.  
  300.    (void) strcpy (temp1, BINKpath);
  301.    (void) strcpy (temp2, BINKpath);
  302.    (void) strcat (temp1, PRDCT_PRFX ".Scd");
  303.    (void) strcat (temp2, PRDCT_PRFX ".Evt");
  304.  
  305.    /* Get the current stat for .Evt file */
  306.  
  307.    if (stat (temp2, &buffer1) == -1)
  308.       {
  309.       (void) strcpy (temp2, BINKpath);
  310.       (void) strcat (temp2, config_name);
  311.       if (stat (temp2, &buffer1) == -1)
  312.          {
  313.          return;
  314.          }
  315.       }
  316.  
  317.    /*
  318.     * If it is newer than current time, we have a problem and we must
  319.     * reset the file date - yucky, but it will probably work 
  320.     */
  321.    if (t < buffer1.st_atime)
  322.       {
  323.       times.UT_ACTIME = buffer1.st_atime;
  324.       times.modtime = buffer1.st_atime;
  325.       status_line (MSG_TXT(M_DATE_PROBLEM));
  326.       }
  327.    else
  328.       {
  329.       times.UT_ACTIME = t;
  330.       times.modtime = t;
  331.       }
  332.  
  333.   if ((stream = open (temp1, O_CREAT|O_RDWR|O_BINARY, S_IREAD|S_IWRITE)) == -1)
  334.       {
  335.       return;
  336.       }
  337.  
  338.    (void) write (stream, BinkSched, 16);
  339.    (void) write (stream, (char *) &hist, (int) sizeof (HISTORY));
  340.  
  341.    for (i = 0; i < num_events; i++)
  342.       {
  343.       /* If it is skipped, but not dynamic, reset it */
  344.       if ((e_ptrs[i].behavior & MAT_SKIP) &&
  345.           (!(e_ptrs[i].behavior & MAT_DYNAM)))
  346.          {
  347.          e_ptrs[i].behavior &= ~MAT_SKIP;
  348.          }
  349.  
  350.       }
  351.  
  352.    (void) _dos_write (stream, (char far *)e_ptrs, 
  353.            (unsigned int) (num_events * sizeof (BINK_EVENT)), &got);
  354.  
  355.    (void) close (stream);
  356.  
  357.    (void) utime (temp1, (UTIMBUF *)×);
  358.  
  359.    return;
  360. }
  361.  
  362. void write_stats ()
  363. {
  364.    char temp1[80];
  365.    FILE *f;
  366.  
  367.    (void) strcpy (temp1, BINKpath);
  368.    (void) strcat (temp1, PRDCT_PRFX ".Day");
  369.  
  370.    if ((f = fopen (temp1, "wb")) == NULL)
  371.       {
  372.       return;
  373.       }
  374.  
  375.    (void) fwrite (&hist, (int) sizeof (HISTORY), 1, f);
  376.  
  377.    (void) fclose (f);
  378.  
  379.    return;
  380. }
  381.  
  382. int time_to_next (int skip_bbs)
  383. {
  384.    time_t long_time;
  385.    struct tm *tm;
  386.    
  387.    int cur_day;
  388.    int our_time;
  389.    int i;
  390.    int time_to;
  391.    int guess;
  392.    int nmin;
  393.  
  394.    /* Get the current time into a structure */
  395.  
  396.    (void) time (&long_time);
  397.    tm = localtime (&long_time);
  398.  
  399.    our_time = tm->tm_hour * 60 + tm->tm_min;
  400.  
  401.    next_event = -1;
  402.    cur_day = 1 << tm->tm_wday;
  403.  
  404.    /* A ridiculous number */
  405.    time_to = 3000;
  406.  
  407.    /* Make the month 1-based instead of 0-based */
  408.    tm->tm_mon += 1;
  409.  
  410.    /* Go through the events from top to bottom */
  411.    for (i = 0; i < num_events; i++)
  412.       {
  413.       /* If it is the current event, skip it */
  414.       if (cur_event == i)
  415.          continue;
  416.  
  417.       /* If it is a BBS event, skip it */
  418.       if (skip_bbs && e_ptrs[i].behavior & MAT_BBS)
  419.          continue;
  420.  
  421.       /* If it was already run today, skip it */
  422.       if (e_ptrs[i].last_ran == (char) tm->tm_mday)
  423.          continue;
  424.  
  425.       /* If it doesn't happen today, skip it */
  426.       if (!(e_ptrs[i].days & cur_day))
  427.          continue;
  428.  
  429.       /* If not this day of the month, skip it */
  430.       if ((e_ptrs[i].day) && (e_ptrs[i].day != (char)tm->tm_mday))
  431.          continue;
  432.       
  433.       /* If not this month of the year, skip it */
  434.       if ((e_ptrs[i].month) && (e_ptrs[i].month != (char)tm->tm_mon))
  435.          continue;
  436.  
  437.       /* If it is earlier than now, skip it unless it is forced */
  438.       if (e_ptrs[i].minute <= our_time)
  439.          {
  440.          if (!(e_ptrs[i].behavior & MAT_FORCED))
  441.             {
  442.             continue;
  443.             }
  444.  
  445.          /* Hmm, found a forced event that has not executed yet */
  446.          /* Give the guy 2 minutes and call it quits */
  447.          guess = 2;
  448.          }
  449.       else
  450.          {
  451.          /* Calculate how far it is from now */
  452.          guess = e_ptrs[i].minute - our_time;
  453.          }
  454.  
  455.       /* If less than closest so far, keep it */
  456.       if (time_to > guess)
  457.          {
  458.          time_to = guess;
  459.          next_event = i;
  460.          }
  461.       }
  462.  
  463.    /* If we still have nothing, then do it again, starting at midnight */
  464.    if (time_to >= 1441)
  465.       {
  466.       /* Calculate here to midnight */
  467.       nmin = 1440 - our_time;
  468.  
  469.       /* Go to midnight */
  470.       our_time = 0;
  471.  
  472.       /* Go to the next possible day */
  473.       cur_day = (int) (((unsigned) cur_day) << 1);
  474.       if (cur_day > DAY_SATURDAY)
  475.          cur_day = DAY_SUNDAY;
  476.  
  477.       /* Go through the events from top to bottom */
  478.       for (i = 0; i < num_events; i++)
  479.          {
  480.          /* If it is a BBS event, skip it */
  481.          if (skip_bbs && e_ptrs[i].behavior & MAT_BBS)
  482.             continue;
  483.  
  484.          /* If it doesn't happen today, skip it */
  485.          if (!(e_ptrs[i].days & cur_day))
  486.             continue;
  487.  
  488.          /* If not this day of the month, skip it */
  489.          if ((e_ptrs[i].day) && (e_ptrs[i].day != (char)tm->tm_mday))
  490.             continue;
  491.       
  492.          /* If not this month of the year, skip it */
  493.          if ((e_ptrs[i].month) && (e_ptrs[i].month != (char)tm->tm_mon))
  494.             continue;
  495.  
  496.          /* Calculate how far it is from now */
  497.          guess = e_ptrs[i].minute + nmin;
  498.  
  499.          /* If less than closest so far, keep it */
  500.          if (time_to > guess)
  501.             {
  502.             time_to = guess;
  503.             next_event = i;
  504.             }
  505.          }
  506.       }
  507.  
  508.    if (time_to > 1440)
  509.       time_to = 1440;
  510.  
  511.    if (skip_bbs && (time_to < 1))
  512.       time_to = 1;
  513.  
  514.    return (time_to);
  515. }
  516.  
  517.