Upload Tizen:Base source
[framework/base/util-linux-ng.git] / hwclock / hwclock.c
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>
18  * and Jay Estabrook <jestabro@amt.tay1.dec.com>
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
22  * Change of local time handling, Stefan Ring <e9725446@stud3.tuwien.ac.at>
23  * Change of adjtime handling, James P. Rutledge <ao112@rgfn.epcc.edu>.
24  *
25  * Distributed under GPL
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>
81 #include <stdarg.h>
82 #include <getopt.h>
83 #include <sysexits.h>
84
85 #include "clock.h"
86 #include "nls.h"
87
88 #ifdef HAVE_LIBAUDIT
89 #include <libaudit.h>
90 static int hwaudit_fd = -1;
91 static int hwaudit_on;
92 #endif
93
94 #define MYNAME "hwclock"
95
96 char *progname = MYNAME;
97
98 /* The struct that holds our hardware access routines */
99 struct 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
106 const char *adj_file_name = NULL;
107
108 /* Store the date here when "badyear" flag is set. */
109 #define LASTDATE "/var/lib/lastdate"
110
111 struct 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
117      updated since read from the disk file).
118      */
119   bool dirty;
120
121   /* line 1 */
122   double drift_factor;
123   time_t last_adj_time;
124   double not_adjusted;
125
126   /* line 2 */
127   time_t last_calib_time;
128       /* The most recent time that we set the clock from an external
129          authority (as opposed to just doing a drift adjustment) */
130
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. */
135 };
136
137 bool 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
141 bool badyear;
142   /* Workaround for Award 4.50g BIOS bug: keep the year in a file. */
143
144 int epoch_option = -1;
145   /* User-specified epoch, used when rtc fails to return epoch. */
146
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  */
157 static void
158 write_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
169 static void
170 read_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
185 double
186 time_diff(struct timeval subtrahend, struct timeval subtractor) {
187 /*---------------------------------------------------------------------------
188   The difference in seconds between two times in "timeval" format.
189 ----------------------------------------------------------------------------*/
190   return (subtrahend.tv_sec - subtractor.tv_sec)
191            + (subtrahend.tv_usec - subtractor.tv_usec) / 1E6;
192 }
193
194
195 static struct timeval
196 time_inc(struct timeval addend, double increment) {
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   }
214   return newtime;
215 }
216
217
218 static bool
219 hw_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
237
238 static int
239 read_adjtime(struct adjtime *adjtime_p) {
240 /*----------------------------------------------------------------------------
241   Read the adjustment parameters out of the /etc/adjtime file.
242
243   Return them as the adjtime structure <*adjtime_p>.
244   If there is no /etc/adjtime file, return defaults.
245   If values are missing from the file, return defaults for them.
246
247   return value 0 if all OK, !=0 otherwise.
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
254     rc = stat(adj_file_name, &statbuf);
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;
262       adjtime_p->dirty = FALSE;        /* don't create a zero adjfile */
263
264       return 0;
265     }
266
267     adjfile = fopen(adj_file_name, "r");   /* open file for reading */
268     if (adjfile == NULL) {
269       outsyserr("cannot open file %s", adj_file_name);
270       return EX_OSFILE;
271     }
272
273     {
274       char line1[81];           /* String: first line of adjtime file */
275       char line2[81];           /* String: second line of adjtime file */
276       char line3[81];           /* String: third line of adjtime file */
277       long timeval;
278
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 */
285
286       fclose(adjfile);
287
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;
293       timeval = 0;
294
295       sscanf(line1, "%lf %ld %lf",
296              &adjtime_p->drift_factor,
297              &timeval,
298              &adjtime_p->not_adjusted);
299       adjtime_p->last_adj_time = timeval;
300
301       sscanf(line2, "%ld", &timeval);
302       adjtime_p->last_calib_time = timeval;
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]) {
311           fprintf(stderr,
312                   _("%s: Warning: unrecognized third line in adjtime file\n"),
313                   MYNAME);
314           fprintf(stderr, _("(Expected: `UTC' or `LOCAL' or nothing.)\n"));
315         }
316       }
317     }
318     adjtime_p->dirty = FALSE;
319
320     if (debug) {
321       printf(_("Last drift adjustment done at %ld seconds after 1969\n"),
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);
325       printf(_("Hardware clock is on %s time\n"),
326              (adjtime_p->local_utc == LOCAL) ? _("local") :
327              (adjtime_p->local_utc == UTC) ? _("UTC") : _("unknown"));
328     }
329
330     return 0;
331 }
332
333
334 static int
335 synchronize_to_clock_tick(void) {
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
345   or in a CPU spin loop.  The former is probably not very accurate.
346
347   Return 0 if it worked, nonzero if it didn't.
348 -----------------------------------------------------------------------------*/
349         int rc;
350
351         if (debug) printf(_("Waiting for clock tick...\n"));
352
353         rc = ur->synchronize_to_clock_tick();
354
355         if (debug) {
356                 if (rc)
357                         printf(_("...synchronization failed\n"));
358                 else
359                         printf(_("...got clock tick\n"));
360         }
361
362         return rc;
363 }
364
365
366
367 static void
368 mktime_tz(struct tm tm, const bool universal,
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
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
392      changing the local time zone to UTC.
393      */
394   zone = getenv("TZ");  /* remember original time zone */
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: "
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);
417   } else {
418     *valid_p = TRUE;
419     *systime_p = mktime_result;
420     if (debug)
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);
425   }
426   /* now put back the original zone.  */
427   if (zone) setenv("TZ", zone, TRUE);
428   else unsetenv("TZ");
429   tzset();
430 }
431
432
433 static int
434 read_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);
444   if (err)
445           return err;
446
447   if (badyear)
448     read_date_from_file(&tm);
449
450   if (debug)
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,
453             tm.tm_hour, tm.tm_min, tm.tm_sec);
454   mktime_tz(tm, universal, valid_p, systime_p);
455
456   return 0;
457 }
458
459
460 static void
461 set_hardware_clock(const time_t newtime,
462                    const bool universal,
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;
469   struct tm new_broken_time;
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
479   if (debug)
480     printf(_("Setting Hardware Clock to %.2d:%.2d:%.2d "
481            "= %ld seconds since 1969\n"),
482            new_broken_time.tm_hour, new_broken_time.tm_min,
483            new_broken_time.tm_sec, (long) newtime);
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
503 static void
504 set_hardware_clock_exact(const time_t sethwtime,
505                          const struct timeval refsystime,
506                          const bool universal,
507                          const bool testing) {
508 /*----------------------------------------------------------------------------
509   Set the Hardware Clock to the time "sethwtime", in local time zone or UTC,
510   according to "universal".
511
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.
518
519   (Don't be confused by the fact that the system clock and the Hardware
520   Clock differ by two hours in the above example.  That's just to remind
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.
525 -----------------------------------------------------------------------------*/
526
527   time_t newhwtime;
528   struct timeval beginsystime, nowsystime;
529   double tdiff;
530
531  time_resync:
532   gettimeofday(&beginsystime, NULL);
533   tdiff = time_diff(beginsystime, refsystime);
534   newhwtime = sethwtime + (int) (tdiff + 0.5);
535   if (debug)
536     printf(_("Time elapsed since reference time has been %.6f seconds.\n"
537            "Delaying further to reach the new time.\n"), tdiff);
538
539   /*
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
542    * (because it is designed to update to the next second precisely 500 ms
543    * after you finish the setting).
544    */
545   do {
546           gettimeofday(&nowsystime, NULL);
547           tdiff = time_diff(nowsystime, beginsystime);
548           if (tdiff < 0)
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));
555
556   set_hardware_clock(newhwtime, universal, testing);
557 }
558
559
560
561 static void
562 display_time(const bool hclock_valid, const time_t systime,
563              const double sync_duration) {
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 {
576     struct tm *lt;
577     char *format = "%c";
578     char ctime_now[200];
579
580     lt = localtime(&systime);
581     strftime(ctime_now, sizeof(ctime_now), format, lt);
582     printf(_("%s  %.6f seconds\n"), ctime_now, -(sync_duration));
583   }
584 }
585
586
587
588 static int
589 interpret_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
594   question is our "dateopt" argument.
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 ----------------------------------------------------------------------------*/
608         FILE *date_child_fp;
609         char date_resp[100];
610         const char magic[]="seconds-into-epoch=";
611         char date_command[100];
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         }
619
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
634         sprintf(date_command, "date --date=\"%s\" +seconds-into-epoch=%%s",
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
646         if (!fgets(date_resp, sizeof(date_resp), date_child_fp))
647                 date_resp[0] = '\0';  /* in case fgets fails */
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"
654                                   "The response was:\n  %s\n"),
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;
673                         if (debug)
674                                 printf(_("date string %s equates to "
675                                          "%ld seconds since 1969.\n"),
676                                        date_opt, (long) *time_p);
677                 }
678         }
679         pclose(date_child_fp);
680
681         return retcode;
682 }
683
684
685
686 static int
687 set_system_clock(const bool hclock_valid, const time_t newtime,
688                  const bool testing) {
689 /*----------------------------------------------------------------------------
690    Set the System Clock to time 'newtime'.
691
692    Also set the kernel time zone value to the value indicated by the
693    TZ environment variable and/or /usr/lib/zoneinfo/, interpreted as
694    tzset() would interpret them.
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
700    If 'testing' is true, don't actually update anything -- just say we
701    would have.
702 -----------------------------------------------------------------------------*/
703   int retcode;
704
705   if (!hclock_valid) {
706     fprintf(stderr, _("The Hardware Clock does not contain a valid time, so "
707             "we cannot set the System Time from it.\n"));
708     retcode = 1;
709   } else {
710     struct timeval tv;
711     struct tm *broken;
712     int minuteswest;
713     int rc;
714
715     tv.tv_sec = newtime;
716     tv.tv_usec = 0;
717
718     broken = localtime(&newtime);
719 #ifdef HAVE_TM_GMTOFF
720     minuteswest = -broken->tm_gmtoff/60;                /* GNU extension */
721 #else
722     minuteswest = timezone/60;
723     if (broken->tm_isdst)
724             minuteswest -= 60;
725 #endif
726
727     if (debug) {
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);
732     }
733     if (testing) {
734       printf(_("Not setting system clock because running in test mode.\n"));
735       retcode = 0;
736     } else {
737       const struct timezone tz = { minuteswest, 0 };
738
739       rc = settimeofday(&tv, &tz);
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               }
749       } else retcode = 0;
750     }
751   }
752   return retcode;
753 }
754
755
756 static int
757 set_system_clock_timezone(const bool universal, const bool testing) {
758 /*----------------------------------------------------------------------------
759    Reset the System Clock from local time to UTC, based on its current
760    value and the timezone unless universal is TRUE.
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   if (!universal)
796     tv.tv_sec += minuteswest * 60;
797
798   if (debug) {
799     struct tm broken_time;
800     char ctime_now[200];
801
802     broken_time = *gmtime(&tv.tv_sec);
803     strftime(ctime_now, sizeof(ctime_now), "%Y/%m/%d %H:%M:%S", &broken_time);
804
805     printf(_("Calling settimeofday:\n"));
806     printf(_("\tUTC: %s\n"), ctime_now);
807     printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
808            (long) tv.tv_sec, (long) tv.tv_usec);
809     printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
810   }
811   if (testing) {
812     printf(_("Not setting system clock because running in test mode.\n"));
813     retcode = 0;
814   } else {
815     const struct timezone tz = { minuteswest, 0 };
816
817     rc = settimeofday(&tv, &tz);
818     if (rc) {
819             if (errno == EPERM) {
820                     fprintf(stderr,
821                             _("Must be superuser to set system clock.\n"));
822                     retcode = EX_NOPERM;
823             } else {
824                     outsyserr(_("settimeofday() failed"));
825                     retcode = 1;
826             }
827     } else retcode = 0;
828   }
829   return retcode;
830 }
831
832
833 static void
834 adjust_drift_factor(struct adjtime *adjtime_p,
835                     const time_t nowtime,
836                     const bool hclock_valid,
837                     const time_t hclocktime,
838                     const double sync_delay) {
839 /*------------------------------------------------------------------------
840   Update the drift factor in <*adjtime_p> to reflect the fact that the
841   Hardware Clock was calibrated to <nowtime> and before that was set
842   to <hclocktime>.
843
844   We record in the adjtime file the time at which we last calibrated
845   the clock so we can compute the drift rate each time we calibrate.
846
847   EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set
848   before to anything meaningful and regular adjustments have not been
849   done, so don't adjust the drift factor.
850   ------------------------------------------------------------------------*/
851         if (!hclock_valid) {
852                 if (debug)
853                         printf(_("Not adjusting drift factor because the "
854                                  "Hardware Clock previously contained "
855                                  "garbage.\n"));
856         } else if (adjtime_p->last_calib_time == 0) {
857                 if (debug)
858                         printf(_("Not adjusting drift factor because last "
859                                  "calibration time is zero,\n"
860                                  "so history is bad and calibration startover "
861                                  "is necessary.\n"));
862         } else if ((hclocktime - adjtime_p->last_calib_time) < 23 * 60 * 60) {
863                 if (debug)
864                         printf(_("Not adjusting drift factor because it has "
865                                  "been less than a day since the last "
866                                  "calibration.\n"));
867         } else if (adjtime_p->last_calib_time != 0) {
868                 /*
869                  * At adjustment time we adjust the hardware clock according
870                  * to the contents of /etc/adjtime.
871                  *
872                  * At calibration time we set the hardware clock and
873                  * update /etc/adjtime, that is, for each calibration
874                  * (except the first) we also do an adjustment.
875                  *
876                  * We are now at calibration time.
877                  *
878                  * Let us do computation in doubles. (Floats almost suffice,
879                  * but 195 days + 1 second equals 195 days in floats.)
880                  */
881                 const double sec_per_day = 24.0 * 60.0 * 60.0;
882                 double atime_per_htime;
883                 double adj_days, cal_days;
884                 double exp_drift, unc_drift;
885                 double factor_adjust;
886
887                 /* Adjusted time units per hardware time unit */
888                 atime_per_htime = 1.0 + adjtime_p->drift_factor / sec_per_day;
889
890                 /* Days since last adjustment (in hardware clock time) */
891                 adj_days = (double)(hclocktime - adjtime_p->last_adj_time)
892                         / sec_per_day;
893
894                 /* Expected drift (sec) since last adjustment */
895                 exp_drift = adj_days * adjtime_p->drift_factor
896                         + adjtime_p->not_adjusted;
897
898                 /* Uncorrected drift (sec) since last calibration */
899                 unc_drift = (double)(nowtime - hclocktime)
900                         + sync_delay - exp_drift;
901
902                 /* Days since last calibration (in hardware clock time) */
903                 cal_days = ((double)(adjtime_p->last_adj_time
904                                     - adjtime_p->last_calib_time)
905                             + adjtime_p->not_adjusted)
906                         / (sec_per_day * atime_per_htime) + adj_days;
907
908                 /* Amount to add to previous drift factor */
909                 factor_adjust = unc_drift / cal_days;
910
911                 if (debug)
912                         printf(_("Clock drifted %.1f seconds in the past "
913                                  "%d seconds in spite of a drift factor of "
914                                  "%f seconds/day.\n"
915                                  "Adjusting drift factor by %f seconds/day\n"),
916                                unc_drift,
917                                (int) (nowtime - adjtime_p->last_calib_time),
918                                adjtime_p->drift_factor,
919                                factor_adjust);
920
921                 adjtime_p->drift_factor += factor_adjust;
922         }
923         adjtime_p->last_calib_time = nowtime;
924
925         adjtime_p->last_adj_time = nowtime;
926
927         adjtime_p->not_adjusted = 0;
928
929         adjtime_p->dirty = TRUE;
930 }
931
932
933
934 static void
935 calculate_adjustment(const double factor,
936                      const time_t last_time,
937                      const double not_adjusted,
938                      const time_t systime,
939                      int *adjustment_p,
940                      double *retro_p) {
941 /*----------------------------------------------------------------------------
942   Do the drift adjustment calculation.
943
944   The way we have to set the clock, we need the adjustment in two parts:
945
946     1) an integer number of seconds (return as *adjustment_p)
947
948     2) a positive fraction of a second (less than 1) (return as *retro_p)
949
950   The sum of these two values is the adjustment needed.  Positive means to
951   advance the clock or insert seconds.  Negative means to retard the clock
952   or remove seconds.
953 ----------------------------------------------------------------------------*/
954   double exact_adjustment;
955
956   exact_adjustment = ((double) (systime - last_time)) * factor / (24 * 60 * 60)
957                      + not_adjusted;
958   *adjustment_p = FLOOR(exact_adjustment);
959
960   *retro_p = exact_adjustment - (double) *adjustment_p;
961   if (debug) {
962     printf (_("Time since last adjustment is %d seconds\n"),
963             (int) (systime - last_time));
964     printf (_("Need to insert %d seconds and refer time back "
965             "%.6f seconds ago\n"),
966             *adjustment_p, *retro_p);
967   }
968 }
969
970
971
972 static void
973 save_adjtime(const struct adjtime adjtime, const bool testing) {
974 /*-----------------------------------------------------------------------------
975   Write the contents of the <adjtime> structure to its disk file.
976
977   But if the contents are clean (unchanged since read from disk), don't
978   bother.
979 -----------------------------------------------------------------------------*/
980   char newfile[412];   /* Stuff to write to disk file */
981
982   if (adjtime.dirty) {
983     /* snprintf is not always available, but this is safe
984        as long as libc does not use more than 100 positions for %ld or %f */
985     sprintf(newfile, "%f %ld %f\n%ld\n%s\n",
986              adjtime.drift_factor,
987              (long) adjtime.last_adj_time,
988              adjtime.not_adjusted,
989              (long) adjtime.last_calib_time,
990              (adjtime.local_utc == UTC) ? "UTC" : "LOCAL");
991
992     if (testing) {
993       printf(_("Not updating adjtime file because of testing mode.\n"));
994       printf(_("Would have written the following to %s:\n%s"),
995              adj_file_name, newfile);
996     } else {
997       FILE *adjfile;
998       int err = 0;
999
1000       adjfile = fopen(adj_file_name, "w");
1001       if (adjfile == NULL) {
1002         outsyserr(_("Could not open file with the clock adjustment parameters "
1003                "in it (%s) for writing"), adj_file_name);
1004         err = 1;
1005       } else {
1006         if (fputs(newfile, adjfile) < 0) {
1007           outsyserr(_("Could not update file with the clock adjustment "
1008                     "parameters (%s) in it"), adj_file_name);
1009           err = 1;
1010         }
1011         if (fclose(adjfile) < 0) {
1012           outsyserr(_("Could not update file with the clock adjustment "
1013                     "parameters (%s) in it"), adj_file_name);
1014           err = 1;
1015         }
1016       }
1017       if (err)
1018         fprintf(stderr, _("Drift adjustment parameters not updated.\n"));
1019     }
1020   }
1021 }
1022
1023
1024
1025 static void
1026 do_adjustment(struct adjtime *adjtime_p,
1027               const bool hclock_valid, const time_t hclocktime,
1028               const struct timeval read_time,
1029               const bool universal, const bool testing) {
1030 /*---------------------------------------------------------------------------
1031   Do the adjustment requested, by 1) setting the Hardware Clock (if
1032   necessary), and 2) updating the last-adjusted time in the adjtime
1033   structure.
1034
1035   Do not update anything if the Hardware Clock does not currently present
1036   a valid time.
1037
1038   arguments <factor> and <last_time> are current values from the adjtime
1039   file.
1040
1041   <hclock_valid> means the Hardware Clock contains a valid time, and that
1042   time is <hclocktime>.
1043
1044   <read_time> is the current system time (to be precise, it is the system
1045   time at the time <hclocktime> was read, which due to computational delay
1046   could be a short time ago).
1047
1048   <universal>: the Hardware Clock is kept in UTC.
1049
1050   <testing>:  We are running in test mode (no updating of clock).
1051
1052   We do not bother to update the clock if the adjustment would be less than
1053   one second.  This is to avoid cumulative error and needless CPU hogging
1054   (remember we use an infinite loop for some timing) if the user runs us
1055   frequently.
1056
1057 ----------------------------------------------------------------------------*/
1058   if (!hclock_valid) {
1059     fprintf(stderr, _("The Hardware Clock does not contain a valid time, "
1060             "so we cannot adjust it.\n"));
1061     adjtime_p->last_calib_time = 0;  /* calibration startover is required */
1062     adjtime_p->last_adj_time = 0;
1063     adjtime_p->not_adjusted = 0;
1064     adjtime_p->dirty = TRUE;
1065   } else if (adjtime_p->last_adj_time == 0) {
1066     if (debug)
1067       printf(_("Not setting clock because last adjustment time is zero, "
1068              "so history is bad."));
1069   } else {
1070     int adjustment;
1071     /* Number of seconds we must insert in the Hardware Clock */
1072     double retro;
1073     /* Fraction of second we have to remove from clock after inserting
1074        <adjustment> whole seconds.
1075        */
1076     calculate_adjustment(adjtime_p->drift_factor,
1077                          adjtime_p->last_adj_time,
1078                          adjtime_p->not_adjusted,
1079                          hclocktime,
1080                          &adjustment, &retro);
1081     if (adjustment > 0 || adjustment < -1) {
1082       set_hardware_clock_exact(hclocktime + adjustment,
1083                                time_inc(read_time, -retro),
1084                                universal, testing);
1085       adjtime_p->last_adj_time = hclocktime + adjustment;
1086       adjtime_p->not_adjusted = 0;
1087       adjtime_p->dirty = TRUE;
1088     } else
1089       if (debug)
1090         printf(_("Needed adjustment is less than one second, "
1091                "so not setting clock.\n"));
1092   }
1093 }
1094
1095
1096
1097 static void
1098 determine_clock_access_method(const bool user_requests_ISA) {
1099
1100   ur = NULL;
1101
1102   if (user_requests_ISA)
1103           ur = probe_for_cmos_clock();
1104
1105   if (!ur)
1106           ur = probe_for_rtc_clock();
1107
1108   if (!ur)
1109           ur = probe_for_kd_clock();
1110
1111   if (!ur && !user_requests_ISA)
1112           ur = probe_for_cmos_clock();
1113
1114   if (debug) {
1115           if (ur)
1116                   printf(_("Using %s.\n"), ur->interface_name);
1117           else
1118                   printf(_("No usable clock interface found.\n"));
1119   }
1120 }
1121
1122 static int
1123 manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
1124                  const bool set, const time_t set_time,
1125                  const bool hctosys, const bool systohc, const bool systz,
1126                  const struct timeval startup_time,
1127                  const bool utc, const bool local_opt,
1128                  const bool testing) {
1129 /*---------------------------------------------------------------------------
1130   Do all the normal work of hwclock - read, set clock, etc.
1131
1132   Issue output to stdout and error message to stderr where appropriate.
1133
1134   Return rc == 0 if everything went OK, rc != 0 if not.
1135 ----------------------------------------------------------------------------*/
1136     struct adjtime adjtime;
1137       /* Contents of the adjtime file, or what they should be. */
1138     int rc;  /* local return code */
1139     bool no_auth;  /* User lacks necessary authorization to access the clock */
1140
1141     if (!systz) {
1142       no_auth = ur->get_permissions();
1143       if (no_auth)
1144               return EX_NOPERM;
1145     }
1146
1147     if (!noadjfile && (adjust || set || systohc || (!utc && !local_opt))) {
1148       rc = read_adjtime(&adjtime);
1149       if (rc)
1150               return rc;
1151     } else {
1152       /* A little trick to avoid reading the file if we don't have to */
1153       adjtime.dirty = FALSE;
1154       rc = 0;
1155     }
1156
1157     {
1158       const bool universal = hw_clock_is_utc(utc, local_opt, adjtime);
1159
1160       if ((set || systohc || adjust) &&
1161           (adjtime.local_utc == UTC) != universal) {
1162         adjtime.local_utc = universal ? UTC : LOCAL;
1163         adjtime.dirty = TRUE;
1164       }
1165
1166       {
1167         struct timeval read_time;
1168           /* The time at which we read the Hardware Clock */
1169
1170         bool hclock_valid = FALSE;
1171           /* The Hardware Clock gives us a valid time, or at least something
1172              close enough to fool mktime().
1173              */
1174
1175         time_t hclocktime = 0;
1176           /* The time the hardware clock had just after we
1177              synchronized to its next clock tick when we started up.
1178              Defined only if hclock_valid is true.
1179              */
1180
1181         if (show || adjust || hctosys || (!noadjfile && !systz)) {
1182           /* data from HW-clock are required */
1183           rc = synchronize_to_clock_tick();
1184           if (rc && rc != 2)            /* 2= synchronization timeout */
1185             return EX_IOERR;
1186           gettimeofday(&read_time, NULL);
1187           rc = read_hardware_clock(universal, &hclock_valid, &hclocktime);
1188           if (rc)
1189              return EX_IOERR;
1190         }
1191
1192         if (show) {
1193           display_time(hclock_valid, hclocktime,
1194                        time_diff(read_time, startup_time));
1195         } else if (set) {
1196           set_hardware_clock_exact(set_time, startup_time,
1197                                       universal, testing);
1198           if (!noadjfile)
1199             adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime,
1200                                 time_diff(read_time, startup_time));
1201         } else if (adjust) {
1202           do_adjustment(&adjtime, hclock_valid, hclocktime,
1203                         read_time, universal, testing);
1204         } else if (systohc) {
1205           struct timeval nowtime, reftime;
1206           /* We can only set_hardware_clock_exact to a whole seconds
1207              time, so we set it with reference to the most recent
1208              whole seconds time.
1209              */
1210           gettimeofday(&nowtime, NULL);
1211           reftime.tv_sec = nowtime.tv_sec;
1212           reftime.tv_usec = 0;
1213
1214           set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
1215                                    universal, testing);
1216           if (!noadjfile)
1217             adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
1218                                 hclocktime, (double) read_time.tv_usec / 1E6);
1219         } else if (hctosys) {
1220           rc = set_system_clock(hclock_valid, hclocktime, testing);
1221           if (rc) {
1222             printf(_("Unable to set system clock.\n"));
1223             return rc;
1224           }
1225         } else if (systz) {
1226           rc = set_system_clock_timezone(universal, testing);
1227           if (rc) {
1228             printf(_("Unable to set system clock.\n"));
1229             return rc;
1230           }
1231         }
1232         if (!noadjfile)
1233          save_adjtime(adjtime, testing);
1234       }
1235     }
1236     return 0;
1237 }
1238
1239
1240 static void
1241 manipulate_epoch(const bool getepoch, const bool setepoch,
1242                  const int epoch_opt, const bool testing) {
1243 /*----------------------------------------------------------------------------
1244    Get or set the Hardware Clock epoch value in the kernel, as appropriate.
1245    <getepoch>, <setepoch>, and <epoch> are hwclock invocation options.
1246
1247    <epoch> == -1 if the user did not specify an "epoch" option.
1248
1249 -----------------------------------------------------------------------------*/
1250   /*
1251    Maintenance note:  This should work on non-Alpha machines, but the
1252    evidence today (98.03.04) indicates that the kernel only keeps the
1253    epoch value on Alphas.  If that is ever fixed, this function should be
1254    changed.
1255    */
1256
1257 #ifndef __alpha__
1258     fprintf(stderr, _("The kernel keeps an epoch value for the Hardware Clock "
1259             "only on an Alpha machine.\nThis copy of hwclock was built for "
1260             "a machine other than Alpha\n(and thus is presumably not running "
1261             "on an Alpha now).  No action taken.\n"));
1262 #else
1263     if (getepoch) {
1264       unsigned long epoch;
1265
1266       if (get_epoch_rtc(&epoch, 0))
1267         fprintf(stderr, _("Unable to get the epoch value from the kernel.\n"));
1268       else
1269         printf(_("Kernel is assuming an epoch value of %lu\n"), epoch);
1270     } else if (setepoch) {
1271       if (epoch_opt == -1)
1272         fprintf(stderr, _("To set the epoch value, you must use the 'epoch' "
1273                 "option to tell to what value to set it.\n"));
1274       else if (testing)
1275         printf(_("Not setting the epoch to %d - testing only.\n"),
1276                epoch_opt);
1277       else if (set_epoch_rtc(epoch_opt))
1278         printf(_("Unable to set the epoch value in the kernel.\n"));
1279     }
1280 #endif
1281 }
1282
1283 #ifdef __ia64__
1284 #define RTC_DEV "/dev/efirtc"
1285 #else
1286 #define RTC_DEV "/dev/rtc"
1287 #endif
1288
1289 static void
1290 out_version(void) {
1291         printf(_("%s from %s\n"), MYNAME, PACKAGE_STRING);
1292 }
1293
1294 /*
1295     usage - Output (error and) usage information
1296
1297     This function is called both directly from main to show usage
1298     information and as fatal function from shhopt if some argument is
1299     not understood. In case of normal usage info FMT should be NULL.
1300     In that case the info is printed to stdout. If FMT is given
1301     usage will act like fprintf( stderr, fmt, ... ), show a usage
1302     information and terminate the program afterwards.
1303 */
1304 static void
1305 usage( const char *fmt, ... ) {
1306   FILE    *usageto;
1307   va_list ap;
1308
1309   usageto = fmt ? stderr : stdout;
1310
1311   fprintf( usageto, _(
1312     "hwclock - query and set the hardware clock (RTC)\n\n"
1313     "Usage: hwclock [function] [options...]\n\n"
1314     "Functions:\n"
1315         "  -h | --help         show this help\n"
1316         "  -r | --show         read hardware clock and print result\n"
1317         "       --set          set the rtc to the time given with --date\n"
1318         "  -s | --hctosys      set the system time from the hardware clock\n"
1319         "  -w | --systohc      set the hardware clock to the current system time\n"
1320         "       --systz        set the system time based on the current timezone\n"
1321         "       --adjust       adjust the rtc to account for systematic drift since\n"
1322         "                      the clock was last set or adjusted\n"
1323         "       --getepoch     print out the kernel's hardware clock epoch value\n"
1324         "       --setepoch     set the kernel's hardware clock epoch value to the \n"
1325         "                      value given with --epoch\n"
1326         "  -v | --version      print out the version of hwclock to stdout\n"
1327         "\nOptions: \n"
1328         "  -u | --utc          the hardware clock is kept in UTC\n"
1329         "       --localtime    the hardware clock is kept in local time\n"
1330         "  -f | --rtc=path     special /dev/... file to use instead of default\n"
1331         "       --directisa    access the ISA bus directly instead of %s\n"
1332         "       --badyear      ignore rtc's year because the bios is broken\n"
1333         "       --date         specifies the time to which to set the hardware clock\n"
1334         "       --epoch=year   specifies the year which is the beginning of the \n"
1335         "                      hardware clock's epoch value\n"
1336         "       --noadjfile    do not access /etc/adjtime. Requires the use of\n"
1337         "                      either --utc or --localtime\n"
1338         "       --adjfile=path specifies the path to the adjust file (default is\n"
1339         "                      /etc/adjtime)\n"
1340         "       --test         do everything except actually updating the hardware\n"
1341         "                      clock or anything else\n"
1342         "  -D | --debug        debug mode\n"
1343         "\n"
1344     ),RTC_DEV);
1345 #ifdef __alpha__
1346   fprintf(usageto, _(
1347         "  -J|--jensen, -A|--arc, -S|--srm, -F|--funky-toy\n"
1348         "       tell hwclock the type of alpha you have (see hwclock(8))\n"
1349         "\n"
1350     ) );
1351 #endif
1352
1353   fflush(stdout);
1354   if (fmt) {
1355     usageto = stderr;
1356     va_start(ap, fmt);
1357     vfprintf(stderr, fmt, ap);
1358     va_end(ap);
1359   }
1360
1361   hwclock_exit(fmt ? EX_USAGE : 0);
1362 }
1363
1364 static const struct option longopts[] = {
1365         { "adjust", 0, 0, 'a' },
1366         { "help", 0, 0, 'h' },
1367         { "show", 0, 0, 'r' },
1368         { "hctosys", 0, 0, 's' },
1369         { "utc", 0, 0, 'u' },
1370         { "version", 0, 0, 'v' },
1371         { "systohc", 0, 0, 'w' },
1372         { "debug", 0, 0, 'D' },
1373 #ifdef __alpha__
1374         { "ARC", 0, 0, 'A' },
1375         { "arc", 0, 0, 'A' },
1376         { "Jensen", 0, 0, 'J' },
1377         { "jensen", 0, 0, 'J' },
1378         { "SRM", 0, 0, 'S' },
1379         { "srm", 0, 0, 'S' },
1380         { "funky-toy", 0, 0, 'F'},
1381 #endif
1382         { "set", 0, 0, 128 },
1383         { "getepoch", 0, 0, 129 },
1384         { "setepoch", 0, 0, 130 },
1385         { "noadjfile", 0, 0, 131 },
1386         { "localtime", 0, 0, 132 },
1387         { "badyear", 0, 0, 133 },
1388         { "directisa", 0, 0, 134 },
1389         { "test", 0, 0, 135 },
1390         { "date", 1, 0, 136 },
1391         { "epoch", 1, 0, 137 },
1392         { "rtc", 1, 0, 'f' },
1393         { "adjfile", 1, 0, 138 },
1394         { "systz", 0, 0, 139 },
1395         { NULL, 0, 0, 0 }
1396 };
1397
1398 /*
1399  * Returns:
1400  *  EX_USAGE: bad invocation
1401  *  EX_NOPERM: no permission
1402  *  EX_OSFILE: cannot open /dev/rtc or /etc/adjtime
1403  *  EX_IOERR: ioctl error getting or setting the time
1404  *  0: OK (or not)
1405  *  1: failure
1406  */
1407 int
1408 main(int argc, char **argv) {
1409
1410         struct timeval startup_time;
1411         /* The time we started up, in seconds into the epoch, including
1412            fractions. */
1413         time_t set_time = 0;  /* Time to which user said to set Hardware Clock */
1414
1415         bool permitted;  /* User is permitted to do the function */
1416         int rc, c;
1417
1418         /* Variables set by various options; show may also be set later */
1419         /* The options debug, badyear and epoch_option are global */
1420         bool show, set, systohc, hctosys, systz, adjust, getepoch, setepoch;
1421         bool utc, testing, local_opt, noadjfile, directisa;
1422         bool ARCconsole, Jensen, SRM, funky_toy;
1423         char *date_opt;
1424
1425         /* Remember what time we were invoked */
1426         gettimeofday(&startup_time, NULL);
1427
1428 #ifdef HAVE_LIBAUDIT
1429         hwaudit_fd = audit_open();
1430         if (hwaudit_fd < 0 && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
1431                                 errno == EAFNOSUPPORT)) {
1432                 /* You get these error codes only when the kernel doesn't have
1433                  * audit compiled in. */
1434                 fprintf(stderr, _("%s: Unable to connect to audit system\n"),
1435                                 MYNAME);
1436                 return EX_NOPERM;
1437         }
1438 #endif
1439         setlocale(LC_ALL, "");
1440 #ifdef LC_NUMERIC
1441         /* We need LC_CTYPE and LC_TIME and LC_MESSAGES, but must avoid
1442            LC_NUMERIC since it gives problems when we write to /etc/adjtime.
1443            - gqueri@mail.dotcom.fr */
1444         setlocale(LC_NUMERIC, "C");
1445 #endif
1446         bindtextdomain(PACKAGE, LOCALEDIR);
1447         textdomain(PACKAGE);
1448
1449         /* Set option defaults */
1450         show = set = systohc = hctosys = systz = adjust = noadjfile = FALSE;
1451         getepoch = setepoch = utc = local_opt = testing = debug = FALSE;
1452         ARCconsole = Jensen = SRM = funky_toy = directisa = badyear = FALSE;
1453         date_opt = NULL;
1454
1455         while ((c = getopt_long (argc, argv, "?hvVDarsuwAJSFf:", longopts, NULL))
1456                != -1) {
1457                 switch (c) {
1458                 case 'D':
1459                         debug = TRUE;
1460                         break;
1461                 case 'a':
1462                         adjust = TRUE;
1463                         break;
1464                 case 'r':
1465                         show = TRUE;
1466                         break;
1467                 case 's':
1468                         hctosys = TRUE;
1469                         break;
1470                 case 'u':
1471                         utc = TRUE;
1472                         break;
1473                 case 'w':
1474                         systohc = TRUE;
1475                         break;
1476 #ifdef __alpha__
1477                 case 'A':
1478                         ARCconsole = TRUE;
1479                         break;
1480                 case 'J':
1481                         Jensen = TRUE;
1482                         break;
1483                 case 'S':
1484                         SRM = TRUE;
1485                         break;
1486                 case 'F':
1487                         funky_toy = TRUE;
1488                         break;
1489 #endif
1490                 case 128:
1491                         set = TRUE;
1492                         break;
1493                 case 129:
1494                         getepoch = TRUE;
1495                         break;
1496                 case 130:
1497                         setepoch = TRUE;
1498                         break;
1499                 case 131:
1500                         noadjfile = TRUE;
1501                         break;
1502                 case 132:
1503                         local_opt = TRUE;               /* --localtime */
1504                         break;
1505                 case 133:
1506                         badyear = TRUE;
1507                         break;
1508                 case 134:
1509                         directisa = TRUE;
1510                         break;
1511                 case 135:
1512                         testing = TRUE;                 /* --test */
1513                         break;
1514                 case 136:
1515                         date_opt = optarg;              /* --date */
1516                         break;
1517                 case 137:
1518                         epoch_option = atoi(optarg);    /* --epoch */
1519                         break;
1520                 case 138:
1521                         adj_file_name = optarg;         /* --adjfile */
1522                         break;
1523                 case 139:
1524                         systz = TRUE;                   /* --systz */
1525                         break;
1526                 case 'f':
1527                         rtc_dev_name = optarg;          /* --rtc */
1528                         break;
1529                 case 'v':                               /* --version */
1530                 case 'V':
1531                         out_version();
1532                         return 0;
1533                 case 'h':                               /* --help */
1534                 case '?':
1535                 default:
1536                         usage(NULL);
1537                 }
1538         }
1539
1540         argc -= optind;
1541         argv += optind;
1542
1543 #ifdef HAVE_LIBAUDIT
1544         if (testing != TRUE) {
1545                 if (adjust == TRUE || hctosys == TRUE || systohc == TRUE ||
1546                                         set == TRUE || setepoch == TRUE) {
1547                         hwaudit_on = TRUE;
1548                 }
1549         }
1550 #endif
1551         if (argc > 0) {
1552                 usage(_("%s takes no non-option arguments.  "
1553                         "You supplied %d.\n"),
1554                       MYNAME, argc);
1555         }
1556
1557         if (show + set + systohc + hctosys + systz + adjust + getepoch
1558             + setepoch > 1){
1559                 fprintf(stderr, _("You have specified multiple functions.\n"
1560                                   "You can only perform one function "
1561                                   "at a time.\n"));
1562                 hwclock_exit(EX_USAGE);
1563         }
1564
1565         if (utc && local_opt) {
1566                 fprintf(stderr, _("%s: The --utc and --localtime options "
1567                                   "are mutually exclusive.  You specified "
1568                                   "both.\n"), MYNAME);
1569                 hwclock_exit(EX_USAGE);
1570         }
1571
1572         if (adjust && noadjfile) {
1573                 fprintf(stderr, _("%s: The --adjust and --noadjfile options "
1574                                   "are mutually exclusive.  You specified "
1575                                   "both.\n"), MYNAME);
1576                 hwclock_exit(EX_USAGE);
1577         }
1578
1579         if (adj_file_name && noadjfile) {
1580                 fprintf(stderr, _("%s: The --adjfile and --noadjfile options "
1581                                   "are mutually exclusive.  You specified "
1582                                   "both.\n"), MYNAME);
1583                 hwclock_exit(EX_USAGE);
1584         }
1585         if (!adj_file_name)
1586                 adj_file_name = ADJPATH;
1587
1588         if (noadjfile && !(utc || local_opt)) {
1589                 fprintf(stderr, _("%s: With --noadjfile, you must specify "
1590                                   "either --utc or --localtime\n"), MYNAME);
1591                 hwclock_exit(EX_USAGE);
1592         }
1593
1594 #ifdef __alpha__
1595         set_cmos_epoch(ARCconsole, SRM);
1596         set_cmos_access(Jensen, funky_toy);
1597 #endif
1598
1599         if (set) {
1600                 rc = interpret_date_string(date_opt, &set_time);
1601                 /* (time-consuming) */
1602                 if (rc != 0) {
1603                         fprintf(stderr, _("No usable set-to time.  "
1604                                           "Cannot set clock.\n"));
1605                         hwclock_exit(EX_USAGE);
1606                 }
1607         }
1608
1609         if (!(show | set | systohc | hctosys | systz | adjust | getepoch
1610               | setepoch))
1611                 show = 1; /* default to show */
1612
1613
1614         if (getuid() == 0)
1615                 permitted = TRUE;
1616         else {
1617                 /* program is designed to run setuid (in some situations) */
1618                 if (set || systohc || adjust) {
1619                         fprintf(stderr,
1620                                 _("Sorry, only the superuser can change "
1621                                   "the Hardware Clock.\n"));
1622                         permitted = FALSE;
1623                 } else if (systz || hctosys) {
1624                         fprintf(stderr,
1625                                 _("Sorry, only the superuser can change "
1626                                   "the System Clock.\n"));
1627                         permitted = FALSE;
1628                 } else if (setepoch) {
1629                         fprintf(stderr,
1630                                 _("Sorry, only the superuser can change the "
1631                                   "Hardware Clock epoch in the kernel.\n"));
1632                         permitted = FALSE;
1633                 } else
1634                         permitted = TRUE;
1635         }
1636
1637         if (!permitted)
1638                 hwclock_exit(EX_NOPERM);
1639
1640         if (getepoch || setepoch) {
1641                 manipulate_epoch(getepoch, setepoch, epoch_option, testing);
1642                 hwclock_exit(0);
1643         }
1644
1645         if (debug)
1646                 out_version();
1647         if (!systz) {
1648                 determine_clock_access_method(directisa);
1649                 if (!ur) {
1650                         fprintf(stderr,
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 "
1656                                           "details of our search for an access "
1657                                           "method.\n"));
1658                         hwclock_exit(1);
1659                 }
1660         }
1661
1662         rc = manipulate_clock(show, adjust, noadjfile, set, set_time,
1663                                 hctosys, systohc, systz, startup_time, utc,
1664                                 local_opt, testing);
1665         hwclock_exit(rc);
1666         return rc;      /* Not reached */
1667 }
1668
1669 /* A single routine for greater uniformity */
1670 void
1671 outsyserr(char *msg, ...) {
1672         va_list args;
1673         int errsv = errno;
1674
1675         fprintf(stderr, "%s: ", progname);
1676         va_start(args, msg);
1677         vfprintf(stderr, msg, args);
1678         va_end(args);
1679         fprintf(stderr, ", errno=%d: %s.\n",
1680                 errsv, strerror(errsv));
1681 }
1682
1683
1684 #ifdef HAVE_LIBAUDIT
1685 void
1686 hwaudit_exit(int status)
1687 {
1688         if (hwaudit_on) {
1689                 audit_log_user_message(hwaudit_fd, AUDIT_USYS_CONFIG,
1690                         "changing system time", NULL, NULL, NULL, status ? 0 : 1);
1691                 close(hwaudit_fd);
1692         }
1693         exit(status);
1694 }
1695 #endif
1696
1697 /****************************************************************************
1698
1699   History of this program:
1700
1701   98.08.12 BJH   Version 2.4
1702
1703   Don't use century byte from Hardware Clock.  Add comments telling why.
1704
1705
1706   98.06.20 BJH   Version 2.3.
1707
1708   Make --hctosys set the kernel timezone from TZ environment variable
1709   and/or /usr/lib/zoneinfo.  From Klaus Ripke (klaus@ripke.com).
1710
1711   98.03.05 BJH.  Version 2.2.
1712
1713   Add --getepoch and --setepoch.
1714
1715   Fix some word length things so it works on Alpha.
1716
1717   Make it work when /dev/rtc doesn't have the interrupt functions.
1718   In this case, busywait for the top of a second instead of blocking and
1719   waiting for the update complete interrupt.
1720
1721   Fix a bunch of bugs too numerous to mention.
1722
1723   97.06.01: BJH.  Version 2.1.  Read and write the century byte (Byte
1724   50) of the ISA Hardware Clock when using direct ISA I/O.  Problem
1725   discovered by job (jei@iclnl.icl.nl).
1726
1727   Use the rtc clock access method in preference to the KDGHWCLK method.
1728   Problem discovered by Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>.
1729
1730   November 1996: Version 2.0.1.  Modifications by Nicolai Langfeldt
1731   (janl@math.uio.no) to make it compile on linux 1.2 machines as well
1732   as more recent versions of the kernel. Introduced the NO_CLOCK
1733   access method and wrote feature test code to detect absense of rtc
1734   headers.
1735
1736
1737 **************************************************************************
1738   Maintenance notes
1739
1740   To compile this, you must use GNU compiler optimization (-O option)
1741   in order to make the "extern inline" functions from asm/io.h (inb(),
1742   etc.)  compile.  If you don't optimize, which means the compiler
1743   will generate no inline functions, the references to these functions
1744   in this program will be compiled as external references.  Since you
1745   probably won't be linking with any functions by these names, you will
1746   have unresolved external references when you link.
1747
1748   The program is designed to run setuid superuser, since we need to be
1749   able to do direct I/O.  (More to the point: we need permission to
1750   execute the iopl() system call).  (However, if you use one of the
1751   methods other than direct ISA I/O to access the clock, no setuid is
1752   required).
1753
1754   Here's some info on how we must deal with the time that elapses while
1755   this program runs: There are two major delays as we run:
1756
1757     1) Waiting up to 1 second for a transition of the Hardware Clock so
1758        we are synchronized to the Hardware Clock.
1759
1760     2) Running the "date" program to interpret the value of our --date
1761        option.
1762
1763   Reading the /etc/adjtime file is the next biggest source of delay and
1764   uncertainty.
1765
1766   The user wants to know what time it was at the moment he invoked us,
1767   not some arbitrary time later.  And in setting the clock, he is
1768   giving us the time at the moment we are invoked, so if we set the
1769   clock some time later, we have to add some time to that.
1770
1771   So we check the system time as soon as we start up, then run "date"
1772   and do file I/O if necessary, then wait to synchronize with a
1773   Hardware Clock edge, then check the system time again to see how
1774   much time we spent.  We immediately read the clock then and (if
1775   appropriate) report that time, and additionally, the delay we measured.
1776
1777   If we're setting the clock to a time given by the user, we wait some
1778   more so that the total delay is an integral number of seconds, then
1779   set the Hardware Clock to the time the user requested plus that
1780   integral number of seconds.  N.B. The Hardware Clock can only be set
1781   in integral seconds.
1782
1783   If we're setting the clock to the system clock value, we wait for
1784   the system clock to reach the top of a second, and then set the
1785   Hardware Clock to the system clock's value.
1786
1787   Here's an interesting point about setting the Hardware Clock:  On my
1788   machine, when you set it, it sets to that precise time.  But one can
1789   imagine another clock whose update oscillator marches on a steady one
1790   second period, so updating the clock between any two oscillator ticks
1791   is the same as updating it right at the earlier tick.  To avoid any
1792   complications that might cause, we set the clock as soon as possible
1793   after an oscillator tick.
1794
1795
1796   About synchronizing to the Hardware Clock when reading the time: The
1797   precision of the Hardware Clock counters themselves is one second.
1798   You can't read the counters and find out that is 12:01:02.5.  But if
1799   you consider the location in time of the counter's ticks as part of
1800   its value, then its precision is as infinite as time is continuous!
1801   What I'm saying is this: To find out the _exact_ time in the
1802   hardware clock, we wait until the next clock tick (the next time the
1803   second counter changes) and measure how long we had to wait.  We
1804   then read the value of the clock counters and subtract the wait time
1805   and we know precisely what time it was when we set out to query the
1806   time.
1807
1808   hwclock uses this method, and considers the Hardware Clock to have
1809   infinite precision.
1810
1811
1812   Enhancements needed:
1813
1814    - When waiting for whole second boundary in set_hardware_clock_exact,
1815      fail if we miss the goal by more than .1 second, as could happen if
1816      we get pre-empted (by the kernel dispatcher).
1817
1818 ****************************************************************************/
1819