summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/cron/config.h4
-rw-r--r--usr.sbin/cron/cron.c70
-rw-r--r--usr.sbin/cron/funcs.h4
-rw-r--r--usr.sbin/cron/globals.h5
-rw-r--r--usr.sbin/cron/misc.c46
-rw-r--r--usr.sbin/cron/structs.h4
6 files changed, 93 insertions, 40 deletions
diff --git a/usr.sbin/cron/config.h b/usr.sbin/cron/config.h
index 1fe14732974..a0bd8d994c9 100644
--- a/usr.sbin/cron/config.h
+++ b/usr.sbin/cron/config.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.h,v 1.8 2001/02/18 20:28:45 millert Exp $ */
+/* $OpenBSD: config.h,v 1.9 2001/02/19 14:33:32 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
@@ -86,6 +86,8 @@
#define CAPITALIZE_FOR_PS /*-*/
+#define HAVE_TM_GMTOFF /*-*/
+
/* if your OS supports a BSD-style login.conf file */
#define LOGIN_CAP /*-*/
diff --git a/usr.sbin/cron/cron.c b/usr.sbin/cron/cron.c
index b9086c8c2c0..b12cb33fc82 100644
--- a/usr.sbin/cron/cron.c
+++ b/usr.sbin/cron/cron.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cron.c,v 1.10 2001/02/18 19:48:31 millert Exp $ */
+/* $OpenBSD: cron.c,v 1.11 2001/02/19 14:33:32 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +21,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$OpenBSD: cron.c,v 1.10 2001/02/18 19:48:31 millert Exp $";
+static char rcsid[] = "$OpenBSD: cron.c,v 1.11 2001/02/19 14:33:32 millert Exp $";
#endif
#define MAIN_PROGRAM
@@ -30,15 +30,16 @@ static char rcsid[] = "$OpenBSD: cron.c,v 1.10 2001/02/18 19:48:31 millert Exp $
static void usage(void),
run_reboot_jobs(cron_db *),
- find_jobs __P((time_min, cron_db *, int, int)),
- set_time __P((void)),
- cron_sleep __P((time_min)),
+ find_jobs __P((int, cron_db *, int, int)),
+ set_time __P((int)),
+ cron_sleep __P((int)),
sigchld_handler(int),
sighup_handler(int),
sigchld_reaper(void),
parse_args(int c, char *v[]);
static int got_sighup, got_sigchld;
+static int timeRunning, virtualTime, clockTime;
static void
usage(void) {
@@ -115,13 +116,13 @@ main(int argc, char *argv[]) {
database.tail = NULL;
database.mtime = (time_t) 0;
load_database(&database);
- set_time();
+ set_time(1);
run_reboot_jobs(&database);
timeRunning = virtualTime = clockTime;
/*
* Too many clocks, not enough time (Al. Einstein)
- * These clocks are in minutes since the epoch (time()/60).
+ * These clocks are in minutes since the epoch, adjusted for timezone.
* virtualTime: is the time it *would* be if we woke up
* promptly and nobody ever changed the clock. It is
* monotonically increasing... unless a timejump happens.
@@ -130,7 +131,7 @@ main(int argc, char *argv[]) {
* clockTime: is the time when set_time was last called.
*/
while (TRUE) {
- time_min timeDiff;
+ int timeDiff;
int wakeupKind;
if (got_sighup) {
@@ -146,7 +147,7 @@ main(int argc, char *argv[]) {
/* ... wait for the time (in minutes) to change ... */
do {
cron_sleep(timeRunning + 1);
- set_time();
+ set_time(0);
} while (clockTime == timeRunning);
timeRunning = clockTime;
@@ -179,14 +180,14 @@ main(int argc, char *argv[]) {
* minute until caught up.
*/
Debug(DSCH, ("[%d], normal case %d minutes to go\n",
- getpid(), timeRunning - virtualTime))
+ getpid(), timeDiff))
do {
if (job_runqueue())
sleep(10);
virtualTime++;
find_jobs(virtualTime, &database,
TRUE, TRUE);
- } while (virtualTime< timeRunning);
+ } while (virtualTime < timeRunning);
break;
case 2:
@@ -202,7 +203,7 @@ main(int argc, char *argv[]) {
* housekeeping.
*/
Debug(DSCH, ("[%d], DST begins %d minutes to go\n",
- getpid(), timeRunning - virtualTime))
+ getpid(), timeDiff))
/* run wildcard jobs for current minute */
find_jobs(timeRunning, &database, TRUE, FALSE);
@@ -213,7 +214,7 @@ main(int argc, char *argv[]) {
virtualTime++;
find_jobs(virtualTime, &database,
FALSE, TRUE);
- set_time();
+ set_time(0);
} while (virtualTime< timeRunning &&
clockTime == timeRunning);
break;
@@ -221,14 +222,14 @@ main(int argc, char *argv[]) {
case 0:
/*
* case 3: timeDiff is a small or medium-sized
- * negative num, eg. because of DST ending just
- * run the wildcard jobs. The fixed-time jobs
- * probably have already run, and should not be
- * repeated. Virtual time does not change until
- * we are caught up.
+ * negative num, eg. because of DST ending.
+ * Just run the wildcard jobs. The fixed-time
+ * jobs probably have already run, and should
+ * not be repeated. Virtual time does not
+ * change until we are caught up.
*/
Debug(DSCH, ("[%d], DST ends %d minutes to go\n",
- getpid(), virtualTime - timeRunning))
+ getpid(), timeDiff))
find_jobs(timeRunning, &database, TRUE, FALSE);
break;
default:
@@ -262,9 +263,9 @@ run_reboot_jobs(cron_db *db) {
}
static void
-find_jobs(time_min vtime, cron_db *db, int doWild, int doNonWild) {
+find_jobs(int vtime, cron_db *db, int doWild, int doNonWild) {
time_t virtualSecond = vtime * SECONDS_PER_MINUTE;
- struct tm *tm = localtime(&virtualSecond);
+ struct tm *tm = gmtime(&virtualSecond);
int minute, hour, dom, month, dow;
user *u;
entry *e;
@@ -311,20 +312,35 @@ find_jobs(time_min vtime, cron_db *db, int doWild, int doNonWild) {
* Note that clockTime is a unix wallclock time converted to minutes.
*/
static void
-set_time(void) {
-
- StartTime = time((time_t *)0);
- clockTime = StartTime / (unsigned long)SECONDS_PER_MINUTE;
+set_time(int initialize) {
+ struct tm *tm;
+ static long gmtoff;
+ static int isdst;
+
+ StartTime = time(NULL);
+
+ /* We adjust the time to GMT so we can catch DST changes. */
+ tm = localtime(&StartTime);
+ if (initialize || tm->tm_isdst != isdst) {
+ isdst = tm->tm_isdst;
+ gmtoff = get_gmtoff(&StartTime);
+ }
+ clockTime = (StartTime + gmtoff) / (time_t)SECONDS_PER_MINUTE;
}
/*
* Try to just hit the next minute.
*/
static void
-cron_sleep(time_min target) {
+cron_sleep(int target) {
+ time_t t;
+ struct tm *tm;
int seconds_to_wait;
- seconds_to_wait = (int)(target * SECONDS_PER_MINUTE - time(NULL)) + 1;
+ t = time(NULL);
+ tm = localtime(&t);
+ t += tm->tm_gmtoff;
+ seconds_to_wait = (int)(target * SECONDS_PER_MINUTE - t) + 1;
Debug(DSCH, ("[%ld] Target time=%ld, sec-to-wait=%d\n",
(long)getpid(), (long)target*SECONDS_PER_MINUTE, seconds_to_wait))
diff --git a/usr.sbin/cron/funcs.h b/usr.sbin/cron/funcs.h
index 4e2e0289b89..20ff142b460 100644
--- a/usr.sbin/cron/funcs.h
+++ b/usr.sbin/cron/funcs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: funcs.h,v 1.1 2001/02/18 19:48:35 millert Exp $ */
+/* $OpenBSD: funcs.h,v 1.2 2001/02/19 14:33:32 millert Exp $ */
/*
* Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
@@ -68,3 +68,5 @@ entry *load_entry(FILE *, void (*)(),
struct passwd *, char **);
FILE *cron_popen(char *, char *, entry *);
+
+long get_gmtoff(time_t *clock);
diff --git a/usr.sbin/cron/globals.h b/usr.sbin/cron/globals.h
index fcbc52274b7..dfd1874cc3c 100644
--- a/usr.sbin/cron/globals.h
+++ b/usr.sbin/cron/globals.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: globals.h,v 1.2 2001/02/18 20:14:01 millert Exp $ */
+/* $OpenBSD: globals.h,v 1.3 2001/02/19 14:33:33 millert Exp $ */
/*
* Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
@@ -58,9 +58,6 @@ XTRN const char *DowNames[]
XTRN char *ProgramName INIT("amnesia");
XTRN int LineNumber INIT(0);
XTRN time_t StartTime INIT(0);
-XTRN time_min timeRunning INIT(0);
-XTRN time_min virtualTime INIT(0);
-XTRN time_min clockTime INIT(0);
#if DEBUGGING
XTRN int DebugFlags INIT(0);
diff --git a/usr.sbin/cron/misc.c b/usr.sbin/cron/misc.c
index 07ca1452e0c..7764aeb9fd2 100644
--- a/usr.sbin/cron/misc.c
+++ b/usr.sbin/cron/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.8 2001/02/18 19:48:35 millert Exp $ */
+/* $OpenBSD: misc.c,v 1.9 2001/02/19 14:33:33 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* All rights reserved
*/
@@ -21,7 +21,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$OpenBSD: misc.c,v 1.8 2001/02/18 19:48:35 millert Exp $";
+static char rcsid[] = "$OpenBSD: misc.c,v 1.9 2001/02/19 14:33:33 millert Exp $";
#endif
/* vix 26jan87 [RCS has the rest of the log]
@@ -692,8 +692,9 @@ arpadate(clock)
static char ret[64]; /* zone name might be >3 chars */
char *qmark;
size_t len;
- int hours = tm->tm_gmtoff / 3600;
- int minutes = (tm->tm_gmtoff - (hours * 3600)) / 60;
+ long gmtoff = get_gmtoff(&t);
+ int hours = gmtoff / 3600;
+ int minutes = (gmtoff - (hours * 3600)) / 60;
if (minutes < 0)
minutes = -minutes;
@@ -722,3 +723,40 @@ int swap_uids_back() { return (seteuid(save_euid)); }
int swap_uids() { return (setreuid(geteuid(), getuid())); }
int swap_uids_back() { return (swap_uids()); }
#endif /*HAVE_SAVED_UIDS*/
+
+/* Return the offset from GMT in seconds (algorithm taken from sendmail). */
+#ifdef HAVE_TM_GMTOFF
+long get_gmtoff(time_t *clock)
+{
+ struct tm *tm;
+
+ tm = localtime(clock);
+ return (tm->tm_gmtoff);
+}
+#else
+long get_gmtoff(time_t *clock)
+{
+ struct tm local;
+ struct tm *gmt;
+ long offset;
+
+ local = *localtime(clock);
+ gmt = gmtime(clock);
+
+ offset = (local.tm_sec - gmt->tm_sec) +
+ ((local.tm_min - gmt->tm_min) * 60) +
+ ((local.tm_hour - gmt->tm_hour) * 3600);
+
+ /* Timezone may cause year rollover to happen on a different day. */
+ if (local.tm_year < gmt->tm_year)
+ offset -= 24 * 3600;
+ else if (local.tm_year > gmt->tm_year)
+ offset -= 24 * 3600;
+ else if (local.tm_yday < gmt->tm_yday)
+ offset -= 24 * 3600;
+ else if (local.tm_yday > gmt->tm_yday)
+ offset += 24 * 3600;
+
+ return (offset);
+}
+#endif /* HAVE_TM_GMTOFF */
diff --git a/usr.sbin/cron/structs.h b/usr.sbin/cron/structs.h
index 7dd49ae87d7..f0a4aee5f10 100644
--- a/usr.sbin/cron/structs.h
+++ b/usr.sbin/cron/structs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: structs.h,v 1.1 2001/02/18 19:48:36 millert Exp $ */
+/* $OpenBSD: structs.h,v 1.2 2001/02/19 14:33:33 millert Exp $ */
/*
* Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
@@ -17,8 +17,6 @@
* SOFTWARE.
*/
-typedef int time_min; /* time in minutes */
-
typedef struct _entry {
struct _entry *next;
uid_t uid;