chiark / gitweb /
warn if a PHYSEDV* key, the "device" link, or a parent attribute is used
[elogind.git] / udev_rules_parse.c
index 8d69e74864310e5f584f2d490402b914aeb92dd2..bc16f72e2c2cd662bea30d806719c59586e999ea 100644 (file)
@@ -1,8 +1,6 @@
 /*
- * udev_rules_parse.c
- *
  * Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2003-2005 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2003-2006 Kay Sievers <kay.sievers@vrfy.org>
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the
@@ -15,7 +13,7 @@
  * 
  *     You should have received a copy of the GNU General Public License along
  *     with this program; if not, write to the Free Software Foundation, Inc.,
- *     675 Mass Ave, Cambridge, MA 02139, USA.
+ *     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
  */
 
@@ -219,7 +217,7 @@ static int add_rule_key_pair(struct udev_rule *rule, struct key_pairs *pairs,
        size_t key_len = strnlen(key, PATH_SIZE);
 
        if (pairs->count >= PAIRS_MAX) {
-               err("skip, too many keys in a single rule");
+               err("skip, too many keys of the same type in a single rule");
                return -1;
        }
 
@@ -263,14 +261,24 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                if (retval)
                        break;
 
-               if (strcasecmp(key, "LABEL") == 0) {
-                       add_rule_key(rule, &rule->label, operation, value);
+               if (strcasecmp(key, "ACTION") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid ACTION operation");
+                               goto invalid;
+                       }
+                       add_rule_key(rule, &rule->action, operation, value);
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "GOTO") == 0) {
-                       add_rule_key(rule, &rule->goto_label, operation, value);
+               if (strcasecmp(key, "DEVPATH") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid DEVPATH operation");
+                               goto invalid;
+                       }
+                       add_rule_key(rule, &rule->devpath, operation, value);
                        valid = 1;
                        continue;
                }
@@ -281,7 +289,7 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                                err("invalid KERNEL operation");
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->kernel_name, operation, value);
+                       add_rule_key(rule, &rule->kernel, operation, value);
                        valid = 1;
                        continue;
                }
@@ -297,79 +305,114 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                        continue;
                }
 
-               if (strcasecmp(key, "ACTION") == 0) {
+               if (strcasecmp(key, "DRIVER") == 0) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
-                               err("invalid ACTION operation");
+                               err("invalid DRIVER operation");
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->action, operation, value);
+                       err("DRIVER== will change in a future relase, "
+                           "please use DRIVERS== in %s:%u", filename, lineno);
+                       /* FIXME: this should be rule->driver to match only the event device */
+                       add_rule_key(rule, &rule->drivers, operation, value);
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "DEVPATH") == 0) {
-                       if (operation != KEY_OP_MATCH &&
-                           operation != KEY_OP_NOMATCH) {
-                               err("invalid DEVPATH operation");
+               if (strncasecmp(key, "ATTR{", sizeof("ATTR{")-1) == 0) {
+                       attr = get_key_attribute(key + sizeof("ATTR")-1);
+                       if (attr == NULL) {
+                               err("error parsing ATTR attribute");
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->devpath, operation, value);
+                       if (add_rule_key_pair(rule, &rule->attr, operation, attr, value) != 0)
+                               goto invalid;
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "BUS") == 0) {
+               if (strcasecmp(key, "KERNELS") == 0 ||
+                   strcasecmp(key, "ID") == 0) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
-                               err("invalid BUS operation");
+                               err("invalid KERNELS operation");
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->bus, operation, value);
+                       add_rule_key(rule, &rule->kernels, operation, value);
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "ID") == 0) {
+               if (strcasecmp(key, "SUBSYSTEMS") == 0 ||
+                   strcasecmp(key, "BUS") == 0) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
-                               err("invalid ID operation");
+                               err("invalid SUBSYSTEMS operation");
                                goto invalid;
                        }
-                       add_rule_key(rule, &rule->id, operation, value);
+                       add_rule_key(rule, &rule->subsystems, operation, value);
                        valid = 1;
                        continue;
                }
 
