- case TK_M_TEST:
- {
- char filename[UTIL_PATH_SIZE];
- struct stat statbuf;
- int match;
-
- util_strlcpy(filename, &rules->buf[cur->key.value_off], sizeof(filename));
- udev_event_apply_format(event, filename, sizeof(filename));
- if (util_resolve_subsys_kernel(event->udev, NULL, filename, sizeof(filename), 0) != 0)
- if (filename[0] != '/') {
- char tmp[UTIL_PATH_SIZE];
-
- util_strlcpy(tmp, udev_device_get_syspath(event->dev), sizeof(tmp));
- util_strlcat(tmp, "/", sizeof(tmp));
- util_strlcat(tmp, filename, sizeof(tmp));
- util_strlcpy(filename, tmp, sizeof(filename));
- }
+ /* move behind our sequence of parent match keys */
+ cur = next;
+ continue;
+ }
+ case TK_M_TEST: {
+ char filename[UTIL_PATH_SIZE];
+ struct stat statbuf;
+ int match;
+
+ udev_event_apply_format(event, &rules->buf[cur->key.value_off], filename, sizeof(filename));
+ if (util_resolve_subsys_kernel(event->udev, filename, filename, sizeof(filename), 0) != 0) {
+ if (filename[0] != '/') {
+ char tmp[UTIL_PATH_SIZE];
+
+ util_strscpy(tmp, sizeof(tmp), filename);
+ util_strscpyl(filename, sizeof(filename),
+ udev_device_get_syspath(event->dev), "/", tmp, NULL);
+ }
+ }
+ attr_subst_subdir(filename, sizeof(filename));
+
+ match = (stat(filename, &statbuf) == 0);
+ dbg(event->udev, "'%s' %s", filename, match ? "exists\n" : "does not exist\n");
+ if (match && cur->key.mode > 0) {
+ match = ((statbuf.st_mode & cur->key.mode) > 0);
+ dbg(event->udev, "'%s' has mode=%#o and %s %#o\n", filename, statbuf.st_mode,
+ match ? "matches" : "does not match", cur->key.mode);
+ }
+ if (match && cur->key.op == OP_NOMATCH)
+ goto nomatch;
+ if (!match && cur->key.op == OP_MATCH)
+ goto nomatch;
+ break;
+ }
+ case TK_M_EVENT_TIMEOUT:
+ info(event->udev, "OPTIONS event_timeout=%u\n", cur->key.event_timeout);
+ event->timeout_usec = cur->key.event_timeout * 1000 * 1000;
+ break;
+ case TK_M_PROGRAM: {
+ char program[UTIL_PATH_SIZE];
+ char **envp;
+ char result[UTIL_PATH_SIZE];
+
+ free(event->program_result);
+ event->program_result = NULL;
+ udev_event_apply_format(event, &rules->buf[cur->key.value_off], program, sizeof(program));
+ envp = udev_device_get_properties_envp(event->dev);
+ info(event->udev, "PROGRAM '%s' %s:%u\n",
+ program,
+ &rules->buf[rule->rule.filename_off],
+ rule->rule.filename_line);