chiark / gitweb /
063 release
[elogind.git] / udev_rules_parse.c
index a2f2f1804b2279470b5a0e786c3764e1967382d9..be0757374e216f2e2822e75c955c83a49a7b138f 100644 (file)
@@ -1,12 +1,9 @@
 /*
  * udev_rules_parse.c
  *
- * Userspace devfs
- *
  * Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com>
  * Copyright (C) 2003-2005 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
  *     Free Software Foundation version 2 of the License.
@@ -52,8 +49,10 @@ struct udev_rule *udev_rules_iter_next(struct udev_rules *rules)
                return NULL;
 
        dbg("current=%zi", rules->current);
-       if (rules->current >= rules->bufsize)
+       if (rules->current >= rules->bufsize) {
+               dbg("no more rules");
                return NULL;
+       }
 
        /* get next rule */
        rule = (struct udev_rule *) (rules->buf + rules->current);
@@ -62,6 +61,28 @@ struct udev_rule *udev_rules_iter_next(struct udev_rules *rules)
        return rule;
 }
 
+struct udev_rule *udev_rules_iter_label(struct udev_rules *rules, const char *label)
+{
+       static struct udev_rule *rule;
+
+next:
+       dbg("current=%zi", rules->current);
+       if (rules->current >= rules->bufsize) {
+               dbg("no more rules");
+               return NULL;
+       }
+       rule = (struct udev_rule *) (rules->buf + rules->current);
+
+       if (strcmp(&rule->buf[rule->label.val_off], label) != 0) {
+               dbg("moving forward, looking for label '%s'", label);
+               rules->current += sizeof(struct udev_rule) + rule->bufsize;
+               goto next;
+       }
+
+       dbg("found label '%s'", label);
+       return rule;
+}
+
 static int get_key(char **line, char **key, enum key_operation *operation, char **value)
 {
        char *linepos;
@@ -217,6 +238,7 @@ static int add_to_rules(struct udev_rules *rules, char *line)
        int valid;
        char *linepos;
        char *attr;
+       size_t padding;
        int retval;
 
        /* get all the keys */
@@ -237,6 +259,18 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                if (retval)
                        break;
 
+               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;
+               }
+
                if (strcasecmp(key, "KERNEL") == 0) {
                        add_rule_key(rule, &rule->kernel_name, operation, value);
                        valid = 1;
@@ -311,9 +345,13 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                        attr = get_key_attribute(key + sizeof("IMPORT")-1);
                        if (attr && strstr(attr, "program")) {
                                dbg("IMPORT will be executed");
-                               rule->import_exec = 1;
+                               rule->import_type  = IMPORT_PROGRAM;
                        } else if (attr && strstr(attr, "file")) {
                                dbg("IMPORT will be included as file");
+                               rule->import_type  = IMPORT_FILE;
+                       } else if (attr && strstr(attr, "parent")) {
+                               dbg("IMPORT will include the parent values");
+                               rule->import_type = IMPORT_PARENT;
                        } else {
                                /* figure it out if it is executable */
                                char file[PATH_SIZE];
@@ -326,8 +364,11 @@ static int add_to_rules(struct udev_rules *rules, char *line)
                                        pos[0] = '\0';
                                dbg("IMPORT auto mode for '%s'", file);
                                if (!lstat(file, &stats) && (stats.st_mode & S_IXUSR)) {
-                                               dbg("IMPORT is executable, will be executed");
-                                               rule->import_exec = 1;
+                                       dbg("IMPORT is executable, will be executed (autotype)");
+                                       rule->import_type  = IMPORT_PROGRAM;
+                               } else {
+                                       dbg("IMPORT is not executable, will be included as file (autotype)");
+                                       rule->import_type  = IMPORT_FILE;
                                }
                        }
                        add_rule_key(rule, &rule->import, operation, value);
@@ -463,11 +504,17 @@ static int add_to_rules(struct udev_rules *rules, char *line)
 
        /* grow buffer and add rule */
        rule_size = sizeof(struct udev_rule) + rule->bufsize;
+       padding = (sizeof(size_t) - rule_size % sizeof(size_t)) % sizeof(size_t);
+       dbg("add %zi padding bytes", padding);
+       rule_size += padding;
+       rule->bufsize += padding;
+
        rules->buf = realloc(rules->buf, rules->bufsize + rule_size);
        if (!rules->buf) {
                err("realloc failed");
                goto exit;
        }
+       dbg("adding rule to offset %zi", rules->bufsize);
        memcpy(rules->buf + rules->bufsize, rule, rule_size);
        rules->bufsize += rule_size;
 exit:
@@ -548,6 +595,7 @@ static int rules_map(struct udev_rules *rules, const char *filename)
                rules->buf = NULL;
                return -1;
        }
+       rules->mapped = 1;
 
        return 0;
 }