#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
-#define OPTUTILS_EXIT_CODE EX_USAGE
-#define XALLOC_EXIT_CODE EX_OSERR
-
#include "c.h"
#include "closestream.h"
#include "nls.h"
#include "timeutils.h"
#include "env.h"
#include "xalloc.h"
+#include "path.h"
+#include "strutils.h"
#ifdef HAVE_LIBAUDIT
#include <libaudit.h>
static int hwaudit_fd = -1;
#endif
+UL_DEBUG_DEFINE_MASK(hwclock);
+UL_DEBUG_DEFINE_MASKNAMES(hwclock) = UL_DEBUG_EMPTY_MASKNAMES;
+
/* The struct that holds our hardware access routines */
static struct clock_ops *ur;
*/
};
+static void hwclock_init_debug(const char *str)
+{
+ __UL_INIT_DEBUG_FROM_STRING(hwclock, HWCLOCK_DEBUG_, 0, str);
+
+ DBG(INIT, ul_debug("hwclock debug mask: 0x%04x", hwclock_debug_mask));
+ DBG(INIT, ul_debug("hwclock version: %s", PACKAGE_STRING));
+}
+
+/* FOR TESTING ONLY: inject random delays of up to 1000ms */
+static void up_to_1000ms_sleep(void)
+{
+ int usec = random() % 1000000;
+
+ DBG(RANDOM_SLEEP, ul_debug("sleeping ~%d usec", usec));
+ xusleep(usec);
+}
+
/*
* time_t to timeval conversion.
*/
else
/* get info from adjtime file - default is UTC */
ret = (adjtime.local_utc != LOCAL);
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Assuming hardware clock is kept in %s time.\n"),
ret ? _("UTC") : _("local"));
return ret;
/*
* Read the adjustment parameters out of the /etc/adjtime file.
*
- * Return them as the adjtime structure <*adjtime_p>. If there is no
- * /etc/adjtime file, return defaults. If values are missing from the file,
- * return defaults for them.
- *
- * return value 0 if all OK, !=0 otherwise.
+ * Return them as the adjtime structure <*adjtime_p>. Its defaults are
+ * initialized in main().
*/
static int read_adjtime(const struct hwclock_control *ctl,
struct adjtime *adjtime_p)
char line3[81]; /* String: third line of adjtime file */
if (access(ctl->adj_file_name, R_OK) != 0)
- return 0;
+ return EXIT_SUCCESS;
adjfile = fopen(ctl->adj_file_name, "r"); /* open file for reading */
if (adjfile == NULL) {
warn(_("cannot open %s"), ctl->adj_file_name);
- return EX_OSFILE;
+ return EXIT_FAILURE;
}
if (!fgets(line1, sizeof(line1), adjfile))
}
}
- if (ctl->debug) {
+ if (ctl->verbose) {
printf(_
("Last drift adjustment done at %ld seconds after 1969\n"),
(long)adjtime_p->last_adj_time);
UTC) ? _("UTC") : _("unknown"));
}
- return 0;
+ return EXIT_SUCCESS;
}
/*
{
int rc;
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Waiting for clock tick...\n"));
rc = ur->synchronize_to_clock_tick(ctl);
- if (ctl->debug) {
+ if (ctl->verbose) {
if (rc)
printf(_("...synchronization failed\n"));
else
* mktime() returns -1).
*/
valid = 0;
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Invalid values in hardware clock: "
"%4d/%.2d/%.2d %.2d:%.2d:%.2d\n"),
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
} else {
valid = 1;
- if (ctl->debug)
+ if (ctl->verbose)
printf(_
("Hw clock time : %4d/%.2d/%.2d %.2d:%.2d:%.2d = "
"%ld seconds since 1969\n"), tm.tm_year + 1900,
if (err)
return err;
- if (ctl->debug)
+ if (ctl->verbose)
printf(_
("Time read from Hardware Clock: %4d/%.2d/%.2d %02d:%02d:%02d\n"),
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
*/
if (ctl->universal)
- new_broken_time = *gmtime(&newtime);
+ gmtime_r(&newtime, &new_broken_time);
else
- new_broken_time = *localtime(&newtime);
+ localtime_r(&newtime, &new_broken_time);
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Setting Hardware Clock to %.2d:%.2d:%.2d "
"= %ld seconds since 1969\n"),
new_broken_time.tm_hour, new_broken_time.tm_min,
new_broken_time.tm_sec, (long)newtime);
- if (ctl->testing)
- printf(_("Test mode: clock was not changed\n"));
- else
+ if (!ctl->testing)
ur->set_hardware_clock(ctl, &new_broken_time);
}
+static double
+get_hardware_delay(const struct hwclock_control *ctl)
+{
+ const char *devpath, *rtcname;
+ char name[128 + 1];
+ struct path_cxt *pc;
+ int rc;
+
+ devpath = ur->get_device_path();
+ if (!devpath)
+ goto unknown;
+
+ rtcname = strrchr(devpath, '/');
+ if (!rtcname || !*(rtcname + 1))
+ goto unknown;
+ rtcname++;
+
+ pc = ul_new_path("/sys/class/rtc/%s", rtcname);
+ if (!pc)
+ goto unknown;
+ rc = ul_path_scanf(pc, "name", "%128[^\n ]", &name);
+ ul_unref_path(pc);
+
+ if (rc != 1 || !*name)
+ goto unknown;
+
+ if (ctl->verbose)
+ printf(_("RTC type: '%s'\n"), name);
+
+ /* MC146818A-compatible (x86) */
+ if (strcmp(name, "rtc_cmos") == 0)
+ return 0.5;
+
+ /* Another HW */
+ return 0;
+unknown:
+ /* Let's be backwardly compatible */
+ return 0.5;
+}
+
+
/*
* Set the Hardware Clock to the time "sethwtime", in local time zone or
* UTC, according to "universal".
* example, if "sethwtime" is 14:03:05 and "refsystime" is 12:10:04.5 and
* the current system time is 12:10:06.0: Wait .5 seconds (to make exactly 2
* seconds since "refsystime") and then set the Hardware Clock to 14:03:07,
- * thus getting a precise and retroactive setting of the clock.
+ * thus getting a precise and retroactive setting of the clock. The .5 delay is
+ * default on x86, see --delay and get_hardware_delay().
*
* (Don't be confused by the fact that the system clock and the Hardware
* Clock differ by two hours in the above example. That's just to remind you
time_t newhwtime = sethwtime;
double target_time_tolerance_secs = 0.001; /* initial value */
double tolerance_incr_secs = 0.001; /* initial value */
- const double RTC_SET_DELAY_SECS = 0.5; /* 500 ms */
- const struct timeval RTC_SET_DELAY_TV = { 0, RTC_SET_DELAY_SECS * 1E6 };
+ double delay;
+ struct timeval rtc_set_delay_tv;
struct timeval targetsystime;
struct timeval nowsystime;
struct timeval prevsystime = refsystime;
double deltavstarget;
- timeradd(&refsystime, &RTC_SET_DELAY_TV, &targetsystime);
+ if (ctl->rtc_delay != -1.0) /* --delay specified */
+ delay = ctl->rtc_delay;
+ else
+ delay = get_hardware_delay(ctl);
+
+ if (ctl->verbose)
+ printf(_("Using delay: %.6f seconds\n"), delay);
+
+ rtc_set_delay_tv.tv_sec = 0;
+ rtc_set_delay_tv.tv_usec = delay * 1E6;
+
+ timeradd(&refsystime, &rtc_set_delay_tv, &targetsystime);
while (1) {
double ticksize;
- /* FOR TESTING ONLY: inject random delays of up to 1000ms */
- if (ctl->debug >= 10) {
- int usec = random() % 1000000;
- printf(_("sleeping ~%d usec\n"), usec);
- xusleep(usec);
- }
+ ON_DBG(RANDOM_SLEEP, up_to_1000ms_sleep());
gettimeofday(&nowsystime, NULL);
deltavstarget = time_diff(nowsystime, targetsystime);
prevsystime = nowsystime;
if (ticksize < 0) {
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("time jumped backward %.6f seconds "
"to %ld.%06ld - retargeting\n"),
ticksize, nowsystime.tv_sec,
/* The retarget is handled at the end of the loop. */
} else if (deltavstarget < 0) {
/* deltavstarget < 0 if current time < target time */
- if (ctl->debug >= 2)
- printf(_("%ld.%06ld < %ld.%06ld (%.6f)\n"),
- nowsystime.tv_sec,
- nowsystime.tv_usec,
- targetsystime.tv_sec,
- targetsystime.tv_usec,
- deltavstarget);
+ DBG(DELTA_VS_TARGET,
+ ul_debug("%ld.%06ld < %ld.%06ld (%.6f)",
+ nowsystime.tv_sec, nowsystime.tv_usec,
+ targetsystime.tv_sec,
+ targetsystime.tv_usec, deltavstarget));
continue; /* not there yet - keep spinning */
} else if (deltavstarget <= target_time_tolerance_secs) {
/* Close enough to the target time; done waiting. */
* We missed our window. Increase the tolerance and
* aim for the next opportunity.
*/
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("missed it - %ld.%06ld is too far "
"past %ld.%06ld (%.6f > %.6f)\n"),
nowsystime.tv_sec,
newhwtime = sethwtime
+ (int)(time_diff(nowsystime, refsystime)
- - RTC_SET_DELAY_SECS /* don't count this */
+ - delay /* don't count this */
+ 0.5 /* for rounding */);
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("%ld.%06ld is close enough to %ld.%06ld (%.6f < %.6f)\n"
"Set RTC to %ld (%ld + %d; refsystime = %ld.%06ld)\n"),
nowsystime.tv_sec, nowsystime.tv_usec,
set_hardware_clock(ctl, newhwtime);
}
-static void
+static int
display_time(struct timeval hwctime)
{
- char buf[ISO_8601_BUFSIZ];
+ char buf[ISO_BUFSIZ];
+
+ if (strtimeval_iso(&hwctime, ISO_TIMESTAMP_DOT, buf, sizeof(buf)))
+ return EXIT_FAILURE;
- strtimeval_iso(&hwctime, ISO_8601_DATE|ISO_8601_TIME|ISO_8601_DOTUSEC|
- ISO_8601_TIMEZONE|ISO_8601_SPACE,
- buf, sizeof(buf));
printf("%s\n", buf);
+ return EXIT_SUCCESS;
}
/*
set_system_clock(const struct hwclock_control *ctl,
const struct timeval newtime)
{
- struct tm *broken;
+ struct tm broken;
int minuteswest;
int rc = 0;
const struct timezone tz_utc = { 0 };
- broken = localtime(&newtime.tv_sec);
-#ifdef HAVE_TM_GMTOFF
- minuteswest = -broken->tm_gmtoff / 60; /* GNU extension */
-#else
- minuteswest = timezone / 60;
- if (broken->tm_isdst)
- minuteswest -= 60;
-#endif
+ localtime_r(&newtime.tv_sec, &broken);
+ minuteswest = -get_gmtoff(&broken) / 60;
- if (ctl->debug) {
+ if (ctl->verbose) {
if (ctl->hctosys && !ctl->universal)
printf(_("Calling settimeofday(NULL, %d) to set "
"persistent_clock_is_local.\n"), minuteswest);
}
}
- if (ctl->testing) {
- printf(_
- ("Test mode: clock was not changed\n"));
- } else {
+ if (!ctl->testing) {
const struct timezone tz = { minuteswest };
if (ctl->hctosys && !ctl->universal) /* set PCIL */
if (rc) {
warn(_("settimeofday() failed"));
- return 1;
+ return EXIT_FAILURE;
}
}
- return 0;
+ return EXIT_SUCCESS;
}
/*
const struct timeval hclocktime)
{
if (!ctl->update) {
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Not adjusting drift factor because the "
"--update-drift option was not used.\n"));
} else if (adjtime_p->last_calib_time == 0) {
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Not adjusting drift factor because last "
"calibration time is zero,\n"
"so history is bad and calibration startover "
"is necessary.\n"));
} else if ((hclocktime.tv_sec - adjtime_p->last_calib_time) < 4 * 60 * 60) {
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Not adjusting drift factor because it has "
"been less than four hours since the last "
"calibration.\n"));
drift_factor = adjtime_p->drift_factor + factor_adjust;
if (fabs(drift_factor) > MAX_DRIFT) {
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Clock drift factor was calculated as "
"%f seconds/day.\n"
"It is far too much. Resetting to zero.\n"),
drift_factor);
drift_factor = 0;
} else {
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Clock drifted %f seconds in the past "
"%f seconds\nin spite of a drift factor of "
"%f seconds/day.\n"
tdrift_p->tv_sec = (time_t) floor(exact_adjustment);
tdrift_p->tv_usec = (exact_adjustment -
(double)tdrift_p->tv_sec) * 1E6;
- if (ctl->debug) {
+ if (ctl->verbose) {
printf(P_("Time since last adjustment is %ld second\n",
"Time since last adjustment is %ld seconds\n",
(systime - last_time)),
* But if the contents are clean (unchanged since read from disk), don't
* bother.
*/
-static void save_adjtime(const struct hwclock_control *ctl,
+static int save_adjtime(const struct hwclock_control *ctl,
const struct adjtime *adjtime)
{
char *content; /* Stuff to write to disk file */
FILE *fp;
- int err = 0;
-
- if (!adjtime->dirty)
- return;
xasprintf(&content, "%f %ld %f\n%ld\n%s\n",
adjtime->drift_factor,
adjtime->last_calib_time,
(adjtime->local_utc == LOCAL) ? "LOCAL" : "UTC");
- if (ctl->testing) {
- if (ctl->debug){
- printf(_("Test mode: %s was not updated with:\n%s"),
- ctl->adj_file_name, content);
- }
- free(content);
- return;
+ if (ctl->verbose){
+ printf(_("New %s data:\n%s"),
+ ctl->adj_file_name, content);
}
- fp = fopen(ctl->adj_file_name, "w");
- if (fp == NULL) {
- warn(_("Could not open file with the clock adjustment parameters "
- "in it (%s) for writing"), ctl->adj_file_name);
- err = 1;
- } else if (fputs(content, fp) < 0 || close_stream(fp) != 0) {
- warn(_("Could not update file with the clock adjustment "
- "parameters (%s) in it"), ctl->adj_file_name);
- err = 1;
+ if (!ctl->testing) {
+ fp = fopen(ctl->adj_file_name, "w");
+ if (fp == NULL) {
+ warn(_("cannot open %s"), ctl->adj_file_name);
+ return EXIT_FAILURE;
+ } else if (fputs(content, fp) < 0 || close_stream(fp) != 0) {
+ warn(_("cannot update %s"), ctl->adj_file_name);
+ return EXIT_FAILURE;
+ }
}
- free(content);
- if (err)
- warnx(_("Drift adjustment parameters not updated."));
+ return EXIT_SUCCESS;
}
/*
const struct timeval read_time)
{
if (adjtime_p->last_adj_time == 0) {
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Not setting clock because last adjustment time is zero, "
"so history is bad.\n"));
} else if (fabs(adjtime_p->drift_factor) > MAX_DRIFT) {
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("Not setting clock because drift factor %f is far too high.\n"),
adjtime_p->drift_factor);
} else {
ur = probe_for_rtc_clock(ctl);
#endif
if (ur) {
- if (ctl->debug)
+ if (ctl->verbose)
puts(ur->interface_name);
} else {
- if (ctl->debug)
+ if (ctl->verbose)
printf(_("No usable clock interface found.\n"));
warnx(_("Cannot access the Hardware Clock via "
"any known method."));
- if (!ctl->debug)
- warnx(_("Use the --debug option to see the "
+ if (!ctl->verbose)
+ warnx(_("Use the --verbose option to see the "
"details of our search for an access "
"method."));
- hwclock_exit(ctl, EX_SOFTWARE);
+ hwclock_exit(ctl, EXIT_FAILURE);
}
}
-/*
- * Do all the normal work of hwclock - read, set clock, etc.
- *
- * Issue output to stdout and error message to stderr where appropriate.
- *
- * Return rc == 0 if everything went OK, rc != 0 if not.
- */
+/* Do all the normal work of hwclock - read, set clock, etc. */
static int
manipulate_clock(const struct hwclock_control *ctl, const time_t set_time,
const struct timeval startup_time, struct adjtime *adjtime)
hclocktime.tv_sec, &tdrift);
hclocktime = time_inc(hclocktime, (double)
-(tdrift.tv_sec + tdrift.tv_usec / 1E6));
- if (ctl->debug) {
+ if (ctl->verbose) {
printf(_ ("Target date: %ld\n"), set_time);
printf(_ ("Predicted RTC: %ld\n"), hclocktime.tv_sec);
}
- display_time(hclocktime);
- return 0;
+ return display_time(hclocktime);
}
if (ctl->systz)
return set_system_clock(ctl, startup_time);
if (ur->get_permissions())
- return EX_NOPERM;
+ return EXIT_FAILURE;
/*
* Read and drift correct RTC time; except for RTC set functions
* operations are invalid without it.
*/
if (synchronize_to_clock_tick(ctl))
- return EX_IOERR;
+ return EXIT_FAILURE;
read_hardware_clock(ctl, &hclock_valid, &hclocktime.tv_sec);
gettimeofday(&read_time, NULL);
if (!hclock_valid) {
warnx(_("RTC read returned an invalid value."));
- return EX_IOERR;
+ return EXIT_FAILURE;
}
/*
* Calculate and apply drift correction to the Hardware Clock
time_inc(hclocktime, time_diff(startup_time, read_time));
}
if (ctl->show || ctl->get) {
- display_time(startup_hclocktime);
+ return display_time(startup_hclocktime);
} else if (ctl->set) {
set_hardware_clock_exact(ctl, set_time, startup_time);
if (!ctl->noadjfile)
} else if (ctl->hctosys) {
return set_system_clock(ctl, hclocktime);
}
- if (!ctl->noadjfile)
- save_adjtime(ctl, adjtime);
- return 0;
+ if (!ctl->noadjfile && adjtime->dirty)
+ return save_adjtime(ctl, adjtime);
+ return EXIT_SUCCESS;
}
/**
} else if (ctl->setepoch) {
if (!ctl->epoch_option)
warnx(_("--epoch is required for --setepoch."));
- else if (ctl->testing)
- printf(_("Test mode: epoch was not set to %s.\n"),
- ctl->epoch_option);
- else if (set_epoch_rtc(ctl))
- warnx(_("unable to set the RTC epoch."));
+ else if (!ctl->testing)
+ if (set_epoch_rtc(ctl))
+ warnx(_("unable to set the RTC epoch."));
}
}
#endif /* __linux__ __alpha__ */
}
static void __attribute__((__noreturn__))
-usage(const struct hwclock_control *ctl)
+usage(void)
{
fputs(USAGE_HEADER, stdout);
printf(_(" %s [function] [option...]\n"), program_invocation_short_name);
puts(_(" -s, --hctosys set the system time from the RTC"));
puts(_(" -w, --systohc set the RTC from the system time"));
puts(_(" --systz send timescale configurations to the kernel"));
- puts(_(" --adjust adjust the RTC to account for systematic drift"));
+ puts(_(" -a, --adjust adjust the RTC to account for systematic drift"));
#if defined(__linux__) && defined(__alpha__)
puts(_(" --getepoch display the RTC epoch"));
puts(_(" --setepoch set the RTC epoch according to --epoch"));
printf(_(
" --directisa use the ISA bus instead of %1$s access\n"), _PATH_RTC_DEV);
puts(_(" --date <time> date/time input for --set and --predict"));
+ puts(_(" --delay <sec> delay used when set new RTC time"));
#if defined(__linux__) && defined(__alpha__)
puts(_(" --epoch <year> epoch input for --setepoch"));
#endif
" --noadjfile do not use %1$s\n"), _PATH_ADJTIME);
printf(_(
" --adjfile <file> use an alternate file to %1$s\n"), _PATH_ADJTIME);
- puts(_(" --test dry run; use -D to view what would have happened"));
- puts(_(" -D, --debug use debug mode"));
+ puts(_(" --test dry run; implies --verbose"));
+ puts(_(" -v, --verbose display more details"));
fputs(USAGE_SEPARATOR, stdout);
printf(USAGE_HELP_OPTIONS(22));
printf(USAGE_MAN_TAIL("hwclock(8)"));
- hwclock_exit(ctl, EXIT_SUCCESS);
+ exit(EXIT_SUCCESS);
}
-/*
- * Returns:
- * EX_USAGE: bad invocation
- * EX_NOPERM: no permission
- * EX_OSFILE: cannot open /dev/rtc or /etc/adjtime
- * EX_IOERR: ioctl error getting or setting the time
- * 0: OK (or not)
- * 1: failure
- */
int main(int argc, char **argv)
{
- struct hwclock_control ctl = { .show = 1 }; /* default op is show */
+ struct hwclock_control ctl = {
+ .show = 1, /* default op is show */
+ .rtc_delay = -1.0 /* unspecified */
+ };
struct timeval startup_time;
struct adjtime adjtime = { 0 };
struct timespec when = { 0 };
enum {
OPT_ADJFILE = CHAR_MAX + 1,
OPT_DATE,
+ OPT_DELAY,
OPT_DIRECTISA,
OPT_EPOCH,
OPT_GET,
{ "show", no_argument, NULL, 'r' },
{ "hctosys", no_argument, NULL, 's' },
{ "utc", no_argument, NULL, 'u' },
- { "version", no_argument, NULL, 'v' },
+ { "version", no_argument, NULL, 'V' },
{ "systohc", no_argument, NULL, 'w' },
{ "debug", no_argument, NULL, 'D' },
+ { "ul-debug", required_argument, NULL, 'd' },
+ { "verbose", no_argument, NULL, 'v' },
{ "set", no_argument, NULL, OPT_SET },
#if defined(__linux__) && defined(__alpha__)
{ "getepoch", no_argument, NULL, OPT_GETEPOCH },
{ "directisa", no_argument, NULL, OPT_DIRECTISA },
{ "test", no_argument, NULL, OPT_TEST },
{ "date", required_argument, NULL, OPT_DATE },
+ { "delay", required_argument, NULL, OPT_DELAY },
#ifdef __linux__
{ "rtc", required_argument, NULL, 'f' },
#endif
* have audit compiled in.
*/
warnx(_("Unable to connect to audit system"));
- return EX_NOPERM;
+ return EXIT_FAILURE;
}
#endif
setlocale(LC_ALL, "");
atexit(close_stdout);
while ((c = getopt_long(argc, argv,
- "hvVDalrsuwf:", longopts, NULL)) != -1) {
+ "hvVDd:alrsuwf:", longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st);
switch (c) {
case 'D':
- ctl.debug++;
+ warnx(_("use --verbose, --debug has been deprecated."));
+ break;
+ case 'v':
+ ctl.verbose = 1;
+ break;
+ case 'd':
+ hwclock_init_debug(optarg);
break;
case 'a':
ctl.adjust = 1;
break;
case OPT_TEST:
ctl.testing = 1; /* --test */
+ ctl.verbose = 1;
break;
case OPT_DATE:
ctl.date_opt = optarg; /* --date */
break;
+ case OPT_DELAY:
+ ctl.rtc_delay = strtod_or_err(optarg, "invalid --delay argument");
+ break;
case OPT_ADJFILE:
ctl.adj_file_name = optarg; /* --adjfile */
break;
ctl.rtc_dev_name = optarg; /* --rtc */
break;
#endif
- case 'v': /* --version */
- case 'V':
+ case 'V': /* --version */
out_version();
return 0;
case 'h': /* --help */
- usage(&ctl);
+ usage();
default:
- errtryhelp(EX_USAGE);
+ errtryhelp(EXIT_FAILURE);
}
}
if (argc -= optind) {
warnx(_("%d too many arguments given"), argc);
- errtryhelp(EX_USAGE);
+ errtryhelp(EXIT_FAILURE);
}
if (!ctl.adj_file_name)
if (ctl.update && !ctl.set && !ctl.systohc) {
warnx(_("--update-drift requires --set or --systohc"));
- hwclock_exit(&ctl, EX_USAGE);
+ exit(EXIT_FAILURE);
}
if (ctl.noadjfile && !ctl.utc && !ctl.local_opt) {
warnx(_("With --noadjfile, you must specify "
"either --utc or --localtime"));
- hwclock_exit(&ctl, EX_USAGE);
+ exit(EXIT_FAILURE);
}
if (ctl.set || ctl.predict) {
if (!ctl.date_opt) {
warnx(_("--date is required for --set or --predict"));
- hwclock_exit(&ctl, EX_USAGE);
+ exit(EXIT_FAILURE);
}
if (parse_date(&when, ctl.date_opt, NULL))
set_time = when.tv_sec;
else {
warnx(_("invalid date '%s'"), ctl.date_opt);
- hwclock_exit(&ctl, EX_USAGE);
+ exit(EXIT_FAILURE);
}
}
#if defined(__linux__) && defined(__alpha__)
if (ctl.getepoch || ctl.setepoch) {
manipulate_epoch(&ctl);
- hwclock_exit(&ctl, EX_OK);
+ hwclock_exit(&ctl, EXIT_SUCCESS);
}
#endif
- if (ctl.debug) {
+ if (ctl.verbose) {
out_version();
printf(_("System Time: %ld.%06ld\n"),
startup_time.tv_sec, startup_time.tv_usec);
adjtime.dirty = 0;
ctl.universal = hw_clock_is_utc(&ctl, adjtime);
rc = manipulate_clock(&ctl, set_time, startup_time, &adjtime);
+ if (ctl.testing)
+ puts(_("Test mode: nothing was changed."));
hwclock_exit(&ctl, rc);
return rc; /* Not reached */
}
if (ctl->hwaudit_on && !ctl->testing) {
audit_log_user_message(hwaudit_fd, AUDIT_USYS_CONFIG,
"op=change-system-time", NULL, NULL, NULL,
- status ? 0 : 1);
- close(hwaudit_fd);
+ status);
}
+ close(hwaudit_fd);
#endif
exit(status);
}