]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev-event: refactor udev_event_apply_format
authorDan Streetman <ddstreet@ieee.org>
Thu, 26 Jan 2017 01:06:54 +0000 (20:06 -0500)
committerDan Streetman <ddstreet@ieee.org>
Fri, 27 Jan 2017 12:58:00 +0000 (07:58 -0500)
Move the large case statement into its own function

src/udev/udev-event.c

index deffefd60be21cf44adbd87e1660448e196f16c2..3cb2673291856574c44ffa80c1dfbc9716cde101 100644 (file)
@@ -73,29 +73,221 @@ void udev_event_unref(struct udev_event *event) {
         free(event);
 }
 
+enum subst_type {
+        SUBST_UNKNOWN,
+        SUBST_DEVNODE,
+        SUBST_ATTR,
+        SUBST_ENV,
+        SUBST_KERNEL,
+        SUBST_KERNEL_NUMBER,
+        SUBST_DRIVER,
+        SUBST_DEVPATH,
+        SUBST_ID,
+        SUBST_MAJOR,
+        SUBST_MINOR,
+        SUBST_RESULT,
+        SUBST_PARENT,
+        SUBST_NAME,
+        SUBST_LINKS,
+        SUBST_ROOT,
+        SUBST_SYS,
+};
+
+static size_t subst_format_var(struct udev_event *event, struct udev_device *dev,
+                               enum subst_type type, char *attr,
+                               char **dest, size_t l) {
+        char *s = *dest;
+
+        switch (type) {
+        case SUBST_DEVPATH:
+                l = strpcpy(&s, l, udev_device_get_devpath(dev));
+                break;
+        case SUBST_KERNEL:
+                l = strpcpy(&s, l, udev_device_get_sysname(dev));
+                break;
+        case SUBST_KERNEL_NUMBER:
+                if (udev_device_get_sysnum(dev) == NULL)
+                        break;
+                l = strpcpy(&s, l, udev_device_get_sysnum(dev));
+                break;
+        case SUBST_ID:
+                if (event->dev_parent == NULL)
+                        break;
+                l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent));
+                break;
+        case SUBST_DRIVER: {
+                const char *driver;
+
+                if (event->dev_parent == NULL)
+                        break;
+
+                driver = udev_device_get_driver(event->dev_parent);
+                if (driver == NULL)
+                        break;
+                l = strpcpy(&s, l, driver);
+                break;
+        }
+        case SUBST_MAJOR: {
+                char num[UTIL_PATH_SIZE];
+
+                sprintf(num, "%u", major(udev_device_get_devnum(dev)));
+                l = strpcpy(&s, l, num);
+                break;
+        }
+        case SUBST_MINOR: {
+                char num[UTIL_PATH_SIZE];
+
+                sprintf(num, "%u", minor(udev_device_get_devnum(dev)));
+                l = strpcpy(&s, l, num);
+                break;
+        }
+        case SUBST_RESULT: {
+                char *rest;
+                int i;
+
+                if (event->program_result == NULL)
+                        break;
+                /* get part of the result string */
+                i = 0;
+                if (attr != NULL)
+                        i = strtoul(attr, &rest, 10);
+                if (i > 0) {
+                        char result[UTIL_PATH_SIZE];
+                        char tmp[UTIL_PATH_SIZE];
+                        char *cpos;
+
+                        strscpy(result, sizeof(result), event->program_result);
+                        cpos = result;
+                        while (--i) {
+                                while (cpos[0] != '\0' && !isspace(cpos[0]))
+                                        cpos++;
+                                while (isspace(cpos[0]))
+                                        cpos++;
+                                if (cpos[0] == '\0')
+                                        break;
+                        }
+                        if (i > 0) {
+                                log_error("requested part of result string not found");
+                                break;
+                        }
+                        strscpy(tmp, sizeof(tmp), cpos);
+                        /* %{2+}c copies the whole string from the second part on */
+                        if (rest[0] != '+') {
+                                cpos = strchr(tmp, ' ');
+                                if (cpos)
+                                        cpos[0] = '\0';
+                        }
+                        l = strpcpy(&s, l, tmp);
+                } else {
+                        l = strpcpy(&s, l, event->program_result);
+                }
+                break;
+        }
+        case SUBST_ATTR: {
+                const char *value = NULL;
+                char vbuf[UTIL_NAME_SIZE];
+                size_t len;
+                int count;
+
+                if (attr == NULL) {
+                        log_error("missing file parameter for attr");
+                        break;
+                }
+
+                /* try to read the value specified by "[dmi/id]product_name" */
+                if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0)
+                        value = vbuf;
+
+                /* try to read the attribute the device */
+                if (value == NULL)
+                        value = udev_device_get_sysattr_value(event->dev, attr);
+
+                /* try to read the attribute of the parent device, other matches have selected */
+                if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev)
+                        value = udev_device_get_sysattr_value(event->dev_parent, attr);
+
+                if (value == NULL)
+                        break;
+
+                /* strip trailing whitespace, and replace unwanted characters */
+                if (value != vbuf)
+                        strscpy(vbuf, sizeof(vbuf), value);
+                len = strlen(vbuf);
+                while (len > 0 && isspace(vbuf[--len]))
+                        vbuf[len] = '\0';
+                count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
+                if (count > 0)
+                        log_debug("%i character(s) replaced" , count);
+                l = strpcpy(&s, l, vbuf);
+                break;
+        }
+        case SUBST_PARENT: {
+                struct udev_device *dev_parent;
+                const char *devnode;
+
+                dev_parent = udev_device_get_parent(event->dev);
+                if (dev_parent == NULL)
+                        break;
+                devnode = udev_device_get_devnode(dev_parent);
+                if (devnode != NULL)
+                        l = strpcpy(&s, l, devnode + strlen("/dev/"));
+                break;
+        }
+        case SUBST_DEVNODE:
+                if (udev_device_get_devnode(dev) != NULL)
+                        l = strpcpy(&s, l, udev_device_get_devnode(dev));
+                break;
+        case SUBST_NAME:
+                if (event->name != NULL)
+                        l = strpcpy(&s, l, event->name);
+                else if (udev_device_get_devnode(dev) != NULL)
+                        l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
+                else
+                        l = strpcpy(&s, l, udev_device_get_sysname(dev));
+                break;
+        case SUBST_LINKS: {
+                struct udev_list_entry *list_entry;
+
+                list_entry = udev_device_get_devlinks_list_entry(dev);
+                if (list_entry == NULL)
+                        break;
+                l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
+                udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
+                        l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
+                break;
+        }
+        case SUBST_ROOT:
+                l = strpcpy(&s, l, "/dev");
+                break;
+        case SUBST_SYS:
+                l = strpcpy(&s, l, "/sys");
+                break;
+        case SUBST_ENV:
+                if (attr == NULL) {
+                        break;
+                } else {
+                        const char *value;
+
+                        value = udev_device_get_property_value(event->dev, attr);
+                        if (value == NULL)
+                                break;
+                        l = strpcpy(&s, l, value);
+                        break;
+                }
+        default:
+                log_error("unknown substitution type=%i", type);
+                break;
+        }
+
+        *dest = s;
+
+        return l;
+}
+
 size_t udev_event_apply_format(struct udev_event *event,
                                const char *src, char *dest, size_t size,
                                bool replace_whitespace) {
         struct udev_device *dev = event->dev;
-        enum subst_type {
-                SUBST_UNKNOWN,
-                SUBST_DEVNODE,
-                SUBST_ATTR,
-                SUBST_ENV,
-                SUBST_KERNEL,
-                SUBST_KERNEL_NUMBER,
-                SUBST_DRIVER,
-                SUBST_DEVPATH,
-                SUBST_ID,
-                SUBST_MAJOR,
-                SUBST_MINOR,
-                SUBST_RESULT,
-                SUBST_PARENT,
-                SUBST_NAME,
-                SUBST_LINKS,
-                SUBST_ROOT,
-                SUBST_SYS,
-        };
         static const struct subst_map {
                 const char *name;
                 const char fmt;
@@ -217,186 +409,7 @@ subst:
                         l = UTIL_PATH_SIZE;
                 }
 
-                switch (type) {
-                case SUBST_DEVPATH:
-                        l = strpcpy(&s, l, udev_device_get_devpath(dev));
-                        break;
-                case SUBST_KERNEL:
-                        l = strpcpy(&s, l, udev_device_get_sysname(dev));
-                        break;
-                case SUBST_KERNEL_NUMBER:
-                        if (udev_device_get_sysnum(dev) == NULL)
-                                break;
-                        l = strpcpy(&s, l, udev_device_get_sysnum(dev));
-                        break;
-                case SUBST_ID:
-                        if (event->dev_parent == NULL)
-                                break;
-                        l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent));
-                        break;
-                case SUBST_DRIVER: {
-                        const char *driver;
-
-                        if (event->dev_parent == NULL)
-                                break;
-
-                        driver = udev_device_get_driver(event->dev_parent);
-                        if (driver == NULL)
-                                break;
-                        l = strpcpy(&s, l, driver);
-                        break;
-                }
-                case SUBST_MAJOR: {
-                        char num[UTIL_PATH_SIZE];
-
-                        sprintf(num, "%u", major(udev_device_get_devnum(dev)));
-                        l = strpcpy(&s, l, num);
-                        break;
-                }
-                case SUBST_MINOR: {
-                        char num[UTIL_PATH_SIZE];
-
-                        sprintf(num, "%u", minor(udev_device_get_devnum(dev)));
-                        l = strpcpy(&s, l, num);
-                        break;
-                }
-                case SUBST_RESULT: {
-                        char *rest;
-                        int i;
-
-                        if (event->program_result == NULL)
-                                break;
-                        /* get part of the result string */
-                        i = 0;
-                        if (attr != NULL)
-                                i = strtoul(attr, &rest, 10);
-                        if (i > 0) {
-                                char result[UTIL_PATH_SIZE];
-                                char tmp[UTIL_PATH_SIZE];
-                                char *cpos;
-
-                                strscpy(result, sizeof(result), event->program_result);
-                                cpos = result;
-                                while (--i) {
-                                        while (cpos[0] != '\0' && !isspace(cpos[0]))
-                                                cpos++;
-                                        while (isspace(cpos[0]))
-                                                cpos++;
-                                        if (cpos[0] == '\0')
-                                                break;
-                                }
-                                if (i > 0) {
-                                        log_error("requested part of result string not found");
-                                        break;
-                                }
-                                strscpy(tmp, sizeof(tmp), cpos);
-                                /* %{2+}c copies the whole string from the second part on */
-                                if (rest[0] != '+') {
-                                        cpos = strchr(tmp, ' ');
-                                        if (cpos)
-                                                cpos[0] = '\0';
-                                }
-                                l = strpcpy(&s, l, tmp);
-                        } else {
-                                l = strpcpy(&s, l, event->program_result);
-                        }
-                        break;
-                }
-                case SUBST_ATTR: {
-                        const char *value = NULL;
-                        char vbuf[UTIL_NAME_SIZE];
-                        size_t len;
-                        int count;
-
-                        if (attr == NULL) {
-                                log_error("missing file parameter for attr");
-                                break;
-                        }
-
-                        /* try to read the value specified by "[dmi/id]product_name" */
-                        if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0)
-                                value = vbuf;
-
-                        /* try to read the attribute the device */
-                        if (value == NULL)
-                                value = udev_device_get_sysattr_value(event->dev, attr);
-
-                        /* try to read the attribute of the parent device, other matches have selected */
-                        if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev)
-                                value = udev_device_get_sysattr_value(event->dev_parent, attr);
-
-                        if (value == NULL)
-                                break;
-
-                        /* strip trailing whitespace, and replace unwanted characters */
-                        if (value != vbuf)
-                                strscpy(vbuf, sizeof(vbuf), value);
-                        len = strlen(vbuf);
-                        while (len > 0 && isspace(vbuf[--len]))
-                                vbuf[len] = '\0';
-                        count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
-                        if (count > 0)
-                                log_debug("%i character(s) replaced" , count);
-                        l = strpcpy(&s, l, vbuf);
-                        break;
-                }
-                case SUBST_PARENT: {
-                        struct udev_device *dev_parent;
-                        const char *devnode;
-
-                        dev_parent = udev_device_get_parent(event->dev);
-                        if (dev_parent == NULL)
-                                break;
-                        devnode = udev_device_get_devnode(dev_parent);
-                        if (devnode != NULL)
-                                l = strpcpy(&s, l, devnode + strlen("/dev/"));
-                        break;
-                }
-                case SUBST_DEVNODE:
-                        if (udev_device_get_devnode(dev) != NULL)
-                                l = strpcpy(&s, l, udev_device_get_devnode(dev));
-                        break;
-                case SUBST_NAME:
-                        if (event->name != NULL)
-                                l = strpcpy(&s, l, event->name);
-                        else if (udev_device_get_devnode(dev) != NULL)
-                                l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
-                        else
-                                l = strpcpy(&s, l, udev_device_get_sysname(dev));
-                        break;
-                case SUBST_LINKS: {
-                        struct udev_list_entry *list_entry;
-
-                        list_entry = udev_device_get_devlinks_list_entry(dev);
-                        if (list_entry == NULL)
-                                break;
-                        l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
-                        udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
-                                l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
-                        break;
-                }
-                case SUBST_ROOT:
-                        l = strpcpy(&s, l, "/dev");
-                        break;
-                case SUBST_SYS:
-                        l = strpcpy(&s, l, "/sys");
-                        break;
-                case SUBST_ENV:
-                        if (attr == NULL) {
-                                break;
-                        } else {
-                                const char *value;
-
-                                value = udev_device_get_property_value(event->dev, attr);
-                                if (value == NULL)
-                                        break;
-                                l = strpcpy(&s, l, value);
-                                break;
-                        }
-                default:
-                        log_error("unknown substitution type=%i", type);
-                        break;
-                }
+                l = subst_format_var(event, dev, type, attr, &s, l);
 
                 /* replace whitespace in sbuf and copy to dest */
                 if (replws) {