]> granicus.if.org Git - fcron/commitdiff
added timezone support
authorthib <thib>
Sat, 11 Jun 2005 22:50:02 +0000 (22:50 +0000)
committerthib <thib>
Sat, 11 Jun 2005 22:50:02 +0000 (22:50 +0000)
conf.c
database.c
database.h
doc/en/fcrontab.5.sgml
fcron.c
fcron.h
fileconf.c
global.h
save.h

diff --git a/conf.c b/conf.c
index 72f130110e5c92ad1daf4f5df89ed49088e5e8ae..174b8e92b409b3106a7e5ca0df6e8a907fe26aad 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -22,7 +22,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: conf.c,v 1.68 2004-08-12 09:43:41 thib Exp $ */
+ /* $Id: conf.c,v 1.69 2005-06-11 22:51:05 thib Exp $ */
 
 #include "fcron.h"
 
@@ -294,7 +294,8 @@ synchronize_file(char *file_name)
                            struct tm *ftime;
                            ftime = localtime(&new_l->cl_nextexe);
                            debug("  from last conf: %s next exec %d/%d/%d"
-                                 " wday:%d %02d:%02d", new_l->cl_shell,
+                                 " wday:%d %02d:%02d (system time)",
+                                 new_l->cl_shell,
                                  (ftime->tm_mon + 1), ftime->tm_mday,
                                  (ftime->tm_year + 1900), ftime->tm_wday,
                                  ftime->tm_hour, ftime->tm_min);
@@ -590,6 +591,11 @@ read_file(const char *file_name, cf_t *cf)
            cf->cf_tzdiff = (signed char) bufi;
            break;
 
+       case S_TZ_T:
+           /* read the timezone (string) in which the line should run */
+           Read_strn(cl->cl_tz, size, "Error while reading timezone field");
+           break;
+
        case S_SHELL_T:
            Read_strn(cl->cl_shell, size, "Error while reading shell field");
            break;
@@ -827,9 +833,16 @@ add_line_to_file(cl_t *cl, cf_t *cf, uid_t runas, char *runas_str, time_t t_save
                    /* set next exe and mail user */
                    struct tm *since2 = localtime(&cl->cl_nextexe);
                    struct tm since;
+
+                   int tz_changed = 0;
+                   tz_changed = switch_timezone(orig_tz_envvar, cl->cl_tz);
+
                    memcpy(&since, since2, sizeof(since));
                    set_next_exe(cl, NO_GOTO, -1);
                    mail_notrun(cl, SYSDOWN, &since);
+
+                   if ( tz_changed > 0 )
+                       switch_back_timezone(orig_tz_envvar);
                } 
                else
                    set_next_exe(cl, NO_GOTO, -1);
