]> git.ipfire.org Git - thirdparty/util-linux.git/blame - sys-utils/hwclock.c
build-sys: move hwclock to sys-utils/
[thirdparty/util-linux.git] / sys-utils / hwclock.c
CommitLineData
7eda085c
KZ
1/*
2 * hwclock.c
3 *
4 * clock.c was written by Charles Hedrick, hedrick@cs.rutgers.edu, Apr 1992
5 * Modified for clock adjustments - Rob Hooft <hooft@chem.ruu.nl>, Nov 1992
6 * Improvements by Harald Koenig <koenig@nova.tat.physik.uni-tuebingen.de>
7 * and Alan Modra <alan@spri.levels.unisa.edu.au>.
8 *
9 * Major rewrite by Bryan Henderson <bryanh@giraffe-data.com>, 96.09.19.
10 * The new program is called hwclock. New features:
ef71b8f1
SK
11 *
12 * - You can set the hardware clock without also modifying the system
13 * clock.
14 * - You can read and set the clock with finer than 1 second precision.
15 * - When you set the clock, hwclock automatically refigures the drift
16 * rate, based on how far off the clock was before you set it.
7eda085c
KZ
17 *
18 * Reshuffled things, added sparc code, and re-added alpha stuff
19 * by David Mosberger <davidm@azstarnet.com>
9abb2685 20 * and Jay Estabrook <jestabro@amt.tay1.dec.com>
7eda085c
KZ
21 * and Martin Ostermann <ost@coments.rwth-aachen.de>, aeb@cwi.nl, 990212.
22 *
ef71b8f1 23 * Fix for Award 2094 bug, Dave Coffin (dcoffin@shore.net) 11/12/98
22853e4a 24 * Change of local time handling, Stefan Ring <e9725446@stud3.tuwien.ac.at>
63cccae4 25 * Change of adjtime handling, James P. Rutledge <ao112@rgfn.epcc.edu>.
66ee8158
KZ
26 *
27 * Distributed under GPL
7eda085c 28 */
7eda085c
KZ
29/*
30 * Explanation of `adjusting' (Rob Hooft):
31 *
32 * The problem with my machine is that its CMOS clock is 10 seconds
33 * per day slow. With this version of clock.c, and my '/etc/rc.local'
34 * reading '/etc/clock -au' instead of '/etc/clock -u -s', this error
35 * is automatically corrected at every boot.
36 *
37 * To do this job, the program reads and writes the file '/etc/adjtime'
38 * to determine the correction, and to save its data. In this file are
39 * three numbers:
40 *
ef71b8f1
SK
41 * 1) the correction in seconds per day. (So if your clock runs 5
42 * seconds per day fast, the first number should read -5.0)
43 * 2) the number of seconds since 1/1/1970 the last time the program
44 * was used
45 * 3) the remaining part of a second which was leftover after the last
46 * adjustment
7eda085c
KZ
47 *
48 * Installation and use of this program:
49 *
ef71b8f1
SK
50 * a) create a file '/etc/adjtime' containing as the first and only
51 * line: '0.0 0 0.0'
52 * b) run 'clock -au' or 'clock -a', depending on whether your cmos is
53 * in universal or local time. This updates the second number.
54 * c) set your system time using the 'date' command.
55 * d) update your cmos time using 'clock -wu' or 'clock -w'
56 * e) replace the first number in /etc/adjtime by your correction.
57 * f) put the command 'clock -au' or 'clock -a' in your '/etc/rc.local'
7eda085c
KZ
58 */
59
7eda085c 60#include <errno.h>
63cccae4 61#include <getopt.h>
33ed2d02 62#include <limits.h>
998f392a
SK
63#include <stdarg.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
63cccae4 67#include <sysexits.h>
998f392a
SK
68#include <sys/stat.h>
69#include <sys/time.h>
70#include <time.h>
71#include <unistd.h>
7eda085c 72
e1f4706d
SK
73#define OPTUTILS_EXIT_CODE EX_USAGE
74
998f392a 75#include "c.h"
db116df7 76#include "closestream.h"
7eda085c 77#include "nls.h"
e1f4706d 78#include "optutils.h"
9d413ecb 79#include "pathnames.h"
4ac41d61 80#include "strutils.h"
c7f75390 81#include "hwclock.h"
7eda085c 82
88058a71
KZ
83#ifdef HAVE_LIBAUDIT
84#include <libaudit.h>
85static int hwaudit_fd = -1;
86static int hwaudit_on;
87#endif
88
c7f75390
KZ
89#define EXCL_ERROR "--{adjust,getepoch,hctosys,predict,set,setepoch,show,systohc,systz}"
90
7eda085c
KZ
91/* The struct that holds our hardware access routines */
92struct clock_ops *ur;
93
94#define FLOOR(arg) ((arg >= 0 ? (int) arg : ((int) arg) - 1));
95
da82f6fe
KZ
96const char *adj_file_name = NULL;
97
7eda085c 98struct adjtime {
ef71b8f1
SK
99 /*
100 * This is information we keep in the adjtime file that tells us how
101 * to do drift corrections. Elements are all straight from the
102 * adjtime file, so see documentation of that file for details.
103 * Exception is <dirty>, which is an indication that what's in this
104 * structure is not what's in the disk file (because it has been
105 * updated since read from the disk file).
106 */
107 bool dirty;
108 /* line 1 */
109 double drift_factor;
110 time_t last_adj_time;
111 double not_adjusted;
112 /* line 2 */
113 time_t last_calib_time;
114 /*
115 * The most recent time that we set the clock from an external
116 * authority (as opposed to just doing a drift adjustment)
117 */
118 /* line 3 */
119 enum a_local_utc { LOCAL, UTC, UNKNOWN } local_utc;
120 /*
121 * To which time zone, local or UTC, we most recently set the
122 * hardware clock.
123 */
7eda085c
KZ
124};
125
33ed2d02
SK
126/* Long only options. */
127enum {
128 OPT_SET = CHAR_MAX + 1,
129 OPT_GETEPOCH,
130 OPT_SETEPOCH,
131 OPT_NOADJFILE,
132 OPT_LOCALTIME,
133 OPT_BADYEAR,
134 OPT_DIRECTISA,
135 OPT_TEST,
136 OPT_DATE,
137 OPT_EPOCH,
138 OPT_ADJFILE,
139 OPT_SYSTZ,
140 OPT_PREDICT_HC
141};
ef71b8f1
SK
142
143/*
144 * We are running in debug mode, wherein we put a lot of information about
145 * what we're doing to standard output.
146 */
7eda085c 147bool debug;
7eda085c 148
ef71b8f1 149/* Workaround for Award 4.50g BIOS bug: keep the year in a file. */
7eda085c 150bool badyear;
7eda085c 151
ef71b8f1 152/* User-specified epoch, used when rtc fails to return epoch. */
4ac41d61 153unsigned long epoch_option = -1;
22853e4a 154
7eda085c 155/*
ef71b8f1
SK
156 * Almost all Award BIOS's made between 04/26/94 and 05/31/95 have a nasty
157 * bug limiting the RTC year byte to the range 94-99. Any year between 2000
158 * and 2093 gets changed to 2094, every time you start the system.
159 *
160 * With the --badyear option, we write the date to file and hope that the
161 * file is updated at least once a year. I recommend putting this command
162 * "hwclock --badyear" in the monthly crontab, just to be safe.
163 *
164 * -- Dave Coffin 11/12/98
7eda085c 165 */
ef71b8f1
SK
166static void write_date_to_file(struct tm *tm)
167{
168 FILE *fp;
169
9d413ecb 170 if ((fp = fopen(_PATH_LASTDATE, "w"))) {
ef71b8f1
SK
171 fprintf(fp, "%02d.%02d.%04d\n", tm->tm_mday, tm->tm_mon + 1,
172 tm->tm_year + 1900);
db116df7
SK
173 if (close_stream(fp) != 0)
174 warn(_("cannot write %s"), _PATH_LASTDATE);
ef71b8f1 175 } else
9d413ecb 176 warn(_("cannot write %s"), _PATH_LASTDATE);
7eda085c
KZ
177}
178
ef71b8f1
SK
179static void read_date_from_file(struct tm *tm)
180{
181 int last_mday, last_mon, last_year;
182 FILE *fp;
183
9d413ecb 184 if ((fp = fopen(_PATH_LASTDATE, "r"))) {
ef71b8f1
SK
185 if (fscanf(fp, "%d.%d.%d\n", &last_mday, &last_mon, &last_year)
186 == 3) {
187 tm->tm_year = last_year - 1900;
188 if ((tm->tm_mon << 5) + tm->tm_mday <
189 ((last_mon - 1) << 5) + last_mday)
190 tm->tm_year++;
191 }
192 fclose(fp);
193 }
194 write_date_to_file(tm);
7eda085c
KZ
195}
196
ef71b8f1
SK
197/*
198 * The difference in seconds between two times in "timeval" format.
199 */
200double time_diff(struct timeval subtrahend, struct timeval subtractor)
201{
202 return (subtrahend.tv_sec - subtractor.tv_sec)
203 + (subtrahend.tv_usec - subtractor.tv_usec) / 1E6;
7eda085c
KZ
204}
205
ef71b8f1
SK
206/*
207 * The time, in "timeval" format, which is <increment> seconds after the
208 * time <addend>. Of course, <increment> may be negative.
209 */
210static struct timeval time_inc(struct timeval addend, double increment)
211{
212 struct timeval newtime;
213
214 newtime.tv_sec = addend.tv_sec + (int)increment;
215 newtime.tv_usec = addend.tv_usec + (increment - (int)increment) * 1E6;
216
217 /*
218 * Now adjust it so that the microsecond value is between 0 and 1
219 * million.
220 */
221 if (newtime.tv_usec < 0) {
222 newtime.tv_usec += 1E6;
223 newtime.tv_sec -= 1;
224 } else if (newtime.tv_usec >= 1E6) {
225 newtime.tv_usec -= 1E6;
226 newtime.tv_sec += 1;
227 }
228 return newtime;
7eda085c
KZ
229}
230
eb63b9b8
KZ
231static bool
232hw_clock_is_utc(const bool utc, const bool local_opt,
ef71b8f1
SK
233 const struct adjtime adjtime)
234{
eb63b9b8
KZ
235 bool ret;
236
237 if (utc)
238 ret = TRUE; /* --utc explicitly given on command line */
239 else if (local_opt)
240 ret = FALSE; /* --localtime explicitly given */
241 else
ef71b8f1 242 /* get info from adjtime file - default is UTC */
7894bf0f 243 ret = (adjtime.local_utc != LOCAL);
eb63b9b8
KZ
244 if (debug)
245 printf(_("Assuming hardware clock is kept in %s time.\n"),
246 ret ? _("UTC") : _("local"));
247 return ret;
248}
249
ef71b8f1
SK
250/*
251 * Read the adjustment parameters out of the /etc/adjtime file.
252 *
253 * Return them as the adjtime structure <*adjtime_p>. If there is no
254 * /etc/adjtime file, return defaults. If values are missing from the file,
255 * return defaults for them.
256 *
257 * return value 0 if all OK, !=0 otherwise.
258 */
259static int read_adjtime(struct adjtime *adjtime_p)
260{
261 FILE *adjfile;
262 int rc; /* local return code */
263 struct stat statbuf; /* We don't even use the contents of this. */
264 char line1[81]; /* String: first line of adjtime file */
265 char line2[81]; /* String: second line of adjtime file */
266 char line3[81]; /* String: third line of adjtime file */
267 long timeval;
268
269 rc = stat(adj_file_name, &statbuf);
270 if (rc < 0 && errno == ENOENT) {
271 /* He doesn't have a adjtime file, so we'll use defaults. */
272 adjtime_p->drift_factor = 0;
273 adjtime_p->last_adj_time = 0;
274 adjtime_p->not_adjusted = 0;
275 adjtime_p->last_calib_time = 0;
276 adjtime_p->local_utc = UNKNOWN;
277 adjtime_p->dirty = FALSE; /* don't create a zero adjfile */
278
279 return 0;
280 }
eb63b9b8 281
ef71b8f1
SK
282 adjfile = fopen(adj_file_name, "r"); /* open file for reading */
283 if (adjfile == NULL) {
111c05d3 284 warn("cannot open file %s", adj_file_name);
ef71b8f1 285 return EX_OSFILE;
eb63b9b8 286 }
7eda085c
KZ
287
288
ef71b8f1
SK
289 if (!fgets(line1, sizeof(line1), adjfile))
290 line1[0] = '\0'; /* In case fgets fails */
291 if (!fgets(line2, sizeof(line2), adjfile))
292 line2[0] = '\0'; /* In case fgets fails */
293 if (!fgets(line3, sizeof(line3), adjfile))
294 line3[0] = '\0'; /* In case fgets fails */
295
296 fclose(adjfile);
297
298 /* Set defaults in case values are missing from file */
299 adjtime_p->drift_factor = 0;
300 adjtime_p->last_adj_time = 0;
301 adjtime_p->not_adjusted = 0;
302 adjtime_p->last_calib_time = 0;
303 timeval = 0;
304
305 sscanf(line1, "%lf %ld %lf",
306 &adjtime_p->drift_factor,
307 &timeval, &adjtime_p->not_adjusted);
308 adjtime_p->last_adj_time = timeval;
309
310 sscanf(line2, "%ld", &timeval);
311 adjtime_p->last_calib_time = timeval;
312
313 if (!strcmp(line3, "UTC\n")) {
314 adjtime_p->local_utc = UTC;
315 } else if (!strcmp(line3, "LOCAL\n")) {
316 adjtime_p->local_utc = LOCAL;
317 } else {
318 adjtime_p->local_utc = UNKNOWN;
319 if (line3[0]) {
111c05d3
SK
320 warnx(_("Warning: unrecognized third line in adjtime file\n"
321 "(Expected: `UTC' or `LOCAL' or nothing.)"));
ef71b8f1
SK
322 }
323 }
7eda085c 324
ef71b8f1 325 adjtime_p->dirty = FALSE;
7eda085c 326
ef71b8f1
SK
327 if (debug) {
328 printf(_
329 ("Last drift adjustment done at %ld seconds after 1969\n"),
330 (long)adjtime_p->last_adj_time);
331 printf(_("Last calibration done at %ld seconds after 1969\n"),
332 (long)adjtime_p->last_calib_time);
333 printf(_("Hardware clock is on %s time\n"),
334 (adjtime_p->local_utc ==
335 LOCAL) ? _("local") : (adjtime_p->local_utc ==
336 UTC) ? _("UTC") : _("unknown"));
337 }
338
339 return 0;
340}
7eda085c 341
ef71b8f1
SK
342/*
343 * Wait until the falling edge of the Hardware Clock's update flag so that
344 * any time that is read from the clock immediately after we return will be
345 * exact.
346 *
347 * The clock only has 1 second precision, so it gives the exact time only
348 * once per second, right on the falling edge of the update flag.
349 *
350 * We wait (up to one second) either blocked waiting for an rtc device or in
351 * a CPU spin loop. The former is probably not very accurate.
352 *
353 * Return 0 if it worked, nonzero if it didn't.
354 */
355static int synchronize_to_clock_tick(void)
356{
63cccae4 357 int rc;
7eda085c 358
ef71b8f1
SK
359 if (debug)
360 printf(_("Waiting for clock tick...\n"));
7eda085c 361
63cccae4
KZ
362 rc = ur->synchronize_to_clock_tick();
363
3b96a7ac
KZ
364 if (debug) {
365 if (rc)
366 printf(_("...synchronization failed\n"));
367 else
368 printf(_("...got clock tick\n"));
369 }
63cccae4
KZ
370
371 return rc;
7eda085c
KZ
372}
373
ef71b8f1
SK
374/*
375 * Convert a time in broken down format (hours, minutes, etc.) into standard
376 * unix time (seconds into epoch). Return it as *systime_p.
377 *
378 * The broken down time is argument <tm>. This broken down time is either
379 * in local time zone or UTC, depending on value of logical argument
380 * "universal". True means it is in UTC.
381 *
382 * If the argument contains values that do not constitute a valid time, and
383 * mktime() recognizes this, return *valid_p == false and *systime_p
384 * undefined. However, mktime() sometimes goes ahead and computes a
385 * fictional time "as if" the input values were valid, e.g. if they indicate
386 * the 31st day of April, mktime() may compute the time of May 1. In such a
387 * case, we return the same fictional value mktime() does as *systime_p and
388 * return *valid_p == true.
389 */
7eda085c 390static void
9abb2685 391mktime_tz(struct tm tm, const bool universal,
ef71b8f1
SK
392 bool * valid_p, time_t * systime_p)
393{
394 time_t mktime_result; /* The value returned by our mktime() call */
395 char *zone; /* Local time zone name */
396
397 /*
398 * We use the C library function mktime(), but since it only works
399 * on local time zone input, we may have to fake it out by
400 * temporarily changing the local time zone to UTC.
401 */
402 zone = getenv("TZ"); /* remember original time zone */
403 if (universal) {
404 /* Set timezone to UTC */
405 setenv("TZ", "", TRUE);
406 /*
407 * Note: tzset() gets called implicitly by the time code,
408 * but only the first time. When changing the environment
409 * variable, better call tzset() explicitly.
410 */
411 tzset();
412 }
413 mktime_result = mktime(&tm);
414 if (mktime_result == -1) {
415 /*
416 * This apparently (not specified in mktime() documentation)
417 * means the 'tm' structure does not contain valid values
418 * (however, not containing valid values does _not_ imply
419 * mktime() returns -1).
420 */
421 *valid_p = FALSE;
422 *systime_p = 0;
423 if (debug)
424 printf(_("Invalid values in hardware clock: "
425 "%4d/%.2d/%.2d %.2d:%.2d:%.2d\n"),
426 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
427 tm.tm_hour, tm.tm_min, tm.tm_sec);
428 } else {
429 *valid_p = TRUE;
430 *systime_p = mktime_result;
431 if (debug)
432 printf(_
433 ("Hw clock time : %4d/%.2d/%.2d %.2d:%.2d:%.2d = "
434 "%ld seconds since 1969\n"), tm.tm_year + 1900,
435 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
436 tm.tm_sec, (long)*systime_p);
437 }
438 /* now put back the original zone. */
439 if (zone)
440 setenv("TZ", zone, TRUE);
441 else
442 unsetenv("TZ");
443 tzset();
7eda085c
KZ
444}
445
ef71b8f1
SK
446/*
447 * Read the hardware clock and return the current time via <tm> argument.
448 *
449 * Use the method indicated by <method> argument to access the hardware
450 * clock.
451 */
cdedde03 452static int
ef71b8f1
SK
453read_hardware_clock(const bool universal, bool * valid_p, time_t * systime_p)
454{
455 struct tm tm;
456 int err;
7eda085c 457
ef71b8f1
SK
458 err = ur->read_hardware_clock(&tm);
459 if (err)
460 return err;
7eda085c 461
ef71b8f1
SK
462 if (badyear)
463 read_date_from_file(&tm);
7eda085c 464
ef71b8f1
SK
465 if (debug)
466 printf(_
467 ("Time read from Hardware Clock: %4d/%.2d/%.2d %02d:%02d:%02d\n"),
468 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
469 tm.tm_min, tm.tm_sec);
470 mktime_tz(tm, universal, valid_p, systime_p);
cdedde03 471
ef71b8f1 472 return 0;
7eda085c
KZ
473}
474
ef71b8f1
SK
475/*
476 * Set the Hardware Clock to the time <newtime>, in local time zone or UTC,
477 * according to <universal>.
478 */
7eda085c 479static void
9abb2685 480set_hardware_clock(const time_t newtime,
ef71b8f1
SK
481 const bool universal, const bool testing)
482{
483 struct tm new_broken_time;
484 /*
485 * Time to which we will set Hardware Clock, in broken down format,
486 * in the time zone of caller's choice
487 */
488
489 if (universal)
490 new_broken_time = *gmtime(&newtime);
491 else
492 new_broken_time = *localtime(&newtime);
7eda085c 493
ef71b8f1
SK
494 if (debug)
495 printf(_("Setting Hardware Clock to %.2d:%.2d:%.2d "
496 "= %ld seconds since 1969\n"),
497 new_broken_time.tm_hour, new_broken_time.tm_min,
498 new_broken_time.tm_sec, (long)newtime);
7eda085c 499
ef71b8f1
SK
500 if (testing)
501 printf(_("Clock not changed - testing only.\n"));
502 else {
503 if (badyear) {
504 /*
505 * Write the real year to a file, then write a fake
506 * year between 1995 and 1998 to the RTC. This way,
507 * Award BIOS boots on 29 Feb 2000 thinking that
508 * it's 29 Feb 1996.
509 */
510 write_date_to_file(&new_broken_time);
511 new_broken_time.tm_year =
512 95 + ((new_broken_time.tm_year + 1) & 3);
513 }
514 ur->set_hardware_clock(&new_broken_time);
515 }
516}
7eda085c 517
ef71b8f1
SK
518/*
519 * Set the Hardware Clock to the time "sethwtime", in local time zone or
520 * UTC, according to "universal".
521 *
522 * Wait for a fraction of a second so that "sethwtime" is the value of the
523 * Hardware Clock as of system time "refsystime", which is in the past. For
524 * example, if "sethwtime" is 14:03:05 and "refsystime" is 12:10:04.5 and
525 * the current system time is 12:10:06.0: Wait .5 seconds (to make exactly 2
526 * seconds since "refsystime") and then set the Hardware Clock to 14:03:07,
527 * thus getting a precise and retroactive setting of the clock.
528 *
529 * (Don't be confused by the fact that the system clock and the Hardware
530 * Clock differ by two hours in the above example. That's just to remind you
531 * that there are two independent time scales here).
532 *
533 * This function ought to be able to accept set times as fractional times.
534 * Idea for future enhancement.
535 */
7eda085c 536static void
9abb2685 537set_hardware_clock_exact(const time_t sethwtime,
ef71b8f1
SK
538 const struct timeval refsystime,
539 const bool universal, const bool testing)
540{
36acca1e 541 time_t newhwtime = sethwtime;
ef71b8f1
SK
542 struct timeval beginsystime, nowsystime;
543 double tdiff;
ea0804b0 544 int time_resync = 1;
ef71b8f1
SK
545
546 /*
547 * Now delay some more until Hardware Clock time newhwtime arrives.
548 * The 0.5 s is because the Hardware Clock always sets to your set
549 * time plus 500 ms (because it is designed to update to the next
550 * second precisely 500 ms after you finish the setting).
551 */
552 do {
ea0804b0
SK
553 if (time_resync) {
554 gettimeofday(&beginsystime, NULL);
555 tdiff = time_diff(beginsystime, refsystime);
556 newhwtime = sethwtime + (int)(tdiff + 0.5);
557 if (debug)
558 printf(_
559 ("Time elapsed since reference time has been %.6f seconds.\n"
560 "Delaying further to reach the new time.\n"),
561 tdiff);
562 time_resync = 0;
563 }
564
ef71b8f1
SK
565 gettimeofday(&nowsystime, NULL);
566 tdiff = time_diff(nowsystime, beginsystime);
ea0804b0
SK
567 if (tdiff < 0) {
568 time_resync = 1; /* probably backward time reset */
569 continue;
570 }
571 if (tdiff > 0.1) {
572 time_resync = 1; /* probably forward time reset */
573 continue;
574 }
ef71b8f1
SK
575 beginsystime = nowsystime;
576 tdiff = time_diff(nowsystime, refsystime);
577 } while (newhwtime == sethwtime + (int)(tdiff + 0.5));
578
579 set_hardware_clock(newhwtime, universal, testing);
7eda085c
KZ
580}
581
ef71b8f1
SK
582/*
583 * Put the time "systime" on standard output in display format. Except if
584 * hclock_valid == false, just tell standard output that we don't know what
585 * time it is.
586 *
587 * Include in the output the adjustment "sync_duration".
588 */
7eda085c 589static void
9abb2685 590display_time(const bool hclock_valid, const time_t systime,
ef71b8f1
SK
591 const double sync_duration)
592{
593 if (!hclock_valid)
111c05d3
SK
594 warnx(_
595 ("The Hardware Clock registers contain values that are "
596 "either invalid (e.g. 50th day of month) or beyond the range "
597 "we can handle (e.g. Year 2095)."));
ef71b8f1
SK
598 else {
599 struct tm *lt;
600 char *format = "%c";
601 char ctime_now[200];
7eda085c 602
ef71b8f1
SK
603 lt = localtime(&systime);
604 strftime(ctime_now, sizeof(ctime_now), format, lt);
605 printf(_("%s %.6f seconds\n"), ctime_now, -(sync_duration));
606 }
607}
7eda085c 608
ef71b8f1
SK
609/*
610 * Interpret the value of the --date option, which is something like
611 * "13:05:01". In fact, it can be any of the myriad ASCII strings that
612 * specify a time which the "date" program can understand. The date option
613 * value in question is our "dateopt" argument.
614 *
615 * The specified time is in the local time zone.
616 *
617 * Our output, "*time_p", is a seconds-into-epoch time.
618 *
619 * We use the "date" program to interpret the date string. "date" must be
620 * runnable by issuing the command "date" to the /bin/sh shell. That means
621 * in must be in the current PATH.
622 *
623 * If anything goes wrong (and many things can), we return return code 10
624 * and arbitrary *time_p. Otherwise, return code is 0 and *time_p is valid.
625 */
626static int interpret_date_string(const char *date_opt, time_t * const time_p)
627{
e8f26419
KZ
628 FILE *date_child_fp;
629 char date_resp[100];
ef71b8f1 630 const char magic[] = "seconds-into-epoch=";
9abb2685 631 char date_command[100];
ef71b8f1
SK
632 int retcode; /* our eventual return code */
633 int rc; /* local return code */
e8f26419
KZ
634
635 if (date_opt == NULL) {
111c05d3 636 warnx(_("No --date option specified."));
e8f26419
KZ
637 return 14;
638 }
7eda085c 639
e8f26419
KZ
640 /* prevent overflow - a security risk */
641 if (strlen(date_opt) > sizeof(date_command) - 50) {
111c05d3 642 warnx(_("--date argument too long"));
e8f26419
KZ
643 return 13;
644 }
645
646 /* Quotes in date_opt would ruin the date command we construct. */
647 if (strchr(date_opt, '"') != NULL) {
111c05d3
SK
648 warnx(_
649 ("The value of the --date option is not a valid date.\n"
650 "In particular, it contains quotation marks."));
e8f26419
KZ
651 return 12;
652 }
653
9abb2685 654 sprintf(date_command, "date --date=\"%s\" +seconds-into-epoch=%%s",
e8f26419
KZ
655 date_opt);
656 if (debug)
657 printf(_("Issuing date command: %s\n"), date_command);
658
659 date_child_fp = popen(date_command, "r");
660 if (date_child_fp == NULL) {
111c05d3 661 warn(_("Unable to run 'date' program in /bin/sh shell. "
e8f26419
KZ
662 "popen() failed"));
663 return 10;
664 }
665
72bcf189 666 if (!fgets(date_resp, sizeof(date_resp), date_child_fp))
ef71b8f1 667 date_resp[0] = '\0'; /* in case fgets fails */
e8f26419
KZ
668 if (debug)
669 printf(_("response from date command = %s\n"), date_resp);
ef71b8f1 670 if (strncmp(date_resp, magic, sizeof(magic) - 1) != 0) {
111c05d3 671 warnx(_("The date command issued by %s returned "
e8f26419
KZ
672 "unexpected results.\n"
673 "The command was:\n %s\n"
111c05d3
SK
674 "The response was:\n %s"),
675 program_invocation_short_name, date_command, date_resp);
e8f26419
KZ
676 retcode = 8;
677 } else {
678 long seconds_since_epoch;
ef71b8f1 679 rc = sscanf(date_resp + sizeof(magic) - 1, "%ld",
e8f26419
KZ
680 &seconds_since_epoch);
681 if (rc < 1) {
111c05d3
SK
682 warnx(_("The date command issued by %s returned "
683 "something other than an integer where the "
684 "converted time value was expected.\n"
685 "The command was:\n %s\n"
686 "The response was:\n %s\n"),
687 program_invocation_short_name, date_command,
688 date_resp);
e8f26419
KZ
689 retcode = 6;
690 } else {
691 retcode = 0;
692 *time_p = seconds_since_epoch;
9abb2685 693 if (debug)
e8f26419
KZ
694 printf(_("date string %s equates to "
695 "%ld seconds since 1969.\n"),
ef71b8f1 696 date_opt, (long)*time_p);
e8f26419
KZ
697 }
698 }
49c0c23d 699 pclose(date_child_fp);
e8f26419 700
63cccae4 701 return retcode;
7eda085c
KZ
702}
703
ef71b8f1
SK
704/*
705 * Set the System Clock to time 'newtime'.
706 *
707 * Also set the kernel time zone value to the value indicated by the TZ
708 * environment variable and/or /usr/lib/zoneinfo/, interpreted as tzset()
709 * would interpret them.
710 *
711 * EXCEPT: if hclock_valid is false, just issue an error message saying
712 * there is no valid time in the Hardware Clock to which to set the system
713 * time.
714 *
715 * If 'testing' is true, don't actually update anything -- just say we would
716 * have.
717 */
9abb2685
KZ
718static int
719set_system_clock(const bool hclock_valid, const time_t newtime,
ef71b8f1
SK
720 const bool testing)
721{
722 int retcode;
723
724 if (!hclock_valid) {
111c05d3
SK
725 warnx(_
726 ("The Hardware Clock does not contain a valid time, so "
727 "we cannot set the System Time from it."));
ef71b8f1
SK
728 retcode = 1;
729 } else {
730 struct timeval tv;
731 struct tm *broken;
732 int minuteswest;
733 int rc;
734
735 tv.tv_sec = newtime;
736 tv.tv_usec = 0;
737
738 broken = localtime(&newtime);
48d7b13a 739#ifdef HAVE_TM_GMTOFF
ef71b8f1 740 minuteswest = -broken->tm_gmtoff / 60; /* GNU extension */
22853e4a 741#else
ef71b8f1
SK
742 minuteswest = timezone / 60;
743 if (broken->tm_isdst)
744 minuteswest -= 60;
22853e4a 745#endif
9abb2685 746
ef71b8f1
SK
747 if (debug) {
748 printf(_("Calling settimeofday:\n"));
749 printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
750 (long)tv.tv_sec, (long)tv.tv_usec);
751 printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
752 }
753 if (testing) {
754 printf(_
755 ("Not setting system clock because running in test mode.\n"));
756 retcode = 0;
757 } else {
758 const struct timezone tz = { minuteswest, 0 };
759
760 rc = settimeofday(&tv, &tz);
761 if (rc) {
762 if (errno == EPERM) {
111c05d3
SK
763 warnx(_
764 ("Must be superuser to set system clock."));
ef71b8f1
SK
765 retcode = EX_NOPERM;
766 } else {
111c05d3 767 warn(_("settimeofday() failed"));
ef71b8f1
SK
768 retcode = 1;
769 }
770 } else
771 retcode = 0;
772 }
773 }
774 return retcode;
7eda085c
KZ
775}
776
ef71b8f1
SK
777/*
778 * Reset the System Clock from local time to UTC, based on its current value
779 * and the timezone unless universal is TRUE.
780 *
781 * Also set the kernel time zone value to the value indicated by the TZ
782 * environment variable and/or /usr/lib/zoneinfo/, interpreted as tzset()
783 * would interpret them.
784 *
785 * If 'testing' is true, don't actually update anything -- just say we would
786 * have.
787 */
788static int set_system_clock_timezone(const bool universal, const bool testing)
789{
790 int retcode;
791 struct timeval tv;
792 struct tm *broken;
793 int minuteswest;
794 int rc;
795
796 gettimeofday(&tv, NULL);
797 if (debug) {
798 struct tm broken_time;
799 char ctime_now[200];
800
801 broken_time = *gmtime(&tv.tv_sec);
802 strftime(ctime_now, sizeof(ctime_now), "%Y/%m/%d %H:%M:%S",
803 &broken_time);
804 printf(_("Current system time: %ld = %s\n"), (long)tv.tv_sec,
805 ctime_now);
806 }
7eda085c 807
ef71b8f1 808 broken = localtime(&tv.tv_sec);
88a3372e 809#ifdef HAVE_TM_GMTOFF
ef71b8f1 810 minuteswest = -broken->tm_gmtoff / 60; /* GNU extension */
88a3372e 811#else
ef71b8f1
SK
812 minuteswest = timezone / 60;
813 if (broken->tm_isdst)
814 minuteswest -= 60;
88a3372e
SJR
815#endif
816
ef71b8f1
SK
817 gettimeofday(&tv, NULL);
818 if (!universal)
819 tv.tv_sec += minuteswest * 60;
88a3372e 820
ef71b8f1
SK
821 if (debug) {
822 struct tm broken_time;
823 char ctime_now[200];
824
825 broken_time = *gmtime(&tv.tv_sec);
826 strftime(ctime_now, sizeof(ctime_now), "%Y/%m/%d %H:%M:%S",
827 &broken_time);
828
829 printf(_("Calling settimeofday:\n"));
830 printf(_("\tUTC: %s\n"), ctime_now);
831 printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
832 (long)tv.tv_sec, (long)tv.tv_usec);
833 printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
834 }
835 if (testing) {
836 printf(_
837 ("Not setting system clock because running in test mode.\n"));
838 retcode = 0;
839 } else {
840 const struct timezone tz = { minuteswest, 0 };
88a3372e 841
ef71b8f1
SK
842 rc = settimeofday(&tv, &tz);
843 if (rc) {
844 if (errno == EPERM) {
111c05d3
SK
845 warnx(_
846 ("Must be superuser to set system clock."));
ef71b8f1
SK
847 retcode = EX_NOPERM;
848 } else {
111c05d3 849 warn(_("settimeofday() failed"));
ef71b8f1
SK
850 retcode = 1;
851 }
852 } else
853 retcode = 0;
854 }
855 return retcode;
856}
857
858/*
859 * Update the drift factor in <*adjtime_p> to reflect the fact that the
860 * Hardware Clock was calibrated to <nowtime> and before that was set to
861 * <hclocktime>.
862 *
863 * We record in the adjtime file the time at which we last calibrated the
864 * clock so we can compute the drift rate each time we calibrate.
865 *
866 * EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set
867 * before to anything meaningful and regular adjustments have not been done,
868 * so don't adjust the drift factor.
869 */
7eda085c
KZ
870static void
871adjust_drift_factor(struct adjtime *adjtime_p,
ef71b8f1
SK
872 const time_t nowtime,
873 const bool hclock_valid,
874 const time_t hclocktime, const double sync_delay)
875{
63cccae4
KZ
876 if (!hclock_valid) {
877 if (debug)
878 printf(_("Not adjusting drift factor because the "
879 "Hardware Clock previously contained "
880 "garbage.\n"));
881 } else if (adjtime_p->last_calib_time == 0) {
882 if (debug)
883 printf(_("Not adjusting drift factor because last "
884 "calibration time is zero,\n"
885 "so history is bad and calibration startover "
886 "is necessary.\n"));
887 } else if ((hclocktime - adjtime_p->last_calib_time) < 23 * 60 * 60) {
888 if (debug)
889 printf(_("Not adjusting drift factor because it has "
890 "been less than a day since the last "
891 "calibration.\n"));
892 } else if (adjtime_p->last_calib_time != 0) {
893 /*
894 * At adjustment time we adjust the hardware clock according
895 * to the contents of /etc/adjtime.
896 *
ef71b8f1
SK
897 * At calibration time we set the hardware clock and update
898 * /etc/adjtime, that is, for each calibration (except the
899 * first) we also do an adjustment.
63cccae4
KZ
900 *
901 * We are now at calibration time.
902 *
903 * Let us do computation in doubles. (Floats almost suffice,
904 * but 195 days + 1 second equals 195 days in floats.)
905 */
906 const double sec_per_day = 24.0 * 60.0 * 60.0;
907 double atime_per_htime;
908 double adj_days, cal_days;
909 double exp_drift, unc_drift;
910 double factor_adjust;
911
912 /* Adjusted time units per hardware time unit */
913 atime_per_htime = 1.0 + adjtime_p->drift_factor / sec_per_day;
914
915 /* Days since last adjustment (in hardware clock time) */
916 adj_days = (double)(hclocktime - adjtime_p->last_adj_time)
ef71b8f1 917 / sec_per_day;
63cccae4
KZ
918
919 /* Expected drift (sec) since last adjustment */
920 exp_drift = adj_days * adjtime_p->drift_factor
ef71b8f1 921 + adjtime_p->not_adjusted;
63cccae4
KZ
922
923 /* Uncorrected drift (sec) since last calibration */
924 unc_drift = (double)(nowtime - hclocktime)
ef71b8f1 925 + sync_delay - exp_drift;
63cccae4
KZ
926
927 /* Days since last calibration (in hardware clock time) */
928 cal_days = ((double)(adjtime_p->last_adj_time
ef71b8f1 929 - adjtime_p->last_calib_time)
63cccae4 930 + adjtime_p->not_adjusted)
ef71b8f1 931 / (sec_per_day * atime_per_htime) + adj_days;
63cccae4
KZ
932
933 /* Amount to add to previous drift factor */
934 factor_adjust = unc_drift / cal_days;
935
936 if (debug)
937 printf(_("Clock drifted %.1f seconds in the past "
938 "%d seconds in spite of a drift factor of "
939 "%f seconds/day.\n"
940 "Adjusting drift factor by %f seconds/day\n"),
941 unc_drift,
ef71b8f1
SK
942 (int)(nowtime - adjtime_p->last_calib_time),
943 adjtime_p->drift_factor, factor_adjust);
9abb2685 944
63cccae4
KZ
945 adjtime_p->drift_factor += factor_adjust;
946 }
947 adjtime_p->last_calib_time = nowtime;
9abb2685 948
63cccae4 949 adjtime_p->last_adj_time = nowtime;
9abb2685 950
63cccae4 951 adjtime_p->not_adjusted = 0;
9abb2685 952
63cccae4 953 adjtime_p->dirty = TRUE;
7eda085c
KZ
954}
955
ef71b8f1
SK
956/*
957 * Do the drift adjustment calculation.
958 *
959 * The way we have to set the clock, we need the adjustment in two parts:
960 *
961 * 1) an integer number of seconds (return as *adjustment_p)
962 * 2) a positive fraction of a second (less than 1) (return as *retro_p)
963 *
964 * The sum of these two values is the adjustment needed. Positive means to
965 * advance the clock or insert seconds. Negative means to retard the clock
966 * or remove seconds.
967 */
7eda085c 968static void
63cccae4 969calculate_adjustment(const double factor,
ef71b8f1
SK
970 const time_t last_time,
971 const double not_adjusted,
972 const time_t systime, int *adjustment_p, double *retro_p)
973{
974 double exact_adjustment;
7eda085c 975
ef71b8f1
SK
976 exact_adjustment =
977 ((double)(systime - last_time)) * factor / (24 * 60 * 60)
978 + not_adjusted;
979 *adjustment_p = FLOOR(exact_adjustment);
7eda085c 980
ef71b8f1
SK
981 *retro_p = exact_adjustment - (double)*adjustment_p;
982 if (debug) {
983 printf(_("Time since last adjustment is %d seconds\n"),
984 (int)(systime - last_time));
985 printf(_("Need to insert %d seconds and refer time back "
986 "%.6f seconds ago\n"), *adjustment_p, *retro_p);
987 }
7eda085c
KZ
988}
989
ef71b8f1
SK
990/*
991 * Write the contents of the <adjtime> structure to its disk file.
992 *
993 * But if the contents are clean (unchanged since read from disk), don't
994 * bother.
995 */
996static void save_adjtime(const struct adjtime adjtime, const bool testing)
997{
998 char newfile[412]; /* Stuff to write to disk file */
7eda085c 999
ef71b8f1
SK
1000 if (adjtime.dirty) {
1001 /*
1002 * snprintf is not always available, but this is safe as
1003 * long as libc does not use more than 100 positions for %ld
1004 * or %f
1005 */
1006 sprintf(newfile, "%f %ld %f\n%ld\n%s\n",
1007 adjtime.drift_factor,
1008 (long)adjtime.last_adj_time,
1009 adjtime.not_adjusted,
1010 (long)adjtime.last_calib_time,
1011 (adjtime.local_utc == UTC) ? "UTC" : "LOCAL");
1012
1013 if (testing) {
1014 printf(_
1015 ("Not updating adjtime file because of testing mode.\n"));
1016 printf(_("Would have written the following to %s:\n%s"),
1017 adj_file_name, newfile);
1018 } else {
1019 FILE *adjfile;
1020 int err = 0;
1021
1022 adjfile = fopen(adj_file_name, "w");
1023 if (adjfile == NULL) {
111c05d3
SK
1024 warn(_
1025 ("Could not open file with the clock adjustment parameters "
1026 "in it (%s) for writing"), adj_file_name);
ef71b8f1
SK
1027 err = 1;
1028 } else {
1029 if (fputs(newfile, adjfile) < 0) {
111c05d3
SK
1030 warn(_
1031 ("Could not update file with the clock adjustment "
1032 "parameters (%s) in it"),
1033 adj_file_name);
ef71b8f1
SK
1034 err = 1;
1035 }
db116df7 1036 if (close_stream(adjfile) != 0) {
111c05d3
SK
1037 warn(_
1038 ("Could not update file with the clock adjustment "
1039 "parameters (%s) in it"),
1040 adj_file_name);
ef71b8f1
SK
1041 err = 1;
1042 }
1043 }
1044 if (err)
111c05d3
SK
1045 warnx(_
1046 ("Drift adjustment parameters not updated."));
ef71b8f1
SK
1047 }
1048 }
1049}
7eda085c 1050
ef71b8f1
SK
1051/*
1052 * Do the adjustment requested, by 1) setting the Hardware Clock (if
1053 * necessary), and 2) updating the last-adjusted time in the adjtime
1054 * structure.
1055 *
1056 * Do not update anything if the Hardware Clock does not currently present a
1057 * valid time.
1058 *
1059 * Arguments <factor> and <last_time> are current values from the adjtime
1060 * file.
1061 *
1062 * <hclock_valid> means the Hardware Clock contains a valid time, and that
1063 * time is <hclocktime>.
1064 *
1065 * <read_time> is the current system time (to be precise, it is the system
1066 * time at the time <hclocktime> was read, which due to computational delay
1067 * could be a short time ago).
1068 *
1069 * <universal>: the Hardware Clock is kept in UTC.
1070 *
1071 * <testing>: We are running in test mode (no updating of clock).
1072 *
1073 * We do not bother to update the clock if the adjustment would be less than
1074 * one second. This is to avoid cumulative error and needless CPU hogging
1075 * (remember we use an infinite loop for some timing) if the user runs us
1076 * frequently.
1077 */
7eda085c
KZ
1078static void
1079do_adjustment(struct adjtime *adjtime_p,
ef71b8f1
SK
1080 const bool hclock_valid, const time_t hclocktime,
1081 const struct timeval read_time,
1082 const bool universal, const bool testing)
1083{
1084 if (!hclock_valid) {
111c05d3
SK
1085 warnx(_("The Hardware Clock does not contain a valid time, "
1086 "so we cannot adjust it."));
ef71b8f1
SK
1087 adjtime_p->last_calib_time = 0; /* calibration startover is required */
1088 adjtime_p->last_adj_time = 0;
1089 adjtime_p->not_adjusted = 0;
1090 adjtime_p->dirty = TRUE;
1091 } else if (adjtime_p->last_adj_time == 0) {
1092 if (debug)
1093 printf(_
1094 ("Not setting clock because last adjustment time is zero, "
1095 "so history is bad."));
1096 } else {
1097 int adjustment;
1098 /* Number of seconds we must insert in the Hardware Clock */
1099 double retro;
1100 /*
1101 * Fraction of second we have to remove from clock after
1102 * inserting <adjustment> whole seconds.
1103 */
1104 calculate_adjustment(adjtime_p->drift_factor,
1105 adjtime_p->last_adj_time,
1106 adjtime_p->not_adjusted,
1107 hclocktime, &adjustment, &retro);
1108 if (adjustment > 0 || adjustment < -1) {
1109 set_hardware_clock_exact(hclocktime + adjustment,
1110 time_inc(read_time, -retro),
1111 universal, testing);
1112 adjtime_p->last_adj_time = hclocktime + adjustment;
1113 adjtime_p->not_adjusted = 0;
1114 adjtime_p->dirty = TRUE;
1115 } else if (debug)
1116 printf(_("Needed adjustment is less than one second, "
1117 "so not setting clock.\n"));
1118 }
7eda085c
KZ
1119}
1120
ef71b8f1
SK
1121static void determine_clock_access_method(const bool user_requests_ISA)
1122{
1123 ur = NULL;
7eda085c 1124
ef71b8f1
SK
1125 if (user_requests_ISA)
1126 ur = probe_for_cmos_clock();
7eda085c 1127
465e9973 1128#ifdef __linux__
ef71b8f1
SK
1129 if (!ur)
1130 ur = probe_for_rtc_clock();
465e9973 1131#endif
7eda085c 1132
ef71b8f1
SK
1133 if (!ur)
1134 ur = probe_for_kd_clock();
7eda085c 1135
ef71b8f1
SK
1136 if (!ur && !user_requests_ISA)
1137 ur = probe_for_cmos_clock();
7eda085c 1138
ef71b8f1
SK
1139 if (debug) {
1140 if (ur)
1141 printf(_("Using %s.\n"), ur->interface_name);
1142 else
1143 printf(_("No usable clock interface found.\n"));
1144 }
7eda085c
KZ
1145}
1146
ef71b8f1
SK
1147/*
1148 * Do all the normal work of hwclock - read, set clock, etc.
1149 *
1150 * Issue output to stdout and error message to stderr where appropriate.
1151 *
1152 * Return rc == 0 if everything went OK, rc != 0 if not.
1153 */
63cccae4 1154static int
364cda48 1155manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
ef71b8f1
SK
1156 const bool set, const time_t set_time,
1157 const bool hctosys, const bool systohc, const bool systz,
1158 const struct timeval startup_time,
1159 const bool utc, const bool local_opt,
1160 const bool testing, const bool predict)
1161{
1162 /* Contents of the adjtime file, or what they should be. */
1163 struct adjtime adjtime;
1164 bool universal;
1165 /* Set if user lacks necessary authorization to access the clock */
1166 bool no_auth;
1167 /* The time at which we read the Hardware Clock */
1168 struct timeval read_time;
1169 /*
1170 * The Hardware Clock gives us a valid time, or at
1171 * least something close enough to fool mktime().
1172 */
1173 bool hclock_valid = FALSE;
1174 /*
1175 * The time the hardware clock had just after we
1176 * synchronized to its next clock tick when we
1177 * started up. Defined only if hclock_valid is true.
1178 */
1179 time_t hclocktime = 0;
1180 /* local return code */
23341bd4 1181 int rc = 0;
ef71b8f1
SK
1182
1183 if (!systz && !predict) {
1184 no_auth = ur->get_permissions();
1185 if (no_auth)
1186 return EX_NOPERM;
1187 }
1188
1189 if (!noadjfile
1190 && (adjust || set || systohc || (!utc && !local_opt) || predict)) {
1191 rc = read_adjtime(&adjtime);
1192 if (rc)
1193 return rc;
1194 } else {
1195 /* A little trick to avoid reading the file if we don't have to */
1196 adjtime.dirty = FALSE;
ef71b8f1
SK
1197 }
1198
1199 universal = hw_clock_is_utc(utc, local_opt, adjtime);
1200
1201 if ((set || systohc || adjust) &&
1202 (adjtime.local_utc == UTC) != universal) {
1203 adjtime.local_utc = universal ? UTC : LOCAL;
1204 adjtime.dirty = TRUE;
1205 }
9abb2685 1206
2e5627fa 1207 if (show || adjust || hctosys || (!noadjfile && !systz && !predict)) {
ef71b8f1
SK
1208 /* data from HW-clock are required */
1209 rc = synchronize_to_clock_tick();
1210
1211 /*
1212 * 2 = synchronization timeout. We don't
1213 * error out if the user is attempting to
1214 * set the RTC - the RTC could be
1215 * functioning but contain invalid time data
1216 * so we still want to allow a user to set
1217 * the RTC time.
1218 */
1219 if (rc && rc != 2 && !set && !systohc)
1220 return EX_IOERR;
1221 gettimeofday(&read_time, NULL);
1222
1223 /*
1224 * If we can't synchronize to a clock tick,
1225 * we likely can't read from the RTC so
1226 * don't bother reading it again.
1227 */
1228 if (!rc) {
1229 rc = read_hardware_clock(universal,
1230 &hclock_valid, &hclocktime);
1231 if (rc && !set && !systohc)
1232 return EX_IOERR;
1233 }
cdedde03 1234 }
9abb2685 1235
ef71b8f1
SK
1236 if (show) {
1237 display_time(hclock_valid, hclocktime,
1238 time_diff(read_time, startup_time));
1239 } else if (set) {
1240 set_hardware_clock_exact(set_time, startup_time,
1241 universal, testing);
1242 if (!noadjfile)
1243 adjust_drift_factor(&adjtime, set_time,
1244 hclock_valid,
1245 hclocktime,
1246 time_diff(read_time, startup_time));
1247 } else if (adjust) {
1248 do_adjustment(&adjtime, hclock_valid,
1249 hclocktime, read_time, universal, testing);
1250 } else if (systohc) {
1251 struct timeval nowtime, reftime;
1252 /*
1253 * We can only set_hardware_clock_exact to a
1254 * whole seconds time, so we set it with
1255 * reference to the most recent whole
1256 * seconds time.
1257 */
1258 gettimeofday(&nowtime, NULL);
1259 reftime.tv_sec = nowtime.tv_sec;
1260 reftime.tv_usec = 0;
1261 set_hardware_clock_exact((time_t)
1262 reftime.tv_sec,
1263 reftime, universal, testing);
1264 if (!noadjfile)
1265 adjust_drift_factor(&adjtime, (time_t)
1266 reftime.tv_sec,
1267 hclock_valid, hclocktime, (double)
1268 read_time.tv_usec / 1E6);
1269 } else if (hctosys) {
1270 rc = set_system_clock(hclock_valid, hclocktime, testing);
1271 if (rc) {
1272 printf(_("Unable to set system clock.\n"));
1273 return rc;
1274 }
88a3372e 1275 } else if (systz) {
ef71b8f1
SK
1276 rc = set_system_clock_timezone(universal, testing);
1277 if (rc) {
1278 printf(_("Unable to set system clock.\n"));
1279 return rc;
1280 }
1281 } else if (predict) {
1282 int adjustment;
1283 double retro;
1284
1285 calculate_adjustment(adjtime.drift_factor,
1286 adjtime.last_adj_time,
1287 adjtime.not_adjusted,
1288 set_time, &adjustment, &retro);
1289 if (debug) {
1290 printf(_
1291 ("At %ld seconds after 1969, RTC is predicted to read %ld seconds after 1969.\n"),
1292 set_time, set_time + adjustment);
1293 }
1294 display_time(TRUE, set_time + adjustment, -retro);
1295 }
1296 if (!noadjfile)
1297 save_adjtime(adjtime, testing);
1298 return 0;
7eda085c
KZ
1299}
1300
ef71b8f1
SK
1301/*
1302 * Get or set the Hardware Clock epoch value in the kernel, as appropriate.
1303 * <getepoch>, <setepoch>, and <epoch> are hwclock invocation options.
1304 *
1305 * <epoch> == -1 if the user did not specify an "epoch" option.
1306 */
465e9973 1307#ifdef __linux__
390c72eb
SK
1308/*
1309 * Maintenance note: This should work on non-Alpha machines, but the
1310 * evidence today (98.03.04) indicates that the kernel only keeps the epoch
1311 * value on Alphas. If that is ever fixed, this function should be changed.
1312 */
1313# ifndef __alpha__
7eda085c 1314static void
390c72eb
SK
1315manipulate_epoch(const bool getepoch __attribute__ ((__unused__)),
1316 const bool setepoch __attribute__ ((__unused__)),
4ac41d61 1317 const unsigned long epoch_opt __attribute__ ((__unused__)),
390c72eb 1318 const bool testing __attribute__ ((__unused__)))
ef71b8f1 1319{
111c05d3
SK
1320 warnx(_("The kernel keeps an epoch value for the Hardware Clock "
1321 "only on an Alpha machine.\nThis copy of hwclock was built for "
1322 "a machine other than Alpha\n(and thus is presumably not running "
1323 "on an Alpha now). No action taken."));
390c72eb
SK
1324}
1325# else
1326static void
1327manipulate_epoch(const bool getepoch,
1328 const bool setepoch,
4ac41d61 1329 const unsigned long epoch_opt,
390c72eb
SK
1330 const bool testing)
1331{
ef71b8f1
SK
1332 if (getepoch) {
1333 unsigned long epoch;
1334
1335 if (get_epoch_rtc(&epoch, 0))
111c05d3
SK
1336 warnx(_
1337 ("Unable to get the epoch value from the kernel."));
ef71b8f1
SK
1338 else
1339 printf(_("Kernel is assuming an epoch value of %lu\n"),
1340 epoch);
1341 } else if (setepoch) {
1342 if (epoch_opt == -1)
111c05d3
SK
1343 warnx(_
1344 ("To set the epoch value, you must use the 'epoch' "
1345 "option to tell to what value to set it."));
ef71b8f1
SK
1346 else if (testing)
1347 printf(_
1348 ("Not setting the epoch to %d - testing only.\n"),
1349 epoch_opt);
1350 else if (set_epoch_rtc(epoch_opt))
1351 printf(_
1352 ("Unable to set the epoch value in the kernel.\n"));
1353 }
7eda085c 1354}
390c72eb
SK
1355# endif /* __alpha__ */
1356#endif /* __linux__ */
7eda085c 1357
ef71b8f1
SK
1358static void out_version(void)
1359{
111c05d3 1360 printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING);
63cccae4
KZ
1361}
1362
eb63b9b8 1363/*
ef71b8f1
SK
1364 * usage - Output (error and) usage information
1365 *
1366 * This function is called both directly from main to show usage information
1367 * and as fatal function from shhopt if some argument is not understood. In
1368 * case of normal usage info FMT should be NULL. In that case the info is
1369 * printed to stdout. If FMT is given usage will act like fprintf( stderr,
1370 * fmt, ... ), show a usage information and terminate the program
1371 * afterwards.
1372 */
1373static void usage(const char *fmt, ...)
1374{
1375 FILE *usageto;
1376 va_list ap;
1377
1378 usageto = fmt ? stderr : stdout;
1379
49deeeac
KZ
1380 fputs(_("\nUsage:\n"), usageto);
1381 fputs(_(" hwclock [function] [option...]\n"), usageto);
1382
1383 fputs(_("\nFunctions:\n"), usageto);
cc5ec693
KZ
1384 fputs(_(" -h, --help show this help text and exit\n"
1385 " -r, --show read hardware clock and print result\n"
1386 " --set set the RTC to the time given with --date\n"), usageto);
1387 fputs(_(" -s, --hctosys set the system time from the hardware clock\n"
1388 " -w, --systohc set the hardware clock from the current system time\n"
1389 " --systz set the system time based on the current timezone\n"
1390 " --adjust adjust the RTC to account for systematic drift since\n"
1391 " the clock was last set or adjusted\n"), usageto);
465e9973 1392#ifdef __linux__
cc5ec693
KZ
1393 fputs(_(" --getepoch print out the kernel's hardware clock epoch value\n"
1394 " --setepoch set the kernel's hardware clock epoch value to the \n"
1395 " value given with --epoch\n"), usageto);
465e9973 1396#endif
cc5ec693
KZ
1397 fputs(_(" --predict predict RTC reading at time given with --date\n"
1398 " -V, --version display version information and exit\n"), usageto);
49deeeac
KZ
1399
1400 fputs(_("\nOptions:\n"), usageto);
cc5ec693
KZ
1401 fputs(_(" -u, --utc the hardware clock is kept in UTC\n"
1402 " --localtime the hardware clock is kept in local time\n"), usageto);
465e9973 1403#ifdef __linux__
cc5ec693 1404 fputs(_(" -f, --rtc <file> special /dev/... file to use instead of default\n"), usageto);
465e9973 1405#endif
49deeeac 1406 fprintf(usageto, _(
cc5ec693
KZ
1407 " --directisa access the ISA bus directly instead of %s\n"
1408 " --badyear ignore RTC's year because the BIOS is broken\n"
1409 " --date <time> specifies the time to which to set the hardware clock\n"
1410 " --epoch <year> specifies the year which is the beginning of the\n"
1411 " hardware clock's epoch value\n"), _PATH_RTC_DEV);
49deeeac 1412 fprintf(usageto, _(
cc5ec693
KZ
1413 " --noadjfile do not access %s; this requires the use of\n"
1414 " either --utc or --localtime\n"
1415 " --adjfile <file> specifies the path to the adjust file;\n"
1416 " the default is %s\n"), _PATH_ADJPATH, _PATH_ADJPATH);
1417 fputs(_(" --test do not update anything, just show what would happen\n"
1418 " -D, --debug debugging mode\n" "\n"), usageto);
eb63b9b8 1419#ifdef __alpha__
49deeeac
KZ
1420 fputs(_(" -J|--jensen, -A|--arc, -S|--srm, -F|--funky-toy\n"
1421 " tell hwclock the type of Alpha you have (see hwclock(8))\n"
1422 "\n"), usageto);
eb63b9b8
KZ
1423#endif
1424
ef71b8f1 1425 if (fmt) {
ef71b8f1 1426 va_start(ap, fmt);
4f899788 1427 vfprintf(usageto, fmt, ap);
ef71b8f1
SK
1428 va_end(ap);
1429 }
9abb2685 1430
4f899788 1431 fflush(usageto);
111c05d3 1432 hwclock_exit(fmt ? EX_USAGE : EX_OK);
eb63b9b8
KZ
1433}
1434
63cccae4
KZ
1435/*
1436 * Returns:
1437 * EX_USAGE: bad invocation
1438 * EX_NOPERM: no permission
1439 * EX_OSFILE: cannot open /dev/rtc or /etc/adjtime
1440 * EX_IOERR: ioctl error getting or setting the time
1441 * 0: OK (or not)
1442 * 1: failure
1443 */
ef71b8f1
SK
1444int main(int argc, char **argv)
1445{
63cccae4 1446 struct timeval startup_time;
ef71b8f1
SK
1447 /*
1448 * The time we started up, in seconds into the epoch, including
1449 * fractions.
1450 */
1451 time_t set_time = 0; /* Time to which user said to set Hardware Clock */
7eda085c 1452
ef71b8f1 1453 bool permitted; /* User is permitted to do the function */
63cccae4 1454 int rc, c;
7eda085c 1455
e1f4706d
SK
1456 enum {
1457 EXCL_NONE,
1458
1459 EXCL_ADJFILE,
1460 EXCL_NO_AJDFILE,
1461
1462 EXCL_LOCALTIME,
1463 EXCL_UTC,
1464
1465 EXCL_ADJUST,
1466 EXCL_GETEPOCH,
1467 EXCL_HCTOSYS,
1468 EXCL_PREDICT,
1469 EXCL_SET,
1470 EXCL_SETEPOCH,
1471 EXCL_SHOW,
1472 EXCL_SYSTOHC,
1473 EXCL_SYSTZ
1474 };
1475 int excl_adj = EXCL_NONE;
1476 int excl_utc_local = EXCL_NONE;
1477 int excl_action = EXCL_NONE;
1478
63cccae4
KZ
1479 /* Variables set by various options; show may also be set later */
1480 /* The options debug, badyear and epoch_option are global */
ef71b8f1
SK
1481 bool show, set, systohc, hctosys, systz, adjust, getepoch, setepoch,
1482 predict;
63cccae4 1483 bool utc, testing, local_opt, noadjfile, directisa;
63cccae4 1484 char *date_opt;
52019d88
KZ
1485#ifdef __alpha__
1486 bool ARCconsole, Jensen, SRM, funky_toy;
1487#endif
33ed2d02
SK
1488
1489 static const struct option longopts[] = {
1490 {"adjust", 0, 0, 'a'},
1491 {"help", 0, 0, 'h'},
1492 {"show", 0, 0, 'r'},
1493 {"hctosys", 0, 0, 's'},
1494 {"utc", 0, 0, 'u'},
1495 {"version", 0, 0, 'v'},
1496 {"systohc", 0, 0, 'w'},
1497 {"debug", 0, 0, 'D'},
1498#ifdef __alpha__
1499 {"ARC", 0, 0, 'A'},
1500 {"arc", 0, 0, 'A'},
1501 {"Jensen", 0, 0, 'J'},
1502 {"jensen", 0, 0, 'J'},
1503 {"SRM", 0, 0, 'S'},
1504 {"srm", 0, 0, 'S'},
1505 {"funky-toy", 0, 0, 'F'},
1506#endif
1507 {"set", 0, 0, OPT_SET},
1508#ifdef __linux__
1509 {"getepoch", 0, 0, OPT_GETEPOCH},
1510 {"setepoch", 0, 0, OPT_SETEPOCH},
1511#endif
1512 {"noadjfile", 0, 0, OPT_NOADJFILE},
1513 {"localtime", 0, 0, OPT_LOCALTIME},
1514 {"badyear", 0, 0, OPT_BADYEAR},
1515 {"directisa", 0, 0, OPT_DIRECTISA},
1516 {"test", 0, 0, OPT_TEST},
1517 {"date", 1, 0, OPT_DATE},
1518 {"epoch", 1, 0, OPT_EPOCH},
1519#ifdef __linux__
1520 {"rtc", 1, 0, 'f'},
1521#endif
1522 {"adjfile", 1, 0, OPT_ADJFILE},
1523 {"systz", 0, 0, OPT_SYSTZ},
1524 {"predict-hc", 0, 0, OPT_PREDICT_HC},
1525 {NULL, 0, NULL, 0}
1526 };
1527
63cccae4
KZ
1528 /* Remember what time we were invoked */
1529 gettimeofday(&startup_time, NULL);
7eda085c 1530
88058a71
KZ
1531#ifdef HAVE_LIBAUDIT
1532 hwaudit_fd = audit_open();
1533 if (hwaudit_fd < 0 && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
1534 errno == EAFNOSUPPORT)) {
ef71b8f1
SK
1535 /*
1536 * You get these error codes only when the kernel doesn't
1537 * have audit compiled in.
1538 */
111c05d3 1539 warnx(_("Unable to connect to audit system"));
88058a71
KZ
1540 return EX_NOPERM;
1541 }
1542#endif
63cccae4 1543 setlocale(LC_ALL, "");
66ee8158 1544#ifdef LC_NUMERIC
ef71b8f1
SK
1545 /*
1546 * We need LC_CTYPE and LC_TIME and LC_MESSAGES, but must avoid
1547 * LC_NUMERIC since it gives problems when we write to /etc/adjtime.
1548 * - gqueri@mail.dotcom.fr
1549 */
63cccae4 1550 setlocale(LC_NUMERIC, "C");
66ee8158 1551#endif
63cccae4
KZ
1552 bindtextdomain(PACKAGE, LOCALEDIR);
1553 textdomain(PACKAGE);
db116df7 1554 atexit(close_stdout);
63cccae4
KZ
1555
1556 /* Set option defaults */
ef71b8f1
SK
1557 show = set = systohc = hctosys = systz = adjust = noadjfile = predict =
1558 FALSE;
b618d6ee 1559 getepoch = setepoch = utc = local_opt = directisa = testing = debug = FALSE;
52019d88 1560#ifdef __alpha__
b618d6ee 1561 ARCconsole = Jensen = SRM = funky_toy = badyear = FALSE;
52019d88 1562#endif
63cccae4
KZ
1563 date_opt = NULL;
1564
ef71b8f1 1565 while ((c = getopt_long(argc, argv, "?hvVDarsuwAJSFf:", longopts, NULL))
63cccae4
KZ
1566 != -1) {
1567 switch (c) {
1568 case 'D':
1569 debug = TRUE;
1570 break;
1571 case 'a':
1572 adjust = TRUE;
e1f4706d 1573 exclusive_option(&excl_action, EXCL_ADJUST, EXCL_ERROR);
63cccae4
KZ
1574 break;
1575 case 'r':
1576 show = TRUE;
e1f4706d 1577 exclusive_option(&excl_action, EXCL_SHOW, EXCL_ERROR);
63cccae4
KZ
1578 break;
1579 case 's':
1580 hctosys = TRUE;
e1f4706d 1581 exclusive_option(&excl_action, EXCL_HCTOSYS, EXCL_ERROR);
63cccae4
KZ
1582 break;
1583 case 'u':
1584 utc = TRUE;
e1f4706d 1585 exclusive_option(&excl_utc_local, EXCL_UTC, "--{utc,localtime}");
63cccae4
KZ
1586 break;
1587 case 'w':
1588 systohc = TRUE;
e1f4706d 1589 exclusive_option(&excl_action, EXCL_SYSTOHC, EXCL_ERROR);
63cccae4
KZ
1590 break;
1591#ifdef __alpha__
1592 case 'A':
1593 ARCconsole = TRUE;
1594 break;
1595 case 'J':
1596 Jensen = TRUE;
1597 break;
1598 case 'S':
1599 SRM = TRUE;
1600 break;
1601 case 'F':
1602 funky_toy = TRUE;
1603 break;
1604#endif
33ed2d02 1605 case OPT_SET:
63cccae4 1606 set = TRUE;
e1f4706d 1607 exclusive_option(&excl_action, EXCL_SET, EXCL_ERROR);
63cccae4 1608 break;
465e9973 1609#ifdef __linux__
33ed2d02 1610 case OPT_GETEPOCH:
63cccae4 1611 getepoch = TRUE;
e1f4706d 1612 exclusive_option(&excl_action, EXCL_GETEPOCH, EXCL_ERROR);
63cccae4 1613 break;
33ed2d02 1614 case OPT_SETEPOCH:
63cccae4 1615 setepoch = TRUE;
e1f4706d 1616 exclusive_option(&excl_action, EXCL_SETEPOCH, EXCL_ERROR);
63cccae4 1617 break;
465e9973 1618#endif
33ed2d02 1619 case OPT_NOADJFILE:
63cccae4 1620 noadjfile = TRUE;
e1f4706d 1621 exclusive_option(&excl_adj, EXCL_NO_AJDFILE, "--{adjfile,noadjfile}");
63cccae4 1622 break;
33ed2d02 1623 case OPT_LOCALTIME:
ef71b8f1 1624 local_opt = TRUE; /* --localtime */
e1f4706d 1625 exclusive_option(&excl_utc_local, EXCL_LOCALTIME, "--{utc,localtime}");
63cccae4 1626 break;
33ed2d02 1627 case OPT_BADYEAR:
63cccae4
KZ
1628 badyear = TRUE;
1629 break;
33ed2d02 1630 case OPT_DIRECTISA:
63cccae4
KZ
1631 directisa = TRUE;
1632 break;
33ed2d02 1633 case OPT_TEST:
ef71b8f1 1634 testing = TRUE; /* --test */
63cccae4 1635 break;
33ed2d02 1636 case OPT_DATE:
ef71b8f1 1637 date_opt = optarg; /* --date */
63cccae4 1638 break;
33ed2d02 1639 case OPT_EPOCH:
4ac41d61 1640 epoch_option = /* --epoch */
99c95585 1641 strtoul_or_err(optarg, _("invalid epoch argument"));
63cccae4 1642 break;
33ed2d02 1643 case OPT_ADJFILE:
ef71b8f1 1644 adj_file_name = optarg; /* --adjfile */
e1f4706d 1645 exclusive_option(&excl_adj, EXCL_ADJFILE, "--{adjfile,noadjfile}");
da82f6fe 1646 break;
33ed2d02 1647 case OPT_SYSTZ:
ef71b8f1 1648 systz = TRUE; /* --systz */
e1f4706d 1649 exclusive_option(&excl_action, EXCL_SYSTZ, EXCL_ERROR);
88a3372e 1650 break;
33ed2d02 1651 case OPT_PREDICT_HC:
ef71b8f1 1652 predict = TRUE; /* --predict-hc */
e1f4706d 1653 exclusive_option(&excl_action, EXCL_PREDICT, EXCL_ERROR);
2e5627fa 1654 break;
465e9973 1655#ifdef __linux__
88681c5f 1656 case 'f':
ef71b8f1 1657 rtc_dev_name = optarg; /* --rtc */
88681c5f 1658 break;
465e9973 1659#endif
ef71b8f1 1660 case 'v': /* --version */
63cccae4
KZ
1661 case 'V':
1662 out_version();
1663 return 0;
ef71b8f1 1664 case 'h': /* --help */
63cccae4
KZ
1665 case '?':
1666 default:
1667 usage(NULL);
1668 }
1669 }
7eda085c 1670
63cccae4
KZ
1671 argc -= optind;
1672 argv += optind;
eb63b9b8 1673
88058a71
KZ
1674#ifdef HAVE_LIBAUDIT
1675 if (testing != TRUE) {
1676 if (adjust == TRUE || hctosys == TRUE || systohc == TRUE ||
ef71b8f1 1677 set == TRUE || setepoch == TRUE) {
88058a71
KZ
1678 hwaudit_on = TRUE;
1679 }
1680 }
1681#endif
63cccae4
KZ
1682 if (argc > 0) {
1683 usage(_("%s takes no non-option arguments. "
111c05d3
SK
1684 "You supplied %d.\n"), program_invocation_short_name,
1685 argc);
63cccae4 1686 }
7eda085c 1687
da82f6fe 1688 if (!adj_file_name)
9d413ecb 1689 adj_file_name = _PATH_ADJPATH;
da82f6fe 1690
e1f4706d 1691 if (noadjfile && !excl_utc_local) {
111c05d3
SK
1692 warnx(_("With --noadjfile, you must specify "
1693 "either --utc or --localtime"));
88058a71 1694 hwclock_exit(EX_USAGE);
63cccae4 1695 }
7eda085c 1696#ifdef __alpha__
63cccae4
KZ
1697 set_cmos_epoch(ARCconsole, SRM);
1698 set_cmos_access(Jensen, funky_toy);
7eda085c
KZ
1699#endif
1700
2e5627fa 1701 if (set || predict) {
63cccae4
KZ
1702 rc = interpret_date_string(date_opt, &set_time);
1703 /* (time-consuming) */
1704 if (rc != 0) {
111c05d3
SK
1705 warnx(_("No usable set-to time. "
1706 "Cannot set clock."));
88058a71 1707 hwclock_exit(EX_USAGE);
63cccae4
KZ
1708 }
1709 }
7eda085c 1710
88a3372e 1711 if (!(show | set | systohc | hctosys | systz | adjust | getepoch
2e5627fa 1712 | setepoch | predict))
ef71b8f1 1713 show = 1; /* default to show */
9abb2685 1714
63cccae4
KZ
1715 if (getuid() == 0)
1716 permitted = TRUE;
1717 else {
1718 /* program is designed to run setuid (in some situations) */
d458f94a 1719 if (set || systohc || adjust) {
111c05d3
SK
1720 warnx(_("Sorry, only the superuser can change "
1721 "the Hardware Clock."));
63cccae4 1722 permitted = FALSE;
88a3372e 1723 } else if (systz || hctosys) {
111c05d3
SK
1724 warnx(_("Sorry, only the superuser can change "
1725 "the System Clock."));
63cccae4
KZ
1726 permitted = FALSE;
1727 } else if (setepoch) {
111c05d3
SK
1728 warnx(_("Sorry, only the superuser can change the "
1729 "Hardware Clock epoch in the kernel."));
63cccae4
KZ
1730 permitted = FALSE;
1731 } else
1732 permitted = TRUE;
1733 }
7eda085c 1734
63cccae4 1735 if (!permitted)
88058a71 1736 hwclock_exit(EX_NOPERM);
63cccae4 1737
465e9973 1738#ifdef __linux__
63cccae4
KZ
1739 if (getepoch || setepoch) {
1740 manipulate_epoch(getepoch, setepoch, epoch_option, testing);
111c05d3 1741 hwclock_exit(EX_OK);
63cccae4 1742 }
465e9973 1743#endif
63cccae4
KZ
1744
1745 if (debug)
1746 out_version();
111c05d3 1747
2e5627fa 1748 if (!systz && !predict) {
304762d6
SJR
1749 determine_clock_access_method(directisa);
1750 if (!ur) {
111c05d3
SK
1751 warnx(_("Cannot access the Hardware Clock via "
1752 "any known method."));
304762d6 1753 if (!debug)
111c05d3
SK
1754 warnx(_("Use the --debug option to see the "
1755 "details of our search for an access "
1756 "method."));
1757 hwclock_exit(EX_SOFTWARE);
304762d6 1758 }
63cccae4
KZ
1759 }
1760
88058a71 1761 rc = manipulate_clock(show, adjust, noadjfile, set, set_time,
ef71b8f1
SK
1762 hctosys, systohc, systz, startup_time, utc,
1763 local_opt, testing, predict);
88058a71 1764 hwclock_exit(rc);
ef71b8f1 1765 return rc; /* Not reached */
7eda085c
KZ
1766}
1767
88058a71 1768#ifdef HAVE_LIBAUDIT
111c05d3
SK
1769/*
1770 * hwclock_exit calls either this function or plain exit depending
842f9176 1771 * HAVE_LIBAUDIT see also clock.h
111c05d3
SK
1772 */
1773void __attribute__((__noreturn__)) hwaudit_exit(int status)
88058a71
KZ
1774{
1775 if (hwaudit_on) {
1776 audit_log_user_message(hwaudit_fd, AUDIT_USYS_CONFIG,
ef71b8f1
SK
1777 "changing system time", NULL, NULL, NULL,
1778 status ? 0 : 1);
88058a71
KZ
1779 close(hwaudit_fd);
1780 }
1781 exit(status);
1782}
1783#endif
1784
ef71b8f1
SK
1785/*
1786 * History of this program:
1787 *
1788 * 98.08.12 BJH Version 2.4
1789 *
1790 * Don't use century byte from Hardware Clock. Add comments telling why.
1791 *
1792 * 98.06.20 BJH Version 2.3.
1793 *
1794 * Make --hctosys set the kernel timezone from TZ environment variable
1795 * and/or /usr/lib/zoneinfo. From Klaus Ripke (klaus@ripke.com).
1796 *
1797 * 98.03.05 BJH. Version 2.2.
1798 *
1799 * Add --getepoch and --setepoch.
1800 *
1801 * Fix some word length things so it works on Alpha.
1802 *
1803 * Make it work when /dev/rtc doesn't have the interrupt functions. In this
1804 * case, busywait for the top of a second instead of blocking and waiting
1805 * for the update complete interrupt.
1806 *
1807 * Fix a bunch of bugs too numerous to mention.
1808 *
1809 * 97.06.01: BJH. Version 2.1. Read and write the century byte (Byte 50) of
1810 * the ISA Hardware Clock when using direct ISA I/O. Problem discovered by
1811 * job (jei@iclnl.icl.nl).
1812 *
1813 * Use the rtc clock access method in preference to the KDGHWCLK method.
1814 * Problem discovered by Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>.
1815 *
1816 * November 1996: Version 2.0.1. Modifications by Nicolai Langfeldt
1817 * (janl@math.uio.no) to make it compile on linux 1.2 machines as well as
1818 * more recent versions of the kernel. Introduced the NO_CLOCK access method
455fe9a0 1819 * and wrote feature test code to detect absence of rtc headers.
ef71b8f1
SK
1820 *
1821 ***************************************************************************
1822 * Maintenance notes
1823 *
1824 * To compile this, you must use GNU compiler optimization (-O option) in
1825 * order to make the "extern inline" functions from asm/io.h (inb(), etc.)
1826 * compile. If you don't optimize, which means the compiler will generate no
1827 * inline functions, the references to these functions in this program will
1828 * be compiled as external references. Since you probably won't be linking
1829 * with any functions by these names, you will have unresolved external
1830 * references when you link.
1831 *
1832 * The program is designed to run setuid superuser, since we need to be able
1833 * to do direct I/O. (More to the point: we need permission to execute the
1834 * iopl() system call). (However, if you use one of the methods other than
1835 * direct ISA I/O to access the clock, no setuid is required).
1836 *
1837 * Here's some info on how we must deal with the time that elapses while
1838 * this program runs: There are two major delays as we run:
1839 *
1840 * 1) Waiting up to 1 second for a transition of the Hardware Clock so
1841 * we are synchronized to the Hardware Clock.
1842 * 2) Running the "date" program to interpret the value of our --date
1843 * option.
1844 *
1845 * Reading the /etc/adjtime file is the next biggest source of delay and
1846 * uncertainty.
1847 *
1848 * The user wants to know what time it was at the moment he invoked us, not
1849 * some arbitrary time later. And in setting the clock, he is giving us the
1850 * time at the moment we are invoked, so if we set the clock some time
1851 * later, we have to add some time to that.
1852 *
1853 * So we check the system time as soon as we start up, then run "date" and
1854 * do file I/O if necessary, then wait to synchronize with a Hardware Clock
1855 * edge, then check the system time again to see how much time we spent. We
1856 * immediately read the clock then and (if appropriate) report that time,
1857 * and additionally, the delay we measured.
1858 *
1859 * If we're setting the clock to a time given by the user, we wait some more
1860 * so that the total delay is an integral number of seconds, then set the
1861 * Hardware Clock to the time the user requested plus that integral number
1862 * of seconds. N.B. The Hardware Clock can only be set in integral seconds.
1863 *
1864 * If we're setting the clock to the system clock value, we wait for the
1865 * system clock to reach the top of a second, and then set the Hardware
1866 * Clock to the system clock's value.
1867 *
1868 * Here's an interesting point about setting the Hardware Clock: On my
1869 * machine, when you set it, it sets to that precise time. But one can
1870 * imagine another clock whose update oscillator marches on a steady one
1871 * second period, so updating the clock between any two oscillator ticks is
1872 * the same as updating it right at the earlier tick. To avoid any
1873 * complications that might cause, we set the clock as soon as possible
1874 * after an oscillator tick.
1875 *
1876 * About synchronizing to the Hardware Clock when reading the time: The
1877 * precision of the Hardware Clock counters themselves is one second. You
1878 * can't read the counters and find out that is 12:01:02.5. But if you
1879 * consider the location in time of the counter's ticks as part of its
1880 * value, then its precision is as infinite as time is continuous! What I'm
1881 * saying is this: To find out the _exact_ time in the hardware clock, we
1882 * wait until the next clock tick (the next time the second counter changes)
1883 * and measure how long we had to wait. We then read the value of the clock
1884 * counters and subtract the wait time and we know precisely what time it
1885 * was when we set out to query the time.
1886 *
1887 * hwclock uses this method, and considers the Hardware Clock to have
1888 * infinite precision.
1889 *
1890 * TODO: Enhancements needed:
1891 *
1892 * - When waiting for whole second boundary in set_hardware_clock_exact,
1893 * fail if we miss the goal by more than .1 second, as could happen if we
1894 * get pre-empted (by the kernel dispatcher).
1895 */