home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / SCHED.C < prev    next >
C/C++ Source or Header  |  1998-05-17  |  18KB  |  634 lines

  1.  
  2. // LoraBBS Version 2.41 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <stdio.h>
  20. #include <ctype.h>
  21. #include <io.h>
  22. #include <fcntl.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <process.h>
  26. #include <time.h>
  27. #include <alloc.h>
  28. #include <mem.h>
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31.  
  32. #include "tc_utime.h"
  33. #include "lsetup.h"
  34. #include "sched.h"
  35. #include "msgapi.h"
  36. #include "zmodem.h"
  37. #include "externs.h"
  38. #include "prototyp.h"
  39.  
  40. extern int outinfo, blanked;
  41. extern char nomailproc;
  42.  
  43. void stop_blanking (void);
  44. void rebuild_call_queue (void);
  45. void write_sched (void);
  46.  
  47. void find_event ()
  48. {
  49.    int cur_day;
  50.    int cur_hour;
  51.    int cur_minute;
  52.    int cur_mday;
  53.    int cur_mon;
  54.    int cur_year;
  55.    int junk;
  56.    int our_time;
  57.    int i;
  58.    char cmds[80];
  59.  
  60.    /* Get the current day of the week */
  61.    dosdate (&cur_mon, &cur_mday, &cur_year, &cur_day);
  62.  
  63.    cur_day = 1 << cur_day;
  64.  
  65.    /* Get the current time in minutes */
  66.    dostime (&cur_hour, &cur_minute, &junk, &junk);
  67.    our_time = (cur_hour % 24) * 60 + (cur_minute % 60);
  68.  
  69.    cur_event = -1;
  70.  
  71.    /* Go through the events from top to bottom */
  72.    for (i = 0; i < num_events; i++) {
  73.       if (our_time >= e_ptrs[i]->minute) {
  74.          if ((cur_day & e_ptrs[i]->days) && ((!e_ptrs[i]->day) || (e_ptrs[i]->day == (char)cur_mday)) && ((!e_ptrs[i]->month) || (e_ptrs[i]->month == (char)cur_mon))) {
  75.             if (((our_time - e_ptrs[i]->minute) < e_ptrs[i]->length) || ((our_time == e_ptrs[i]->minute) && (e_ptrs[i]->length == 0)) || ((e_ptrs[i]->behavior & MAT_FORCED) && (e_ptrs[i]->last_ran != cur_mday))) {
  76.                /* Are we not supposed to force old events */
  77.                if (((our_time - e_ptrs[i]->minute) > e_ptrs[i]->length) && (!noforce)) {
  78.                   e_ptrs[i]->last_ran = cur_mday;
  79.                   continue;
  80.                }
  81.  
  82.                if (e_ptrs[i]->last_ran != cur_mday) {
  83.                   cur_event = i;
  84.  
  85.                   if (blanked)
  86.                      stop_blanking ();
  87.                   if (e_ptrs[i]->cmd[0])
  88.                      status_line (":Starting Event %d - %s", i + 1, e_ptrs[i]->cmd);
  89.                   else
  90.                      status_line (msgtxt[M_STARTING_EVENT], i + 1);
  91.  
  92.                   /* Mark that this one is running */
  93.                   e_ptrs[i]->last_ran = cur_mday;
  94.  
  95.                   /*
  96.                    * Mark that we have not yet skipped it. After all, it just
  97.                    * started! 
  98.                    */
  99.                   e_ptrs[i]->behavior &= ~MAT_SKIP;
  100.  
  101.                   /* Write out the schedule */
  102.                   write_sched ();
  103.                   write_sysinfo ();
  104.                   read_sysinfo ();
  105.  
  106.                   if (!nomailproc)
  107.                      if (e_ptrs[i]->echomail & (ECHO_STARTEXPORT|ECHO_STARTIMPORT)) {
  108.                         if (e_ptrs[cur_event]->echomail & (ECHO_RESERVED4))
  109.                            import_tic_files ();
  110.                         if (e_ptrs[i]->echomail & ECHO_STARTIMPORT)
  111.                            process_startup_mail (1);
  112.                         else
  113.                            process_startup_mail (0);
  114.                      }
  115.  
  116.                   if (e_ptrs[i]->res_net && !(e_ptrs[cur_event]->behavior & MAT_NOOUT)) {
  117.                      if (e_ptrs[cur_event]->echomail & ECHO_FORCECALL) {
  118.                         junk = 'F';
  119.                         if (e_ptrs[i]->behavior & MAT_CM)
  120.                            junk = 'C';
  121.                         sprintf (cmds, "%s%04x%04x.%cLO", HoldAreaNameMunge (e_ptrs[i]->res_zone), e_ptrs[i]->res_net, e_ptrs[i]->res_node, junk);
  122.                         junk = open (cmds, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE);
  123.                         close (junk);
  124.                      }
  125.  
  126.                      bad_call (e_ptrs[i]->res_net, e_ptrs[i]->res_node, -2, 0);
  127.                   }
  128.  
  129.                   /* If we are supposed to exit, then do it */
  130.                   if (e_ptrs[i]->errlevel[0]) {
  131.                      status_line (msgtxt[M_EVENT_EXIT], e_ptrs[i]->errlevel[0]);
  132.                      get_down (e_ptrs[i]->errlevel[0], 1);
  133.                   }
  134.  
  135.                   rebuild_call_queue ();
  136.                   outinfo = 0;
  137.                   display_outbound_info (outinfo);
  138.  
  139.                   if (e_ptrs[i]->behavior & MAT_RESYNC) {
  140.                      status_line ("+Start remote clock adjustments");
  141.                      poll_galileo (e_ptrs[i]->with_connect, e_ptrs[i]->no_connect);
  142.                      initialize_modem ();
  143.                      local_status(msgtxt[M_SETTING_BAUD]);
  144.                   }
  145.  
  146.                   cur_event = i;
  147.                   max_connects = e_ptrs[i]->with_connect;
  148.                   max_noconnects = e_ptrs[i]->no_connect;
  149.                }
  150.                else {
  151.                   /* Don't do events that have been exited already */
  152.                   if (e_ptrs[i]->behavior & MAT_SKIP)
  153.                      continue;
  154.                }
  155.  
  156.                cur_event = i;
  157.  
  158.                if (e_ptrs[i]->behavior & MAT_NOREQ)
  159.                   no_requests = 1;
  160.                else
  161.                   no_requests = 0;
  162.  
  163.                if (e_ptrs[i]->behavior & MAT_NOOUTREQ)
  164.                   requests_ok = 0;
  165.                else
  166.                   requests_ok = 1;
  167.  
  168.                max_connects = e_ptrs[i]->with_connect;
  169.                max_noconnects = e_ptrs[i]->no_connect;
  170.                break;
  171.             }
  172.          }
  173.       }
  174.    }
  175. }
  176.  
  177. void set_event ()
  178. {
  179.    int cur_day;
  180.    int cur_hour;
  181.    int cur_minute;
  182.    int cur_mday;
  183.    int cur_mon;
  184.    int cur_year;
  185.    int junk;
  186.    int our_time;
  187.    int i;
  188.  
  189.    /* Get the current day of the week */
  190.    dosdate (&cur_mon, &cur_mday, &cur_year, &cur_day);
  191.  
  192.    cur_day = 1 << cur_day;
  193.  
  194.    /* Get the current time in minutes */
  195.    dostime (&cur_hour, &cur_minute, &junk, &junk);
  196.    our_time = (cur_hour % 24) * 60 + (cur_minute % 60);
  197.  
  198.    cur_event = -1;
  199.  
  200. /*
  201.    if (cur_mday != hist.which_day)
  202.       {
  203.       }
  204. */
  205.  
  206.    /* Go through the events from top to bottom */
  207.    for (i = 0; i < num_events; i++)
  208.       {
  209.       if (our_time >= e_ptrs[i]->minute)
  210.          {
  211.          if ((cur_day & e_ptrs[i]->days) &&
  212.      ((!e_ptrs[i]->day) || (e_ptrs[i]->day == (char)cur_mday)) &&
  213.      ((!e_ptrs[i]->month) || (e_ptrs[i]->month == (char)cur_mon)))
  214.             {
  215.             if (((our_time - e_ptrs[i]->minute) < e_ptrs[i]->length) ||
  216.             ((our_time == e_ptrs[i]->minute) && (e_ptrs[i]->length == 0)) ||
  217.                 ((e_ptrs[i]->behavior & MAT_FORCED) && (e_ptrs[i]->last_ran != cur_mday)))
  218.                {
  219.                /* Are we not supposed to force old events */
  220.                if (((our_time - e_ptrs[i]->minute) > e_ptrs[i]->length) && (!noforce))
  221.                   {
  222.                   e_ptrs[i]->last_ran = cur_mday;
  223.                   continue;
  224.                   }
  225.  
  226.                if (e_ptrs[i]->last_ran != cur_mday)
  227.                   {
  228.                   cur_event = i;
  229.                   max_connects = e_ptrs[i]->with_connect;
  230.                   max_noconnects = e_ptrs[i]->no_connect;
  231.                   }
  232.                else
  233.                   {
  234.                   /* Don't do events that have been exited already */
  235.                   if (e_ptrs[i]->behavior & MAT_SKIP)
  236.                      continue;
  237.                   }
  238.  
  239.                cur_event = i;
  240.  
  241.                if (e_ptrs[i]->behavior & MAT_NOREQ)
  242.                   {
  243. /*                  matrix_mask &= ~TAKE_REQ;*/
  244.                   no_requests = 1;
  245.                   }
  246.                else
  247.                   {
  248. /*                  matrix_mask |= TAKE_REQ;*/
  249.                   no_requests = 0;
  250.                   }
  251.  
  252.                if (e_ptrs[i]->behavior & MAT_NOOUTREQ)
  253.                   {
  254.                   requests_ok = 0;
  255.                   }
  256.                else
  257.                   {
  258.                   requests_ok = 1;
  259.                   }
  260.  
  261.                max_connects = e_ptrs[i]->with_connect;
  262.                max_noconnects = e_ptrs[i]->no_connect;
  263.  
  264.                break;
  265.                }
  266.             }
  267.          }
  268.       }
  269. }
  270.  
  271. void read_sched ()
  272. {
  273.    EVENT *sptr;
  274.    struct stat buffer1;
  275.    FILE *f;
  276.    int i;
  277.  
  278.    if (stat (config->sched_name, &buffer1))
  279.       {
  280.       return;
  281.       }
  282.  
  283.    if ((sptr = (EVENT *) malloc ((unsigned int) buffer1.st_size)) == NULL)
  284.       {
  285.       return;
  286.       }
  287.  
  288.    if ((f = fopen (config->sched_name, "rb")) == NULL)
  289.       {
  290.       return;
  291.       }
  292.  
  293.    (void) fread (sptr, (unsigned int) buffer1.st_size, 1, f);
  294.    got_sched = 1;
  295.  
  296.    num_events = (int) (buffer1.st_size / sizeof (EVENT));
  297.    for (i = 0; i < num_events; i++)
  298.       {
  299.       e_ptrs[i] = sptr++;
  300.       }
  301.  
  302.    (void) fclose (f);
  303.    return;
  304. }
  305.  
  306. void write_sched ()
  307. {
  308.    char temp1[80];
  309.    FILE *f;
  310.    int i;
  311.    struct stat buffer1;
  312.    struct utimbuf times;
  313.    long t;
  314.  
  315.    /* Get the current time */
  316.    t = time (NULL);
  317.  
  318.    /* Get the current stat for .Evt file */
  319.    if (!stat (config->sched_name, &buffer1))
  320.       {
  321.  
  322.       /*
  323.        * If it is newer than current time, we have a problem and we must
  324.        * reset the file date - yucky, but it will probably work 
  325.        */
  326.       if (t < buffer1.st_atime)
  327.          {
  328.          times.actime = buffer1.st_atime;
  329.          times.modtime = buffer1.st_atime;
  330.          }
  331.       else
  332.          {
  333.          times.actime = t;
  334.          times.modtime = t;
  335.          }
  336.       }
  337.  
  338.    if ((f = fopen (config->sched_name, "wb")) == NULL)
  339.       {
  340.       return;
  341.       }
  342.  
  343.    for (i = 0; i < num_events; i++)
  344.       {
  345.       /* If it is skipped, but not dynamic, reset it */
  346.       if ((e_ptrs[i]->behavior & MAT_SKIP) &&
  347.           (!(e_ptrs[i]->behavior & MAT_DYNAM)))
  348.          {
  349.          e_ptrs[i]->behavior &= ~MAT_SKIP;
  350.          }
  351.  
  352.       /* Write this one out */
  353.       (void) fwrite (e_ptrs[i], sizeof (EVENT), 1, f);
  354.       }
  355.  
  356.    (void) fclose (f);
  357.  
  358.    (void) utime (temp1, ×);
  359.  
  360.    return;
  361. }
  362.  
  363. int time_to_next (skip_bbs)
  364. int skip_bbs;
  365. {
  366.    int cur_day;
  367.    int cur_hour;
  368.    int cur_minute;
  369.    int cur_mday;
  370.    int cur_mon;
  371.    int cur_year;
  372.    int junk;
  373.    int our_time;
  374.    int i;
  375.    int time_to;
  376.    int guess;
  377.    int nmin;
  378.  
  379.    /* Get the current time in minutes */
  380.    dostime (&cur_hour, &cur_minute, &junk, &junk);
  381.    our_time = cur_hour * 60 + cur_minute;
  382.  
  383.    /* Get the current day of the week */
  384.    dosdate (&cur_mon, &cur_mday, &cur_year, &cur_day);
  385.  
  386.    next_event = -1;
  387.    cur_day = 1 << cur_day;
  388.  
  389.    /* A ridiculous number */
  390.    time_to = 3000;
  391.  
  392.    /* Go through the events from top to bottom */
  393.    for (i = 0; i < num_events; i++)
  394.       {
  395.       /* If it is the current event, skip it */
  396.       if (cur_event == i)
  397.          continue;
  398.  
  399.       /* If it is a BBS event, skip it */
  400.       if (skip_bbs && e_ptrs[i]->behavior & MAT_BBS)
  401.          continue;
  402.  
  403.       /* If it was already run today, skip it */
  404.       if (e_ptrs[i]->last_ran == cur_mday)
  405.          continue;
  406.  
  407.       /* If it doesn't happen today, skip it */
  408.       if (!(e_ptrs[i]->days & cur_day))
  409.          continue;
  410.  
  411.       /* If not this day of the month, skip it */
  412.       if ((e_ptrs[i]->day) && (e_ptrs[i]->day != (char)cur_mday))
  413.          continue;
  414.       
  415.       /* If not this month of the year, skip it */
  416.       if ((e_ptrs[i]->month) && (e_ptrs[i]->month != (char)cur_mon))
  417.          continue;
  418.  
  419.       /* If it is earlier than now, skip it unless it is forced */
  420.       if (e_ptrs[i]->minute <= our_time)
  421.          {
  422.          if (!(e_ptrs[i]->behavior & MAT_FORCED))
  423.             {
  424.             continue;
  425.             }
  426.  
  427.          /* Hmm, found a forced event that has not executed yet */
  428.          /* Give the guy 2 minutes and call it quits */
  429.          guess = 2;
  430.          }
  431.       else
  432.          {
  433.          /* Calculate how far it is from now */
  434.          guess = e_ptrs[i]->minute - our_time;
  435.          }
  436.  
  437.       /* If less than closest so far, keep it */
  438.       if (time_to > guess)
  439.          {
  440.          time_to = guess;
  441.          next_event = i;
  442.          }
  443.       }
  444.  
  445.    /* If we still have nothing, then do it again, starting at midnight */
  446.    if (time_to >= 1441)
  447.       {
  448.       /* Calculate here to midnight */
  449.       nmin = 1440 - our_time;
  450.  
  451.       /* Go to midnight */
  452.       our_time = 0;
  453.  
  454.       /* Go to the next possible day */
  455.       cur_day = (int) (((unsigned) cur_day) << 1);
  456.       if (cur_day > DAY_SATURDAY)
  457.          cur_day = DAY_SUNDAY;
  458.  
  459.       /* Go through the events from top to bottom */
  460.       for (i = 0; i < num_events; i++)
  461.          {
  462.          /* If it is a BBS event, skip it */
  463.          if (skip_bbs && e_ptrs[i]->behavior & MAT_BBS)
  464.             continue;
  465.  
  466.          /* If it doesn't happen today, skip it */
  467.          if (!(e_ptrs[i]->days & cur_day))
  468.             continue;
  469.  
  470.          /* If not this day of the month, skip it */
  471.          if ((e_ptrs[i]->day) && (e_ptrs[i]->day != (char)cur_mday))
  472.             continue;
  473.       
  474.          /* If not this month of the year, skip it */
  475.          if ((e_ptrs[i]->month) && (e_ptrs[i]->month != (char)cur_mon))
  476.             continue;
  477.  
  478.          /* Calculate how far it is from now */
  479.          guess = e_ptrs[i]->minute + nmin;
  480.  
  481.          /* If less than closest so far, keep it */
  482.          if (time_to > guess)
  483.             {
  484.             time_to = guess;
  485.             next_event = i;
  486.             }
  487.          }
  488.       }
  489.  
  490.    if (time_to > 1440)
  491.       time_to = 1440;
  492.  
  493.    if (skip_bbs && (time_to < 1))
  494.       time_to = 1;
  495.  
  496.    return (time_to);
  497. }
  498.  
  499. int time_to_next_nonmail (void)
  500. {
  501.    int cur_day;
  502.    int cur_hour;
  503.    int cur_minute;
  504.    int cur_mday;
  505.    int cur_mon;
  506.    int cur_year;
  507.    int junk;
  508.    int our_time;
  509.    int i;
  510.    int time_to;
  511.    int guess;
  512.    int nmin;
  513.  
  514.    /* Get the current time in minutes */
  515.    dostime (&cur_hour, &cur_minute, &junk, &junk);
  516.    our_time = cur_hour * 60 + cur_minute;
  517.  
  518.    /* Get the current day of the week */
  519.    dosdate (&cur_mon, &cur_mday, &cur_year, &cur_day);
  520.  
  521.    next_event = -1;
  522.    cur_day = 1 << cur_day;
  523.  
  524.    /* A ridiculous number */
  525.    time_to = 3000;
  526.  
  527.    /* Go through the events from top to bottom */
  528.    for (i = 0; i < num_events; i++)
  529.       {
  530.       /* If it is the current event, skip it */
  531.       if (cur_event == i)
  532.          continue;
  533.  
  534.       /* If it is a BBS event, skip it */
  535.       if (!(e_ptrs[i]->behavior & MAT_BBS))
  536.          continue;
  537.  
  538.       /* If it was already run today, skip it */
  539.       if (e_ptrs[i]->last_ran == cur_mday)
  540.          continue;
  541.  
  542.       /* If it doesn't happen today, skip it */
  543.       if (!(e_ptrs[i]->days & cur_day))
  544.          continue;
  545.  
  546.       /* If not this day of the month, skip it */
  547.       if ((e_ptrs[i]->day) && (e_ptrs[i]->day != (char)cur_mday))
  548.          continue;
  549.       
  550.       /* If not this month of the year, skip it */
  551.       if ((e_ptrs[i]->month) && (e_ptrs[i]->month != (char)cur_mon))
  552.          continue;
  553.  
  554.       /* If it is earlier than now, skip it unless it is forced */
  555.       if (e_ptrs[i]->minute <= our_time)
  556.          {
  557.          if (!(e_ptrs[i]->behavior & MAT_FORCED))
  558.             {
  559.             continue;
  560.             }
  561.  
  562.          /* Hmm, found a forced event that has not executed yet */
  563.          /* Give the guy 2 minutes and call it quits */
  564.          guess = 2;
  565.          }
  566.       else
  567.          {
  568.          /* Calculate how far it is from now */
  569.          guess = e_ptrs[i]->minute - our_time;
  570.          }
  571.  
  572.       /* If less than closest so far, keep it */
  573.       if (time_to > guess)
  574.          {
  575.          time_to = guess;
  576.          next_event = i;
  577.          }
  578.       }
  579.  
  580.    /* If we still have nothing, then do it again, starting at midnight */
  581.    if (time_to >= 1441)
  582.       {
  583.       /* Calculate here to midnight */
  584.       nmin = 1440 - our_time;
  585.  
  586.       /* Go to midnight */
  587.       our_time = 0;
  588.  
  589.       /* Go to the next possible day */
  590.       cur_day = (int) (((unsigned) cur_day) << 1);
  591.       if (cur_day > DAY_SATURDAY)
  592.          cur_day = DAY_SUNDAY;
  593.  
  594.       /* Go through the events from top to bottom */
  595.       for (i = 0; i < num_events; i++)
  596.          {
  597.          /* If it is a BBS event, skip it */
  598.          if (!(e_ptrs[i]->behavior & MAT_BBS))
  599.             continue;
  600.  
  601.          /* If it doesn't happen today, skip it */
  602.          if (!(e_ptrs[i]->days & cur_day))
  603.             continue;
  604.  
  605.          /* If not this day of the month, skip it */
  606.          if ((e_ptrs[i]->day) && (e_ptrs[i]->day != (char)cur_mday))
  607.             continue;
  608.       
  609.          /* If not this month of the year, skip it */
  610.          if ((e_ptrs[i]->month) && (e_ptrs[i]->month != (char)cur_mon))
  611.             continue;
  612.  
  613.          /* Calculate how far it is from now */
  614.          guess = e_ptrs[i]->minute + nmin;
  615.  
  616.          /* If less than closest so far, keep it */
  617.          if (time_to > guess)
  618.             {
  619.             time_to = guess;
  620.             next_event = i;
  621.             }
  622.          }
  623.       }
  624.  
  625.    if (time_to > 1440)
  626.       time_to = 1440;
  627.  
  628.    if (time_to < 1)
  629.       time_to = 1;
  630.  
  631.    return (time_to);
  632. }
  633.  
  634.