@@ -857,7 +870,8 @@ add_line_to_file(cl_t *cl, cf_t *cf, uid_t runas, char *runas_str, time_t t_save
     if (debug_opt) {
        struct tm *ftime;
        ftime = localtime( &(cl->cl_nextexe) );
-       debug("  cmd %s next exec %d/%d/%d wday:%d %02d:%02d:%02d",
+       debug("  cmd %s next exec %d/%d/%d wday:%d %02d:%02d:%02d"
+             " (system time)",
              cl->cl_shell, (ftime->tm_mon + 1), ftime->tm_mday,
              (ftime->tm_year + 1900), ftime->tm_wday,
              ftime->tm_hour, ftime->tm_min, ftime->tm_sec); 
index 56dc6bf8c6b73d5a79d17330b63930c6bc68ca72..408bc38335548b6fb02cd038c7818def29a5a409 100644 (file)
@@ -21,7 +21,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: database.c,v 1.75 2005-02-26 15:13:00 thib Exp $ */
+ /* $Id: database.c,v 1.76 2005-06-11 22:52:02 thib Exp $ */
 
 #include "fcron.h"
 
@@ -72,6 +72,34 @@ test_jobs(void)
 }
 
 
+int
+switch_timezone(const char *orig_tz, const char* dest_tz)
+/* check if we have already switched to dest_tz timezone, otherwise do it */
+/* If dest_tz is NULL, this function does nothing */
+/* Returns 1 if this function has switched the timezone, 0 otherwise */
+{
+    char *current_tz = getenv("TZ");
+       if ( dest_tz != NULL && 
+            (current_tz == NULL || strcmp(dest_tz, current_tz) != 0)) {
+           setenv("TZ", dest_tz, 1);
+           return 1;
+       }
+       else
+           return 0;
+}
+
+void
+switch_back_timezone(const char *orig_tz)
+/* if orig_tz is NULL, unsets TZ
+ * otherwise, sets TZ to orig_tz */
+{
+    if ( orig_tz == NULL)
+       unsetenv("TZ");
+    else
+       setenv("TZ", orig_tz, 1);
+}
+
+
 time_t
 mktime_no_dst(struct tm *t)
 /* same as mktime(), but without daylight saving time (dst) change adjustment
@@ -81,6 +109,10 @@ mktime_no_dst(struct tm *t)
  *          Unfortunately, the behaviour of mktime() with 
  *          tm_isdst set to -1 depends on the unix you run.
  *          In other word, it wouldn't be portable. */
+/*
+ * WARNING : the content of t has to be valide (for instance, 0<=t->tm_hour<=23,
+ *           etc)
+ */
 {
     struct tm t2;
     time_t ti1;
@@ -402,7 +434,16 @@ add_lavg_job(cl_t *line, int info_fd)
        struct tm *ft;
        struct tm ftime;
        time_t begin_of_cur_int, end_of_cur_int = 0;
-
+       int tz_changed = 0;
+
+       /* Switch to another timezone if necessary. */
+       /* If line should be scheduled in a different time zone
+        * (ie. cl_tz != NULL),
+        * switch to that timezone now, do the calculations,
+        * and switch back to the local timezone at the end 
+        * of the function. */
+       tz_changed = switch_timezone(orig_tz_envvar, line->cl_tz);
+    
        /* handle timezone differences */
        begin_of_cur_int = line->cl_nextexe - (line->cl_file->cf_tzdiff*3600);
 
@@ -423,6 +464,9 @@ add_lavg_job(cl_t *line, int info_fd)
            lavg_array[lavg_num].l_until = end_of_cur_int;
            clear_run_if_late(line->cl_option);
        }
+
+       if ( tz_changed > 0 )
+           switch_back_timezone(orig_tz_envvar);
     }
     else
        lavg_array[lavg_num].l_until = 
@@ -705,9 +749,10 @@ goto_non_matching(cl_t *line, struct tm *ftime, char option)
            if (debug_opt)
                set_wday(ftime);
            debug("   %s beginning of next period %d/%d/%d wday:%d %02d:%02d "
-                 "(tzdiff=%d)", line->cl_shell, (ftime->tm_mon + 1),
+                 "(tzdiff=%d, timezone=%s)", line->cl_shell, (ftime->tm_mon + 1),
                  ftime->tm_mday, (ftime->tm_year + 1900), ftime->tm_wday,
-                 ftime->tm_hour, ftime->tm_min, line->cl_file->cf_tzdiff);
+                 ftime->tm_hour, ftime->tm_min, line->cl_file->cf_tzdiff,
+                 (line->cl_tz != NULL)? line->cl_tz : "localtime");
 
            return;
        }
@@ -828,11 +873,13 @@ goto_non_matching(cl_t *line, struct tm *ftime, char option)
            }
        }
        
-       debug("   %s %s %d/%d/%d wday:%d %02d:%02d (tzdiff=%d)",line->cl_shell,
+       debug("   %s %s %d/%d/%d wday:%d %02d:%02d (tzdiff=%d, timezone=%s)",
+             line->cl_shell,
              (option == STD) ? "first non matching" : "end of interval",
              (ftime->tm_mon + 1), ftime->tm_mday, (ftime->tm_year + 1900),
              ftime->tm_wday, ftime->tm_hour, ftime->tm_min,
-             line->cl_file->cf_tzdiff);
+             line->cl_file->cf_tzdiff,
+             (line->cl_tz != NULL)? line->cl_tz : "localtime");
        return;
     }
 }
