/*
* 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.
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);
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;
char *temp;
linepos = *line;
- if (!linepos)
+ if (linepos == NULL && linepos[0] == '\0')
return -1;
/* skip whitespace */
linepos++;
/* get the key */
+ if (linepos[0] == '\0')
+ return -1;
*key = linepos;
+
while (1) {
linepos++;
if (linepos[0] == '\0')
/* skip whitespace after key */
while (isspace(linepos[0]))
linepos++;
+ if (linepos[0] == '\0')
+ return -1;
/* get operation type */
if (linepos[0] == '=' && linepos[1] == '=') {
/* skip whitespace after operator */
while (isspace(linepos[0]))
linepos++;
+ if (linepos[0] == '\0')
+ return -1;
/* get the value*/
if (linepos[0] == '"')
int valid;
char *linepos;
char *attr;
+ size_t padding;
int retval;
/* get all the keys */
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;
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];
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);
rule->ignore_remove = 1;
}
}
- add_rule_key(rule, &rule->name, operation, value);
+ if (value[0] == '\0') {
+ dbg("name empty device should be ignored");
+ rule->name.operation = operation;
+ rule->ignore_device = 1;
+ } else
+ add_rule_key(rule, &rule->name, operation, value);
continue;
}
gid_t gid = lookup_group(value);
dbg("replacing groupname='%s' by id=%i", value, gid);
sprintf(group, "%li", gid);
- add_rule_key(rule, &rule->owner, operation, group);
+ add_rule_key(rule, &rule->group, operation, group);
continue;
}
}
/* 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:
rules->buf = NULL;
return -1;
}
+ rules->mapped = 1;
return 0;
}
list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) {
parse_file(rules, name_loop->name);
list_del(&name_loop->node);
+ free(name_loop);
}
}