]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
hwclock: get/set param cleanup
authorKarel Zak <kzak@redhat.com>
Mon, 31 Jan 2022 09:05:29 +0000 (10:05 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 31 Jan 2022 09:05:29 +0000 (10:05 +0100)
* move all code to hwclock-rtc.c
* use ul_strtou64() to simplify code
* use base=0 for ul_strtou64() to handle 10 and 16 base
* allocate for strtok() (we keep command line options read-only)

Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/hwclock-rtc.c
sys-utils/hwclock.c
sys-utils/hwclock.h

index e10f7bce01ae9877ee1707681b74a93e9f6704b3..cef487008b661d5a525e6b9edecceffc3e4c4730 100644 (file)
@@ -15,6 +15,8 @@
 #include <unistd.h>
 
 #include "monotonic.h"
+#include "strutils.h"
+#include "xalloc.h"
 #include "nls.h"
 
 #include "hwclock.h"
@@ -86,6 +88,26 @@ struct linux_rtc_time {
 # define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long)  /* Set epoch */
 #endif
 
+#ifndef RTC_PARAM_GET
+struct rtc_param {
+       uint64_t param;
+       union {
+               uint64_t uvalue;
+               int64_t svalue;
+               uint64_t ptr;
+       };
+       uint32_t index;
+       uint32_t __pad;
+};
+
+# define RTC_PARAM_GET _IOW('p', 0x13, struct rtc_param)
+# define RTC_PARAM_SET _IOW('p', 0x14, struct rtc_param)
+
+# define RTC_PARAM_FEATURES            0
+# define RTC_PARAM_CORRECTION          1
+# define RTC_PARAM_BACKUP_SWITCH_MODE  2
+#endif /* RTC_PARAM_GET */
+
 static const struct hwclock_param hwclock_params[] =
 {
        { RTC_PARAM_FEATURES,  "features", N_("supported features") },
@@ -487,22 +509,17 @@ static int resolve_rtc_param_alias(const char *alias, uint64_t *value)
 /*
  * Get the Hardware Clock parameter setting from the kernel.
  */
-int get_param_rtc(const struct hwclock_control *ctl, struct rtc_param *param)
+int get_param_rtc(const struct hwclock_control *ctl,
+                 const char *name, uint64_t *id, uint64_t *value)
 {
        int rtc_fd;
+       struct rtc_param param = { .param = 0 };
 
        /* handle name */
-       if (resolve_rtc_param_alias(ctl->param_get_option, &param->param)) {
-               char *end = NULL;
-               int base;
-
-               base = strncmp(ctl->param_get_option, "0x", 2) ? 10 : 16;
-               errno = 0;
-               param->param = strtoull(ctl->param_get_option, &end, base);
-               if (errno || !end || *end) {
-                       warnx(_("could not convert parameter name to number"));
-                       return 1;
-               }
+       if (resolve_rtc_param_alias(name, &param.param) != 0
+           && ul_strtou64(name, &param.param, 0) != 0) {
+               warnx(_("could not convert parameter name to number"));
+               return 1;
        }
 
        /* get parameter */
@@ -512,12 +529,17 @@ int get_param_rtc(const struct hwclock_control *ctl, struct rtc_param *param)
                return 1;
        }
 
-       if (ioctl(rtc_fd, RTC_PARAM_GET, param) == -1) {
+       if (ioctl(rtc_fd, RTC_PARAM_GET, &param) == -1) {
                warn(_("ioctl(%d, RTC_PARAM_GET, param) to %s failed"),
                     rtc_fd, rtc_dev_name);
                return 1;
        }
 
+       if (id)
+               *id = param.param;
+       if (*value)
+               *value = param.uvalue;
+
        if (ctl->verbose)
                printf(_("ioctl(%d, RTC_PARAM_GET, param) to %s succeeded.\n"),
                       rtc_fd, rtc_dev_name);
@@ -528,41 +550,29 @@ int get_param_rtc(const struct hwclock_control *ctl, struct rtc_param *param)
 /*
  * Set the Hardware Clock parameter in the kernel.
  */
-int set_param_rtc(const struct hwclock_control *ctl)
+int set_param_rtc(const struct hwclock_control *ctl, const char *opt0)
 {
-       char *tok = NULL, *end = NULL;
-       int rtc_fd, base;
-       struct rtc_param param;
-
-       memset(&param, 0, sizeof(param));
+       int rtc_fd, rc = 1;
+       struct rtc_param param = { .param = 0 };
+       char *tok, *opt = xstrdup(opt0);
 
        /* handle name */
-       tok = strtok(ctl->param_set_option, "=");
-       if (resolve_rtc_param_alias(tok, &param.param)) {
-               base = strncmp(tok, "0x", 2) ? 10 : 16;
-
-               errno = 0;
-               param.param = strtoull(tok, &end, base);
-               if (errno || !end || *end) {
-                       warnx(_("could not convert parameter name to number"));
-                       return 1;
-               }
+       tok = strtok(opt, "=");
+       if (resolve_rtc_param_alias(tok, &param.param) != 0
+           && ul_strtou64(tok, &param.param, 0) != 0) {
+               warnx(_("could not convert parameter name to number"));
+               goto done;
        }
 
        /* handle value */
        tok = strtok(NULL, "=");
        if (!tok) {
                warnx(_("expected <param>=<value>"));
-               return 1;
+               goto done;
        }
-
-       base = strncmp(tok, "0x", 2) ? 10 : 16;
-       end = NULL;
-       errno = 0;
-       param.uvalue = strtoull(tok, &end, base);
-       if (errno || !end || *end) {
+       if (ul_strtou64(tok, &param.uvalue, 0) != 0) {
                warnx(_("could not convert parameter value to number"));
-               return 1;
+               goto done;
        }
 
        /* set parameter */
@@ -575,12 +585,15 @@ int set_param_rtc(const struct hwclock_control *ctl)
        if (ioctl(rtc_fd, RTC_PARAM_SET, &param) == -1) {
                warn(_("ioctl(%d, RTC_PARAM_SET, param) to %s failed"),
                     rtc_fd, rtc_dev_name);
-               return 1;
+               goto done;
        }
 
        if (ctl->verbose)
                printf(_("ioctl(%d, RTC_PARAM_SET, param) to %s succeeded.\n"),
                       rtc_fd, rtc_dev_name);
 
-       return 0;
+       rc = 0;
+done:
+       free(opt);
+       return rc;
 }
index 61f684e389b8cc489cde16176194963e72315e77..97c6ca951c7975eda933941e5fbe857e444b903c 100644 (file)
@@ -1158,22 +1158,22 @@ static int
 manipulate_rtc_param(const struct hwclock_control *ctl)
 {
        if (ctl->param_get_option) {
-               struct rtc_param param = {};
+               uint64_t id = 0, value = 0;
 
-               if (get_param_rtc(ctl, &param)) {
-                       warnx(_("unable to read the RTC parameter 0x%jx."),
-                                       (uintmax_t) param.param);
+               if (get_param_rtc(ctl, ctl->param_get_option, &id, &value)) {
+                       warnx(_("unable to read the RTC parameter %s"),
+                                       ctl->param_get_option);
                        return 1;
                }
 
                printf(_("The RTC parameter 0x%jx is set to 0x%jx.\n"),
-                      (uintmax_t) param.param, (uintmax_t) param.uvalue);
+                      (uintmax_t) id, (uintmax_t) value);
 
        } else if (ctl->param_set_option) {
                if (ctl->testing)
                        return 0;
 
-               return set_param_rtc(ctl);
+               return set_param_rtc(ctl, ctl->param_set_option);
        }
 
        return 1;
index 9b553441c4b90f143b3b292be45934ae24a7f06a..951857c2230f5f1e292f115eb8cd264ae7f633e6 100644 (file)
@@ -77,24 +77,6 @@ extern int get_epoch_rtc(const struct hwclock_control *ctl, unsigned long *epoch
 extern int set_epoch_rtc(const struct hwclock_control *ctl);
 #endif
 
-struct rtc_param {
-       uint64_t param;
-       union {
-               uint64_t uvalue;
-               int64_t svalue;
-               uint64_t ptr;
-       };
-       uint32_t index;
-       uint32_t __pad;
-};
-
-#define RTC_PARAM_GET  _IOW('p', 0x13, struct rtc_param)
-#define RTC_PARAM_SET  _IOW('p', 0x14, struct rtc_param)
-
-#define RTC_PARAM_FEATURES             0
-#define RTC_PARAM_CORRECTION           1
-#define RTC_PARAM_BACKUP_SWITCH_MODE   2
-
 struct hwclock_param {
        int id;
        const char *name;
@@ -102,8 +84,9 @@ struct hwclock_param {
 };
 
 extern const struct hwclock_param *get_hwclock_params(void);
-extern int get_param_rtc(const struct hwclock_control *ctl, struct rtc_param *param);
-extern int set_param_rtc(const struct hwclock_control *ctl);
+extern int get_param_rtc(const struct hwclock_control *ctl,
+                       const char *name, uint64_t *id, uint64_t *value);
+extern int set_param_rtc(const struct hwclock_control *ctl, const char *name);
 
 extern void __attribute__((__noreturn__))
 hwclock_exit(const struct hwclock_control *ctl, int status);