@@ -846,9 +893,18 @@ set_next_exe(cl_t *line, char option, int info_fd)
     time_t basetime;
     struct tm *ft;
     struct tm ftime;
+    int tz_changed = 0;
 
     basetime = (option & FROM_CUR_NEXTEXE) ? line->cl_nextexe : now ;
 
+    /* Switch to another timezone if necessary. */
+    /* If line should be scheduled in a different time zone
+     * (ie. cl_tz != NULL),
+     * switch to that timezone now, do the calculations,
+     * and switch back to the local timezone at the end 
+     * of the function. */
+    tz_changed = switch_timezone(orig_tz_envvar, line->cl_tz);
+
     if ( is_td(line->cl_option) ) {
 
        time_t nextexe = 0;
@@ -1011,6 +1067,8 @@ set_next_exe(cl_t *line, char option, int info_fd)
       set_cl_nextexe:
        /* set cl_nextexe (handle the timezone differences) */
 
+       /* NOTE : the output of mktime does not depend on the timezone,
+        *        hence, nextexe is correct even if option timezone is used. */
        nextexe = mktime_no_dst(&ftime);
 
        if ( is_random(line->cl_option) ) {
@@ -1019,9 +1077,10 @@ set_next_exe(cl_t *line, char option, int info_fd)
            time_t intend_int;
 
            debug("   cmd: %s begin int exec %d/%d/%d wday:%d %02d:%02d "
-                 "(tzdiff=%d)", line->cl_shell, (ftime.tm_mon + 1),
+                 "(tzdiff=%d, timezone=%s)", line->cl_shell, (ftime.tm_mon + 1),
                  ftime.tm_mday, (ftime.tm_year + 1900), ftime.tm_wday,
-                 ftime.tm_hour, ftime.tm_min, line->cl_file->cf_tzdiff);
+                 ftime.tm_hour, ftime.tm_min, line->cl_file->cf_tzdiff,
+                 (line->cl_tz != NULL)? line->cl_tz : "localtime");
 
            memcpy(&intend, &ftime, sizeof(intend));
            goto_non_matching(line, &intend, END_OF_INTERVAL);
@@ -1040,11 +1099,12 @@ set_next_exe(cl_t *line, char option, int info_fd)
                memcpy(&ftime, ft, sizeof(ftime));
            }
            send_msg_fd_debug(info_fd, "   cmd: %s next exec %d/%d/%d wday:%d "
-                             "%02d:%02d (tzdiff=%d w/ sys time)", line->cl_shell,
+                             "%02d:%02d (tzdiff=%d, timezone=%s)", line->cl_shell,
                              (ftime.tm_mon + 1), ftime.tm_mday,
                              (ftime.tm_year + 1900), ftime.tm_wday,
                              ftime.tm_hour, ftime.tm_min,
-                             line->cl_file->cf_tzdiff);
+                             line->cl_file->cf_tzdiff,
+                             (line->cl_tz != NULL)? line->cl_tz : "system's");
        }
 
        /* 
@@ -1060,11 +1120,10 @@ set_next_exe(cl_t *line, char option, int info_fd)
        if ( line->cl_nextexe <= now ) {
            error("BUG ??? Fcron thinks the next exe time of %s is %ld, "
                  "hence before now (%ld). To avoid infinite loop, nextexe"
-                 " will be set at now+5s.");
+                 " will be set at now+5s.", line->cl_shell, line->cl_nextexe);
            line->cl_nextexe = now + 5;
        }
 
-       
     }
     else {
        /* this is a job based on system up time */
@@ -1085,6 +1144,9 @@ set_next_exe(cl_t *line, char option, int info_fd)
     
     insert_nextexe(line);
 
+    if ( tz_changed > 0 )
+       switch_back_timezone(orig_tz_envvar);
+
 }
 
 
@@ -1097,11 +1159,21 @@ set_next_exe_notrun(cl_t *line, char context)
     struct tm *ft = NULL;
     struct tm ftime, last_nextexe;
     char set_next_exe_opt = 0;
+    int tz_changed = 0;
 
 /*  // */
     debug("  set_next_exe_notrun : %s %d", line->cl_shell, context);
 /*  // */
 
+
+    /* Switch to another timezone if necessary. */
+    /* If line should be scheduled in a different time zone
+     * (ie. cl_tz != NULL),
+     * switch to that timezone now, do the calculations,
+     * and switch back to the local timezone at the end 
+     * of the function. */
+    tz_changed = switch_timezone(orig_tz_envvar, line->cl_tz);
+    
     if (context == SYSDOWN) {
        /* handle timezone differences */
        previous_period = line->cl_nextexe - (line->cl_file->cf_tzdiff * 3600);
@@ -1130,6 +1202,9 @@ set_next_exe_notrun(cl_t *line, char context)
        mail_notrun(line, context, &last_nextexe);
     }
 
+    if ( tz_changed > 0 )
+       switch_back_timezone(orig_tz_envvar);
+
 }
 
 void
@@ -1139,6 +1214,7 @@ mail_notrun(cl_t *line, char context, struct tm *since)
     int pid = 0;
     FILE *mailf = 0;
     struct tm *time2 = NULL, time;
+    int tz_changed = 0;
 
     switch ( pid = fork() ) {
     case -1:
@@ -1165,6 +1241,14 @@ mail_notrun(cl_t *line, char context, struct tm *since)
        return;
     }
 
+    /* Switch to another timezone if necessary. */
+    /* If line should be scheduled in a different time zone
+     * (ie. cl_tz != NULL),
+     * switch to that timezone now, do the calculations,
+     * and switch back to the local timezone at the end 
+     * of the function. */
+    tz_changed = switch_timezone(orig_tz_envvar, line->cl_tz);
+    
     if ( context == QUEUE_FULL )
        time2 = localtime(&now);
     else
@@ -1177,30 +1261,34 @@ mail_notrun(cl_t *line, char context, struct tm *since)
     switch ( context ) {
     case SYSDOWN:
        fprintf(mailf, "Line %s has not run since and including "
-                "%d/%d/%d wday:%d %02d:%02d\ndue to system's down state.\n",
+               "%d/%d/%d wday:%d %02d:%02d (timezone=%s)\n"
+               "due to system's down state.\n",
                 line->cl_shell, (since->tm_mon + 1), since->tm_mday,
                 (since->tm_year + 1900), since->tm_wday, since->tm_hour,
-                since->tm_min);
+                since->tm_min, (line->cl_tz)? line->cl_tz : "system's");
        fprintf(mailf, "It will be next executed at %d/%d/%d wday:"
                 "%d %02d:%02d\n", (time.tm_mon + 1), time.tm_mday,
                 (time.tm_year+1900), time.tm_wday, time.tm_hour, time.tm_min);
        break;
     case LAVG:
        fprintf(mailf, "Line %s has not run since and including "
-                "%d/%d/%d wday:%d %02d:%02d\n", line->cl_shell,
-                (since->tm_mon + 1), since->tm_mday, (since->tm_year + 1900),
-                since->tm_wday, since->tm_hour, since->tm_min);
+                "%d/%d/%d wday:%d %02d:%02d (timezone=%s)\n",
+               line->cl_shell, (since->tm_mon + 1), since->tm_mday,
+               (since->tm_year + 1900), since->tm_wday, since->tm_hour,
+               since->tm_min, (line->cl_tz)? line->cl_tz : "system's");
        fprintf(mailf, "due to a too high system load average or "
                 "too many lavg-serial jobs.\n");
        fprintf(mailf, "It will be next executed at %d/%d/%d "
-                "wday:%d %02d:%02d\n", (time.tm_mon + 1), time.tm_mday,
-                (time.tm_year+1900), time.tm_wday, time.tm_hour, time.tm_min);
+               "wday:%d %02d:%02d (timezone=%s)\n", (time.tm_mon + 1),
+               time.tm_mday, (time.tm_year+1900), time.tm_wday, time.tm_hour,
+               time.tm_min, (line->cl_tz)? line->cl_tz : "system's");
        break;
     case QUEUE_FULL:
        fprintf(mailf,"Line %s couldn't be added to lavg or serial queue which"
-                " is full ( %d/%d/%d wday:%d %02d:%02d ).\n", line->cl_shell,
-                (time.tm_mon + 1), time.tm_mday, (time.tm_year + 1900),
-                time.tm_wday, time.tm_hour, time.tm_min);
+                " is full ( %d/%d/%d wday:%d %02d:%02d (timezone=%s)).\n",
+               line->cl_shell, (time.tm_mon + 1), time.tm_mday,
+               (time.tm_year + 1900), time.tm_wday, time.tm_hour, time.tm_min,
+               (line->cl_tz)? line->cl_tz : "system's");
        fprintf(mailf, "Consider using options lavgonce, until, strict, "
                 "serialonce and/or fcron's option -m.\n");
        fprintf(mailf, "Note that job %s has not run.\n", line->cl_shell);
