chiark / gitweb /
journal: sort data items of entries by offset
[elogind.git] / src / udev / udev-rules.c
index 0900928d0bd1cdf73242200d4c75f1c4a3d064b9..ee35f464e83d2e93bffddd8b535d9eb9947fbafb 100644 (file)
@@ -202,7 +202,6 @@ struct token {
                         unsigned int value_off;
                         union {
                                 unsigned int attr_off;
-                                int devlink_unique;
                                 unsigned int rule_goto;
                                 mode_t  mode;
                                 uid_t uid;
@@ -1020,6 +1019,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
         case TK_A_OWNER:
         case TK_A_GROUP:
         case TK_A_MODE:
+        case TK_A_DEVLINK:
         case TK_A_NAME:
         case TK_A_GOTO:
         case TK_M_TAG:
@@ -1039,10 +1039,6 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
                 token->key.value_off = add_string(rule_tmp->rules, value);
                 token->key.attr_off = add_string(rule_tmp->rules, attr);
                 break;
-        case TK_A_DEVLINK:
-                token->key.value_off = add_string(rule_tmp->rules, value);
-                token->key.devlink_unique = *(int *)data;
-                break;
         case TK_M_TEST:
                 token->key.value_off = add_string(rule_tmp->rules, value);
                 if (data != NULL)
@@ -1496,17 +1492,11 @@ static int add_rule(struct udev_rules *rules, char *line,
                         continue;
                 }
 
-                if (startswith(key, "SYMLINK")) {
-                        if (op < OP_MATCH_MAX) {
+                if (streq(key, "SYMLINK")) {
+                        if (op < OP_MATCH_MAX)
                                 rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL);
-                        } else {
-                                int flag = 0;
-
-                                attr = get_key_attribute(rules->udev, key + sizeof("SYMLINK")-1);
-                                if (attr != NULL && strstr(attr, "unique") != NULL)
-                                        flag = 1;
-                                rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, &flag);
-                        }
+                        else
+                                rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL);
                         rule_tmp.rule.rule.can_set_name = true;
                         continue;
                 }
@@ -2481,19 +2471,32 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                 case TK_A_ENV: {
                         const char *name = &rules->buf[cur->key.attr_off];
                         char *value = &rules->buf[cur->key.value_off];
+                        char value_new[UTIL_NAME_SIZE];
+                        const char *value_old = NULL;
+                        struct udev_list_entry *entry;
 
-                        if (value[0] != '\0') {
-                                char temp_value[UTIL_NAME_SIZE];
-                                struct udev_list_entry *entry;
-
-                                udev_event_apply_format(event, value, temp_value, sizeof(temp_value));
-                                entry = udev_device_add_property(event->dev, name, temp_value);
-                                /* store in db, skip private keys */
-                                if (name[0] != '.')
-                                        udev_list_entry_set_num(entry, true);
-                        } else {
+                        if (value[0] == '\0') {
+                                if (cur->key.op == OP_ADD)
+                                        break;
                                 udev_device_add_property(event->dev, name, NULL);
+                                break;
                         }
+
+                        if (cur->key.op == OP_ADD)
+                                value_old = udev_device_get_property_value(event->dev, name);
+                        if (value_old) {
+                                char temp[UTIL_NAME_SIZE];
+
+                                /* append value separated by space */
+                                udev_event_apply_format(event, value, temp, sizeof(temp));
+                                util_strscpyl(value_new, sizeof(value_new), value_old, " ", temp, NULL);
+                        } else
+                                udev_event_apply_format(event, value, value_new, sizeof(value_new));
+
+                        entry = udev_device_add_property(event->dev, name, value_new);
+                        /* store in db, skip private keys */
+                        if (name[0] != '.')
+                                udev_list_entry_set_num(entry, true);
                         break;
                 }
                 case TK_A_TAG: {
@@ -2578,7 +2581,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                 log_debug("LINK '%s' %s:%u\n", pos,
                                           &rules->buf[rule->rule.filename_off], rule->rule.filename_line);
                                 util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL);
-                                udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique);
+                                udev_device_add_devlink(event->dev, filename);
                                 while (isspace(next[1]))
                                         next++;
                                 pos = &next[1];
@@ -2588,7 +2591,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                 log_debug("LINK '%s' %s:%u\n", pos,
                                           &rules->buf[rule->rule.filename_off], rule->rule.filename_line);
                                 util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL);
-                                udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique);
+                                udev_device_add_devlink(event->dev, filename);
                         }
                         break;
                 }