-               if (strncasecmp(key, "SYSFS", sizeof("SYSFS")-1) == 0) {
+               if (strcasecmp(key, "DRIVERS") == 0) {
                        if (operation != KEY_OP_MATCH &&
                            operation != KEY_OP_NOMATCH) {
-                               err("invalid SYSFS operation");
+                               err("invalid DRIVERS operation");
                                goto invalid;
                        }
-                       attr = get_key_attribute(key + sizeof("SYSFS")-1);
-                       if (attr == NULL) {
-                               err("error parsing SYSFS attribute in '%s'", line);
-                               continue;
-                       }
-                       add_rule_key_pair(rule, &rule->sysfs, operation, attr, value);
+                       add_rule_key(rule, &rule->drivers, operation, value);
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "WAIT_FOR_SYSFS") == 0) {
-                       add_rule_key(rule, &rule->wait_for_sysfs, operation, value);
+               if (strncasecmp(key, "ATTRS{", sizeof("ATTRS{")-1) == 0 ||
+                   strncasecmp(key, "SYSFS{", sizeof("SYSFS{")-1) == 0) {
+                       attr = get_key_attribute(key + sizeof("ATTRS")-1);
+                       if (attr == NULL) {
+                               err("error parsing ATTRS attribute");
+                               goto invalid;
+                       }
+                       if (strncmp(attr, "device/", 7) == 0)
+                               err("the 'device' link is deprecated and will be removed from a future kernel, "
+                                   "please fix it in %s:%u", filename, lineno);
+                       else if (strchr(attr, '/') != NULL)
+                               err("do not reference parent sysfs directories directly, that may break with a future kernel, "
+                                   "please fix it in %s:%u", filename, lineno);
+                       if (add_rule_key_pair(rule, &rule->attrs, operation, attr, value) != 0)
+                               goto invalid;
                        valid = 1;
                        continue;
                }
 
-               if (strncasecmp(key, "ENV", sizeof("ENV")-1) == 0) {
+               if (strncasecmp(key, "ENV{", sizeof("ENV{")-1) == 0) {
                        attr = get_key_attribute(key + sizeof("ENV")-1);
                        if (attr == NULL) {
                                err("error parsing ENV attribute");
-                               continue;
+                               goto invalid;
                        }
-                       add_rule_key_pair(rule, &rule->env, operation, attr, value);
+                       if (strncmp(attr, "PHYSDEV", 7) == 0)
+                               err("PHYSDEV* values are deprected and will be removed from a future kernel, "
+                                   "please fix it in %s:%u", filename, lineno);
+                       if (add_rule_key_pair(rule, &rule->env, operation, attr, value) != 0)
+                               goto invalid;
+                       valid = 1;
+                       continue;
+               }
+
+               if (strcasecmp(key, "PROGRAM") == 0) {
+                       add_rule_key(rule, &rule->program, operation, value);
+                       valid = 1;
+                       continue;
+               }
+
+               if (strcasecmp(key, "RESULT") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid RESULT operation");
+                               goto invalid;
+                       }
+                       add_rule_key(rule, &rule->result, operation, value);
                        valid = 1;
                        continue;
                }
@@ -419,30 +462,26 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                        continue;
                }
 
-               if (strcasecmp(key, "DRIVER") == 0) {
-                       if (operation != KEY_OP_MATCH &&
-                           operation != KEY_OP_NOMATCH) {
-                               err("invalid DRIVER operation");
-                               goto invalid;
-                       }
-                       add_rule_key(rule, &rule->driver, operation, value);
+               if (strcasecmp(key, "RUN") == 0) {
+                       add_rule_key(rule, &rule->run, operation, value);
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "RESULT") == 0) {
-                       if (operation != KEY_OP_MATCH &&
-                           operation != KEY_OP_NOMATCH) {
-                               err("invalid RESULT operation");
-                               goto invalid;
-                       }
-                       add_rule_key(rule, &rule->result, operation, value);
+               if (strcasecmp(key, "WAIT_FOR_SYSFS") == 0) {
+                       add_rule_key(rule, &rule->wait_for_sysfs, operation, value);
                        valid = 1;
                        continue;
                }
 
-               if (strcasecmp(key, "PROGRAM") == 0) {
-                       add_rule_key(rule, &rule->program, operation, value);
+               if (strcasecmp(key, "LABEL") == 0) {
+                       add_rule_key(rule, &rule->label, operation, value);
+                       valid = 1;
+                       continue;
+               }
+
+               if (strcasecmp(key, "GOTO") == 0) {
+                       add_rule_key(rule, &rule->goto_label, operation, value);
                        valid = 1;
                        continue;
                }
@@ -516,12 +555,6 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                        continue;
                }
 
-               if (strcasecmp(key, "RUN") == 0) {
-                       add_rule_key(rule, &rule->run, operation, value);
-                       valid = 1;
-                       continue;
-               }
-
                if (strcasecmp(key, "OPTIONS") == 0) {
                        if (strstr(value, "last_rule") != NULL) {
                                dbg("last rule to be applied");