* `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);
/* 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;
+ }
}
* `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 :
*/
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__ */