From fdf434f26cb7031423906cfc3da9e20c920ae6d8 Mon Sep 17 00:00:00 2001 From: ache Date: Wed, 2 Nov 1994 09:40:06 +0000 Subject: Restore back -i, -a --- sbin/adjkerntz/adjkerntz.c | 257 +++++++++++++++++++++++---------------------- 1 file changed, 130 insertions(+), 127 deletions(-) (limited to 'sbin/adjkerntz') diff --git a/sbin/adjkerntz/adjkerntz.c b/sbin/adjkerntz/adjkerntz.c index 8c50cce..5e7b0b8 100644 --- a/sbin/adjkerntz/adjkerntz.c +++ b/sbin/adjkerntz/adjkerntz.c @@ -67,176 +67,179 @@ int main(argc, argv) /* Avoid time_t here, can be unsigned long or worse */ long offset, utcsec, localsec, diff; time_t initial_sec, final_sec; - int init = 1, nonex1 = 0, nonex2 = 0; + int ch, init = -1; int disrtcset, need_restore = 0; - if (argc != 1) { - fprintf(stderr, "Usage:\tadjkerntz\n"); - return 2; - } - + while ((ch = getopt(argc, argv, "ai")) != 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; + default: + usage: + fprintf(stderr, "Usage:\n\ +\tadjkerntz -i\t(initial call from /etc/rc)\n\ +\tadjkerntz -a\t(adjustment call from crontab)\n"); + return 2; + } + if (init == -1) + goto usage; + if (access(_PATH_CLOCK, F_OK)) return 0; - if (daemon(0, 0)) { - perror("daemon"); + openlog("adjkerntz", LOG_PID|LOG_PERROR, LOG_DAEMON); + +again: + +/****** Critical section, do all things as fast as possible ******/ + + /* get local CMOS clock and possible kernel offset */ + if (gettimeofday(&tv, &tz)) { + syslog(LOG_ERR, "gettimeofday: %m"); return 1; } - openlog("adjkerntz", LOG_PID, LOG_DAEMON); + /* get the actual local timezone difference */ + initial_sec = tv.tv_sec; + local = *localtime(&initial_sec); + utc = *gmtime(&initial_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) { + /* + * XXX user can only control local time, and it is + * unacceptable to fail here for init. 2:30 am in the + * middle of the nonexistent hour means 3:30 am. + */ + syslog(LOG_WARNING, + "Nonexistent local time -- will retry after %d secs", REPORT_PERIOD); + (void) sleep(REPORT_PERIOD); + goto again; + } + offset = utcsec - localsec; - /* Spy on timezone changes with 1sec accurancy */ - for (;;sleep(1)) { + 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 ******/ + /* correct the kerneltime for this diffs */ + /* subtract kernel offset, if present, old offset too */ - /* get local CMOS clock and possible kernel offset */ - if (gettimeofday(&tv, &tz)) { - syslog(LOG_ERR, "gettimeofday: %m"); - return 1; - } + diff = offset - tz.tz_minuteswest * 60 - kern_offset; + + if (diff != 0) { + + /* Yet one step for final time */ + + final_sec = tv.tv_sec + diff; /* get the actual local timezone difference */ - initial_sec = tv.tv_sec; - local = *localtime(&initial_sec); - utc = *gmtime(&initial_sec); + local = *localtime(&final_sec); + utc = *gmtime(&final_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) { /* - * XXX user can only control local time, and it is - * unacceptable to fail here for init. 2:30 am in the - * middle of the nonexistent hour means 3:30 am. + * XXX as above. The user has even less control, + * but perhaps we never get here. */ - if (!(nonex1++ % REPORT_PERIOD)) { - if (nonex1 > 1) - nonex1 = 0; - syslog(LOG_WARNING, - "Nonexistent local time -- retry each second"); - } - continue; + syslog(LOG_WARNING, + "Nonexistent (final) local time -- will retry after %d secs", REPORT_PERIOD); + (void) sleep(REPORT_PERIOD); + goto again; } offset = utcsec - localsec; - 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; - } - /* correct the kerneltime for this diffs */ /* subtract kernel offset, if present, old offset too */ diff = offset - tz.tz_minuteswest * 60 - kern_offset; if (diff != 0) { - - /* Yet one step for final time */ - - final_sec = tv.tv_sec + diff; - - /* get the actual local timezone difference */ - local = *localtime(&final_sec); - utc = *gmtime(&final_sec); - utc.tm_isdst = local.tm_isdst; /* Use current timezone for mktime(), */ - /* because it assumed local time */ - - utcsec = mktime(&utc); - localsec = mktime(&local); - if (utcsec == -1 || localsec == -1) { - /* - * XXX as above. The user has even less control, - * but perhaps we never get here. - */ - if (!(nonex2++ % REPORT_PERIOD)) { - if (nonex2 > 1) - nonex2 = 0; - syslog(LOG_WARNING, - "Nonexistent (final) local time -- retry each second"); - } - continue; - } - offset = utcsec - localsec; - - /* correct the kerneltime for this diffs */ - /* subtract kernel offset, if present, old offset too */ - - diff = offset - tz.tz_minuteswest * 60 - kern_offset; - - if (diff != 0) { - tv.tv_sec += diff; - tv.tv_usec = 0; /* we are restarting here... */ - stv = &tv; - } - else - stv = NULL; + tv.tv_sec += diff; + tv.tv_usec = 0; /* we are restarting here... */ + stv = &tv; } else stv = NULL; + } + 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 (init && stv != NULL) { - mib[0] = CTL_MACHDEP; - mib[1] = CPU_DISRTCSET; - len = sizeof(disrtcset); - if (sysctl(mib, 2, &disrtcset, &len, NULL, 0) == -1) { - syslog(LOG_ERR, "sysctl(get_disrtcset): %m"); + 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 (init && stv != NULL) { + mib[0] = CTL_MACHDEP; + mib[1] = CPU_DISRTCSET; + len = sizeof(disrtcset); + if (sysctl(mib, 2, &disrtcset, &len, NULL, 0) == -1) { + syslog(LOG_ERR, "sysctl(get_disrtcset): %m"); + return 1; + } + if (disrtcset == 0) { + disrtcset = 1; + need_restore = 1; + if (sysctl(mib, 2, NULL, NULL, &disrtcset, len) == -1) { + syslog(LOG_ERR, "sysctl(set_disrtcset): %m"); return 1; } - if (disrtcset == 0) { - disrtcset = 1; - need_restore = 1; - if (sysctl(mib, 2, NULL, NULL, &disrtcset, len) == -1) { - syslog(LOG_ERR, "sysctl(set_disrtcset): %m"); - return 1; - } - } - } - /* stz means that kernel zone shifted */ - /* clock needs adjustment even if !init */ - if ((init || stz != NULL) && settimeofday(stv, stz)) { - syslog(LOG_ERR, "settimeofday: %m"); - return 1; } } + /* stz means that kernel zone shifted */ + /* clock needs adjustment even if !init */ + if ((init || stz != NULL) && settimeofday(stv, stz)) { + syslog(LOG_ERR, "settimeofday: %m"); + return 1; + } + } - if (kern_offset != offset) { - kern_offset = offset; - mib[0] = CTL_MACHDEP; - mib[1] = CPU_ADJKERNTZ; - len = sizeof(kern_offset); - if (sysctl(mib, 2, NULL, NULL, &kern_offset, len) == -1) { - syslog(LOG_ERR, "sysctl(update_offset): %m"); - return 1; - } + if (kern_offset != offset) { + kern_offset = offset; + mib[0] = CTL_MACHDEP; + mib[1] = CPU_ADJKERNTZ; + len = sizeof(kern_offset); + if (sysctl(mib, 2, NULL, NULL, &kern_offset, len) == -1) { + syslog(LOG_ERR, "sysctl(update_offset): %m"); + return 1; } + } - if (need_restore) { - need_restore = 0; - disrtcset = 0; - if (sysctl(mib, 2, NULL, NULL, &disrtcset, len) == -1) { - syslog(LOG_ERR, "sysctl(restore_disrtcset): %m"); - return 1; - } + if (need_restore) { + need_restore = 0; + disrtcset = 0; + if (sysctl(mib, 2, NULL, NULL, &disrtcset, len) == -1) { + syslog(LOG_ERR, "sysctl(restore_disrtcset): %m"); + return 1; } + } /****** End of critical section ******/ - init = 0; - } - return 1; + return 0; } -- cgit v1.1