]> granicus.if.org Git - fcron/commitdiff
added support of %-lines
authorthib <thib>
Sun, 10 Dec 2000 10:58:33 +0000 (10:58 +0000)
committerthib <thib>
Sun, 10 Dec 2000 10:58:33 +0000 (10:58 +0000)
database.c
option.h

index 582a7ced3e7145f7bd79ae6e06ca5289be13b387..2199284875ff282486f123b796bd4e3e655d65a5 100644 (file)
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: database.c,v 1.39 2000-12-04 20:19:12 thib Exp $ */
+ /* $Id: database.c,v 1.40 2000-12-10 10:58:33 thib Exp $ */
 
 #include "fcron.h"
 
 int is_leap_year(int year);
 int get_nb_mdays(int year, int mon);
+void set_wday(struct tm *date);
 void goto_non_matching(CL *line, struct tm *tm);
 void run_normal_job(CL *line);
 void run_serial_job(void);
@@ -505,77 +506,178 @@ goto_non_matching(CL *line, struct tm *ftime)
     /* search the first the nearest time and date that does
      * not match the line */
 {
-    /* to prevent from invinite loop with unvalid lines : */
-    short int year_limit = MAXYEAR_SCHEDULE_TIME;
-    /* we have to ignore the fields containing single numbers */
-    char ignore_mins = (is_ign_mins(line->cl_option)) ? 1:0;
-    char ignore_hrs = (is_ign_hrs(line->cl_option)) ? 1:0;
-    char ignore_days = (is_ign_days(line->cl_option)) ? 1:0;
-    char ignore_mons = (is_ign_mons(line->cl_option)) ? 1:0;
-    char ignore_dow = (is_ign_dow(line->cl_option)) ? 1:0;
-    
-    /* */
-    debug("   ignore: %d %d %d %d %d", ignore_mins, ignore_hrs, ignore_days, ignore_mons, ignore_dow);
-    /* */
-
-    /* check if we are in an interval of execution */    
-    while ( (ignore_mins == 1 || bit_test(line->cl_mins, ftime->tm_min)) &&
-           (ignore_hrs == 1 || bit_test(line->cl_hrs, ftime->tm_hour)) &&
-           (
-               (is_dayand(line->cl_option) &&
-                (ignore_days==1 || bit_test(line->cl_days, ftime->tm_mday)) &&
-                (ignore_dow==1 || bit_test(line->cl_dow, ftime->tm_wday)))
-               ||
-               (is_dayor(line->cl_option) &&
-                (ignore_days == 1 || bit_test(line->cl_days, ftime->tm_mday)||
-                 ignore_dow == 1 || bit_test(line->cl_dow, ftime->tm_wday)))
-               ) &&
-           (ignore_mons == 1 || bit_test(line->cl_mons, ftime->tm_mon))
-       ) {
-
-       if (ignore_mins) ftime->tm_min = 60; 
-       else {
-           do ftime->tm_min++ ;
-           while(bit_test(line->cl_mins,ftime->tm_min) && (ftime->tm_min<60));
+    if ( is_freq_periodically(line->cl_option)) {
+       int max = get_nb_mdays(ftime->tm_year, ftime->tm_mon);
+       if (is_freq_mid(line->cl_option)) {
+           if (is_freq_mins(line->cl_option))
+               /* nothing to do : return */
+               return;
+           else if (is_freq_hrs(line->cl_option)) {
+               if (ftime->tm_min >= 30)
+                   ftime->tm_hour++;
+               ftime->tm_min = 30;
+           } else {
+               ftime->tm_min = 0;
+               if (is_freq_days(line->cl_option)) {
+                   if (ftime->tm_hour >= 12)
+                       ftime->tm_mday++;
+                   ftime->tm_hour = 12;
+               } else {
+                   ftime->tm_hour = 0;
+                   if (is_freq_dow(line->cl_option)) {
+                       int to_add = (ftime->tm_wday >= 4) ? 11-ftime->tm_wday:
+                           4 - ftime->tm_wday;
+                       if (ftime->tm_mday + to_add > max) {
+                           ftime->tm_mon++;
+                           ftime->tm_mday = ftime->tm_mday + to_add - max;
+                       } else
+                           ftime->tm_mday += to_add;
+                   } else {
+                       ftime->tm_mday = 1;
+                       if (is_freq_mons(line->cl_option)) {
+                           if (ftime->tm_mday >= 15)
+                               ftime->tm_mon++;
+                           ftime->tm_mday = 15;
+                       }
+                   }
+               }
+           }
        }
+       else { /* is_freq_mid(line->cl_option) */
+           if (is_freq_mins(line->cl_option))
+               /* nothing to do */
+               return;
+           else {
+               ftime->tm_min = 0;
+               if (is_freq_hrs(line->cl_option))
+                   ftime->tm_hour++;
+               else {
+                   ftime->tm_hour = 0;
+                   if (is_freq_days(line->cl_option))
+                       ftime->tm_mday++;
+                   else {
+                       if (is_freq_dow(line->cl_option)) {
+                           int to_add=(ftime->tm_wday==0)?1: 8-ftime->tm_wday;
+                           if (ftime->tm_mday + to_add > max) {
+                               ftime->tm_mday = ftime->tm_mday + to_add - max;
+                               ftime->tm_mon++;
+                           } else
+                               ftime->tm_mday += to_add;
+                       } else {
+                           ftime->tm_mday = 1;
+                           if (is_freq_mons(line->cl_option))
+                               ftime->tm_mon++;
+                       }
+                   }
+               }
+           }
+       }
+       /* a value may exceed the max value of a field */
        if (ftime->tm_min >= 60) {
            ftime->tm_min = 0;
-           if (ignore_hrs && ignore_mins) ftime->tm_hour = 24;
-           else ftime->tm_hour++;
-           if (ftime->tm_hour >= 24) {
-               ftime->tm_hour = 0;
-               if (ignore_days && ignore_hrs && ignore_mins)ftime->tm_mday=32;
-               else ftime->tm_mday++;
-               if (ftime->tm_mday >= 
-                   get_nb_mdays((ftime->tm_year+1900),ftime->tm_mon)) {
-                   ftime->tm_mday = 0;
-                   if(ignore_mons && ignore_days && ignore_hrs && ignore_mins)
-                       ftime->tm_mon = 12;
-                   else ftime->tm_mon++;
-                   if (ftime->tm_mon >= 12) {
-                       ftime->tm_mon = 0;
-                       ftime->tm_year++;
-                       if (--year_limit <= 0) {
-                           error("Can't found a non matching date for %s in "
-                                 "the next %d years. Maybe this line is "
-                                 "corrupted : consider reinstalling the "
-                                 "fcrontab", line->cl_shell, 
-                                 MAXYEAR_SCHEDULE_TIME);
-                           return;
+           ftime->tm_hour++;
+       }
+       if (ftime->tm_hour >= 24) {
+           ftime->tm_hour = 0;
+           ftime->tm_mday++;
+       }
+       /* the month field may have changed */
+       max = get_nb_mdays(ftime->tm_year, ftime->tm_mon);
+       if (ftime->tm_mday >= max) {
+           ftime->tm_mday = 1;
+           ftime->tm_mon++;
+       }
+       if (ftime->tm_mon >= 12) {
+           ftime->tm_mon = 0;
+           ftime->tm_year++;
+       }
+       if (debug_opt)
+           set_wday(ftime);
+       debug("   '%s' first non matching %d/%d/%d wday:%d %02d:%02d",
+             line->cl_shell, (ftime->tm_mon + 1), ftime->tm_mday,
+             (ftime->tm_year + 1900), ftime->tm_wday,
+             ftime->tm_hour, ftime->tm_min);
+
+       return;
+    }
+    else { 
+       /* this line should be run once per interval of the selected field */
+       
+       /* to prevent from invinite loop with unvalid lines : */
+       short int year_limit = MAXYEAR_SCHEDULE_TIME;
+       /* we have to ignore the fields containing single numbers */
+       char ignore_mins = (is_freq_mins(line->cl_option)) ? 1:0;
+       char ignore_hrs = (is_freq_hrs(line->cl_option)) ? 1:0;
+       char ignore_days = (is_freq_days(line->cl_option)) ? 1:0;
+       char ignore_mons = (is_freq_mons(line->cl_option)) ? 1:0;
+       char ignore_dow = (is_freq_dow(line->cl_option)) ? 1:0;
+    
+       /* */
+       debug("   ignore: %d %d %d %d %d", ignore_mins, ignore_hrs,
+             ignore_days, ignore_mons, ignore_dow);
+       /* */
+
+       /* check if we are in an interval of execution */    
+       while ((ignore_mins == 1 || bit_test(line->cl_mins, ftime->tm_min)) &&
+              (ignore_hrs == 1 || bit_test(line->cl_hrs, ftime->tm_hour)) &&
+              (
+                  (is_dayand(line->cl_option) &&
+                   (ignore_days==1||bit_test(line->cl_days,ftime->tm_mday)) &&
+                   (ignore_dow==1 || bit_test(line->cl_dow, ftime->tm_wday)))
+                  ||
+                  (is_dayor(line->cl_option) &&
+                   (ignore_days==1||bit_test(line->cl_days, ftime->tm_mday) ||
+                    ignore_dow == 1 || bit_test(line->cl_dow,ftime->tm_wday)))
+                  ) &&
+              (ignore_mons == 1 || bit_test(line->cl_mons, ftime->tm_mon))
+           ) {
+           
+           if (ignore_mins) ftime->tm_min = 60; 
+           else {
+               do ftime->tm_min++ ;
+               while ( bit_test(line->cl_mins, ftime->tm_min) 
+                       && (ftime->tm_min < 60) );
+           }
+           if (ftime->tm_min >= 60) {
+               ftime->tm_min = 0;
+               if (ignore_hrs && ignore_mins) ftime->tm_hour = 24;
+               else ftime->tm_hour++;
+               if (ftime->tm_hour >= 24) {
+                   ftime->tm_hour = 0;
+                   if (ignore_days && ignore_hrs && ignore_mins)
+                       ftime->tm_mday=32;
+                   else ftime->tm_mday++;
+                   if (ftime->tm_mday >= 
+                       get_nb_mdays((ftime->tm_year+1900),ftime->tm_mon)) {
+                       ftime->tm_mday = 0;
+                       if(ignore_mons && ignore_days && ignore_hrs
+                          && ignore_mins)
+                           ftime->tm_mon = 12;
+                       else ftime->tm_mon++;
+                       if (ftime->tm_mon >= 12) {
+                           ftime->tm_mon = 0;
+                           ftime->tm_year++;
+                           if (--year_limit <= 0) {
+                               error("Can't found a non matching date for %s "
+                                     "in the next %d years. Maybe this line "
+                                     "is corrupted : consider reinstalling "
+                                     "the fcrontab", line->cl_shell, 
+                                     MAXYEAR_SCHEDULE_TIME);
+                               return;
+                           }
                        }
                    }
+                   set_wday(ftime);
                }
-               set_wday(ftime);
            }
        }
-    }
          
-    debug("   '%s' first non matching %d/%d/%d wday:%d %02d:%02d",
-         line->cl_shell, (ftime->tm_mon + 1), ftime->tm_mday,
-         (ftime->tm_year + 1900), ftime->tm_wday,
-         ftime->tm_hour, ftime->tm_min);
-    return;
-
+       debug("   '%s' first non matching %d/%d/%d wday:%d %02d:%02d",
+             line->cl_shell, (ftime->tm_mon + 1), ftime->tm_mday,
+             (ftime->tm_year + 1900), ftime->tm_wday,
+             ftime->tm_hour, ftime->tm_min);
+       return;
+    }
 }
 
 
index bbf4a59aa97d2b70aa8e8a0f6ef6197379c725dd..5c8a5d51d194c7a5cf7d66615abdbc23dd7f332b 100644 (file)
--- a/option.h
+++ b/option.h
@@ -21,7 +21,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: option.h,v 1.11 2000-12-04 20:20:09 thib Exp $ */
+ /* $Id: option.h,v 1.12 2000-12-10 10:59:15 thib Exp $ */
 
 /* This has been inspired from bitstring(3) : here is the original copyright :
  */
@@ -73,6 +73,8 @@
   15     should days field be ignored in goto_non_matching() ?
   16     should mons field be ignored in goto_non_matching() ?
   17     should dow field be ignored in goto_non_matching() ?
+  18     First freq is the freq (*ly) or the first field to take into account ?
+  19     Freq (ie daily) is from middle to middle of interval (ie nightly) ?
 
 */
 
 
 
 /*
-  bit 13 : set to 1 : mins field should be ignored in goto_non_matching()
-           set to 0 : mins field should not be ignored in goto_non_matching()
+  bit 13 : set to 1 : mins field is the limit
+           set to 0 : mins field is not the limit
 */
-#define        is_ign_mins(opt) \
+#define        is_freq_mins(opt) \
        (_bit_test(opt, 13))
-#define        set_ign_mins(opt) \
+#define        set_freq_mins(opt) \
        (_bit_set(opt, 13))
-#define clear_ign_mins(opt) \
+#define clear_freq_mins(opt) \
        (_bit_clear(opt, 13))
 
 
 /*
-  bit 14 : set to 1 : hrs field should be ignored in goto_non_matching()
-           set to 0 : hrs field should not be ignored in goto_non_matching()
+  bit 14 : set to 1 : hrs field is the limit
+           set to 0 : hrs field is not the limit
 */
-#define        is_ign_hrs(opt) \
+#define        is_freq_hrs(opt) \
        (_bit_test(opt, 14))
-#define        set_ign_hrs(opt) \
+#define        set_freq_hrs(opt) \
        (_bit_set(opt, 14))
-#define clear_ign_hrs(opt) \
+#define clear_freq_hrs(opt) \
        (_bit_clear(opt, 14))
 
 
 /*
-  bit 15 : set to 1 : days field should be ignored in goto_non_matching()
-           set to 0 : days field should not be ignored in goto_non_matching()
+  bit 15 : set to 1 : days field is the limit
+           set to 0 : days field is not the limit
 */
-#define        is_ign_days(opt) \
+#define        is_freq_days(opt) \
        (_bit_test(opt, 15))
-#define        set_ign_days(opt) \
+#define        set_freq_days(opt) \
        (_bit_set(opt, 15))
-#define clear_ign_days(opt) \
+#define clear_freq_days(opt) \
        (_bit_clear(opt, 15))
 
 
 /*
-  bit 16 : set to 1 : mons field should be ignored in goto_non_matching()
-           set to 0 : mons field should not be ignored in goto_non_matching()
+  bit 16 : set to 1 : mons field is the limit
+           set to 0 : mons field is not the limit
 */
-#define        is_ign_mons(opt) \
+#define        is_freq_mons(opt) \
        (_bit_test(opt, 16))
-#define        set_ign_mons(opt) \
+#define        set_freq_mons(opt) \
        (_bit_set(opt, 16))
-#define clear_ign_mons(opt) \
+#define clear_freq_mons(opt) \
        (_bit_clear(opt, 16))
 
 
 /*
-  bit 17 : set to 1 : dow field should be ignored in goto_non_matching()
-           set to 0 : dow field should not be ignored in goto_non_matching()
+  bit 17 : set to 1 : dow field is the limit
+           set to 0 : dow field is not the limit
 */
-#define        is_ign_dow(opt) \
+#define        is_freq_dow(opt) \
        (_bit_test(opt, 17))
-#define        set_ign_dow(opt) \
+#define        set_freq_dow(opt) \
        (_bit_set(opt, 17))
-#define clear_ign_dow(opt) \
+#define clear_freq_dow(opt) \
        (_bit_clear(opt, 17))
 
 
+/*
+  bit 18 : set to 1 : limit field is freq to run the line (once a hour, etc)
+           set to 0 : run once per interval of the limit field
+*/
+#define        is_freq_periodically(opt) \
+       (_bit_test(opt, 18))
+#define        set_freq_periodically(opt) \
+       (_bit_set(opt, 18))
+#define clear_freq_periodically(opt) \
+       (_bit_clear(opt, 18))
+
+
+/*
+  bit 19 : set to 1 : run once from mid-interval to mid-interval (i.e. nightly)
+           set to 0 : run once from begin to the end of interval (i.e. daily)
+*/
+#define        is_freq_mid(opt) \
+       (_bit_test(opt, 19))
+#define        set_freq_mid(opt) \
+       (_bit_set(opt, 19))
+#define clear_freq_mid(opt) \
+       (_bit_clear(opt, 19))
+
+
 #endif /* __OPTIONH__ */