@@ -1215,7 +1303,7 @@ mail_notrun(cl_t *line, char context, struct tm *since)
     launch_mailer(line, mailf);
     
     /* we should not come here : launch_mailer does not return */
-    error("mail_notrun : launch_mailer failed");
+    die("mail_notrun : launch_mailer failed");
     
 }
 
index 2753d19e0482499425608c3fcd3e931e89017d3a..ea5f643fa36b67b5fe88e2423977cdc08557f638 100644 (file)
@@ -21,7 +21,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: database.h,v 1.7 2004-08-12 09:50:21 thib Exp $ */
+ /* $Id: database.h,v 1.8 2005-06-11 22:52:27 thib Exp $ */
 
 #ifndef __DATABASE_H__
 #define __DATABASE_H__
@@ -46,5 +46,7 @@ extern void run_normal_job(cl_t *line, int fd);
 extern void add_serial_job(struct cl_t *line, int fd);
 extern void add_lavg_job(struct cl_t *line, int fd);
 extern void run_serial_job(void);
+extern int switch_timezone(const char *orig_tz, const char* dest_tz);
+extern void switch_back_timezone(const char *orig_tz);
 
 #endif /* __DATABASE_H__ */
index d787d00ad99e6dbe4c200132c5df43bdacda3eb9..6cf46b03eaae16820575c16fc20482dbba98939b 100644 (file)
@@ -8,7 +8,7 @@ Foundation.
 A copy of the license is included in gfdl.sgml.
 -->
 
-<!-- $Id: fcrontab.5.sgml,v 1.14 2004-01-29 10:37:30 thib Exp $ -->
+<!-- $Id: fcrontab.5.sgml,v 1.15 2005-06-11 22:55:02 thib Exp $ -->
 
 <refentry id="fcrontab.5">
     <refmeta>
@@ -44,7 +44,7 @@ fcrontab file can be either</para>
                <para>entries based on elapsed system up time,</para>
            </listitem>
            <listitem>
-               <para>entries based on absolut time (like normal crontab
+               <para>entries based on absolute time (like normal crontab
 entries), or</para>
            </listitem>
            <listitem>
@@ -678,15 +678,28 @@ not run) or be let there until the system load average allows its execution
                    </listitem>
                </varlistentry>
 
