udev-rules.c revision 775f8b3c74e796e1215aa06b8ea4c5d354bc50ee
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * Copyright (C) 2003-2010 Kay Sievers <kay.sievers@vrfy.org>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * Copyright (C) 2008 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * This program is free software: you can redistribute it and/or modify
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * it under the terms of the GNU General Public License as published by
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers * the Free Software Foundation, either version 2 of the License, or
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * (at your option) any later version.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * This program is distributed in the hope that it will be useful,
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * GNU General Public License for more details.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * You should have received a copy of the GNU General Public License
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * along with this program. If not, see <http://www.gnu.org/licenses/>.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* this node's first child */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* the next child of our parent node's child list */
1b12a7b5896f94bdf33b3a6661ebabd761ea6adcHarald Hoyer /* this node's last child (shortcut for append) */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering unsigned short value_len;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering unsigned char key;
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering unsigned long long *dirs_ts_usec;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* every key in the rules file becomes a token */
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers unsigned int token_max;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers /* all key strings are copied to a single string buffer */
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers unsigned int buf_count;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers /* during rule parsing, strings are indexed and de-duplicated */
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers /* during rule parsing, uid/gid lookup results are cached */
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers unsigned int uids_cur;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers unsigned int uids_max;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers unsigned int gids_cur;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers unsigned int gids_max;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers/* KEY=="", KEY!="", KEY+="", KEY="", KEY:="" */
599659860c770058f2eb04d578c521c16e0b1853Lennart Poettering GL_SPLIT_GLOB, /* multi-value with glob A*|B* */
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden/* tokens of a rule are sorted/handled in this order */
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen TK_M_IMPORT_CMDLINE, /* val */
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen TK_M_IMPORT_PARENT, /* val */
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen TK_A_RUN_BUILTIN, /* val, bool */
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen TK_A_RUN_PROGRAM, /* val, bool */
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen/* we try to pack stuff in a way that we take only 12 bytes per token */
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen unsigned char type; /* same in rule and key */
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen unsigned short filename_line;
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen enum string_glob_type glob:8;
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen enum string_subst_type subst:4;
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen enum string_subst_type attrsubst:4;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers unsigned int rule_goto;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers unsigned int token_cur;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersenstatic const char *operation_str(enum operation_type type)
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers static const char *operation_strs[] = {
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sieversstatic const char *string_glob_str(enum string_glob_type type)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering static const char *string_glob_strs[] = {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic const char *token_str(enum token_type type)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering static const char *token_strs[] = {
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_DEVPATH] = "M DEVPATH",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_DEVLINK] = "M DEVLINK",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_SUBSYSTEM] = "M SUBSYSTEM",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_WAITFOR] = "M WAITFOR",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_SUBSYSTEMS] = "M SUBSYSTEMS",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_DRIVERS] = "M DRIVERS",
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering [TK_M_EVENT_TIMEOUT] = "M EVENT_TIMEOUT",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_IMPORT_FILE] = "M IMPORT_FILE",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_IMPORT_PROG] = "M IMPORT_PROG",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_IMPORT_BUILTIN] = "M IMPORT_BUILTIN",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_IMPORT_DB] = "M IMPORT_DB",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_IMPORT_CMDLINE] = "M IMPORT_CMDLINE",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_M_IMPORT_PARENT] = "M IMPORT_PARENT",
07a062a79374406e8f6b5a1e2f80c80baf031567Jason St. John [TK_A_STRING_ESCAPE_NONE] = "A STRING_ESCAPE_NONE",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_A_STRING_ESCAPE_REPLACE] = "A STRING_ESCAPE_REPLACE",
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen [TK_A_DB_PERSIST] = "A DB_PERSIST",
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering [TK_A_INOTIFY_WATCH] = "A INOTIFY_WATCH",
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poetteringstatic void dump_token(struct udev_rules *rules, struct token *token)
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen enum token_type type = token->type;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen enum operation_type op = token->key.op;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen enum string_glob_type glob = token->key.glob;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering const char *value = &rules->buf[token->key.value_off];
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering const char *attr = &rules->buf[token->key.attr_off];
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering const char *tks_ptr = (char *)rules->tokens;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering unsigned int idx = (tk_ptr - tks_ptr) / sizeof(struct token);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("* RULE %s:%u, token: %u, count: %u, label: '%s'\n",
e5609878d8802e2469c433be418bcbcf55fbe63bLennart Poettering &rules->buf[token->rule.filename_off], token->rule.filename_line,
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering token_str(type), operation_str(op), value, string_glob_str(glob));
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s %i '%s'\n", token_str(type), token->key.builtin_cmd, value);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering token_str(type), operation_str(op), attr, value, string_glob_str(glob));
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s %s '%s'\n", token_str(type), operation_str(op), value);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering token_str(type), operation_str(op), value, string_glob_str(glob), token->key.mode);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s %u\n", token_str(type), token->key.watch);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s %u\n", token_str(type), token->key.devlink_prio);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.uid);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.gid);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s %s %#o\n", token_str(type), operation_str(op), token->key.mode);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s '%s'\n", token_str(type), value);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s %u\n", token_str(type), token->key.event_timeout);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering log_debug("%s '%s' %u\n", token_str(type), value, token->key.rule_goto);
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmekstatic void dump_rules(struct udev_rules *rules)
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings\n",
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic inline const char *operation_str(enum operation_type type) { return NULL; }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic inline const char *token_str(enum token_type type) { return NULL; }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic inline void dump_token(struct udev_rules *rules, struct token *token) {}
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic inline void dump_rules(struct udev_rules *rules) {}
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#endif /* DEBUG */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic int add_new_string(struct udev_rules *rules, const char *str, size_t bytes)
c978343015c787713651dff571acb5207367f5f2Lennart Poettering /* grow buffer if needed */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (rules->buf_cur + bytes+1 >= rules->buf_max) {
c978343015c787713651dff571acb5207367f5f2Lennart Poettering /* double the buffer size */
c978343015c787713651dff571acb5207367f5f2Lennart Poettering buf = realloc(rules->buf, rules->buf_max + add);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering memcpy(&rules->buf[rules->buf_cur], str, bytes);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic int add_string(struct udev_rules *rules, const char *str)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering unsigned char key;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering unsigned short len;
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen /* walk trie, start from last character of str to find matching tails */
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen for (depth = 0; depth <= len; depth++) {
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen /* match against current node */
c978343015c787713651dff571acb5207367f5f2Lennart Poettering if (depth == len || (node->value_len >= len && memcmp(&rules->buf[off], str, len) == 0))
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* lookup child node */
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen /* string not found, add it */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering off = add_new_string(rules, str, len + 1);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* grow trie nodes if needed */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (rules->trie_nodes_cur >= rules->trie_nodes_max) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* double the buffer size */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering nodes = realloc(rules->trie_nodes, (rules->trie_nodes_max + add) * sizeof(struct trie_node));
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* get a new node */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering new_node = &rules->trie_nodes[new_node_idx];
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering memset(new_node, 0x00, sizeof(struct trie_node));
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* join the parent's child list */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering last_child = &rules->trie_nodes[parent->last_child_idx];
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering last_child->next_child_idx = new_node_idx;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic int add_token(struct udev_rules *rules, struct token *token)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* grow buffer if needed */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (rules->token_cur+1 >= rules->token_max) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* double the buffer size */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering tokens = realloc(rules->tokens, (rules->token_max + add ) * sizeof(struct token));
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering memcpy(&rules->tokens[rules->token_cur], token, sizeof(struct token));
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic uid_t add_uid(struct udev_rules *rules, const char *owner)
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering unsigned int i;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* lookup, if we know it already */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering uid = util_lookup_user(rules->udev, owner);
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering /* grow buffer if needed */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (rules->uids_cur+1 >= rules->uids_max) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering /* double the buffer size */
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen uids = realloc(rules->uids, (rules->uids_max + add ) * sizeof(struct uid_gid));
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen rules->uids[rules->uids_cur].uid = uid;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering rules->uids[rules->uids_cur].name_off = off;
unsigned int off;
return gid;
unsigned int add;
return gid;
if (off <= 0)
return gid;
return gid;
char *key;
char *val;
key++;
val++;
val++;
if (len == 0)
len--;
if (len == 0)
len--;
if (len == 0)
val++;
FILE *f;
if (f == NULL)
fclose(f);
static int import_program_into_properties(struct udev_event *event, const char *program, const sigset_t *sigmask)
char **envp;
char *line;
int err;
if (err < 0)
return err;
char *pos;
while (--loop) {
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;
changed = true;
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: