aboutsummaryrefslogtreecommitdiff
path: root/sbin/adjkerntz
diff options
context:
space:
mode:
authorAndrey A. Chernov <ache@FreeBSD.org>1993-12-16 18:44:40 +0000
committerAndrey A. Chernov <ache@FreeBSD.org>1993-12-16 18:44:40 +0000
commit3e714780bebb0be734a0538b7fe4bb2e6951feaf (patch)
tree5f9451ac2f05728daf1698b2b7488075ae4560ef /sbin/adjkerntz
parent68a21a4b381bc6db335d35f0d91681f61a60212a (diff)
downloadsrc-3e714780bebb0be734a0538b7fe4bb2e6951feaf.tar.gz
src-3e714780bebb0be734a0538b7fe4bb2e6951feaf.zip
Notes
Diffstat (limited to 'sbin/adjkerntz')
-rw-r--r--sbin/adjkerntz/Makefile4
-rw-r--r--sbin/adjkerntz/adjkerntz.8122
-rw-r--r--sbin/adjkerntz/adjkerntz.c180
-rw-r--r--sbin/adjkerntz/pathnames.h36
4 files changed, 342 insertions, 0 deletions
diff --git a/sbin/adjkerntz/Makefile b/sbin/adjkerntz/Makefile
new file mode 100644
index 000000000000..1ac5047b6f6a
--- /dev/null
+++ b/sbin/adjkerntz/Makefile
@@ -0,0 +1,4 @@
+PROG= adjkerntz
+MAN8= adjkerntz.8
+
+.include <bsd.prog.mk>
diff --git a/sbin/adjkerntz/adjkerntz.8 b/sbin/adjkerntz/adjkerntz.8
new file mode 100644
index 000000000000..ac8fb5fbc952
--- /dev/null
+++ b/sbin/adjkerntz/adjkerntz.8
@@ -0,0 +1,122 @@
+.\" Copyright (C) 1993 by Andrew A. Chernov, Moscow, Russia.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd December 15, 1993
+.Dt ADJKERNTZ 8
+.Os FreeBSD
+.Sh NAME
+.Nm adjkerntz
+.Nd "adjusts the kernel time if the machine runs wall CMOS clock"
+.Sh SYNOPSIS
+.Nm adjkerntz
+.Fl i
+.Op Fl v
+.Nm adjkerntz
+.Fl a
+.Op Fl v
+.Sh DESCRIPTION
+.Nm Adjkerntz
+fixes kernel time (makes it UTC) using the current wall CMOS clock value,
+the current time zone rule and the kernel timezone value. The adjustment is
+enabled only if the file
+.Pa /etc/wall_cmos_clock
+exists, in other cases it is assumed that the machine runs UTC CMOS clock and
+.Nm adjkerntz
+does nothing.
+.Pp
+The adjustment is needed at boot stage and when a time zone
+change occurs, so
+.Nm adjkerntz
+can be called in two forms:
+.Bl -tag -width 4n
+.It Cm Fl i
+initialization call from
+.Pa /etc/rc
+(before any daemons are started).
+.Nm Adjkerntz
+makes the first adjustment and the initial time zone offset is stored into
+.Pa /var/run/.adjkerntz
+for following subsequent
+.Nm adjkerntz
+calls.
+.It Cm Fl a
+This form is needed, when time zone changes occur.
+.Nm Adjkerntz
+uses the previously stored
+time zone offset and the changed time zone rule to
+produce the new time zone offset, fix the kernel time and store the new
+offset into
+.Pa /var/run/.adjkerntz
+too.
+It is recommended to use this form in root's
+.Xr crontab 5
+near 3am,
+since this time matches most modern time zone changes.
+.It Cm Fl v
+This option is for diagnostic purposes. It causes
+.Nm adjkerntz
+to print differences between the old and new time zone offsets
+to stdout.
+.El
+.Pp
+.Nm Adjkerntz
+clears the kernel timezone structure and makes kernel always run at UTC
+time zone.
+Super-user privilege is required for all operations.
+.Sh ENVIRONMENT
+.Bl -tag -width Fl
+.It Ev TZ
+Time zone change rule, see
+.Xr tzset 3 ;
+not needed when
+.Xr zic 8
+is used.
+.Sh FILES
+.Bl -tag -width /etc/wall_cmos_clock -compact
+.It Pa /etc/localtime
+Link to the current zone info file, see
+.Xr zic 8 .
+.It Pa /etc/wall_cmos_clock
+Empty file.
+Presence of it indicates that the machine runs wall CMOS clock,
+absence indicates UTC CMOS clock.
+.It Pa /var/run/.adjkerntz
+Text file with the stored current time zone offset in seconds.
+.Sh SEE ALSO
+.Xr tzset 3 ,
+.Xr zic 8 ,
+.Xr rc 8 ,
+.Xr crontab 5
+.Sh DIAGNOSTICS
+No diagnostics, unless \-v option is specified.
+If any error occurs, an error message printed to stderr and
+.Nm adjkerntz
+exits with return code greater than zero.
+.Sh AUTHOR
+Andrew A. Chernov <ache@astral.msk.su>
+.Sh HISTORY
+The
+.Nm adjkerntz
+command appeared in FreeBSD 1.0.1
+
diff --git a/sbin/adjkerntz/adjkerntz.c b/sbin/adjkerntz/adjkerntz.c
new file mode 100644
index 000000000000..8cb885cc52b6
--- /dev/null
+++ b/sbin/adjkerntz/adjkerntz.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 1993 by Andrew A. Chernov, Moscow, Russia.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#)Copyright (C) 1993 by Andrew A. Chernov, Moscow, Russia.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+/*
+ * Andrew A. Chernov <ache@astral.msk.su> Dec 15 1993
+ *
+ * Fix kernel time value if machine run wall CMOS clock
+ * (and /etc/wall_cmos_clock file present)
+ * using zoneinfo rules or direct TZ environment variable set.
+ * Use Joerg Wunsch idea for seconds accurate offset calculation
+ * with Garrett Wollman and Bruce Evans fixes.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include "pathnames.h"
+
+char storage[] = _PATH_OFFSET;
+
+int main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct tm local, utc;
+ struct timeval tv, *stv;
+ struct timezone tz, *stz;
+ /* Avoid time_t here, can be unsigned long */
+ long offset, oldoffset, utcsec, localsec, diff;
+ int ch, init = -1, verbose = 0;
+ FILE *f;
+
+ while ((ch = getopt(argc, argv, "aiv")) != EOF)
+ switch((char)ch) {
+ case 'i': /* initial call, save offset */
+ if (init != -1)
+ goto usage;
+ init = 1;
+ break;
+ case 'a': /* adjustment call, use saved offset */
+ if (init != -1)
+ goto usage;
+ init = 0;
+ break;
+ case 'v': /* verbose */
+ verbose = 1;
+ break;
+ default:
+ usage:
+ fprintf(stderr, "Usage:\n\
+\tadjkerntz -i [-v]\t(initial call from /etc/rc)\n\
+\tadjkerntz -a [-v]\t(adjustment call from crontab)\n");
+ return 2;
+ }
+ if (init == -1)
+ goto usage;
+
+ if (access(_PATH_CLOCK, F_OK))
+ return 0;
+
+ /* Restore saved offset */
+
+ if (!init) {
+ if ((f = fopen(storage, "r")) == NULL) {
+ perror(storage);
+ return 1;
+ }
+ if (fscanf(f, "%ld", &oldoffset) != 1) {
+ fprintf(stderr, "Incorrect offset in %s\n", storage);
+ return 1;
+ }
+ (void) fclose(f);
+ }
+ else
+ oldoffset = 0;
+
+/****** Critical section, do all things as fast as possible ******/
+
+ /* get local CMOS clock and possible kernel offset */
+ if (gettimeofday(&tv, &tz)) {
+ perror("gettimeofday");
+ return 1;
+ }
+
+ /* get the actual local timezone difference */
+ local = *localtime(&tv.tv_sec);
+ utc = *gmtime(&tv.tv_sec);
+ utc.tm_isdst = local.tm_isdst; /* Use current timezone for mktime(), */
+ /* because it assumed local time */
+
+ /* calculate local CMOS diff from GMT */
+
+ utcsec = mktime(&utc);
+ localsec = mktime(&local);
+ if (utcsec == -1 || localsec == -1) {
+ fprintf(stderr, "Wrong hour to call\n");
+ return 1;
+ }
+ offset = utcsec - localsec;
+
+ /* correct the kerneltime for this diffs */
+ /* subtract kernel offset, if present, old offset too */
+
+ diff = oldoffset + tz.tz_minuteswest * 60 - offset;
+ if (diff != 0) {
+ tv.tv_sec += diff;
+ tv.tv_usec = 0; /* we are restarting here... */
+ stv = &tv;
+ }
+ else
+ stv = NULL;
+
+ if (tz.tz_dsttime != 0 || tz.tz_minuteswest != 0) {
+ tz.tz_dsttime = tz.tz_minuteswest = 0; /* zone info is garbage */
+ stz = &tz;
+ }
+ else
+ stz = NULL;
+
+ if (stz != NULL || stv != NULL) {
+ if (settimeofday(stv, stz)) {
+ perror("settimeofday");
+ return 1;
+ }
+ }
+
+/****** End of critical section ******/
+
+ if (verbose)
+ printf("Calculated zone offset diffs: %ld seconds\n", diff);
+
+ if (offset != oldoffset) {
+ (void) umask(022);
+ /* Save offset for next calls from crontab */
+ if ((f = fopen(storage, "w")) == NULL) {
+ perror(storage);
+ return 1;
+ }
+ fprintf(f, "%ld\n", offset);
+ if (fclose(f)) {
+ perror(storage);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/sbin/adjkerntz/pathnames.h b/sbin/adjkerntz/pathnames.h
new file mode 100644
index 000000000000..a8b751fa5f23
--- /dev/null
+++ b/sbin/adjkerntz/pathnames.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 1993 by Andrew A. Chernov, Moscow, Russia.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <paths.h>
+
+/*
+ * Offset file name started with '.', because "adjkerntz -i"
+ * called in /etc/rc before cleaning '*' in /var/run,
+ * and this file should be keeped after it.
+ */
+#define _PATH_OFFSET "/var/run/.adjkerntz"
+
+#define _PATH_CLOCK "/etc/wall_cmos_clock"