TK_M_SUBSYSTEMS, /* val */
TK_M_DRIVERS, /* val */
TK_M_ATTRS, /* val, attr */
+ TK_M_TAGS, /* val */
TK_M_PARENTS_MAX,
TK_M_TEST, /* val, mode_t */
[TK_M_SUBSYSTEMS] = "M SUBSYSTEMS",
[TK_M_DRIVERS] = "M DRIVERS",
[TK_M_ATTRS] = "M ATTRS",
+ [TK_M_TAGS] = "M TAGS",
[TK_M_PARENTS_MAX] = "M PARENTS_MAX",
[TK_M_TEST] = "M TEST",
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
+ case TK_M_TAGS:
case TK_M_PROGRAM:
case TK_M_IMPORT_FILE:
case TK_M_IMPORT_PROG:
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
+ case TK_M_TAGS:
case TK_M_PROGRAM:
case TK_M_IMPORT_FILE:
case TK_M_IMPORT_PROG:
continue;
}
+ if (strcmp(key, "TAGS") == 0) {
+ if (op > OP_MATCH_MAX) {
+ err(rules->udev, "invalid TAGS operation\n");
+ goto invalid;
+ }
+ rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL);
+ continue;
+ }
+
if (strncmp(key, "SYSFS{", sizeof("SYSFS{")-1) == 0) {
if (!sysfs_warn) {
sysfs_warn = true;
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
- case TK_M_ATTRS: {
+ case TK_M_ATTRS:
+ case TK_M_TAGS: {
struct token *next;
/* get whole sequence of parent matches */
if (match_attr(rules, event->dev_parent, event, key) != 0)
goto try_parent;
break;
+ case TK_M_TAGS: {
+ bool match = udev_device_has_tag(event->dev_parent, &rules->buf[cur->key.value_off]);
+
+ if (match && key->key.op == OP_NOMATCH)
+ goto try_parent;
+ if (!match && key->key.op == OP_MATCH)
+ goto try_parent;
+ break;
+ }
default:
goto nomatch;
}
dbg(event->udev, "parent key matched\n");
}
dbg(event->udev, "all parent keys matched\n");
- /* all keys matched */
break;
try_parent:
}
break;
}
- case TK_A_TAG:
+ case TK_A_TAG: {
+ char tag[UTIL_PATH_SIZE];
+
+ udev_event_apply_format(event, &rules->buf[cur->key.value_off], tag, sizeof(tag));
if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
udev_device_cleanup_tags_list(event->dev);
- udev_device_add_tag(event->dev, &rules->buf[cur->key.value_off]);
+ udev_device_add_tag(event->dev, tag);
break;
+ }
case TK_A_NAME: {
const char *name = &rules->buf[cur->key.value_off];
char name_str[UTIL_PATH_SIZE];