+              <varlistentry id="fcrontab.5.timezone">
+                 <term>timezone</term>
+                 <listitem>
+                    <para><emphasis><type>timezone-name</type></emphasis>(<constant></constant>)</para>
+                    <para>Run the job in the given time zone. timezone-name is a string which is valid for the environment variable TZ : see the documentation of your system for more details. For instance, "Europe/Paris" is valid on a Linux system. This option handles daylight saving time changes correctly.</para>
+                    <para>Please note that if you give an erroneous timezone-name argument, it will be SILENTLY ignored, and the job will run in system's time zone.</para>
+                    <para>WARNING : do *not* use option timezone and option tzdiff simultaneously ! There is no need to do so, and timezone is cleverer than tzdiff.</para>
+                    <para>&seealso; options &opttzdiff;.</para>
+                 </listitem>
+              </varlistentry>
+
+
                <varlistentry id="fcrontab.5.tzdiff">
                    <term>tzdiff</term>
                    <listitem>
                        <para><emphasis><type>integer</type></emphasis>(<constant>0</constant>)</para>
+                    <para>WARNING : this option is depreciated : use option timezone instead !</para>
                        <para>Time zone difference (in hours, between -24 and
 24) between the system time, and the local real time. This option allows a user
 to define its & and %-lines in the local time. Note that this value is set for a
-whole fcrontab file, and only the last definition is taken into account.</para>
-                       <para>&seealso; options &optlavg;, &optstrict;.</para>
+whole fcrontab file, and only the last definition is taken into account. tzdiff is quite stupid : it doesn't handle daylight saving changes, while option timezone does, so you should use the latter.</para>
+                       <para>&seealso; options &opttimezone;.</para>
                    </listitem>
                </varlistentry>
 
diff --git a/fcron.c b/fcron.c
index ac0ced1c3cd61ae0254c617c02d1654e65240387..245a242dcd8cf7b67a367b3c154c94044dcc1dfe 100644 (file)
--- a/fcron.c
+++ b/fcron.c
@@ -21,7 +21,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: fcron.c,v 1.73 2005-03-12 12:39:21 thib Exp $ */
+ /* $Id: fcron.c,v 1.74 2005-06-11 22:50:02 thib Exp $ */
 
 #include "fcron.h"
 
@@ -33,7 +33,7 @@
 #include "socket.h"
 #endif
 
-char rcs_info[] = "$Id: fcron.c,v 1.73 2005-03-12 12:39:21 thib Exp $";
+char rcs_info[] = "$Id: fcron.c,v 1.74 2005-06-11 22:50:02 thib Exp $";
 
 void main_loop(void);
 void check_signal(void);
@@ -76,7 +76,8 @@ char *tmp_path = "";
 /* process identity */
 pid_t daemon_pid;
 mode_t saved_umask;           /* default root umask */
-char *prog_name = NULL;         
+char *prog_name = NULL;
+char *orig_tz_envvar = NULL;
 
 /* have we got a signal ? */
 char sig_conf = 0;            /* is 1 when we got a SIGHUP, 2 for a SIGUSR1 */ 
@@ -175,7 +176,8 @@ print_schedule(void)
        explain(" File %s", cf->cf_user);
        for (cl = cf->cf_line_base; cl; cl = cl->cl_next) {
            ftime = localtime( &(cl->cl_nextexe) );
-           explain("  cmd %s next exec %d/%d/%d wday:%d %02d:%02d",
+           explain("  cmd %s next exec %d/%d/%d wday:%d %02d:%02d"
+                   " (system time)",
                    cl->cl_shell, (ftime->tm_mon + 1), ftime->tm_mday,
                    (ftime->tm_year + 1900), ftime->tm_wday,
                    ftime->tm_hour, ftime->tm_min); 
@@ -223,6 +225,8 @@ xexit(int exit_value)
     
     free_conf();
 
+    free(orig_tz_envvar);
+
     explain("Exiting with code %d", exit_value);
     exit (exit_value);
 
@@ -503,6 +507,9 @@ main(int argc, char **argv)
      * used in die() and die_e() functions */
     daemon_pid = getpid();
 
+    /* save the value of the TZ env variable (used for option timezone) */
+    orig_tz_envvar = strdup2(getenv("TZ"));
+
     parseopt(argc, argv);
 
     /* read fcron.conf and update global parameters */
diff --git a/fcron.h b/fcron.h
index 117f266389347711dcbd76a138615d927e300500..37bdee579ce8f7d22e4bc73716c87ea30baf632a 100644 (file)
--- a/fcron.h
+++ b/fcron.h
@@ -21,7 +21,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: fcron.h,v 1.31 2003-12-25 22:43:23 thib Exp $ */
+ /* $Id: fcron.h,v 1.32 2005-06-11 22:50:32 thib Exp $ */
 
 #ifndef __FCRON_H__
 #define __FCRON_H__
@@ -66,6 +66,7 @@ extern char dosyslog;
 extern time_t first_sleep;
 extern char *cdir;
 extern pid_t daemon_pid;
+extern char *orig_tz_envvar;
 extern mode_t saved_umask;
 extern char *prog_name;
 extern char sig_hup;
index 129c8b4435e83c97980f69dbc723d1eea742ad73..d1fc92952e9b386b92d41683bddff8e65e09b643 100644 (file)
@@ -22,7 +22,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: fileconf.c,v 1.74 2004-07-11 18:08:08 thib Exp $ */
+ /* $Id: fileconf.c,v 1.75 2005-06-11 22:50:41 thib Exp $ */
 
 #include "fcrontab.h"
 
@@ -181,6 +181,7 @@ read_file(char *filename)
     default_line.cl_file = cf;
     default_line.cl_runas = strdup2(runas);
     default_line.cl_mailto = strdup2(runas);
+    default_line.cl_tz = NULL;
     set_default_opt(default_line.cl_option);
 
     if ( debug_opt )
@@ -264,6 +265,7 @@ read_file(char *filename)
     
     free(default_line.cl_runas);
     free(default_line.cl_mailto);
+    free(default_line.cl_tz);
 
     if ( ! need_correction )
        return OK;
@@ -466,6 +468,7 @@ read_opt(char *ptr, cl_t *cl)
        }
 
        /* global options for a file */
+
        if ( strcmp(opt_name, "tzdiff") == 0 ) {
            char negative = 0;
 
@@ -486,8 +489,30 @@ read_opt(char *ptr, cl_t *cl)
                fprintf(stderr, "  Opt : \"%s\" (-)%d\n", opt_name, i);
        }
        
-
        /* options related to a line (or a set of lines) */
+
+       else if ( strcmp(opt_name, "timezone") == 0 ) {
+           char buf[50];
+           bzero(buf, sizeof(buf));
+
+           if( ! in_brackets )
+               Handle_err;
+
+           i = 0;
+           while ( *ptr != ')' && i + 1 < sizeof(buf) )
+               buf[i++] = *ptr++;
+           
+           if ( strcmp(buf, "\0") == 0 ) {
+               Flush(cl->cl_tz);
+           }
+           else {
+               Set(cl->cl_tz, buf);
+           }
+           if (debug_opt)
+               fprintf(stderr, "  Opt : \"%s\" \"%s\"\n", opt_name, cl->cl_tz);
+       }
+       
+
        else if(strcmp(opt_name, "s") == 0 || strcmp(opt_name, "serial") == 0){
            if ( in_brackets && (ptr = get_bool(ptr, &i)) == NULL )
                Handle_err;
@@ -550,6 +575,7 @@ read_opt(char *ptr, cl_t *cl)
                bzero(cl, sizeof(cl_t));
                Set(cl->cl_runas, runas);
                Set(cl->cl_mailto, runas);
+               Flush(cl->cl_tz);
                set_default_opt(cl->cl_option);
            }
            if (debug_opt)
@@ -1084,6 +1110,8 @@ read_freq(char *ptr, cf_t *cf)
     memcpy(cl, &default_line, sizeof(cl_t));
     cl->cl_runas = strdup2(default_line.cl_runas);
     cl->cl_mailto = strdup2(default_line.cl_mailto);
+    if ( cl->cl_tz != NULL ) 
+       cl->cl_tz = strdup2(default_line.cl_tz);
     cl->cl_first = -1; /* 0 is a valid value, so we have to use -1 to detect unset */
 
     /* skip the @ */
@@ -1182,12 +1210,14 @@ read_arys(char *ptr, cf_t *cf)
     /* read a run freq number plus a normal fcron line */
 {
     cl_t *cl = NULL;
-    unsigned int i = 0;
+    int i = 0;
 
     Alloc(cl, cl_t);
     memcpy(cl, &default_line, sizeof(cl_t));
     cl->cl_runas = strdup2(default_line.cl_runas);
     cl->cl_mailto = strdup2(default_line.cl_mailto);
+    if ( cl->cl_tz != NULL ) 
+       cl->cl_tz = strdup2(default_line.cl_tz);
 
     /* set cl_remain if not specified */
     if ( *ptr == '&' ) {
@@ -1203,7 +1233,7 @@ read_arys(char *ptr, cf_t *cf)
                            " skipping line.\n", file_name, line);
                    goto exiterr;
                }
-               cl->cl_runfreq = i;
+               cl->cl_runfreq = (unsigned short) i;
            }
        }
        else if ( isalnum( (int) *ptr) )
