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