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