@@ -1278,6 +1308,8 @@ read_period(char *ptr, cf_t *cf)
     memcpy(cl, &default_line, sizeof(cl_t));
     cl->cl_runas = strdup2(default_line.cl_runas);
     cl->cl_mailto = strdup2(default_line.cl_mailto);
+    if ( cl->cl_tz != NULL ) 
+       cl->cl_tz = strdup2(default_line.cl_tz);
 
     /* skip the % */
     ptr++;
@@ -1619,6 +1651,7 @@ delete_file(const char *user_name)
                free(line->cl_shell);
                free(line->cl_mailto);
                free(line->cl_runas);
+               free(line->cl_tz);
                free(line);
            }
            break ;
index a2703e7de631a51d8fe300dc10ffc36989fb1325..4143a06bc926e32b208e3322191fe5206f58bbe3 100644 (file)
--- a/global.h
+++ b/global.h
@@ -21,7 +21,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: global.h,v 1.44 2005-03-12 12:39:46 thib Exp $ */
+ /* $Id: global.h,v 1.45 2005-06-11 22:50:54 thib Exp $ */
 
 
 /* 
@@ -197,6 +197,7 @@ typedef struct cl_t {
     char         *cl_shell;      /* shell command                           */
     char          *cl_runas;      /* determine permissions of the job        */
     char          *cl_mailto;     /* mail output to cl_mailto                */
+    char          *cl_tz;         /* time zone of the line                   */
     long int       cl_id;         /* line's unique id number                 */
     time_t         cl_until;      /* timeout of the wait for a lavg value    */
     time_t         cl_first;      /* initial delay preserved for volatile entries */
diff --git a/save.h b/save.h
index d5d03fb39573eb958fe300fb1448c1c19d9a43ae..71708c74872505831350c704f5ded97c3cc3e9c3 100644 (file)
--- a/save.h
+++ b/save.h
@@ -21,7 +21,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: save.h,v 1.10 2003-12-25 22:52:07 thib Exp $ */
+ /* $Id: save.h,v 1.11 2005-06-11 22:53:10 thib Exp $ */
 
 #ifndef __SAVE_H__
 #define __SAVE_H__
@@ -80,5 +80,6 @@ extern int save_file_safe(cf_t *file, char *final_path, char *prog_name, uid_t o
 #define S_DOW_T        2016  /* dow boolean array */
 #define S_OPTION_T     2017  /* options for that line (see option.h) */
 #define S_FIRST_T      2018  /* wait time before first execution */
+#define S_TZ_T         2019  /* time zone of the line */
 
 #endif /* __SAVE_H__ */