Package: bcron
Version: 0.09-10
Severity: wishlist

A simple change to bcron-sched makes it so jobs can have custom
timezones instead of being constrained to the timezone in force when
the process began.  Note that this change has not been extensively
tested.

-- System Information:
Debian Release: lenny/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)

Kernel: Linux 2.6.24-1-686 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages bcron depends on:
ii  libbg1                        1.104-2    BG Libraries Collection
ii  libc6                         2.7-10     GNU C Library: Shared libraries

Versions of packages bcron recommends:
ii  bcron-run                     0.09-10    Bruce's cron system
ii  exim4-daemon-light [mail-tran 4.69-5+b1  lightweight Exim MTA (v4) daemon
ii  runit                         2.0.0-1    a UNIX init scheme with service su
ii  ucspi-unix                    0.36-3     UNIX-domain socket client-server c

-- no debconf information
--- bcron-0.09.orig/bcron-sched.c
+++ bcron-0.09/bcron-sched.c
@@ -1,3 +1,4 @@
+#include <string.h>
 #include <sysdeps.h>
 #include <systime.h>
 #include <errno.h>
@@ -7,6 +8,7 @@
 #include <misc/misc.h>
 #include <msg/msg.h>
 #include <msg/wrap.h>
+#include <str/env.h>
 #include <str/iter.h>
 #include <str/str.h>
 #include <unix/nonblock.h>
@@ -38,6 +40,8 @@
 {
   struct ghashiter i;
   struct job* job;
+  const char* tz = getenv("TZ");
+  const char* restore_tz = tz;
 
   nexttime = next_minute(reftime.tv_sec, &nexttm);
 
@@ -45,10 +49,32 @@
   ghashiter_loop(&i, &crontabs) {
     for (job = ((struct crontabs_entry*)i.entry)->data.jobs;
 	 job != 0; job = job->next) {
-      if (job->nexttime == 0)
-	job->nexttime = timespec_next(&job->times, nexttime, &nexttm);
+        if (job->nexttime == 0) {
+            /* Adjust nexttm for the timezone of this job: */
+            const char* new_tz = envstr_get(&job->environ, "TZ");
+            if ( ! ( new_tz == tz ||
+                     new_tz && tz && strcmp(new_tz, tz) == 0 ) )
+            {
+                if ( new_tz ) {
+                    setenv("TZ", new_tz, 1);
+                } else {
+                    unsetenv("TZ");
+                }
+                tz = new_tz;
+                tzset();
+
+                /* Recompute the nexttm: */
+                next_minute(reftime.tv_sec, &nexttm);
+            }
+            job->nexttime  = timespec_next(&job->times, nexttime, &nexttm);
+        }
     }
   }
+  if ( restore_tz ) {
+      setenv("TZ", restore_tz, 1);
+  } else {
+      unsetenv("TZ");
+  }
 }
 
 static void loadall(void)

Reply via email to