16
16
* Reshuffled things, added sparc code, and re-added alpha stuff
17
17
* by David Mosberger <davidm@azstarnet.com>
18
* and Jay Estabrook <jestabro@amt.tay1.dec.com>
18
* and Jay Estabrook <jestabro@amt.tay1.dec.com>
19
19
* and Martin Ostermann <ost@coments.rwth-aachen.de>, aeb@cwi.nl, 990212.
21
21
* Fix for Award 2094 bug, Dave Coffin (dcoffin@shore.net) 11/12/98
107
112
adjtime file, so see documentation of that file for details.
108
113
Exception is <dirty>, which is an indication that what's in this
109
114
structure is not what's in the disk file (because it has been
110
updated since read from the disk file).
115
updated since read from the disk file).
116
121
time_t last_adj_time;
117
122
double not_adjusted;
236
241
Return them as the adjtime structure <*adjtime_p>.
237
242
If there is no /etc/adjtime file, return defaults.
238
243
If values are missing from the file, return defaults for them.
240
245
return value 0 if all OK, !=0 otherwise.
242
247
-----------------------------------------------------------------------------*/
267
272
char line2[81]; /* String: second line of adjtime file */
268
273
char line3[81]; /* String: third line of adjtime file */
271
line1[0] = '\0'; /* In case fgets fails */
272
fgets(line1, sizeof(line1), adjfile);
273
line2[0] = '\0'; /* In case fgets fails */
274
fgets(line2, sizeof(line2), adjfile);
275
line3[0] = '\0'; /* In case fgets fails */
276
fgets(line3, sizeof(line3), adjfile);
276
if (!fgets(line1, sizeof(line1), adjfile))
277
line1[0] = '\0'; /* In case fgets fails */
278
if (!fgets(line2, sizeof(line2), adjfile))
279
line2[0] = '\0'; /* In case fgets fails */
280
if (!fgets(line3, sizeof(line3), adjfile))
281
line3[0] = '\0'; /* In case fgets fails */
280
285
/* Set defaults in case values are missing from file */
281
286
adjtime_p->drift_factor = 0;
282
287
adjtime_p->last_adj_time = 0;
283
288
adjtime_p->not_adjusted = 0;
284
289
adjtime_p->last_calib_time = 0;
287
sscanf(line1, "%lf %ld %lf",
292
sscanf(line1, "%lf %ld %lf",
288
293
&adjtime_p->drift_factor,
290
295
&adjtime_p->not_adjusted);
291
296
adjtime_p->last_adj_time = timeval;
310
315
adjtime_p->dirty = FALSE;
313
printf(_("Last drift adjustment done at %ld seconds after 1969\n"),
318
printf(_("Last drift adjustment done at %ld seconds after 1969\n"),
314
319
(long) adjtime_p->last_adj_time);
315
320
printf(_("Last calibration done at %ld seconds after 1969\n"),
316
321
(long) adjtime_p->last_calib_time);
334
339
once per second, right on the falling edge of the update flag.
336
341
We wait (up to one second) either blocked waiting for an rtc device
337
or in a CPU spin loop. The former is probably not very accurate.
342
or in a CPU spin loop. The former is probably not very accurate.
339
344
Return 0 if it worked, nonzero if it didn't.
340
345
-----------------------------------------------------------------------------*/
355
mktime_tz(struct tm tm, const bool universal,
360
mktime_tz(struct tm tm, const bool universal,
356
361
bool *valid_p, time_t *systime_p) {
357
362
/*-----------------------------------------------------------------------------
358
363
Convert a time in broken down format (hours, minutes, etc.) into standard
374
379
time_t mktime_result; /* The value returned by our mktime() call */
375
380
char *zone; /* Local time zone name */
377
/* We use the C library function mktime(), but since it only works on
378
local time zone input, we may have to fake it out by temporarily
382
/* We use the C library function mktime(), but since it only works on
383
local time zone input, we may have to fake it out by temporarily
379
384
changing the local time zone to UTC.
381
386
zone = getenv("TZ"); /* remember original time zone */
406
411
*systime_p = mktime_result;
408
413
printf(_("Hw clock time : %4d/%.2d/%.2d %.2d:%.2d:%.2d = "
409
414
"%ld seconds since 1969\n"),
410
415
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
444
set_hardware_clock(const time_t newtime,
445
const bool universal,
449
set_hardware_clock(const time_t newtime,
450
const bool universal,
446
451
const bool testing) {
447
452
/*----------------------------------------------------------------------------
448
453
Set the Hardware Clock to the time <newtime>, in local time zone or UTC,
449
454
according to <universal>.
450
455
----------------------------------------------------------------------------*/
452
struct tm new_broken_time;
457
struct tm new_broken_time;
453
458
/* Time to which we will set Hardware Clock, in broken down format, in
454
459
the time zone of caller's choice
460
465
new_broken_time = *localtime(&newtime);
463
468
printf(_("Setting Hardware Clock to %.2d:%.2d:%.2d "
464
"= %ld seconds since 1969\n"),
465
new_broken_time.tm_hour, new_broken_time.tm_min,
469
"= %ld seconds since 1969\n"),
470
new_broken_time.tm_hour, new_broken_time.tm_min,
466
471
new_broken_time.tm_sec, (long) newtime);
487
set_hardware_clock_exact(const time_t sethwtime,
492
set_hardware_clock_exact(const time_t sethwtime,
488
493
const struct timeval refsystime,
489
const bool universal,
494
const bool universal,
490
495
const bool testing) {
491
496
/*----------------------------------------------------------------------------
492
497
Set the Hardware Clock to the time "sethwtime", in local time zone or UTC,
500
505
to 14:03:07, thus getting a precise and retroactive setting of the clock.
502
507
(Don't be confused by the fact that the system clock and the Hardware
503
Clock differ by two hours in the above example. That's just to remind
508
Clock differ by two hours in the above example. That's just to remind
504
509
you that there are two independent time scales here).
506
511
This function ought to be able to accept set times as fractional times.
514
519
gettimeofday(&beginsystime, NULL);
515
520
newhwtime = sethwtime + (int) time_diff(beginsystime, refsystime) + 1;
517
522
printf(_("Time elapsed since reference time has been %.6f seconds.\n"
518
523
"Delaying further to reach the next full second.\n"),
519
524
time_diff(beginsystime, refsystime));
521
/* Now delay some more until Hardware Clock time newhwtime arrives */
527
* Now delay some more until Hardware Clock time newhwtime arrives. The -500
528
* ms is because the Hardware Clock always sets to your set time plus 500 ms
529
* (because it is designed to update to the next second precisely 500 ms
530
* after you finish the setting).
524
534
gettimeofday(&nowsystime, NULL);
525
535
tdiff = time_diff(nowsystime, beginsystime);
527
537
goto time_resync; /* probably time was reset */
528
} while (time_diff(nowsystime, refsystime) < newhwtime - sethwtime);
538
} while (time_diff(nowsystime, refsystime) - 0.5 < newhwtime - sethwtime);
530
540
set_hardware_clock(newhwtime, universal, testing);
536
display_time(const bool hclock_valid, const time_t systime,
546
display_time(const bool hclock_valid, const time_t systime,
537
547
const double sync_duration) {
538
548
/*----------------------------------------------------------------------------
539
549
Put the time "systime" on standard output in display format.
565
575
Interpret the value of the --date option, which is something like
566
576
"13:05:01". In fact, it can be any of the myriad ASCII strings that specify
567
577
a time which the "date" program can understand. The date option value in
568
question is our "dateopt" argument.
578
question is our "dateopt" argument.
570
580
The specified time is in the local time zone.
620
date_resp[0] = '\0'; /* in case fgets fails */
621
fgets(date_resp, sizeof(date_resp), date_child_fp);
630
if (!fgets(date_resp, sizeof(date_resp), date_child_fp))
631
date_resp[0] = '\0'; /* in case fgets fails */
623
633
printf(_("response from date command = %s\n"), date_resp);
624
634
if (strncmp(date_resp, magic, sizeof(magic)-1) != 0) {
625
635
fprintf(stderr, _("The date command issued by %s returned "
626
636
"unexpected results.\n"
627
637
"The command was:\n %s\n"
628
"The response was:\n %s\n"),
638
"The response was:\n %s\n"),
629
639
MYNAME, date_command, date_resp);
661
set_system_clock(const bool hclock_valid, const time_t newtime,
671
set_system_clock(const bool hclock_valid, const time_t newtime,
662
672
const bool testing) {
663
673
/*----------------------------------------------------------------------------
664
674
Set the System Clock to time 'newtime'.
666
Also set the kernel time zone value to the value indicated by the
676
Also set the kernel time zone value to the value indicated by the
667
677
TZ environment variable and/or /usr/lib/zoneinfo/, interpreted as
668
678
tzset() would interpret them.
685
695
struct tm *broken;
689
699
tv.tv_sec = newtime;
692
702
broken = localtime(&newtime);
693
#ifdef HAVE_tm_gmtoff
703
#ifdef HAVE_TM_GMTOFF
694
704
minuteswest = -broken->tm_gmtoff/60; /* GNU extension */
696
706
minuteswest = timezone/60;
697
707
if (broken->tm_isdst)
698
708
minuteswest -= 60;
702
712
printf(_("Calling settimeofday:\n"));
703
713
printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
924
934
do_adjustment(struct adjtime *adjtime_p,
925
const bool hclock_valid, const time_t hclocktime,
935
const bool hclock_valid, const time_t hclocktime,
926
936
const struct timeval read_time,
927
937
const bool universal, const bool testing) {
928
938
/*---------------------------------------------------------------------------
929
Do the adjustment requested, by 1) setting the Hardware Clock (if
939
Do the adjustment requested, by 1) setting the Hardware Clock (if
930
940
necessary), and 2) updating the last-adjusted time in the adjtime
939
949
<hclock_valid> means the Hardware Clock contains a valid time, and that
940
950
time is <hclocktime>.
942
<read_time> is the current system time (to be precise, it is the system
952
<read_time> is the current system time (to be precise, it is the system
943
953
time at the time <hclocktime> was read, which due to computational delay
944
954
could be a short time ago).
978
988
&adjustment, &retro,
980
990
if (adjustment > 0 || adjustment < -1) {
981
set_hardware_clock_exact(hclocktime + adjustment,
991
set_hardware_clock_exact(hclocktime + adjustment,
982
992
time_inc(read_time, -retro),
983
993
universal, testing);
984
994
adjtime_p->last_adj_time = hclocktime + adjustment;
985
995
adjtime_p->not_adjusted = 0;
986
996
adjtime_p->dirty = TRUE;
989
999
printf(_("Needed adjustment is less than one second, "
990
1000
"so not setting clock.\n"));
1022
1032
manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
1023
1033
const bool set, const time_t set_time,
1024
const bool hctosys, const bool systohc,
1025
const struct timeval startup_time,
1034
const bool hctosys, const bool systohc,
1035
const struct timeval startup_time,
1026
1036
const bool utc, const bool local_opt,
1027
1037
const bool testing) {
1028
1038
/*---------------------------------------------------------------------------
1078
1088
synchronized to its next clock tick when we started up.
1079
1089
Defined only if hclock_valid is true.
1082
1092
gettimeofday(&read_time, NULL);
1083
read_hardware_clock(universal, &hclock_valid, &hclocktime);
1093
read_hardware_clock(universal, &hclock_valid, &hclocktime);
1086
display_time(hclock_valid, hclocktime,
1096
display_time(hclock_valid, hclocktime,
1087
1097
time_diff(read_time, startup_time));
1088
1098
} else if (set) {
1089
set_hardware_clock_exact(set_time, startup_time,
1099
set_hardware_clock_exact(set_time, startup_time,
1090
1100
universal, testing);
1091
1101
adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime,
1092
1102
time_diff(read_time, startup_time));
1093
1103
} else if (adjust) {
1094
do_adjustment(&adjtime, hclock_valid, hclocktime,
1104
do_adjustment(&adjtime, hclock_valid, hclocktime,
1095
1105
read_time, universal, testing);
1096
1106
} else if (systohc) {
1097
1107
struct timeval nowtime, reftime;
1098
1108
/* We can only set_hardware_clock_exact to a whole seconds
1099
1109
time, so we set it with reference to the most recent
1102
1112
gettimeofday(&nowtime, NULL);
1103
1113
reftime.tv_sec = nowtime.tv_sec;
1104
1114
reftime.tv_usec = 0;
1106
set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
1116
set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
1107
1117
universal, testing);
1108
adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
1118
adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
1109
1119
hclocktime, (double) read_time.tv_usec / 1E6);
1110
1120
} else if (hctosys) {
1111
1121
rc = set_system_clock(hclock_valid, hclocktime, testing);
1126
manipulate_epoch(const bool getepoch, const bool setepoch,
1136
manipulate_epoch(const bool getepoch, const bool setepoch,
1127
1137
const int epoch_opt, const bool testing) {
1128
1138
/*----------------------------------------------------------------------------
1129
1139
Get or set the Hardware Clock epoch value in the kernel, as appropriate.
1134
1144
-----------------------------------------------------------------------------*/
1136
Maintenance note: This should work on non-Alpha machines, but the
1146
Maintenance note: This should work on non-Alpha machines, but the
1137
1147
evidence today (98.03.04) indicates that the kernel only keeps the
1138
1148
epoch value on Alphas. If that is ever fixed, this function should be
1175
1185
out_version(void) {
1176
printf(_("%s from %s\n"), MYNAME, util_linux_version);
1186
printf(_("%s from %s\n"), MYNAME, PACKAGE_STRING);
1180
1190
usage - Output (error and) usage information
1182
This function is called both directly from main to show usage
1183
information and as fatal function from shhopt if some argument is
1184
not understood. In case of normal usage info FMT should be NULL.
1185
In that case the info is printed to stdout. If FMT is given
1186
usage will act like fprintf( stderr, fmt, ... ), show a usage
1192
This function is called both directly from main to show usage
1193
information and as fatal function from shhopt if some argument is
1194
not understood. In case of normal usage info FMT should be NULL.
1195
In that case the info is printed to stdout. If FMT is given
1196
usage will act like fprintf( stderr, fmt, ... ), show a usage
1187
1197
information and terminate the program afterwards.
1190
1200
usage( const char *fmt, ... ) {
1211
1221
"\nOptions: \n"
1212
1222
" --utc the hardware clock is kept in coordinated universal time\n"
1213
1223
" --localtime the hardware clock is kept in local time\n"
1224
" --rtc=path special /dev/... file to use instead of default\n"
1214
1225
" --directisa access the ISA bus directly instead of %s\n"
1215
1226
" --badyear ignore rtc's year because the bios is broken\n"
1216
1227
" --date specifies the time to which to set the hardware clock\n"
1278
1290
* 0: OK (or not)
1282
1294
main(int argc, char **argv) {
1284
1296
struct timeval startup_time;
1285
1297
/* The time we started up, in seconds into the epoch, including
1287
time_t set_time; /* Time to which user said to set Hardware Clock */
1299
time_t set_time = 0; /* Time to which user said to set Hardware Clock */
1289
1301
bool permitted; /* User is permitted to do the function */
1299
1311
/* Remember what time we were invoked */
1300
1312
gettimeofday(&startup_time, NULL);
1314
#ifdef HAVE_LIBAUDIT
1315
hwaudit_fd = audit_open();
1316
if (hwaudit_fd < 0 && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
1317
errno == EAFNOSUPPORT)) {
1318
/* You get these error codes only when the kernel doesn't have
1319
* audit compiled in. */
1320
fprintf(stderr, _("%s: Unable to connect to audit system\n"),
1302
1325
setlocale(LC_ALL, "");
1303
1326
#ifdef LC_NUMERIC
1304
1327
/* We need LC_CTYPE and LC_TIME and LC_MESSAGES, but must avoid
1315
1338
ARCconsole = Jensen = SRM = funky_toy = directisa = badyear = FALSE;
1316
1339
date_opt = NULL;
1318
while ((c = getopt_long (argc, argv, "?hvVDarsuwAJSF", longopts, NULL))
1341
while ((c = getopt_long (argc, argv, "?hvVDarsuwAJSFf:", longopts, NULL))
1404
1438
fprintf(stderr, _("You have specified multiple functions.\n"
1405
1439
"You can only perform one function "
1406
1440
"at a time.\n"));
1441
hwclock_exit(EX_USAGE);
1410
1444
if (utc && local_opt) {
1411
1445
fprintf(stderr, _("%s: The --utc and --localtime options "
1412
1446
"are mutually exclusive. You specified "
1413
1447
"both.\n"), MYNAME);
1448
hwclock_exit(EX_USAGE);
1417
1451
if (adjust && noadjfile) {
1418
1452
fprintf(stderr, _("%s: The --adjust and --noadjfile options "
1419
1453
"are mutually exclusive. You specified "
1420
1454
"both.\n"), MYNAME);
1455
hwclock_exit(EX_USAGE);
1424
1458
if (noadjfile && !(utc || local_opt)) {
1425
1459
fprintf(stderr, _("%s: With --noadjfile, you must specify "
1426
1460
"either --utc or --localtime\n"), MYNAME);
1461
hwclock_exit(EX_USAGE);
1430
1464
#ifdef __alpha__
1439
1473
fprintf(stderr, _("No usable set-to time. "
1440
1474
"Cannot set clock.\n"));
1475
hwclock_exit(EX_USAGE);
1445
if (!(show | set | systohc | hctosys | adjust | getepoch | setepoch))
1479
if (!(show | set | systohc | hctosys | adjust | getepoch | setepoch))
1446
1480
show = 1; /* default to show */
1449
1483
if (getuid() == 0)
1450
1484
permitted = TRUE;
1452
1486
/* program is designed to run setuid (in some situations) */
1453
1487
if (set || hctosys || systohc || adjust) {
1455
1489
_("Sorry, only the superuser can change "
1456
1490
"the Hardware Clock.\n"));
1457
1491
permitted = FALSE;
1488
1522
fprintf(stderr,
1489
1523
_("Use the --debug option to see the details "
1490
1524
"of our search for an access method.\n"));
1494
return manipulate_clock(show, adjust, noadjfile, set, set_time,
1528
rc = manipulate_clock(show, adjust, noadjfile, set, set_time,
1495
1529
hctosys, systohc, startup_time, utc,
1496
1530
local_opt, testing);
1532
return rc; /* Not reached */
1499
1535
/* A single routine for greater uniformity */
1510
1546
errsv, strerror(errsv));
1550
#ifdef HAVE_LIBAUDIT
1552
hwaudit_exit(int status)
1555
audit_log_user_message(hwaudit_fd, AUDIT_USYS_CONFIG,
1556
"changing system time", NULL, NULL, NULL, status ? 0 : 1);
1513
1563
/****************************************************************************
1515
1565
History of this program:
1517
98.08.12 BJH Version 2.4
1567
98.08.12 BJH Version 2.4
1519
1569
Don't use century byte from Hardware Clock. Add comments telling why.
1524
1574
Make --hctosys set the kernel timezone from TZ environment variable
1525
1575
and/or /usr/lib/zoneinfo. From Klaus Ripke (klaus@ripke.com).
1527
98.03.05 BJH. Version 2.2.
1577
98.03.05 BJH. Version 2.2.
1529
Add --getepoch and --setepoch.
1579
Add --getepoch and --setepoch.
1531
1581
Fix some word length things so it works on Alpha.
1560
1610
in this program will be compiled as external references. Since you
1561
1611
probably won't be linking with any functions by these names, you will
1562
1612
have unresolved external references when you link.
1564
1614
The program is designed to run setuid superuser, since we need to be
1565
able to do direct I/O. (More to the point: we need permission to
1566
execute the iopl() system call). (However, if you use one of the
1615
able to do direct I/O. (More to the point: we need permission to
1616
execute the iopl() system call). (However, if you use one of the
1567
1617
methods other than direct ISA I/O to access the clock, no setuid is
1570
1620
Here's some info on how we must deal with the time that elapses while
1571
1621
this program runs: There are two major delays as we run:
1587
1637
So we check the system time as soon as we start up, then run "date"
1588
1638
and do file I/O if necessary, then wait to synchronize with a
1589
1639
Hardware Clock edge, then check the system time again to see how
1590
much time we spent. We immediately read the clock then and (if
1640
much time we spent. We immediately read the clock then and (if
1591
1641
appropriate) report that time, and additionally, the delay we measured.
1593
1643
If we're setting the clock to a time given by the user, we wait some
1608
1658
complications that might cause, we set the clock as soon as possible
1609
1659
after an oscillator tick.
1612
1662
About synchronizing to the Hardware Clock when reading the time: The
1613
1663
precision of the Hardware Clock counters themselves is one second.
1614
1664
You can't read the counters and find out that is 12:01:02.5. But if