chiark / gitweb /
ATTR{}== always fails if the attribute does not exist
[elogind.git] / udev / udev-rules.c
index 8c0e1d961b4618c99c05c63f7b5f7f0ab72e0f03..f6cc45ba750d670d8e54fc16be98f838e474e628 100644 (file)
@@ -547,11 +547,12 @@ static int wait_for_file(struct udev_device *dev, const char *file, int timeout)
 {
        struct udev *udev = udev_device_get_udev(dev);
        char filepath[UTIL_PATH_SIZE];
-       char devicepath[UTIL_PATH_SIZE] = "";
+       char devicepath[UTIL_PATH_SIZE];
        struct stat stats;
        int loop = timeout * WAIT_LOOP_PER_SECOND;
 
        /* a relative path is a device attribute */
+       devicepath[0] = '\0';
        if (file[0] != '/') {
                util_strlcpy(devicepath, udev_get_sys_path(udev), sizeof(devicepath));
                util_strlcat(devicepath, udev_device_get_devpath(dev), sizeof(devicepath));
@@ -1791,23 +1792,26 @@ static int match_key(struct udev_rules *rules, struct token *token, const char *
 
 static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct udev_event *event, struct token *cur)
 {
-       char attr[UTIL_PATH_SIZE];
        const char *key_name = &rules->buf[cur->key.attr_off];
        const char *key_value = &rules->buf[cur->key.value_off];
-       char value[UTIL_NAME_SIZE] = "";
+       char value[UTIL_NAME_SIZE];
        size_t len;
 
-       util_strlcpy(attr, key_name, sizeof(attr));
-       util_resolve_subsys_kernel(event->udev, attr, value, sizeof(value), 1);
+       value[0] = '\0';
+       if (key_name[0] == '[') {
+               char attr[UTIL_PATH_SIZE];
+
+               util_strlcpy(attr, key_name, sizeof(attr));
+               util_resolve_subsys_kernel(event->udev, attr, value, sizeof(value), 1);
+       }
        if (value[0] == '\0') {
                const char *val;
 
                val = udev_device_get_sysattr_value(dev, key_name);
-               if (val != NULL)
-                       util_strlcpy(value, val, sizeof(value));
+               if (val == NULL)
+                       return -1;
+               util_strlcpy(value, val, sizeof(value));
        }
-       if (value[0]=='\0')
-               return -1;
 
        /* strip trailing whitespace of value, if not asked to match for it */
        len = strlen(key_value);
@@ -1830,6 +1834,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
 {
        struct token *cur;
        struct token *rule;
+       enum escape_type esc = ESCAPE_UNSET;
 
        if (rules->tokens == NULL)
                return -1;
@@ -1837,8 +1842,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
        /* loop through token list, match, run actions or forward to next rule */
        cur = &rules->tokens[0];
        rule = cur;
-       while (cur != NULL && cur->type != TK_END) {
-               enum escape_type esc = ESCAPE_UNSET;
+       while (1) {
                unsigned int idx;
 
                dump_token(rules, cur);
@@ -2314,11 +2318,11 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                        cur = &rules->tokens[cur->key.rule_goto];
                        continue;
                case TK_A_LAST_RULE:
+               case TK_END:
                        break;
 
                case TK_M_PARENTS_MAX:
                case TK_M_MAX:
-               case TK_END:
                case TK_UNSET:
                        err(rules->udev, "wrong type %u\n", cur->type);
                        goto nomatch;