- if (strstr(value, "last_rule") != NULL) {
- dbg(rules->udev, "last rule to be applied\n");
- rule->last_rule = 1;
- }
- if (strstr(value, "ignore_device") != NULL) {
- dbg(rules->udev, "device should be ignored\n");
- rule->ignore_device = 1;
- }
- if (strstr(value, "ignore_remove") != NULL) {
- dbg(rules->udev, "remove event should be ignored\n");
- rule->ignore_remove = 1;
- }
- pos = strstr(value, "link_priority=");
- if (pos != NULL) {
- rule->link_priority = atoi(&pos[strlen("link_priority=")]);
- dbg(rules->udev, "link priority=%i\n", rule->link_priority);
- }
- pos = strstr(value, "event_timeout=");
- if (pos != NULL) {
- rule->event_timeout = atoi(&pos[strlen("event_timeout=")]);
- dbg(rules->udev, "event timout=%i\n", rule->event_timeout);
- }
- pos = strstr(value, "string_escape=");
- if (pos != NULL) {
- pos = &pos[strlen("string_escape=")];
- if (strncmp(pos, "none", strlen("none")) == 0)
- rule->string_escape = ESCAPE_NONE;
- else if (strncmp(pos, "replace", strlen("replace")) == 0)
- rule->string_escape = ESCAPE_REPLACE;
- }
- if (strstr(value, "all_partitions") != NULL) {
- dbg(rules->udev, "creation of partition nodes requested\n");
- rule->partitions = DEFAULT_FAKE_PARTITIONS_COUNT;
- }
- valid = 1;
- continue;
- }
-
- err(rules->udev, "unknown key '%s' in %s:%u\n", key, filename, lineno);
- }
-
- if (physdev && rule->wait_for.operation == KEY_OP_UNSET)
- err(rules->udev, "PHYSDEV* values are deprecated and will be removed from a future kernel, \n"
- "please fix it in %s:%u", filename, lineno);
-
- /* skip line if not any valid key was found */
- if (!valid)
- goto invalid;
-
- /* 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(rules->udev, "add %zi padding bytes\n", padding);
- rule_size += padding;
- rule->bufsize += padding;
-
- rules->buf = realloc(rules->buf, rules->bufsize + rule_size);
- if (!rules->buf) {
- err(rules->udev, "realloc failed\n");
- goto exit;
- }
- dbg(rules->udev, "adding rule to offset %zi\n", rules->bufsize);
- memcpy(rules->buf + rules->bufsize, rule, rule_size);
- rules->bufsize += rule_size;
-exit:
- return 0;
-
-invalid:
- err(rules->udev, "invalid rule '%s:%u'\n", filename, lineno);
- return -1;
-}
-
-static int parse_file(struct udev_rules *rules, const char *filename)
-{
- FILE *f;
- char line[UTIL_LINE_SIZE];
- size_t start;
- struct udev_rule *rule;
- struct udev_rules_iter iter;
-
- start = rules->bufsize;
- info(rules->udev, "reading '%s' as rules file\n", filename);
-
- f = fopen(filename, "r");
- if (f == NULL)
- return -1;
-
- while(fgets(line, sizeof(line), f) != NULL) {
- int line_nr = 0;
- char *key;
- size_t len;
-
- /* skip whitespace */
- line_nr++;
- key = line;
- while (isspace(key[0]))
- key++;
-
- /* comment */
- if (key[0] == '#')
- continue;
+ /* loop through token list, match, run actions or forward to next rule */
+ cur = &rules->tokens[0];
+ rule = cur;
+ while (1) {
+ dump_token(rules, cur);
+ switch (cur->type) {
+ case TK_RULE:
+ /* current rule */
+ rule = cur;
+ /* possibly skip rules which want to set NAME, SYMLINK, OWNER, GROUP, MODE */
+ if (!can_set_name && rule->rule.flags)
+ goto nomatch;
+ esc = ESCAPE_UNSET;
+ break;
+ case TK_M_ACTION:
+ if (match_key(rules, cur, udev_device_get_action(event->dev)) != 0)
+ goto nomatch;
+ break;
+ case TK_M_DEVPATH:
+ if (match_key(rules, cur, udev_device_get_devpath(event->dev)) != 0)
+ goto nomatch;
+ break;
+ case TK_M_KERNEL:
+ if (match_key(rules, cur, udev_device_get_sysname(event->dev)) != 0)
+ goto nomatch;
+ break;
+ case TK_M_DEVLINK:
+ {
+ size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
+ struct udev_list_entry *list_entry;
+ int match = 0;