]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
hwclock: move command-line options to control structure
authorSami Kerola <kerolasa@iki.fi>
Sat, 16 Jul 2016 15:45:07 +0000 (16:45 +0100)
committerSami Kerola <kerolasa@iki.fi>
Sat, 4 Feb 2017 23:39:37 +0000 (23:39 +0000)
The control structure is read-only everywhere else but in main().  Almost
all changes are about how variables are referred, with one exception.  Calls
to read_adjtime() from manipulate_clock() and compare_clock() are moved to
main().  This way it is possible to keep variable that tells if hwclock is
using UTC-0 be part of control structure.

Changes within #ifdef __alpha__ segments were tested by flipping the
preprocessor directivive otherway around and getting good compilaton all the
way to the point where linking on none-alpha system failed.

Reviewed-by: J William Piggott <elseifthen@gmx.com>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
sys-utils/hwclock-cmos.c
sys-utils/hwclock-rtc.c
sys-utils/hwclock.c
sys-utils/hwclock.h

index 9103b73436fbb003892f2c44836e6bafc50524af..625da75c82cd5a5169d6efc6d71497e3253f0897 100644 (file)
@@ -175,20 +175,21 @@ static int is_in_cpuinfo(char *fmt, char *str)
  * Set cmos_epoch, either from user options, or by asking the kernel, or by
  * looking at /proc/cpu_info
  */
