chiark / gitweb /
remove udevsend
[elogind.git] / udev_rules_parse.c
index 376006c7c4d4a6210d7047277dc45ef681dd8fc5..91cc9744fb6cb044e643a62906dbbd9cd628395b 100644 (file)
@@ -235,7 +235,7 @@ static int add_rule_key_pair(struct udev_rule *rule, struct key_pairs *pairs,
        return 0;
 }
 
-static int add_to_rules(struct udev_rules *rules, char *line)
+static int add_to_rules(struct udev_rules *rules, char *line, const char *filename, unsigned int lineno)
 {
        struct udev_rule *rule;
        size_t rule_size;
@@ -276,42 +276,77 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                }
 
                if (strcasecmp(key, "KERNEL") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid KERNEL operation");
+                               goto invalid;
+                       }
                        add_rule_key(rule, &rule->kernel_name, operation, value);
                        valid = 1;
                        continue;
                }
 
                if (strcasecmp(key, "SUBSYSTEM") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid SUBSYSTEM operation");
+                               goto invalid;
+                       }
                        add_rule_key(rule, &rule->subsystem, operation, value);
                        valid = 1;
                        continue;
                }
 
                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, "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;
                }
 
                if (strcasecmp(key, "BUS") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid BUS operation");
+                               goto invalid;
+                       }
                        add_rule_key(rule, &rule->bus, operation, value);
                        valid = 1;
                        continue;
                }
 
                if (strcasecmp(key, "ID") == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid ID operation");
+                               goto invalid;
+                       }
                        add_rule_key(rule, &rule->id, operation, value);
                        valid = 1;
                        continue;
                }
 
                if (strncasecmp(key, "SYSFS", sizeof("SYSFS")-1) == 0) {
+                       if (operation != KEY_OP_MATCH &&
+                           operation != KEY_OP_NOMATCH) {
+                               err("invalid SYSFS operation");
+                               goto invalid;
+                       }
                        attr = get_key_attribute(key + sizeof("SYSFS")-1);
                        if (attr == NULL) {
                                err("error parsing SYSFS attribute in '%s'", line);
@@ -391,12 +426,22 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                }
 
                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);
                        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;
@@ -421,7 +466,7 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                                }
                        }
                        if (value[0] == '\0')
-                               dbg("name empty, not creation supressed");
+                               dbg("name empty, node creation supressed");
                        add_rule_key(rule, &rule->name, operation, value);
                        continue;
                }
@@ -504,14 +549,12 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                        continue;
                }
 
-               err("unknown key '%s', in '%s'", key, line);
+               err("unknown key '%s'", key);
        }
 
        /* skip line if not any valid key was found */
-       if (!valid) {
-               err("invalid rule '%s'", line);
-               goto exit;
-       }
+       if (!valid)
+               goto invalid;
 
        /* grow buffer and add rule */
        rule_size = sizeof(struct udev_rule) + rule->bufsize;
@@ -531,13 +574,18 @@ static int add_to_rules(struct udev_rules *rules, char *line)
 exit:
        free(rule);
        return 0;
+
+invalid:
+       free(rule);
+       err("invalid rule '%s:%u'", filename, lineno);
+       return -1;
 }
 
 static int parse_file(struct udev_rules *rules, const char *filename)
 {
        char line[LINE_SIZE];
        char *bufline;
-       int lineno;
+       unsigned int lineno;
        char *buf;
        size_t bufsize;
        size_t cur;
@@ -562,7 +610,7 @@ static int parse_file(struct udev_rules *rules, const char *filename)
                lineno++;
 
                if (count >= sizeof(line)) {
-                       info("line too long, rule skipped %s, line %d", filename, lineno);
+                       err("line too long, rule skipped '%s:%u'", filename, lineno);
                        continue;
                }
 
@@ -588,7 +636,7 @@ static int parse_file(struct udev_rules *rules, const char *filename)
                line[j] = '\0';
 
                dbg("read '%s'", line);
-               add_to_rules(rules, line);
+               add_to_rules(rules, line, filename, lineno);
        }
 
        file_unmap(buf, bufsize);