diff options
author | ache <ache@FreeBSD.org> | 1995-03-26 22:51:51 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 1995-03-26 22:51:51 +0000 |
commit | e6a1b97276e57a6fc73770fc7f26fc12b16f20bf (patch) | |
tree | ee526404acadb5bfe5b56536e0085f6c6bb94e9e /sbin | |
parent | 4522c9df34373401f2b1cf77f4e58a961137d2de (diff) | |
download | FreeBSD-src-e6a1b97276e57a6fc73770fc7f26fc12b16f20bf.zip FreeBSD-src-e6a1b97276e57a6fc73770fc7f26fc12b16f20bf.tar.gz |
Use more AI to predict initial/final isdst,
latest isdst preffered.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/adjkerntz/adjkerntz.c | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/sbin/adjkerntz/adjkerntz.c b/sbin/adjkerntz/adjkerntz.c index d2f6739..d5e10f8 100644 --- a/sbin/adjkerntz/adjkerntz.c +++ b/sbin/adjkerntz/adjkerntz.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1993, 1994 by Andrew A. Chernov, Moscow, Russia. + * Copyright (C) 1993, 1994, 1995 by Andrey A. Chernov, Moscow, Russia. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,12 +26,12 @@ #ifndef lint char copyright[] = -"@(#)Copyright (C) 1993 by Andrew A. Chernov, Moscow, Russia.\n\ +"@(#)Copyright (C) 1993, 1994, 1995 by Andrey A. Chernov, Moscow, Russia.\n\ All rights reserved.\n"; #endif /* not lint */ /* - * Andrew A. Chernov <ache@astral.msk.su> Dec 20 1993 + * Andrey A. Chernov <ache@astral.msk.su> Dec 20 1993 * * Fix kernel time value if machine run wall CMOS clock * (and /etc/wall_cmos_clock file present) @@ -72,6 +72,7 @@ int main(argc, argv) long offset, utcsec, localsec, diff; time_t initial_sec, final_sec; int ch, init = -1; + int initial_isdst = -1, final_isdst, looping; int disrtcset, need_restore = 0; sigset_t mask, emask; @@ -118,6 +119,19 @@ again: (void) sigprocmask(SIG_BLOCK, &mask, NULL); (void) signal(SIGTERM, fake); + diff = 0; + stv = NULL; + stz = NULL; + looping = 0; + + mib[0] = CTL_MACHDEP; + mib[1] = CPU_ADJKERNTZ; + len = sizeof(kern_offset); + if (sysctl(mib, 2, &kern_offset, &len, NULL, 0) == -1) { + syslog(LOG_ERR, "sysctl(get_offset): %m"); + return 1; + } + /****** Critical section, do all things as fast as possible ******/ /* get local CMOS clock and possible kernel offset */ @@ -128,13 +142,18 @@ again: /* get the actual local timezone difference */ initial_sec = tv.tv_sec; + +recalculate: local = *localtime(&initial_sec); + if (diff == 0) + initial_isdst = local.tm_isdst; utc = *gmtime(&initial_sec); + local.tm_isdst = utc.tm_isdst = initial_isdst; /* calculate local CMOS diff from GMT */ - utcsec = timelocal(&utc); - localsec = timelocal(&local); + utcsec = mktime(&utc); + localsec = mktime(&local); if (utcsec == -1 || localsec == -1) { /* * XXX user can only control local time, and it is @@ -153,17 +172,6 @@ again: fprintf(stderr, "Initial offset: %ld secs\n", offset); #endif - mib[0] = CTL_MACHDEP; - mib[1] = CPU_ADJKERNTZ; - len = sizeof(kern_offset); - if (sysctl(mib, 2, &kern_offset, &len, NULL, 0) == -1) { - syslog(LOG_ERR, "sysctl(get_offset): %m"); - return 1; - } - - stv = NULL; - stz = NULL; - /* correct the kerneltime for this diffs */ /* subtract kernel offset, if present, old offset too */ @@ -175,15 +183,25 @@ again: #endif /* Yet one step for final time */ - final_sec = tv.tv_sec + diff; + final_sec = initial_sec + diff; /* get the actual local timezone difference */ local = *localtime(&final_sec); + final_isdst = diff < 0 ? initial_isdst : local.tm_isdst; + if (diff > 0 && initial_isdst != final_isdst) { + if (looping) + goto bad_final; + looping++; + initial_isdst = final_isdst; + goto recalculate; + } utc = *gmtime(&final_sec); + local.tm_isdst = utc.tm_isdst = final_isdst; - utcsec = timelocal(&utc); - localsec = timelocal(&local); + utcsec = mktime(&utc); + localsec = mktime(&local); if (utcsec == -1 || localsec == -1) { + bad_final: /* * XXX as above. The user has even less control, * but perhaps we never get here. |