-void set_cmos_epoch(int ARCconsole, int SRM)
+void set_cmos_epoch(const struct hwclock_control *ctl)
 {
        unsigned long epoch;
+       int set_epoc;
 
        /* Believe the user */
-       if (epoch_option != -1) {
-               cmos_epoch = epoch_option;
+       if (ctl->epoch_option) {
+               cmos_epoch = ctl->epoch_option;
                return;
        }
 
-       if (ARCconsole)
+       if (ctl->ARCconsole)
                cmos_epoch = 1980;
 
-       if (ARCconsole || SRM)
+       if (ctl->ARCconsole || ctl->SRM)
                return;
 
 #ifdef __linux__
@@ -196,7 +197,7 @@ void set_cmos_epoch(int ARCconsole, int SRM)
         * If we can ask the kernel, we don't need guessing from
         * /proc/cpuinfo
         */
-       if (get_epoch_rtc(&epoch, 1) == 0) {
+       if (get_epoch_rtc(ctl, &epoch, 1) == 0) {
                cmos_epoch = epoch;
                return;
        }
@@ -218,8 +219,8 @@ void set_cmos_epoch(int ARCconsole, int SRM)
         * different "epoch" ideas.
         */
        if (is_in_cpuinfo("system serial number", "MILO")) {
-               ARCconsole = 1;
-               if (debug)
+               set_epoc = 1;
+               if (ctl->debug)
                        printf(_("booted from MILO\n"));
        }
 
@@ -229,28 +230,28 @@ void set_cmos_epoch(int ARCconsole, int SRM)
         * and not an ARC-style epoch. BCD is detected dynamically, but we
         * must NOT adjust like ARC.
         */
-       if (ARCconsole && is_in_cpuinfo("system type", "Ruffian")) {
-               ARCconsole = 0;
-               if (debug)
+       if (set_epoc && is_in_cpuinfo("system type", "Ruffian")) {
+               set_epoc = 0;
+               if (ctl->debug)
                        printf(_("Ruffian BCD clock\n"));
        }
 
-       if (ARCconsole)
+       if (set_epoc)
                cmos_epoch = 1980;
 }
 
-void set_cmos_access(int Jensen, int funky_toy)
+void set_cmos_access(const struct hwclock_control *ctl)
 {
 
        /*
         * See whether we're dealing with a Jensen---it has a weird I/O
         * system. DEC was just learning how to build Alpha PCs.
         */
-       if (Jensen || is_in_cpuinfo("system type", "Jensen")) {
+       if (ctl->Jensen || is_in_cpuinfo("system type", "Jensen")) {
                use_dev_port = 1;
                clock_ctl_addr = 0x170;
                clock_data_addr = 0x171;
-               if (debug)
+               if (ctl->debug)
                        printf(_("clockport adjusted to 0x%x\n"),
                               clock_ctl_addr);
        }
@@ -260,13 +261,13 @@ void set_cmos_access(int Jensen, int funky_toy)
         * TOY that must be accessed differently to work correctly.
         */
        /* Nautilus stuff reported by Neoklis Kyriazis */
-       if (funky_toy ||
+       if (ctl->funky_toy ||
            is_in_cpuinfo("system variation", "PC164") ||
            is_in_cpuinfo("system variation", "LX164") ||
            is_in_cpuinfo("system variation", "SX164") ||
            is_in_cpuinfo("system type", "Nautilus")) {
                funkyTOY = 1;
-               if (debug)
+               if (ctl->debug)
                        printf(_("funky TOY!\n"));
        }
 }
@@ -282,13 +283,16 @@ void set_cmos_access(int Jensen, int funky_toy)
  * atomically, eventually.
  */
 static unsigned long
-atomic(const char *name, unsigned long (*op) (unsigned long), unsigned long arg)
+atomic(const char *name,
+       unsigned long (*op) (const struct hwclock_control *ctl, unsigned long),
+       const struct hwclock_control *ctl,
+       unsigned long arg)
 {
        unsigned long ts1, ts2, n, v;
 
        for (n = 0; n < 1000; ++n) {
                asm volatile ("rpcc %0":"r=" (ts1));
-               v = (*op) (arg);
+               v = (*op) (ctl, arg);
                asm volatile ("rpcc %0":"r=" (ts2));
 
                if ((ts1 ^ ts2) >> 32 == 0) {
@@ -307,24 +311,26 @@ atomic(const char *name, unsigned long (*op) (unsigned long), unsigned long arg)
  */
 static unsigned long
 atomic(const char *name __attribute__ ((__unused__)),
-       unsigned long (*op) (unsigned long),
+       unsigned long (*op) (const struct hwclock_control *ctl, unsigned long),
+       const struct hwclock_control *ctl,
        unsigned long arg)
 {
-       return (*op) (arg);
+       return (*op) (ctl, arg);
 }
 
 #endif
 
-static inline unsigned long cmos_read(unsigned long reg)
+static inline unsigned long cmos_read(const struct hwclock_control *ctl,
+                                     unsigned long reg)
 {
        if (use_dev_port) {
                unsigned char v = reg | 0x80;
                lseek(dev_port_fd, clock_ctl_addr, 0);
-               if (write(dev_port_fd, &v, 1) == -1 && debug)
+               if (write(dev_port_fd, &v, 1) == -1 && ctl->debug)
                        warn(_("cmos_read(): write to control address %X failed"),
                               clock_ctl_addr);
                lseek(dev_port_fd, clock_data_addr, 0);
-               if (read(dev_port_fd, &v, 1) == -1 && debug)
+               if (read(dev_port_fd, &v, 1) == -1 && ctl->debug)
                        warn(_("cmos_read(): read from data address %X failed"),
                               clock_data_addr);
                return v;
@@ -356,17 +362,18 @@ static inline unsigned long cmos_read(unsigned long reg)
        }
 }
 
-static inline unsigned long cmos_write(unsigned long reg, unsigned long val)
+static inline unsigned long cmos_write(const struct hwclock_control *ctl,
+                                      unsigned long reg, unsigned long val)
 {
        if (use_dev_port) {
                unsigned char v = reg | 0x80;
                lseek(dev_port_fd, clock_ctl_addr, 0);
-               if (write(dev_port_fd, &v, 1) == -1 && debug)
+               if (write(dev_port_fd, &v, 1) == -1 && ctl->debug)
                        warn(_("cmos_write(): write to control address %X failed"),
                               clock_ctl_addr);
                v = (val & 0xff);
                lseek(dev_port_fd, clock_data_addr, 0);
-               if (write(dev_port_fd, &v, 1) == -1 && debug)
+               if (write(dev_port_fd, &v, 1) == -1 && ctl->debug)
                        warn(_("cmos_write(): write to data address %X failed"),
                               clock_data_addr);
        } else {
@@ -376,7 +383,8 @@ static inline unsigned long cmos_write(unsigned long reg, unsigned long val)
        return 0;
 }
 
-static unsigned long cmos_set_time(unsigned long arg)
+static unsigned long cmos_set_time(const struct hwclock_control *ctl,
+                                  unsigned long arg)
 {
        unsigned char save_control, save_freq_select, pmbit = 0;
        struct tm tm = *(struct tm *)arg;
@@ -399,10 +407,10 @@ static unsigned long cmos_set_time(unsigned long arg)
  *         1111 500 milliseconds (maximum, 2 Hz)
  *         0110 976.562 microseconds (default 1024 Hz)
  */
-       save_control = cmos_read(11);   /* tell the clock it's being set */
-       cmos_write(11, (save_control | 0x80));
-       save_freq_select = cmos_read(10);       /* stop and reset prescaler */
-       cmos_write(10, (save_freq_select | 0x70));
+       save_control = cmos_read(ctl, 11);      /* tell the clock it's being set */
+       cmos_write(ctl, 11, (save_control | 0x80));
+       save_freq_select = cmos_read(ctl, 10);  /* stop and reset prescaler */
+       cmos_write(ctl, 10, (save_freq_select | 0x70));
 
        tm.tm_year += TM_EPOCH;
        century = tm.tm_year / 100;
@@ -431,15 +439,15 @@ static unsigned long cmos_set_time(unsigned long arg)
                BIN_TO_BCD(century);
        }
 
-       cmos_write(0, tm.tm_sec);
-       cmos_write(2, tm.tm_min);
-       cmos_write(4, tm.tm_hour | pmbit);
-       cmos_write(6, tm.tm_wday);
-       cmos_write(7, tm.tm_mday);
-       cmos_write(8, tm.tm_mon);
-       cmos_write(9, tm.tm_year);
+       cmos_write(ctl, 0, tm.tm_sec);
+       cmos_write(ctl, 2, tm.tm_min);
+       cmos_write(ctl, 4, tm.tm_hour | pmbit);
+       cmos_write(ctl, 6, tm.tm_wday);
+       cmos_write(ctl, 7, tm.tm_mday);
+       cmos_write(ctl, 8, tm.tm_mon);
+       cmos_write(ctl, 9, tm.tm_year);
        if (century_byte)
-               cmos_write(century_byte, century);
+               cmos_write(ctl, century_byte, century);
 
        /*
         * The kernel sources, linux/arch/i386/kernel/time.c, have the
@@ -452,33 +460,34 @@ static unsigned long cmos_set_time(unsigned long arg)
         * the Dallas Semiconductor data sheets, but who believes data
         * sheets anyway ... -- Markus Kuhn
         */
-       cmos_write(11, save_control);
-       cmos_write(10, save_freq_select);
+       cmos_write(ctl, 11, save_control);
+       cmos_write(ctl, 10, save_freq_select);
        return 0;
 }
 
-static int hclock_read(unsigned long reg)
+static int hclock_read(const struct hwclock_control *ctl, unsigned long reg)
 {
-       return atomic("clock read", cmos_read, (reg));
+       return atomic("clock read", cmos_read, ctl, reg);
 }
 
-static void hclock_set_time(const struct tm *tm)
+static void hclock_set_time(const struct hwclock_control *ctl, const struct tm *tm)
 {
-       atomic("set time", cmos_set_time, (unsigned long)(tm));
+       atomic("set time", cmos_set_time, ctl, (unsigned long)(tm));
 }
 
-static inline int cmos_clock_busy(void)
+static inline int cmos_clock_busy(const struct hwclock_control *ctl)
 {
        return
 #ifdef __alpha__
            /* poll bit 4 (UF) of Control Register C */
-           funkyTOY ? (hclock_read(12) & 0x10) :
+           funkyTOY ? (hclock_read(ctl, 12) & 0x10) :
 #endif
            /* poll bit 7 (UIP) of Control Register A */
-           (hclock_read(10) & 0x80);
+           (hclock_read(ctl, 10) & 0x80);
 }
 
-static int synchronize_to_clock_tick_cmos(void)
+static int synchronize_to_clock_tick_cmos(const struct hwclock_control *ctl
+                                         __attribute__((__unused__)))
 {
        int i;
 
@@ -487,12 +496,12 @@ static int synchronize_to_clock_tick_cmos(void)
         * weird happens, we have a limit on this loop to reduce the impact
         * of this failure.
         */
-       for (i = 0; !cmos_clock_busy(); i++)
+       for (i = 0; !cmos_clock_busy(ctl); i++)
                if (i >= 10000000)
                        return 1;
 
        /* Wait for fall.  Should be within 2.228 ms. */
-       for (i = 0; cmos_clock_busy(); i++)
+       for (i = 0; cmos_clock_busy(ctl); i++)
                if (i >= 1000000)
                        return 1;
        return 0;
@@ -514,7 +523,8 @@ static int synchronize_to_clock_tick_cmos(void)
  * In practice, the chance of this function returning the wrong time is
  * extremely remote.
  */
-static int read_hardware_clock_cmos(struct tm *tm)
+static int read_hardware_clock_cmos(const struct hwclock_control *ctl
+                                   __attribute__((__unused__)), struct tm *tm)
 {
        bool got_time = FALSE;
        unsigned char status, pmbit;
@@ -536,25 +546,25 @@ static int read_hardware_clock_cmos(struct tm *tm)
                 * at first, the clock has changed while we were running. We
                 * check for that too, and if it happens, we start over.
                 */
-               if (!cmos_clock_busy()) {
+               if (!cmos_clock_busy(ctl)) {
                        /* No clock update in progress, go ahead and read */
-                       tm->tm_sec = hclock_read(0);
-                       tm->tm_min = hclock_read(2);
-                       tm->tm_hour = hclock_read(4);
-                       tm->tm_wday = hclock_read(6);
-                       tm->tm_mday = hclock_read(7);
-                       tm->tm_mon = hclock_read(8);
-                       tm->tm_year = hclock_read(9);
-                       status = hclock_read(11);
+                       tm->tm_sec = hclock_read(ctl, 0);
+                       tm->tm_min = hclock_read(ctl, 2);
+                       tm->tm_hour = hclock_read(ctl, 4);
+                       tm->tm_wday = hclock_read(ctl, 6);
+                       tm->tm_mday = hclock_read(ctl, 7);
+                       tm->tm_mon = hclock_read(ctl, 8);
+                       tm->tm_year = hclock_read(ctl, 9);
+                       status = hclock_read(ctl, 11);
 #if 0
                        if (century_byte)
-                               century = hclock_read(century_byte);
+                               century = hclock_read(ctl, century_byte);
 #endif
                        /*
                         * Unless the clock changed while we were reading,
                         * consider this a good clock read .
                         */
-                       if (tm->tm_sec == hclock_read(0))
+                       if (tm->tm_sec == hclock_read(ctl, 0))
                                got_time = TRUE;
                }
                /*
@@ -602,10 +612,12 @@ static int read_hardware_clock_cmos(struct tm *tm)
        return 0;
 }
 
-static int set_hardware_clock_cmos(const struct tm *new_broken_time)
+static int set_hardware_clock_cmos(const struct hwclock_control *ctl
+                                  __attribute__((__unused__)),
+                                  const struct tm *new_broken_time)
 {
 
-       hclock_set_time(new_broken_time);
+       hclock_set_time(ctl, new_broken_time);
        return 0;
 }
 
index 3e32399a31c4452b68f5801d45f0171fa7ec4b59..e9ca9ce393966bb96d0434bb6789b98b5a32bc40 100644 (file)
@@ -104,8 +104,7 @@ struct linux_rtc_time {
  */
 
 /* default or user defined dev (by hwclock --rtc=<path>) */
-char *rtc_dev_name;
-
+static char *rtc_dev_name;
 static int rtc_dev_fd = -1;
 
 static void close_rtc(void)
@@ -115,7 +114,7 @@ static void close_rtc(void)
        rtc_dev_fd = -1;
 }
 
-static int open_rtc(void)
+static int open_rtc(const struct hwclock_control *ctl)
 {
        char *fls[] = {
 #ifdef __ia64__
@@ -133,9 +132,10 @@ static int open_rtc(void)
                return rtc_dev_fd;
 
        /* --rtc option has been given */
-       if (rtc_dev_name)
+       if (ctl->rtc_dev_name) {
+               rtc_dev_name = ctl->rtc_dev_name;
                rtc_dev_fd = open(rtc_dev_name, O_RDONLY);
-       else {
+       else {
                for (p = fls; *p; ++p) {
                        rtc_dev_fd = open(*p, O_RDONLY);
 
@@ -154,13 +154,13 @@ static int open_rtc(void)
        return rtc_dev_fd;
 }
 
-static int open_rtc_or_exit(void)
+static int open_rtc_or_exit(const struct hwclock_control *ctl)
 {
-       int rtc_fd = open_rtc();
+       int rtc_fd = open_rtc(ctl);
 
        if (rtc_fd < 0) {
                warn(_("cannot open %s"), rtc_dev_name);
-               hwclock_exit(EX_OSFILE);
+               hwclock_exit(ctl, EX_OSFILE);
        }
        return rtc_fd;
 }
@@ -205,7 +205,8 @@ static int do_rtc_read_ioctl(int rtc_fd, struct tm *tm)
  * Wait for the top of a clock tick by reading /dev/rtc in a busy loop until
  * we see it.
  */
-static int busywait_for_rtc_clock_tick(const int rtc_fd)
+static int busywait_for_rtc_clock_tick(const struct hwclock_control *ctl,
+                                      const int rtc_fd)
 {
        struct tm start_time;
        /* The time when we were called (and started waiting) */
@@ -213,7 +214,7 @@ static int busywait_for_rtc_clock_tick(const int rtc_fd)
        int rc;
        struct timeval begin, now;
 
-       if (debug)
+       if (ctl->debug)
                printf(_("Waiting in loop for time from %s to change\n"),
                       rtc_dev_name);
 
@@ -246,12 +247,12 @@ static int busywait_for_rtc_clock_tick(const int rtc_fd)
 /*
  * Same as synchronize_to_clock_tick(), but just for /dev/rtc.
  */
-static int synchronize_to_clock_tick_rtc(void)
+static int synchronize_to_clock_tick_rtc(const struct hwclock_control *ctl)
 {
        int rtc_fd;             /* File descriptor of /dev/rtc */
        int ret;
 
-       rtc_fd = open_rtc();
+       rtc_fd = open_rtc(ctl);
        if (rtc_fd == -1) {
                warn(_("cannot open %s"), rtc_dev_name);
                ret = 1;
@@ -275,10 +276,10 @@ static int synchronize_to_clock_tick_rtc(void)
                         * Clock interrupts are used by the kernel for the
                         * system clock, so aren't at the user's disposal.
                         */
-                       if (debug)
+                       if (ctl->debug)
                                printf(_("%s does not have interrupt functions. "),
                                       rtc_dev_name);
-                       ret = busywait_for_rtc_clock_tick(rtc_fd);
+                       ret = busywait_for_rtc_clock_tick(ctl, rtc_fd);
                } else if (rc == 0) {
                        /*
                         * Just reading rtc_fd fails on broken hardware: no
@@ -302,7 +303,7 @@ static int synchronize_to_clock_tick_rtc(void)
                                warn(_("select() to %s to wait for clock tick failed"),
                                     rtc_dev_name);
                        else if (rc == 0) {
-                               if (debug)
+                               if (ctl->debug)
                                        printf(_("select() to %s to wait for clock tick timed out"),
                                               rtc_dev_name);
                        } else
@@ -321,11 +322,12 @@ static int synchronize_to_clock_tick_rtc(void)
        return ret;
 }
 
-static int read_hardware_clock_rtc(struct tm *tm)
+static int read_hardware_clock_rtc(const struct hwclock_control *ctl,
+                                  struct tm *tm)
 {
        int rtc_fd, rc;
 
-       rtc_fd = open_rtc_or_exit();
+       rtc_fd = open_rtc_or_exit(ctl);
 
        /* Read the RTC time/date, return answer via tm */
        rc = do_rtc_read_ioctl(rtc_fd, tm);
@@ -337,13 +339,14 @@ static int read_hardware_clock_rtc(struct tm *tm)
  * Set the Hardware Clock to the broken down time <new_broken_time>. Use
  * ioctls to "rtc" device /dev/rtc.
  */
-static int set_hardware_clock_rtc(const struct tm *new_broken_time)
+static int set_hardware_clock_rtc(const struct hwclock_control *ctl,
+                                 const struct tm *new_broken_time)
 {
        int rc = -1;
        int rtc_fd;
        char *ioctlname;
 
-       rtc_fd = open_rtc_or_exit();
+       rtc_fd = open_rtc_or_exit(ctl);
 
 #ifdef __sparc__
        {
@@ -369,10 +372,10 @@ static int set_hardware_clock_rtc(const struct tm *new_broken_time)
        if (rc == -1) {
                warn(_("ioctl(%s) to %s to set the time failed."),
                        ioctlname, rtc_dev_name);
-               hwclock_exit(EX_IOERR);
+               hwclock_exit(ctl, EX_IOERR);
        }
 
-       if (debug)
+       if (ctl->debug)
                printf(_("ioctl(%s) was successful.\n"), ioctlname);
 
        return 0;
@@ -392,24 +395,25 @@ static struct clock_ops rtc = {
 };
 
 /* return &rtc if /dev/rtc can be opened, NULL otherwise */
-struct clock_ops *probe_for_rtc_clock(void)
+struct clock_ops *probe_for_rtc_clock(const struct hwclock_control *ctl)
 {
-       int rtc_fd = open_rtc();
+       int rtc_fd = open_rtc(ctl);
        if (rtc_fd >= 0)
                return &rtc;
-       if (debug)
-               warn(_("cannot open %s"), rtc_dev_name);
+       if (ctl->debug)
+               warn(_("cannot open %s"), ctl->rtc_dev_name);
        return NULL;
 }
 
 /*
  * Get the Hardware Clock epoch setting from the kernel.
  */
-int get_epoch_rtc(unsigned long *epoch_p, int silent)
+int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch_p,
+                 int silent)
 {
        int rtc_fd;
 
-       rtc_fd = open_rtc();
+       rtc_fd = open_rtc(ctl);
        if (rtc_fd < 0) {
                if (!silent) {
                        if (errno == ENOENT)
@@ -431,7 +435,7 @@ int get_epoch_rtc(unsigned long *epoch_p, int silent)
                return 1;
        }
 
-       if (debug)
+       if (ctl->debug)
                printf(_("we have read epoch %lu from %s "
                         "with RTC_EPOCH_READ ioctl.\n"), *epoch_p,
                       rtc_dev_name);
@@ -442,22 +446,22 @@ int get_epoch_rtc(unsigned long *epoch_p, int silent)
 /*
  * Set the Hardware Clock epoch in the kernel.
  */
-int set_epoch_rtc(unsigned long epoch)
+int set_epoch_rtc(const struct hwclock_control *ctl)
 {
        int rtc_fd;
 
-       if (epoch < 1900) {
+       if (ctl->epoch_option < 1900) {
                /* kernel would not accept this epoch value
                 *
                 * Bad habit, deciding not to do what the user asks just
                 * because one believes that the kernel might not like it.
                 */
                warnx(_("The epoch value may not be less than 1900.  "
-                       "You requested %ld"), epoch);
+                       "You requested %ld"), ctl->epoch_option);
                return 1;
        }
 
-       rtc_fd = open_rtc();
+       rtc_fd = open_rtc(ctl);
        if (rtc_fd < 0) {
                if (errno == ENOENT)
                        warnx(_
@@ -466,16 +470,16 @@ int set_epoch_rtc(unsigned long epoch)
                               "file %s.  This file does not exist on this system."),
                              rtc_dev_name);
                else
-                       warn(_("cannot open %s"), rtc_dev_name);
+                       warn(_("cannot open %s"), ctl->rtc_dev_name);
                return 1;
        }
 
-       if (debug)
+       if (ctl->debug)
                printf(_("setting epoch to %lu "
-                        "with RTC_EPOCH_SET ioctl to %s.\n"), epoch,
+                        "with RTC_EPOCH_SET ioctl to %s.\n"), ctl->epoch_option,
                       rtc_dev_name);
 
-       if (ioctl(rtc_fd, RTC_EPOCH_SET, epoch) == -1) {
+       if (ioctl(rtc_fd, RTC_EPOCH_SET, ctl->epoch_option) == -1) {
                if (errno == EINVAL)
                        warnx(_("The kernel device driver for %s "
                                "does not have the RTC_EPOCH_SET ioctl."),
index b57a29e0aab07368fcbb4468ab313371c97ce929..fe0d6736da1c6cc4baaa6614639ddf696fd69b4e 100644 (file)
@@ -86,7 +86,6 @@
 #ifdef HAVE_LIBAUDIT
 #include <libaudit.h>
 static int hwaudit_fd = -1;
-static int hwaudit_on;
 #endif
 
 /* The struct that holds our hardware access routines */
@@ -97,8 +96,6 @@ struct clock_ops *ur;
    43219 is a maximal safe value preventing exact_adjustment overflow.) */
 #define MAX_DRIFT 2145.0
 
-const char *adj_file_name = NULL;
-
 struct adjtime {
        /*
         * This is information we keep in the adjtime file that tells us how
@@ -127,18 +124,6 @@ struct adjtime {
         */
 };
 
-/*
- * We are running in debug mode, wherein we put a lot of information about
- * what we're doing to standard output.
- */
-int debug;
-
-/* Workaround for Award 4.50g BIOS bug: keep the year in a file. */
-bool badyear;
-
-/* User-specified epoch, used when rtc fails to return epoch. */
-unsigned long epoch_option = ULONG_MAX;
-
 /*
  * Almost all Award BIOS's made between 04/26/94 and 05/31/95 have a nasty
  * bug limiting the RTC year byte to the range 94-99. Any year between 2000
@@ -228,19 +213,19 @@ static struct timeval time_inc(struct timeval addend, double increment)
 }
 
 static bool
-hw_clock_is_utc(const bool utc, const bool local_opt,
+hw_clock_is_utc(const struct hwclock_control *ctl,
                const struct adjtime adjtime)
 {
        bool ret;
 
-       if (utc)
+       if (ctl->utc)
                ret = TRUE;     /* --utc explicitly given on command line */
-       else if (local_opt)
+       else if (ctl->local_opt)
                ret = FALSE;    /* --localtime explicitly given */
        else
                /* get info from adjtime file - default is UTC */
                ret = (adjtime.local_utc != LOCAL);
-       if (debug)
+       if (ctl->debug)
                printf(_("Assuming hardware clock is kept in %s time.\n"),
                       ret ? _("UTC") : _("local"));
        return ret;
@@ -255,7 +240,8 @@ hw_clock_is_utc(const bool utc, const bool local_opt,
  *
  * return value 0 if all OK, !=0 otherwise.
  */
-static int read_adjtime(struct adjtime *adjtime_p)
+static int read_adjtime(const struct hwclock_control *ctl,
+                       struct adjtime *adjtime_p)
 {
        FILE *adjfile;
        char line1[81];         /* String: first line of adjtime file */
@@ -263,7 +249,7 @@ static int read_adjtime(struct adjtime *adjtime_p)
        char line3[81];         /* String: third line of adjtime file */
        long timeval;
 
-       if (access(adj_file_name, R_OK) != 0) {
+       if (access(ctl->adj_file_name, R_OK) != 0) {
                /* He doesn't have a adjtime file, so we'll use defaults. */
                adjtime_p->drift_factor = 0;
                adjtime_p->last_adj_time = 0;
@@ -275,9 +261,9 @@ static int read_adjtime(struct adjtime *adjtime_p)
                return 0;
        }
 
-       adjfile = fopen(adj_file_name, "r");    /* open file for reading */
+       adjfile = fopen(ctl->adj_file_name, "r");       /* open file for reading */
        if (adjfile == NULL) {
-               warn(_("cannot open %s"), adj_file_name);
+               warn(_("cannot open %s"), ctl->adj_file_name);
                return EX_OSFILE;
        }
 
@@ -320,7 +306,7 @@ static int read_adjtime(struct adjtime *adjtime_p)
 
        adjtime_p->dirty = FALSE;
 
-       if (debug) {
+       if (ctl->debug) {
                printf(_
                       ("Last drift adjustment done at %ld seconds after 1969\n"),
                       (long)adjtime_p->last_adj_time);
@@ -348,16 +334,16 @@ static int read_adjtime(struct adjtime *adjtime_p)
  *
  * Return 0 if it worked, nonzero if it didn't.
  */
-static int synchronize_to_clock_tick(void)
+static int synchronize_to_clock_tick(const struct hwclock_control *ctl)
 {
        int rc;
 
-       if (debug)
+       if (ctl->debug)
                printf(_("Waiting for clock tick...\n"));
 
-       rc = ur->synchronize_to_clock_tick();
+       rc = ur->synchronize_to_clock_tick(ctl);
 
-       if (debug) {
+       if (ctl->debug) {
                if (rc)
                        printf(_("...synchronization failed\n"));
                else
@@ -384,10 +370,10 @@ static int synchronize_to_clock_tick(void)
  * return *valid_p == true.
  */
 static void
-mktime_tz(struct tm tm, const bool universal,
-         bool * valid_p, time_t * systime_p)
+mktime_tz(const struct hwclock_control *ctl, struct tm tm,
+         bool *valid_p, time_t *systime_p)
 {
-       if (universal)
+       if (ctl->universal)
                *systime_p = timegm(&tm);
        else
                *systime_p = mktime(&tm);
@@ -399,14 +385,14 @@ mktime_tz(struct tm tm, const bool universal,
                 * mktime() returns -1).
                 */
                *valid_p = FALSE;
-               if (debug)
+               if (ctl->debug)
                        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_p = TRUE;
-               if (debug)
+               if (ctl->debug)
                        printf(_
                               ("Hw clock time : %4d/%.2d/%.2d %.2d:%.2d:%.2d = "
                                "%ld seconds since 1969\n"), tm.tm_year + 1900,
@@ -422,24 +408,25 @@ mktime_tz(struct tm tm, const bool universal,
  * clock.
  */
 static int
-read_hardware_clock(const bool universal, bool * valid_p, time_t * systime_p)
+read_hardware_clock(const struct hwclock_control *ctl,
+                   bool * valid_p, time_t *systime_p)
 {
        struct tm tm;
        int err;
 
-       err = ur->read_hardware_clock(&tm);
+       err = ur->read_hardware_clock(ctl, &tm);
        if (err)
                return err;
 
-       if (badyear)
+       if (ctl->badyear)
                read_date_from_file(&tm);
 
-       if (debug)
+       if (ctl->debug)
                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,
                       tm.tm_min, tm.tm_sec);
-       mktime_tz(tm, universal, valid_p, systime_p);
+       mktime_tz(ctl, tm, valid_p, systime_p);
 
        return 0;
 }
@@ -449,8 +436,7 @@ read_hardware_clock(const bool universal, bool * valid_p, time_t * systime_p)
  * according to <universal>.
  */
 static void
-set_hardware_clock(const time_t newtime,
-                  const bool universal, const bool testing)
+set_hardware_clock(const struct hwclock_control *ctl, const time_t newtime)
 {
        struct tm new_broken_time;
        /*
@@ -458,21 +444,21 @@ set_hardware_clock(const time_t newtime,
         * in the time zone of caller's choice
         */
 
-       if (universal)
+       if (ctl->universal)
                new_broken_time = *gmtime(&newtime);
        else
                new_broken_time = *localtime(&newtime);
 
-       if (debug)
+       if (ctl->debug)
                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 (testing)
+       if (ctl->testing)
                printf(_("Clock not changed - testing only.\n"));
        else {
-               if (badyear) {
+               if (ctl->badyear) {
                        /*
                         * Write the real year to a file, then write a fake
                         * year between 1995 and 1998 to the RTC. This way,
@@ -483,7 +469,7 @@ set_hardware_clock(const time_t newtime,
                        new_broken_time.tm_year =
                            95 + ((new_broken_time.tm_year + 1) & 3);
                }
-               ur->set_hardware_clock(&new_broken_time);
+               ur->set_hardware_clock(ctl, &new_broken_time);
        }
 }
 
@@ -506,9 +492,9 @@ set_hardware_clock(const time_t newtime,
  * Idea for future enhancement.
  */
 static void
-set_hardware_clock_exact(const time_t sethwtime,
-                        const struct timeval refsystime,
-                        const bool universal, const bool testing)
+set_hardware_clock_exact(const struct hwclock_control *ctl,
+                        const time_t sethwtime,
+                        const struct timeval refsystime)
 {
        /*
         * The Hardware Clock can only be set to any integer time plus one
@@ -572,7 +558,7 @@ set_hardware_clock_exact(const time_t sethwtime,
                double ticksize;
 
                /* FOR TESTING ONLY: inject random delays of up to 1000ms */
-               if (debug >= 10) {
+               if (ctl->debug >= 10) {
                        int usec = random() % 1000000;
                        printf(_("sleeping ~%d usec\n"), usec);
                        xusleep(usec);
@@ -584,7 +570,7 @@ set_hardware_clock_exact(const time_t sethwtime,
                prevsystime = nowsystime;
 
                if (ticksize < 0) {
-                       if (debug)
+                       if (ctl->debug)
                                printf(_("time jumped backward %.6f seconds "
                                         "to %ld.%06ld - retargeting\n"),
                                       ticksize, nowsystime.tv_sec,
@@ -592,7 +578,7 @@ set_hardware_clock_exact(const time_t sethwtime,
                        /* The retarget is handled at the end of the loop. */
                } else if (deltavstarget < 0) {
                        /* deltavstarget < 0 if current time < target time */
-                       if (debug >= 2)
+                       if (ctl->debug >= 2)
                                printf(_("%ld.%06ld < %ld.%06ld (%.6f)\n"),
                                       nowsystime.tv_sec,
                                       nowsystime.tv_usec,
@@ -608,7 +594,7 @@ set_hardware_clock_exact(const time_t sethwtime,
                         * We missed our window.  Increase the tolerance and
                         * aim for the next opportunity.
                         */
-                       if (debug)
+                       if (ctl->debug)
                                printf(_("missed it - %ld.%06ld is too far "
                                         "past %ld.%06ld (%.6f > %.6f)\n"),
                                       nowsystime.tv_sec,
@@ -636,7 +622,7 @@ set_hardware_clock_exact(const time_t sethwtime,
                    + (int)(time_diff(nowsystime, refsystime)
                            - RTC_SET_DELAY_SECS /* don't count this */
                            + 0.5 /* for rounding */);
-       if (debug)
+       if (ctl->debug)
                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,
@@ -646,7 +632,7 @@ set_hardware_clock_exact(const time_t sethwtime,
                       (int)(newhwtime - sethwtime),
                       refsystime.tv_sec, refsystime.tv_usec);
 
-       set_hardware_clock(newhwtime, universal, testing);
+       set_hardware_clock(ctl, newhwtime);
 }
 
 /*
@@ -689,7 +675,8 @@ display_time(const bool hclock_valid, struct timeval hwctime)
  * If anything goes wrong (and many things can), we return return code 10
  * and arbitrary *time_p. Otherwise, return code is 0 and *time_p is valid.
  */
-static int interpret_date_string(const char *date_opt, time_t * const time_p)
+static int interpret_date_string(const struct hwclock_control *ctl,
+                                time_t *const time_p)
 {
        FILE *date_child_fp;
        char date_resp[100];
@@ -698,19 +685,19 @@ static int interpret_date_string(const char *date_opt, time_t * const time_p)
        int retcode;            /* our eventual return code */
        int rc;                 /* local return code */
 
-       if (date_opt == NULL) {
+       if (!ctl->date_opt) {
                warnx(_("No --date option specified."));
                return 14;
        }
 
        /* prevent overflow - a security risk */
-       if (strlen(date_opt) > sizeof(date_command) - 50) {
+       if (strlen(ctl->date_opt) > sizeof(date_command) - 50) {
                warnx(_("--date argument too long"));
                return 13;
        }
 
        /* Quotes in date_opt would ruin the date command we construct. */
-       if (strchr(date_opt, '"') != NULL) {
+       if (strchr(ctl->date_opt, '"') != NULL) {
                warnx(_
                      ("The value of the --date option is not a valid date.\n"
                       "In particular, it contains quotation marks."));
@@ -718,8 +705,8 @@ static int interpret_date_string(const char *date_opt, time_t * const time_p)
        }
 
        sprintf(date_command, "date --date=\"%s\" +%s%%s",
-               date_opt, magic);
-       if (debug)
+               ctl->date_opt, magic);
+       if (ctl->debug)
                printf(_("Issuing date command: %s\n"), date_command);
 
        date_child_fp = popen(date_command, "r");
@@ -731,7 +718,7 @@ static int interpret_date_string(const char *date_opt, time_t * const time_p)
 
        if (!fgets(date_resp, sizeof(date_resp), date_child_fp))
                date_resp[0] = '\0';    /* in case fgets fails */
-       if (debug)
+       if (ctl->debug)
                printf(_("response from date command = %s\n"), date_resp);
        if (strncmp(date_resp, magic, sizeof(magic) - 1) != 0) {
                warnx(_("The date command issued by %s returned "
@@ -756,10 +743,10 @@ static int interpret_date_string(const char *date_opt, time_t * const time_p)
                } else {
                        retcode = 0;
                        *time_p = seconds_since_epoch;
-                       if (debug)
+                       if (ctl->debug)
                                printf(_("date string %s equates to "
                                         "%ld seconds since 1969.\n"),
-                                      date_opt, *time_p);
+                                      ctl->date_opt, *time_p);
                }
        }
        pclose(date_child_fp);
@@ -788,8 +775,8 @@ static int interpret_date_string(const char *date_opt, time_t * const time_p)
  * have.
  */
 static int
-set_system_clock(const bool hclock_valid, const struct timeval newtime,
-                const bool testing, const bool universal)
+set_system_clock(const struct hwclock_control *ctl, const bool hclock_valid,
+                const struct timeval newtime)
 {
        int retcode;
 
@@ -813,13 +800,13 @@ set_system_clock(const bool hclock_valid, const struct timeval newtime,
                        minuteswest -= 60;
 #endif
 
-               if (debug) {
+               if (ctl->debug) {
                        printf(_("Calling settimeofday:\n"));
                        printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
                               newtime.tv_sec, newtime.tv_usec);
                        printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
                }
-               if (testing) {
+               if (ctl->testing) {
                        printf(_
                               ("Not setting system clock because running in test mode.\n"));
                        retcode = 0;
@@ -830,7 +817,7 @@ set_system_clock(const bool hclock_valid, const struct timeval newtime,
                         * mode does not clobber the Hardware Clock with UTC. This
                         * is only available on first call of settimeofday after boot.
                         */
-                       if (!universal)
+                       if (!ctl->universal)
                                rc = settimeofday(tv_null, &tz);
                        if (!rc)
                                rc = settimeofday(&newtime, &tz);
@@ -861,7 +848,7 @@ set_system_clock(const bool hclock_valid, const struct timeval newtime,
  * If 'testing' is true, don't actually update anything -- just say we would
  * have.
  */
-static int set_system_clock_timezone(const bool universal, const bool testing)
+static int set_system_clock_timezone(const struct hwclock_control *ctl)
 {
        int retcode;
        struct timeval tv;
@@ -869,7 +856,7 @@ static int set_system_clock_timezone(const bool universal, const bool testing)
        int minuteswest;
 
        gettimeofday(&tv, NULL);
-       if (debug) {
+       if (ctl->debug) {
                struct tm broken_time;
                char ctime_now[200];
 
@@ -889,12 +876,12 @@ static int set_system_clock_timezone(const bool universal, const bool testing)
                minuteswest -= 60;
 #endif
 
-       if (debug) {
+       if (ctl->debug) {
                struct tm broken_time;
                char ctime_now[200];
 
                gettimeofday(&tv, NULL);
-               if (!universal)
+               if (!ctl->universal)
                        tv.tv_sec += minuteswest * 60;
 
                broken_time = *gmtime(&tv.tv_sec);
@@ -907,7 +894,7 @@ static int set_system_clock_timezone(const bool universal, const bool testing)
                       tv.tv_sec, tv.tv_usec);
                printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
        }
-       if (testing) {
+       if (ctl->testing) {
                printf(_
                       ("Not setting system clock because running in test mode.\n"));
                retcode = 0;
@@ -922,7 +909,7 @@ static int set_system_clock_timezone(const bool universal, const bool testing)
                 * compensate. If the systemtime is in fact in UTC, then this is wrong
                 * so we first do a dummy call to make sure the time is not shifted.
                 */
-               if (universal)
+               if (ctl->universal)
                        rc = settimeofday(tv_null, &tz_utc);
 
                /* Now we set the real timezone. Due to the above dummy call, this will
@@ -959,29 +946,29 @@ static int set_system_clock_timezone(const bool universal, const bool testing)
  * so don't adjust the drift factor.
  */
 static void
-adjust_drift_factor(struct adjtime *adjtime_p,
+adjust_drift_factor(const struct hwclock_control *ctl,
+                   struct adjtime *adjtime_p,
                    const struct timeval nowtime,
                    const bool hclock_valid,
-                   const struct timeval hclocktime,
-                   const bool update)
+                   const struct timeval hclocktime)
 {
-       if (!update) {
-               if (debug)
+       if (!ctl->update) {
+               if (ctl->debug)
                        printf(_("Not adjusting drift factor because the "
                                 "--update-drift option was not used.\n"));
        } else if (!hclock_valid) {
-               if (debug)
+               if (ctl->debug)
                        printf(_("Not adjusting drift factor because the "
                                 "Hardware Clock previously contained "
                                 "garbage.\n"));
        } else if (adjtime_p->last_calib_time == 0) {
-               if (debug)
+               if (ctl->debug)
                        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 (debug)
+               if (ctl->debug)
                        printf(_("Not adjusting drift factor because it has "
                                 "been less than four hours since the last "
                                 "calibration.\n"));
@@ -1019,14 +1006,14 @@ adjust_drift_factor(struct adjtime *adjtime_p,
 
                drift_factor = adjtime_p->drift_factor + factor_adjust;
                if (fabs(drift_factor) > MAX_DRIFT) {
-                       if (debug)
+                       if (ctl->debug)
                                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 (debug)
+                       if (ctl->debug)
                                printf(_("Clock drifted %f seconds in the past "
                                         "%f seconds\nin spite of a drift factor of "
                                         "%f seconds/day.\n"
@@ -1056,7 +1043,8 @@ adjust_drift_factor(struct adjtime *adjtime_p,
  *
  */
 static void
-calculate_adjustment(const double factor,
+calculate_adjustment(const struct hwclock_control *ctl,
+                    const double factor,
                     const time_t last_time,
                     const double not_adjusted,
                     const time_t systime, struct timeval *tdrift_p)
@@ -1069,7 +1057,7 @@ calculate_adjustment(const double factor,
        tdrift_p->tv_sec = (time_t) floor(exact_adjustment);
        tdrift_p->tv_usec = (exact_adjustment -
                                 (double)tdrift_p->tv_sec) * 1E6;
-       if (debug) {
+       if (ctl->debug) {
                printf(P_("Time since last adjustment is %ld second\n",
                        "Time since last adjustment is %ld seconds\n",
                       (systime - last_time)),
@@ -1085,51 +1073,52 @@ calculate_adjustment(const double factor,
  * But if the contents are clean (unchanged since read from disk), don't
  * bother.
  */
-static void save_adjtime(const struct adjtime adjtime, const bool testing)
+static void save_adjtime(const struct hwclock_control *ctl,
+                        const struct adjtime *adjtime)
 {
        char newfile[412];      /* Stuff to write to disk file */
 
-       if (adjtime.dirty) {
+       if (adjtime->dirty) {
                /*
                 * snprintf is not always available, but this is safe as
                 * long as libc does not use more than 100 positions for %ld
                 * or %f
                 */
                sprintf(newfile, "%f %ld %f\n%ld\n%s\n",
-                       adjtime.drift_factor,
-                       adjtime.last_adj_time,
-                       adjtime.not_adjusted,
-                       adjtime.last_calib_time,
-                       (adjtime.local_utc == LOCAL) ? "LOCAL" : "UTC");
+                       adjtime->drift_factor,
+                       adjtime->last_adj_time,
+                       adjtime->not_adjusted,
+                       adjtime->last_calib_time,
+                       (adjtime->local_utc == LOCAL) ? "LOCAL" : "UTC");
 
-               if (testing) {
+               if (ctl->testing) {
                        printf(_
                               ("Not updating adjtime file because of testing mode.\n"));
                        printf(_("Would have written the following to %s:\n%s"),
-                              adj_file_name, newfile);
+                              ctl->adj_file_name, newfile);
                } else {
                        FILE *adjfile;
                        int err = 0;
 
-                       adjfile = fopen(adj_file_name, "w");
+                       adjfile = fopen(ctl->adj_file_name, "w");
                        if (adjfile == NULL) {
                                warn(_
                                     ("Could not open file with the clock adjustment parameters "
-                                     "in it (%s) for writing"), adj_file_name);
+                                     "in it (%s) for writing"), ctl->adj_file_name);
                                err = 1;
                        } else {
                                if (fputs(newfile, adjfile) < 0) {
                                        warn(_
                                             ("Could not update file with the clock adjustment "
                                              "parameters (%s) in it"),
-                                            adj_file_name);
+                                            ctl->adj_file_name);
                                        err = 1;
                                }
                                if (close_stream(adjfile) != 0) {
                                        warn(_
                                             ("Could not update file with the clock adjustment "
                                              "parameters (%s) in it"),
-                                            adj_file_name);
+                                            ctl->adj_file_name);
                                        err = 1;
                                }
                        }
@@ -1165,10 +1154,9 @@ static void save_adjtime(const struct adjtime adjtime, const bool testing)
  *
  */
 static void
-do_adjustment(struct adjtime *adjtime_p,
+do_adjustment(const struct hwclock_control *ctl, struct adjtime *adjtime_p,
              const bool hclock_valid, const struct timeval hclocktime,
-             const struct timeval read_time,
-             const bool universal, const bool testing)
+             const struct timeval read_time)
 {
        if (!hclock_valid) {
                warnx(_("The Hardware Clock does not contain a valid time, "
@@ -1178,37 +1166,36 @@ do_adjustment(struct adjtime *adjtime_p,
                adjtime_p->not_adjusted = 0;
                adjtime_p->dirty = TRUE;
        } else if (adjtime_p->last_adj_time == 0) {
-               if (debug)
+               if (ctl->debug)
                        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 (debug)
+               if (ctl->debug)
                        printf(_("Not setting clock because drift factor %f is far too high.\n"),
                                adjtime_p->drift_factor);
        } else {
-               set_hardware_clock_exact(hclocktime.tv_sec,
+               set_hardware_clock_exact(ctl, hclocktime.tv_sec,
                                         time_inc(read_time,
-                                                 -(hclocktime.tv_usec / 1E6)),
-                                        universal, testing);
+                                                 -(hclocktime.tv_usec / 1E6)));
                adjtime_p->last_adj_time = hclocktime.tv_sec;
                adjtime_p->not_adjusted = 0;
                adjtime_p->dirty = TRUE;
        }
 }
 
-static void determine_clock_access_method(const bool user_requests_ISA)
+static void determine_clock_access_method(const struct hwclock_control *ctl)
 {
        ur = NULL;
 
-       if (user_requests_ISA)
+       if (ctl->directisa)
                ur = probe_for_cmos_clock();
 
 #ifdef __linux__
        if (!ur)
-               ur = probe_for_rtc_clock();
+               ur = probe_for_rtc_clock(ctl);
 #endif
 
-       if (debug) {
+       if (ctl->debug) {
                if (ur)
                        puts(_(ur->interface_name));
                else
@@ -1224,16 +1211,9 @@ static void determine_clock_access_method(const bool user_requests_ISA)
  * Return rc == 0 if everything went OK, rc != 0 if not.
  */
 static int
-manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
-                const bool set, const time_t set_time,
-                const bool hctosys, const bool systohc, const bool systz,
-                const struct timeval startup_time,
-                const bool utc, const bool local_opt, const bool update,
-                const bool testing, const bool predict, const bool get)
+manipulate_clock(const struct hwclock_control *ctl, const time_t set_time,
+                const struct timeval startup_time, struct adjtime *adjtime)
 {
-       /* Contents of the adjtime file, or what they should be. */
-       struct adjtime adjtime = { 0 };
-       bool universal;
        /* Set if user lacks necessary authorization to access the clock */
        bool no_auth;
        /* The time at which we read the Hardware Clock */
@@ -1253,32 +1233,22 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
        /* local return code */
        int rc = 0;
 
-       if (!systz && !predict) {
+       if (!ctl->systz && !ctl->predict) {
                no_auth = ur->get_permissions();
                if (no_auth)
                        return EX_NOPERM;
        }
 
-       if (!noadjfile && !(systz && (utc || local_opt))) {
-               rc = read_adjtime(&adjtime);
-               if (rc)
-                       return rc;
-       } else {
-               /* A little trick to avoid writing the file if we don't have to */
-               adjtime.dirty = FALSE;
-       }
-
-       universal = hw_clock_is_utc(utc, local_opt, adjtime);
-
-       if ((set || systohc || adjust) &&
-           (adjtime.local_utc == UTC) != universal) {
-               adjtime.local_utc = universal ? UTC : LOCAL;
-               adjtime.dirty = TRUE;
+       if ((ctl->set || ctl->systohc || ctl->adjust) &&
+           (adjtime->local_utc == UTC) != ctl->universal) {
+               adjtime->local_utc = ctl->universal ? UTC : LOCAL;
+               adjtime->dirty = TRUE;
        }
 
-       if (show || get || adjust || hctosys || (!noadjfile && !systz && !predict)) {
+       if (ctl->show || ctl->get || ctl->adjust || ctl->hctosys
+           || (!ctl->noadjfile && !ctl->systz && !ctl->predict)) {
                /* data from HW-clock are required */
-               rc = synchronize_to_clock_tick();
+               rc = synchronize_to_clock_tick(ctl);
 
                /*
                 * 2 = synchronization timeout. We don't
@@ -1288,7 +1258,7 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
                 * so we still want to allow a user to set
                 * the RTC time.
                 */
-               if (rc && rc != 2 && !set && !systohc)
+               if (rc && rc != 2 && !ctl->set && !ctl->systohc)
                        return EX_IOERR;
                gettimeofday(&read_time, NULL);
 
@@ -1298,9 +1268,9 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
                 * don't bother reading it again.
                 */
                if (!rc) {
-                       rc = read_hardware_clock(universal,
-                                                &hclock_valid, &hclocktime.tv_sec);
-                       if (rc && !set && !systohc)
+                       rc = read_hardware_clock(ctl, &hclock_valid,
+                                                &hclocktime.tv_sec);
+                       if (rc && !ctl->set && !ctl->systohc)
                                return EX_IOERR;
                }
        }
@@ -1312,33 +1282,32 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
         * --predict.  For --predict negate the drift correction, because we
         * want to 'predict' a future Hardware Clock time that includes drift.
         */
-       hclocktime = predict ? t2tv(set_time) : hclocktime;
-       calculate_adjustment(adjtime.drift_factor,
-                            adjtime.last_adj_time,
-                            adjtime.not_adjusted,
+       hclocktime = ctl->predict ? t2tv(set_time) : hclocktime;
+       calculate_adjustment(ctl, adjtime->drift_factor,
+                            adjtime->last_adj_time,
+                            adjtime->not_adjusted,
                             hclocktime.tv_sec, &tdrift);
-       if (!show && !predict)
+       if (!ctl->show && !ctl->predict)
                hclocktime = time_inc(tdrift, hclocktime.tv_sec);
-       if (show || get) {
+       if (ctl->show || ctl->get) {
                display_time(hclock_valid,
                             time_inc(hclocktime, -time_diff
                                      (read_time, startup_time)));
-       } else if (set) {
-               set_hardware_clock_exact(set_time, startup_time,
-                                        universal, testing);
-               if (!noadjfile)
-                       adjust_drift_factor(&adjtime,
+       } else if (ctl->set) {
+               set_hardware_clock_exact(ctl, set_time, startup_time);
+               if (!ctl->noadjfile)
+                       adjust_drift_factor(ctl, adjtime,
                                            time_inc(t2tv(set_time), time_diff
                                                     (read_time, startup_time)),
-                                           hclock_valid, hclocktime, update);
-       } else if (adjust) {
+                                           hclock_valid, hclocktime);
+       } else if (ctl->adjust) {
                if (tdrift.tv_sec > 0 || tdrift.tv_sec < -1)
-                       do_adjustment(&adjtime, hclock_valid,
-                                     hclocktime, read_time, universal, testing);
+                       do_adjustment(ctl, adjtime, hclock_valid,
+                                     hclocktime, read_time);
                else
                        printf(_("Needed adjustment is less than one second, "
                                 "so not setting clock.\n"));
-       } else if (systohc) {
+       } else if (ctl->systohc) {
                struct timeval nowtime, reftime;
                /*
                 * We can only set_hardware_clock_exact to a
@@ -1349,37 +1318,34 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
                gettimeofday(&nowtime, NULL);
                reftime.tv_sec = nowtime.tv_sec;
                reftime.tv_usec = 0;
-               set_hardware_clock_exact((time_t)
-                                        reftime.tv_sec,
-                                        reftime, universal, testing);
-               if (!noadjfile)
-                       adjust_drift_factor(&adjtime, nowtime,
-                                           hclock_valid, hclocktime, update);
-       } else if (hctosys) {
-               rc = set_system_clock(hclock_valid, hclocktime,
-                                     testing, universal);
+               set_hardware_clock_exact(ctl, (time_t) reftime.tv_sec, reftime);
+               if (!ctl->noadjfile)
+                       adjust_drift_factor(ctl, adjtime, nowtime,
+                                           hclock_valid, hclocktime);
+       } else if (ctl->hctosys) {
+               rc = set_system_clock(ctl, hclock_valid, hclocktime);
                if (rc) {
                        printf(_("Unable to set system clock.\n"));
                        return rc;
                }
-       } else if (systz) {
-               rc = set_system_clock_timezone(universal, testing);
+       } else if (ctl->systz) {
+               rc = set_system_clock_timezone(ctl);
                if (rc) {
                        printf(_("Unable to set system clock.\n"));
                        return rc;
                }
-       } else if (predict) {
+       } else if (ctl->predict) {
                hclocktime = time_inc(hclocktime, (double)
                                      -(tdrift.tv_sec + tdrift.tv_usec / 1E6));
-               if (debug) {
+               if (ctl->debug) {
                        printf(_
                               ("At %ld seconds after 1969, RTC is predicted to read %ld seconds after 1969.\n"),
                               set_time, hclocktime.tv_sec);
                }
                display_time(TRUE, hclocktime);
        }
-       if (!noadjfile)
-               save_adjtime(adjtime, testing);
+       if (!ctl->noadjfile)
+               save_adjtime(ctl, adjtime);
        return 0;
 }
 
@@ -1397,10 +1363,7 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
  */
 # ifndef __alpha__
 static void
-manipulate_epoch(const bool getepoch __attribute__ ((__unused__)),
-                const bool setepoch __attribute__ ((__unused__)),
-                const unsigned long epoch_opt __attribute__ ((__unused__)),
-                const bool testing __attribute__ ((__unused__)))
+manipulate_epoch(const struct hwclock_control *ctl __attribute__((__unused__)))
 {
        warnx(_("The kernel keeps an epoch value for the Hardware Clock "
                "only on an Alpha machine.\nThis copy of hwclock was built for "
@@ -1409,30 +1372,27 @@ manipulate_epoch(const bool getepoch __attribute__ ((__unused__)),
 }
 # else
 static void
-manipulate_epoch(const bool getepoch,
-                const bool setepoch,
-                const unsigned long epoch_opt,
-                const bool testing)
+manipulate_epoch(const struct hwclock_control *ctl)
 {
-       if (getepoch) {
+       if (ctl->getepoch) {
                unsigned long epoch;
 
-               if (get_epoch_rtc(&epoch, 0))
+               if (get_epoch_rtc(ctl, &epoch, 0))
                        warnx(_
                              ("Unable to get the epoch value from the kernel."));
                else
                        printf(_("Kernel is assuming an epoch value of %lu\n"),
                               epoch);
-       } else if (setepoch) {
-               if (epoch_opt == ULONG_MAX)
+       } else if (ctl->setepoch) {
+               if (ctl->epoch_option == 0)
                        warnx(_
                              ("To set the epoch value, you must use the 'epoch' "
                               "option to tell to what value to set it."));
-               else if (testing)
+               else if (ctl->testing)
                        printf(_
                               ("Not setting the epoch to %lu - testing only.\n"),
-                              epoch_opt);
-               else if (set_epoch_rtc(epoch_opt))
+                              ctl->epoch_option);
+               else if (set_epoch_rtc(ctl))
                        printf(_
                               ("Unable to set the epoch value in the kernel.\n"));
        }
@@ -1444,15 +1404,13 @@ manipulate_epoch(const bool getepoch,
  * Compare the system and CMOS time and output the drift
  * in 10 second intervals.
  */
-static int compare_clock (const bool utc, const bool local_opt)
+static int compare_clock(const struct hwclock_control *ctl)
 {
        struct tm tm;
        struct timeval tv;
-       struct adjtime adjtime;
        double time1_sys, time2_sys;
        time_t time1_hw, time2_hw;
-       bool hclock_valid = FALSE, universal, first_pass = TRUE;
-       int rc;
+       bool hclock_valid = FALSE, first_pass = TRUE;
 
        if (ur->get_permissions())
                return EX_NOPERM;
@@ -1460,30 +1418,24 @@ static int compare_clock (const bool utc, const bool local_opt)
        /* dummy call for increased precision */
        gettimeofday(&tv, NULL);
 
-       rc = read_adjtime(&adjtime);
-       if (rc)
-               return rc;
-
-       universal = hw_clock_is_utc(utc, local_opt, adjtime);
-
-       synchronize_to_clock_tick();
-       ur->read_hardware_clock(&tm);
+       synchronize_to_clock_tick(ctl);
+       ur->read_hardware_clock(ctl, &tm);
 
        gettimeofday(&tv, NULL);
        time1_sys = tv.tv_sec + tv.tv_usec / 1000000.0;
 
-       mktime_tz(tm, universal, &hclock_valid, &time1_hw);
+       mktime_tz(ctl, tm, &hclock_valid, &time1_hw);
 
        while (1) {
                double res;
 
-               synchronize_to_clock_tick();
-               ur->read_hardware_clock(&tm);
+               synchronize_to_clock_tick(ctl);
+               ur->read_hardware_clock(ctl, &tm);
 
                gettimeofday(&tv, NULL);
                time2_sys = tv.tv_sec + tv.tv_usec / 1000000.0;
 
-               mktime_tz(tm, universal, &hclock_valid, &time2_hw);
+               mktime_tz(ctl, tm, &hclock_valid, &time2_hw);
 
                res = (((double) time1_hw - time1_sys) -
                       ((double) time2_hw - time2_sys))
@@ -1519,7 +1471,7 @@ static void out_version(void)
  * fmt, ... ), show a usage information and terminate the program
  * afterwards.
  */
-static void usage(const char *fmt, ...)
+static void usage(const struct hwclock_control *ctl, const char *fmt, ...)
 {
        FILE *usageto;
        va_list ap;
@@ -1585,7 +1537,7 @@ static void usage(const char *fmt, ...)
        }
 
        fflush(usageto);
-       hwclock_exit(fmt ? EX_USAGE : EX_OK);
+       hwclock_exit(ctl, fmt ? EX_USAGE : EX_OK);
 }
 
 /*
@@ -1599,7 +1551,9 @@ static void usage(const char *fmt, ...)
  */
 int main(int argc, char **argv)
 {
+       struct hwclock_control ctl = { 0 };
        struct timeval startup_time;
+       struct adjtime adjtime = { 0 };
        /*
         * The time we started up, in seconds into the epoch, including
         * fractions.
@@ -1607,15 +1561,6 @@ int main(int argc, char **argv)
        time_t set_time = 0;    /* Time to which user said to set Hardware Clock */
        int rc, c;
 
-       /* Variables set by various options; show may also be set later */
-       /* The options debug, badyear and epoch_option are global */
-       bool show, set, systohc, hctosys, systz, adjust, getepoch, setepoch,
-           predict, compare, get;
-       bool utc, testing, local_opt, update, noadjfile, directisa;
-       char *date_opt;
-#ifdef __alpha__
-       bool ARCconsole, Jensen, SRM, funky_toy;
-#endif
        /* Long only options. */
        enum {
                OPT_ADJFILE = CHAR_MAX + 1,
@@ -1716,15 +1661,6 @@ int main(int argc, char **argv)
        textdomain(PACKAGE);
        atexit(close_stdout);
 
-       /* Set option defaults */
-       show = set = systohc = hctosys = systz = adjust = noadjfile = predict =
-           compare = get = update = FALSE;
-       getepoch = setepoch = utc = local_opt = directisa = testing = debug = FALSE;
-#ifdef __alpha__
-       ARCconsole = Jensen = SRM = funky_toy = badyear = FALSE;
-#endif
-       date_opt = NULL;
-
        while ((c = getopt_long(argc, argv,
                                "?hvVDacrsuwAJSFf:", longopts, NULL)) != -1) {
 
@@ -1732,91 +1668,91 @@ int main(int argc, char **argv)
 
                switch (c) {
                case 'D':
-                       ++debug;
+                       ctl.debug++;
                        break;
                case 'a':
-                       adjust = TRUE;
+                       ctl.adjust = 1;
                        break;
                case 'c':
-                       compare = TRUE;
+                       ctl.compare = 1;
                        break;
                case 'r':
-                       show = TRUE;
+                       ctl.show = 1;
                        break;
                case 's':
-                       hctosys = TRUE;
+                       ctl.hctosys = 1;
                        break;
                case 'u':
-                       utc = TRUE;
+                       ctl.utc = 1;
                        break;
                case 'w':
-                       systohc = TRUE;
+                       ctl.systohc = 1;
                        break;
 #ifdef __alpha__
                case 'A':
-                       ARCconsole = TRUE;
+                       ctl.ARCconsole = 1;
                        break;
                case 'J':
-                       Jensen = TRUE;
+                       ctl.Jensen = 1;
                        break;
                case 'S':
-                       SRM = TRUE;
+                       ctl.SRM = 1;
                        break;
                case 'F':
-                       funky_toy = TRUE;
+                       ctl.funky_toy = 1;
                        break;
 #endif
                case OPT_SET:
-                       set = TRUE;
+                       ctl.set = 1;
                        break;
 #ifdef __linux__
                case OPT_GETEPOCH:
-                       getepoch = TRUE;
+                       ctl.getepoch = 1;
                        break;
                case OPT_SETEPOCH:
-                       setepoch = TRUE;
+                       ctl.setepoch = 1;
                        break;
 #endif
                case OPT_NOADJFILE:
-                       noadjfile = TRUE;
+                       ctl.noadjfile = 1;
                        break;
                case OPT_LOCALTIME:
-                       local_opt = TRUE;       /* --localtime */
+                       ctl.local_opt = 1;      /* --localtime */
                        break;
                case OPT_BADYEAR:
-                       badyear = TRUE;
+                       ctl.badyear = 1;
                        break;
                case OPT_DIRECTISA:
-                       directisa = TRUE;
+                       ctl.directisa = 1;
                        break;
                case OPT_TEST:
-                       testing = TRUE;         /* --test */
+                       ctl.testing = 1;        /* --test */
                        break;
                case OPT_DATE:
-                       date_opt = optarg;      /* --date */
+                       ctl.date_opt = optarg;  /* --date */
                        break;
                case OPT_EPOCH:
-                       epoch_option =          /* --epoch */
+                       ctl.epoch_option =      /* --epoch */
                            strtoul_or_err(optarg, _("invalid epoch argument"));
                        break;
                case OPT_ADJFILE:
-                       adj_file_name = optarg; /* --adjfile */
+                       ctl.adj_file_name = optarg;     /* --adjfile */
                        break;
                case OPT_SYSTZ:
-                       systz = TRUE;           /* --systz */
+                       ctl.systz = 1;          /* --systz */
                        break;
                case OPT_PREDICT_HC:
-                       predict = TRUE;         /* --predict-hc */
+                       ctl.predict = 1;        /* --predict-hc */
                        break;
                case OPT_GET:
-                       get = TRUE;             /* --get */
+                       ctl.get = 1;            /* --get */
                        break;
                case OPT_UPDATE:
-                       update = TRUE;          /* --update-drift */
+                       ctl.update = 1;         /* --update-drift */
                        break;
 #ifdef __linux__
                case 'f':
-                       rtc_dev_name = optarg;  /* --rtc */
+                       ctl.rtc_dev_name = optarg;      /* --rtc */
                        break;
 #endif
                case 'v':                       /* --version */
@@ -1824,9 +1760,9 @@ int main(int argc, char **argv)
                        out_version();
                        return 0;
                case 'h':                       /* --help */
-                       usage(NULL);
+               case '?':
                default:
-                       errtryhelp(EXIT_FAILURE);
+                       usage(&ctl, NULL);
                }
        }
 
@@ -1834,88 +1770,98 @@ int main(int argc, char **argv)
        argv += optind;
 
 #ifdef HAVE_LIBAUDIT
-       if (testing != TRUE) {
-               if (adjust == TRUE || hctosys == TRUE || systohc == TRUE ||
-                   set == TRUE || setepoch == TRUE) {
-                       hwaudit_on = TRUE;
+       if (!ctl.testing) {
+               if (ctl.adjust || ctl.hctosys || ctl.systohc ||
+                   ctl.set || ctl.setepoch) {
+                       ctl.hwaudit_on = 1;
                }
        }
 #endif
        if (argc > 0) {
-               usage(_("%s takes no non-option arguments.  "
+               usage(&ctl, _("%s takes no non-option arguments.  "
                        "You supplied %d.\n"), program_invocation_short_name,
                      argc);
        }
 
-       if (!adj_file_name)
-               adj_file_name = _PATH_ADJTIME;
+       if (!ctl.adj_file_name)
+               ctl.adj_file_name = _PATH_ADJTIME;
 
-       if (noadjfile && !utc && !local_opt) {
+       if (ctl.noadjfile && !ctl.utc && !ctl.local_opt) {
                warnx(_("With --noadjfile, you must specify "
                        "either --utc or --localtime"));
-               hwclock_exit(EX_USAGE);
+               hwclock_exit(&ctl, EX_USAGE);
        }
 #ifdef __alpha__
-       set_cmos_epoch(ARCconsole, SRM);
-       set_cmos_access(Jensen, funky_toy);
+       set_cmos_epoch(&ctl);
+       set_cmos_access(&ctl);
 #endif
 
-       if (set || predict) {
-               rc = interpret_date_string(date_opt, &set_time);
+       if (ctl.set || ctl.predict) {
+               rc = interpret_date_string(&ctl, &set_time);
                /* (time-consuming) */
                if (rc != 0) {
                        warnx(_("No usable set-to time.  "
                                "Cannot set clock."));
-                       hwclock_exit(EX_USAGE);
+                       hwclock_exit(&ctl, EX_USAGE);
                }
        }
 
-       if (!(show | set | systohc | hctosys | systz | adjust | getepoch
-             | setepoch | predict | compare | get))
-               show = 1;       /* default to show */
-
+       if (!(ctl.show | ctl.set | ctl.systohc | ctl.hctosys |
+            ctl.systz | ctl.adjust | ctl.getepoch | ctl.setepoch |
+            ctl.predict | ctl.compare | ctl.get))
+               ctl.show = 1;   /* default to show */
 
 #ifdef __linux__
-       if (getepoch || setepoch) {
-               manipulate_epoch(getepoch, setepoch, epoch_option, testing);
-               hwclock_exit(EX_OK);
+       if (ctl.getepoch || ctl.setepoch) {
+               manipulate_epoch(&ctl);
+               hwclock_exit(&ctl, EX_OK);
        }
 #endif
 
-       if (debug)
+       if (ctl.debug)
                out_version();
 
-       if (!systz && !predict) {
-               determine_clock_access_method(directisa);
+       if (!ctl.systz && !ctl.predict) {
+               determine_clock_access_method(&ctl);
                if (!ur) {
                        warnx(_("Cannot access the Hardware Clock via "
                                "any known method."));
-                       if (!debug)
+                       if (!ctl.debug)
                                warnx(_("Use the --debug option to see the "
                                        "details of our search for an access "
                                        "method."));
-                       hwclock_exit(EX_SOFTWARE);
+                       hwclock_exit(&ctl, EX_SOFTWARE);
                }
        }
 
-       if (compare) {
-               if (compare_clock(utc, local_opt))
-                       hwclock_exit(EX_NOPERM);
+       if (!ctl.noadjfile && !(ctl.systz && (ctl.utc || ctl.local_opt))) {
+               if ((rc = read_adjtime(&ctl, &adjtime)) != 0)
+                       hwclock_exit(&ctl, rc);
+       } else
+               /* Avoid writing adjtime file if we don't have to. */
+               adjtime.dirty = FALSE;
+       ctl.universal = hw_clock_is_utc(&ctl, adjtime);
+       if (ctl.compare) {
+               if (compare_clock(&ctl))
+                       hwclock_exit(&ctl, EX_NOPERM);
 
                rc = EX_OK;
        } else
-               rc = manipulate_clock(show, adjust, noadjfile, set, set_time,
-                             hctosys, systohc, systz, startup_time, utc,
-                             local_opt, update, testing, predict, get);
+               rc = manipulate_clock(&ctl, set_time, startup_time, &adjtime);
 
-       hwclock_exit(rc);
+       hwclock_exit(&ctl, rc);
        return rc;              /* Not reached */
 }
 
-void __attribute__((__noreturn__)) hwclock_exit(int status)
+void __attribute__((__noreturn__))
+hwclock_exit(const struct hwclock_control *ctl
+#ifndef HAVE_LIBAUDIT
+            __attribute__((__unused__))
+#endif
+            , int status)
 {
 #ifdef HAVE_LIBAUDIT
-       if (hwaudit_on) {
+       if (ctl->hwaudit_on) {
                audit_log_user_message(hwaudit_fd, AUDIT_USYS_CONFIG,
                                       "op=change-system-time", NULL, NULL, NULL,
                                       status ? 0 : 1);
index d58ebbc6f1d090587c77e75832f47a010760f5ce..c76068c881af5e7496b6d04e23ef707cbe59c726 100644 (file)
@@ -9,16 +9,57 @@
 
 #include "c.h"
 
+struct hwclock_control {
+       char *date_opt;
+       unsigned long epoch_option;
+       char *adj_file_name;
+#ifdef __linux__
+       char *rtc_dev_name;
+#endif
+       unsigned int debug;
+       unsigned int
+#ifdef HAVE_LIBAUDIT
+               hwaudit_on:1,
+#endif
+               adjust:1,
+               compare:1,
+               show:1,
+               hctosys:1,
+               utc:1,
+               systohc:1,
+#ifdef __alpha__
+               ARCconsole:1,
+               Jensen:1,
+               SRM:1,
+               funky_toy:1,
+#endif
+#ifdef __linux__
+               getepoch:1,
+               setepoch:1,
+#endif
+               noadjfile:1,
+               local_opt:1,
+               badyear:1,
+               directisa:1,
+               testing:1,
+               systz:1,
+               predict:1,
+               get:1,
+               set:1,
+               update:1,
+               universal:1;    /* will store hw_clock_is_utc() return value */
+};
+
 struct clock_ops {
        char *interface_name;
        int (*get_permissions) (void);
-       int (*read_hardware_clock) (struct tm * tm);
-       int (*set_hardware_clock) (const struct tm * tm);
-       int (*synchronize_to_clock_tick) (void);
+       int (*read_hardware_clock) (const struct hwclock_control *ctl, struct tm * tm);
+       int (*set_hardware_clock) (const struct hwclock_control *ctl, const struct tm * tm);
+       int (*synchronize_to_clock_tick) (const struct hwclock_control *ctl);
 };
 
 extern struct clock_ops *probe_for_cmos_clock(void);
-extern struct clock_ops *probe_for_rtc_clock(void);
+extern struct clock_ops *probe_for_rtc_clock(const struct hwclock_control *ctl);
 
 typedef int bool;
 
@@ -27,14 +68,13 @@ extern int debug;
 extern unsigned long epoch_option;
 extern double time_diff(struct timeval subtrahend, struct timeval subtractor);
 /* cmos.c */
-extern void set_cmos_epoch(int ARCconsole, int SRM);
-extern void set_cmos_access(int Jensen, int funky_toy);
+extern void set_cmos_epoch(const struct hwclock_control *ctl);
+extern void set_cmos_access(const struct hwclock_control *ctl);
 
 /* rtc.c */
-extern int get_epoch_rtc(unsigned long *epoch, int silent);
-extern int set_epoch_rtc(unsigned long epoch);
-extern char *rtc_dev_name;
+extern int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch, int silent);
+extern int set_epoch_rtc(const struct hwclock_control *ctl);
 
-extern void hwclock_exit(int status);
+extern void hwclock_exit(const struct hwclock_control *ctl, int status);
 
 #endif                         /* HWCLOCK_CLOCK_H */