chiark / gitweb /
unify/cleanup event handling
[elogind.git] / udev / udev-rules.c
index 07cb4a7fbf8f58d18330232f6b4080e66d1a1160..60daad520afdf55e4fb8193e420512034b9caba4 100644 (file)
@@ -19,6 +19,7 @@
 #include <stddef.h>
 #include <limits.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <string.h>
 #include <stdio.h>
 #include <fcntl.h>
@@ -716,7 +717,7 @@ static int import_property_from_string(struct udev_device *dev, char *line)
                entry = udev_device_add_property(dev, key, val);
                /* store in db, skip private keys */
                if (key[0] != '.')
-                       udev_list_entry_set_flag(entry, 1);
+                       udev_list_entry_set_flags(entry, 1);
        }
        return 0;
 }
@@ -784,7 +785,7 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi
                        entry = udev_device_add_property(dev, key, val);
                        /* store in db, skip private keys */
                        if (key[0] != '.')
-                               udev_list_entry_set_flag(entry, 1);
+                               udev_list_entry_set_flags(entry, 1);
                }
        }
        return 0;
@@ -1156,6 +1157,9 @@ static int add_rule(struct udev_rules *rules, char *line,
        char *linepos;
        char *attr;
        struct rule_tmp rule_tmp;
+       bool bus_warn = false;
+       bool sysfs_warn = false;
+       bool id_warn = false;
 
        memset(&rule_tmp, 0x00, sizeof(struct rule_tmp));
        rule_tmp.rules = rules;
@@ -1240,8 +1244,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                        continue;
                }
 
-               if (strcmp(key, "KERNELS") == 0 ||
-                   strcmp(key, "ID") == 0) {
+               if (strcmp(key, "KERNELS") == 0) {
                        if (op > OP_MATCH_MAX) {
                                err(rules->udev, "invalid KERNELS operation\n");
                                goto invalid;
@@ -1250,8 +1253,37 @@ static int add_rule(struct udev_rules *rules, char *line,
                        continue;
                }
 
-               if (strcmp(key, "SUBSYSTEMS") == 0 ||
-                   strcmp(key, "BUS") == 0) {
+               if (strcmp(key, "ID") == 0) {
+                       if (!id_warn) {
+                               id_warn = true;
+                               err(rules->udev, "ID= will be removed in a future udev version, "
+                                   "please use KERNEL= to match the event device, or KERNELS= "
+                                   "to match a parent device, in %s:%u\n", filename, lineno);
+                       }
+                       if (op > OP_MATCH_MAX) {
+                               err(rules->udev, "invalid KERNELS operation\n");
+                               goto invalid;
+                       }
+                       rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL);
+                       continue;
+               }
+
+               if (strcmp(key, "SUBSYSTEMS") == 0) {
+                       if (op > OP_MATCH_MAX) {
+                               err(rules->udev, "invalid SUBSYSTEMS operation\n");
+                               goto invalid;
+                       }
+                       rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL);
+                       continue;
+               }
+
+               if (strcmp(key, "BUS") == 0) {
+                       if (!bus_warn) {
+                               bus_warn = true;
+                               err(rules->udev, "BUS= will be removed in a future udev version, "
+                                   "please use SUBSYSTEM= to match the event device, or SUBSYSTEMS= "
+                                   "to match a parent device, in %s:%u\n", filename, lineno);
+                       }
                        if (op > OP_MATCH_MAX) {
                                err(rules->udev, "invalid SUBSYSTEMS operation\n");
                                goto invalid;
@@ -1269,8 +1301,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                        continue;
                }
 
-               if (strncmp(key, "ATTRS{", sizeof("ATTRS{")-1) == 0 ||
-                   strncmp(key, "SYSFS{", sizeof("SYSFS{")-1) == 0) {
+               if (strncmp(key, "ATTRS{", sizeof("ATTRS{")-1) == 0) {
                        if (op > OP_MATCH_MAX) {
                                err(rules->udev, "invalid ATTRS operation\n");
                                goto invalid;
@@ -1290,6 +1321,26 @@ static int add_rule(struct udev_rules *rules, char *line,
                        continue;
                }
 
+               if (strncmp(key, "SYSFS{", sizeof("SYSFS{")-1) == 0) {
+                       if (!sysfs_warn) {
+                               sysfs_warn = true;
+                               err(rules->udev, "SYSFS{}= will be removed in a future udev version, "
+                                   "please use ATTR{}= to match the event device, or ATTRS{}= "
+                                   "to match a parent device, in %s:%u\n", filename, lineno);
+                       }
+                       if (op > OP_MATCH_MAX) {
+                               err(rules->udev, "invalid ATTRS operation\n");
+                               goto invalid;
+                       }
+                       attr = get_key_attribute(rules->udev, key + sizeof("ATTRS")-1);
+                       if (attr == NULL) {
+                               err(rules->udev, "error parsing ATTRS attribute\n");
+                               goto invalid;
+                       }
+                       rule_add_key(&rule_tmp, TK_M_ATTRS, op, value, attr);
+                       continue;
+               }
+
                if (strncmp(key, "ENV{", sizeof("ENV{")-1) == 0) {
                        attr = get_key_attribute(rules->udev, key + sizeof("ENV")-1);
                        if (attr == NULL) {
@@ -1780,13 +1831,13 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
                filename_off = add_string(rules, filename);
                /* the offset in the rule is limited to unsigned short */
                if (filename_off < USHRT_MAX)
-                       udev_list_entry_set_flag(file_loop, filename_off);
+                       udev_list_entry_set_flags(file_loop, filename_off);
        }
 
        /* parse list of files */
        udev_list_entry_foreach_safe(file_loop, file_tmp, udev_list_get_entry(&file_list)) {
                const char *filename = udev_list_entry_get_name(file_loop);
-               unsigned int filename_off = udev_list_entry_get_flag(file_loop);
+               unsigned int filename_off = udev_list_entry_get_flags(file_loop);
 
                if (stat(filename, &statbuf) == 0 && statbuf.st_size > 0)
                        parse_file(rules, filename, filename_off);
@@ -2369,7 +2420,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                        entry = udev_device_add_property(event->dev, name, temp_value);
                                        /* store in db, skip private keys */
                                        if (name[0] != '.')
-                                               udev_list_entry_set_flag(entry, 1);
+                                               udev_list_entry_set_flags(entry, 1);
                                } else {
                                        udev_device_add_property(event->dev, name, NULL);
                                }
@@ -2491,7 +2542,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                list_entry = udev_list_entry_add(event->udev, &event->run_list,
                                                                 &rules->buf[cur->key.value_off], NULL, 1, 0);
                                if (cur->key.fail_on_error)
-                                       udev_list_entry_set_flag(list_entry, 1);
+                                       udev_list_entry_set_flags(list_entry, 1);
                                break;
                        }
                case TK_A_GOTO: