udev-rules.c revision 3b8c1cb01f1b752543738779668d9841ecbca0d3
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * Copyright (C) 2003-2010 Kay Sievers <kay.sievers@vrfy.org>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * Copyright (C) 2008 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * This program is free software: you can redistribute it and/or modify
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * it under the terms of the GNU General Public License as published by
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * the Free Software Foundation, either version 2 of the License, or
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * (at your option) any later version.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * This program is distributed in the hope that it will be useful,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * but WITHOUT ANY WARRANTY; without even the implied warranty of
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * GNU General Public License for more details.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * You should have received a copy of the GNU General Public License
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * along with this program. If not, see <http://www.gnu.org/licenses/>.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt unsigned int name_off;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt /* this node's first child */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* the next child of our parent node's child list */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt /* this node's last child (shortcut for append) */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt unsigned short value_len;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt unsigned char key;
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen unsigned long long *dirs_ts_usec;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* every key in the rules file becomes a token */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt /* all key strings are copied to a single string buffer */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt /* during rule parsing, strings are indexed and de-duplicated */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt /* during rule parsing, uid/gid lookup results are cached */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt unsigned int uids_cur;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt unsigned int uids_max;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int gids_cur;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int gids_max;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt/* KEY=="", KEY!="", KEY+="", KEY="", KEY:="" */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt GL_SPLIT_GLOB, /* multi-value with glob A*|B* */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/* tokens of a rule are sorted/handled in this order */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/* we try to pack stuff in a way that we take only 12 bytes per token */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt unsigned short token_count;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt unsigned short filename_off;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt unsigned short filename_line;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt unsigned int attr_off;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flyktstatic const char *operation_str(enum operation_type type)
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt static const char *operation_strs[] = {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flyktstatic const char *string_glob_str(enum string_glob_type type)
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt static const char *string_glob_strs[] = {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic const char *token_str(enum token_type type)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt static const char *token_strs[] = {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt [TK_A_STRING_ESCAPE_NONE] = "A STRING_ESCAPE_NONE",
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt [TK_A_STRING_ESCAPE_REPLACE] = "A STRING_ESCAPE_REPLACE",
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic void dump_token(struct udev_rules *rules, struct token *token)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt const char *value = &rules->buf[token->key.value_off];
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt const char *attr = &rules->buf[token->key.attr_off];
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt unsigned int idx = (tk_ptr - tks_ptr) / sizeof(struct token);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_debug("* RULE %s:%u, token: %u, count: %u, label: '%s'\n",
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt &rules->buf[token->rule.filename_off], token->rule.filename_line,
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt token_str(type), operation_str(op), value, string_glob_str(glob));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_debug("%s %i '%s'\n", token_str(type), token->key.builtin_cmd, value);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt token_str(type), operation_str(op), attr, value, string_glob_str(glob));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_debug("%s %s '%s'\n", token_str(type), operation_str(op), value);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt token_str(type), operation_str(op), value, string_glob_str(glob), token->key.mode);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_debug("%s %u\n", token_str(type), token->key.watch);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_debug("%s %u\n", token_str(type), token->key.devlink_prio);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.uid);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.gid);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_debug("%s %s %#o\n", token_str(type), operation_str(op), token->key.mode);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_debug("%s '%s'\n", token_str(type), value);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_debug("%s %u\n", token_str(type), token->key.event_timeout);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_debug("%s '%s' %u\n", token_str(type), value, token->key.rule_goto);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flyktstatic void dump_rules(struct udev_rules *rules)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt unsigned int i;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings\n",
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic inline const char *operation_str(enum operation_type type) { return NULL; }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic inline const char *token_str(enum token_type type) { return NULL; }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic inline void dump_token(struct udev_rules *rules, struct token *token) {}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic inline void dump_rules(struct udev_rules *rules) {}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt#endif /* DEBUG */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int add_new_string(struct udev_rules *rules, const char *str, size_t bytes)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* grow buffer if needed */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (rules->buf_cur + bytes+1 >= rules->buf_max) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int add;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* double the buffer size */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt buf = realloc(rules->buf, rules->buf_max + add);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt memcpy(&rules->buf[rules->buf_cur], str, bytes);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int add_string(struct udev_rules *rules, const char *str)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int node_idx;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned char key;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned short len;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int depth;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int off;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* walk trie, start from last character of str to find matching tails */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* match against current node */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (depth == len || (node->value_len >= len && memcmp(&rules->buf[off], str, len) == 0))
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* lookup child node */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* string not found, add it */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* grow trie nodes if needed */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (rules->trie_nodes_cur >= rules->trie_nodes_max) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int add;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* double the buffer size */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt nodes = realloc(rules->trie_nodes, (rules->trie_nodes_max + add) * sizeof(struct trie_node));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* get a new node */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt memset(new_node, 0x00, sizeof(struct trie_node));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* join the parent's child list */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt last_child = &rules->trie_nodes[parent->last_child_idx];
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int add_token(struct udev_rules *rules, struct token *token)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* grow buffer if needed */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt unsigned int add;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt /* double the buffer size */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt tokens = realloc(rules->tokens, (rules->token_max + add ) * sizeof(struct token));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt memcpy(&rules->tokens[rules->token_cur], token, sizeof(struct token));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic uid_t add_uid(struct udev_rules *rules, const char *owner)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int i;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int off;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* lookup, if we know it already */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* grow buffer if needed */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int add;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* double the buffer size */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt uids = realloc(rules->uids, (rules->uids_max + add ) * sizeof(struct uid_gid));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic gid_t add_gid(struct udev_rules *rules, const char *group)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned int i;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt unsigned int off;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* lookup, if we know it already */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* grow buffer if needed */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt unsigned int add;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt /* double the buffer size */
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt gids = realloc(rules->gids, (rules->gids_max + add ) * sizeof(struct uid_gid));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic int import_property_from_string(struct udev_device *dev, char *line)
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt /* find key */
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt /* comment or empty line */
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt /* find value */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt /* terminate key */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* terminate value */
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt /* unquote */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_debug("inconsistent quoting: '%s', skip\n", line);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* handle device, renamed by external tool, returning new path */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_debug("updating devpath from '%s' to '%s'\n",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt util_strscpyl(syspath, sizeof(syspath), "/sys", val, NULL);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt entry = udev_device_add_property(dev, key, val);
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt /* store in db, skip private keys */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int import_file_into_properties(struct udev_device *dev, const char *filename)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int import_program_into_properties(struct udev_event *event, const char *program, const sigset_t *sigmask)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt err = udev_event_spawn(event, program, envp, sigmask, result, sizeof(result));
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int import_parent_into_properties(struct udev_device *dev, const char *filter)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev_parent)) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt const char *key = udev_list_entry_get_name(list_entry);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt const char *val = udev_list_entry_get_value(list_entry);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt entry = udev_device_add_property(dev, key, val);
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen /* store in db, skip private keys */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int wait_for_file(struct udev_device *dev, const char *file, int timeout)
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen /* a relative path is a device attribute */
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen util_strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL);
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen util_strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL);
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen const struct timespec duration = { 0, 1000 * 1000 * 1000 / WAIT_LOOP_PER_SECOND };
a276e6d68606861b552140cbcc003f4af10626fcTom Gundersen /* lookup file */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_debug("file '%s' appeared after %i loops\n", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* make sure, the device did not disappear in the meantime */
bool found = false;
char *pos;
const char *tail;
found = true;
return found;
static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value)
char *linepos;
char *temp;
linepos++;
linepos++;
linepos++;
linepos++;
linepos++;
linepos++;
if (!temp)
temp++;
char *pos;
char *attr;
attr++;
return NULL;
return attr;
return NULL;
switch (type) {
case TK_M_ACTION:
case TK_M_DEVPATH:
case TK_M_KERNEL:
case TK_M_SUBSYSTEM:
case TK_M_DRIVER:
case TK_M_WAITFOR:
case TK_M_DEVLINK:
case TK_M_NAME:
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_IMPORT_DB:
case TK_M_IMPORT_CMDLINE:
case TK_M_IMPORT_PARENT:
case TK_M_RESULT:
case TK_A_OWNER:
case TK_A_GROUP:
case TK_A_MODE:
case TK_A_NAME:
case TK_A_GOTO:
case TK_M_TAG:
case TK_A_TAG:
case TK_M_IMPORT_BUILTIN:
case TK_M_ENV:
case TK_M_ATTR:
case TK_M_ATTRS:
case TK_A_ATTR:
case TK_A_ENV:
case TK_A_DEVLINK:
case TK_M_TEST:
case TK_A_STRING_ESCAPE_NONE:
case TK_A_DB_PERSIST:
case TK_A_RUN_BUILTIN:
case TK_A_RUN_PROGRAM:
case TK_A_INOTIFY_WATCH:
case TK_A_DEVLINK_PRIO:
case TK_A_OWNER_ID:
case TK_A_GROUP_ID:
case TK_A_MODE_ID:
case TK_A_STATIC_NODE:
case TK_M_EVENT_TIMEOUT:
case TK_RULE:
case TK_M_PARENTS_MIN:
case TK_M_PARENTS_MAX:
case TK_M_MAX:
case TK_END:
case TK_UNSET:
int has_split;
int has_glob;
has_glob = (strchr(value, '*') != NULL || strchr(value, '?') != NULL || strchr(value, '[') != NULL);
} else if (has_split) {
} else if (has_glob) {
unsigned int start = 0;
unsigned int next_idx = 0;
next_idx = j;
start++;
end--;
char *linepos;
const char *attr;
char *key;
char *value;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
goto invalid;
static const char *blacklist[] = {
goto invalid;
goto invalid;
goto invalid;
goto invalid;
int flag = 0;
char *endptr;
char *endptr;
char *endptr;
const char *pos;
const int off = 0;
goto invalid;
goto invalid;
goto invalid;
FILE *f;
unsigned int first_token;
unsigned int filename_off;
int line_nr = 0;
if (f == NULL)
char *key;
line_nr++;
key++;
line_nr++;
fclose(f);
char **files, **f;
return NULL;
return NULL;
return NULL;
return NULL;
NULL);
return NULL;
return NULL;
return NULL;
char *buf;
return rules;
return NULL;
return NULL;
bool changed = false;
goto out;
changed = true;
out:
return changed;
char *pos;
bool match = false;
case GL_PLAIN:
case GL_GLOB:
case GL_SPLIT:
const char *next;
if (match)
case GL_SPLIT_GLOB:
if (match)
case GL_SOMETHING:
case GL_UNSET:
static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct udev_event *event, struct token *cur)
const char *name;
const char *value;
case SB_FORMAT:
case SB_NONE:
case SB_SUBSYS:
const char *key_value;
enum escape_type {
int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask)
bool can_set_name;
case TK_RULE:
goto nomatch;
case TK_M_ACTION:
goto nomatch;
case TK_M_DEVPATH:
goto nomatch;
case TK_M_KERNEL:
goto nomatch;
case TK_M_DEVLINK: {
bool match = false;
const char *devlink;
match = true;
if (!match)
goto nomatch;
case TK_M_NAME:
goto nomatch;
case TK_M_ENV: {
const char *value;
goto nomatch;
case TK_M_TAG: {
bool match = false;
match = true;
goto nomatch;
case TK_M_SUBSYSTEM:
goto nomatch;
case TK_M_DRIVER:
goto nomatch;
case TK_M_WAITFOR: {
int found;
goto nomatch;
case TK_M_ATTR:
goto nomatch;
case TK_M_KERNELS:
case TK_M_SUBSYSTEMS:
case TK_M_DRIVERS:
case TK_M_ATTRS:
case TK_M_TAGS: {
next++;
case TK_M_KERNELS:
goto try_parent;
case TK_M_SUBSYSTEMS:
goto try_parent;
case TK_M_DRIVERS:
goto try_parent;
case TK_M_ATTRS:
goto try_parent;
case TK_M_TAGS: {
goto try_parent;
goto try_parent;
goto nomatch;
goto nomatch;
case TK_M_TEST: {
int match;
goto nomatch;
goto nomatch;
case TK_M_EVENT_TIMEOUT:
case TK_M_PROGRAM: {
char **envp;
goto nomatch;
int count;
if (count > 0)
goto nomatch;
case TK_M_IMPORT_FILE: {
goto nomatch;
case TK_M_IMPORT_PROG: {
goto nomatch;
case TK_M_IMPORT_BUILTIN: {
goto nomatch;
goto nomatch;
case TK_M_IMPORT_DB: {
const char *value;
goto nomatch;
case TK_M_IMPORT_CMDLINE: {
FILE *f;
bool imported = false;
if (f != NULL) {
char *pos;
imported = true;
const char *value;
pos++;
pos++;
imported = true;
fclose(f);
goto nomatch;
case TK_M_IMPORT_PARENT: {
goto nomatch;
case TK_M_RESULT:
goto nomatch;
case TK_A_STRING_ESCAPE_NONE:
case TK_A_DB_PERSIST:
case TK_A_INOTIFY_WATCH:
case TK_A_DEVLINK_PRIO:
case TK_A_OWNER: {
case TK_A_GROUP: {
case TK_A_MODE: {
char *endptr;
case TK_A_OWNER_ID:
case TK_A_GROUP_ID:
case TK_A_MODE_ID:
case TK_A_ENV: {
case TK_A_TAG: {
case TK_A_NAME: {
int count;
if (count > 0)
case TK_A_DEVLINK: {
int count = 0;
if (count > 0)
pos++;
next++;
case TK_A_ATTR: {
FILE *f;
if (f != NULL) {
fclose(f);
case TK_A_RUN_BUILTIN:
case TK_A_RUN_PROGRAM: {
case TK_A_GOTO:
case TK_END:
case TK_M_PARENTS_MIN:
case TK_M_PARENTS_MAX:
case TK_M_MAX:
case TK_UNSET:
goto nomatch;
cur++;
case TK_RULE:
goto next;
uid = 0;
gid = 0;
mode = 0;
case TK_A_OWNER_ID:
case TK_A_GROUP_ID:
case TK_A_MODE_ID:
case TK_A_STATIC_NODE: {
goto next;
goto next;
goto next;
if (mode == 0) {
if (gid > 0)
case TK_END:
cur++;
next: