diff options
author | Andrey A. Chernov <ache@FreeBSD.org> | 1993-12-16 18:44:40 +0000 |
---|---|---|
committer | Andrey A. Chernov <ache@FreeBSD.org> | 1993-12-16 18:44:40 +0000 |
commit | 3e714780bebb0be734a0538b7fe4bb2e6951feaf (patch) | |
tree | 5f9451ac2f05728daf1698b2b7488075ae4560ef /sbin/adjkerntz | |
parent | 68a21a4b381bc6db335d35f0d91681f61a60212a (diff) | |
download | src-3e714780bebb0be734a0538b7fe4bb2e6951feaf.tar.gz src-3e714780bebb0be734a0538b7fe4bb2e6951feaf.zip |
Notes
Diffstat (limited to 'sbin/adjkerntz')
-rw-r--r-- | sbin/adjkerntz/Makefile | 4 | ||||
-rw-r--r-- | sbin/adjkerntz/adjkerntz.8 | 122 | ||||
-rw-r--r-- | sbin/adjkerntz/adjkerntz.c | 180 | ||||
-rw-r--r-- | sbin/adjkerntz/pathnames.h | 36 |
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" |