udev-rules.c revision 8e18485284a8718d4a9111b7c1ed91cb2f9634b0
3988N/A * along with this program. If not, see <http://www.gnu.org/licenses/>.
3988N/A#include "path-util.h"
4011N/A#include "conf-files.h"
6153N/Astruct udev_rules {
6339N/A int resolve_names;
6756N/Aenum operation_type {
6756N/Aenum string_glob_type {
6756N/Aenum string_subst_type {
6345N/Aenum token_type {
3988N/A unsigned short token_count;
3988N/A unsigned short filename_off;
3988N/A unsigned short filename_line;
3988N/A int devlink_prio;
3988N/A int event_timeout;
4641N/A static const char *operation_strs[] = {
3988N/A static const char *string_glob_strs[] = {
3988N/A static const char *token_strs[] = {
4988N/A case TK_M_ACTION:
3988N/A case TK_M_DEVPATH:
3988N/A case TK_M_KERNEL:
3988N/A case TK_M_SUBSYSTEM:
3988N/A case TK_M_DRIVER:
3988N/A case TK_M_WAITFOR:
4988N/A case TK_M_DEVLINK:
3988N/A case TK_M_KERNELS:
3988N/A case TK_M_SUBSYSTEMS:
4988N/A case TK_M_DRIVERS:
3988N/A case TK_M_PROGRAM:
4011N/A case TK_M_IMPORT_FILE:
3988N/A case TK_M_IMPORT_PROG:
3988N/A case TK_M_IMPORT_DB:
3988N/A case TK_M_IMPORT_CMDLINE:
3988N/A case TK_M_IMPORT_PARENT:
3988N/A case TK_M_RESULT:
4988N/A case TK_A_DEVLINK:
4988N/A case TK_A_OWNER:
4988N/A case TK_A_GROUP:
4988N/A case TK_A_RUN_BUILTIN:
4988N/A case TK_A_RUN_PROGRAM:
3988N/A case TK_M_IMPORT_BUILTIN:
6678N/A case TK_M_ATTRS:
3988N/A case TK_A_DB_PERSIST:
3988N/A case TK_A_INOTIFY_WATCH:
3988N/A case TK_A_DEVLINK_PRIO:
3988N/A case TK_A_OWNER_ID:
3988N/A case TK_A_GROUP_ID:
3988N/A case TK_A_MODE_ID:
3988N/A case TK_A_STATIC_NODE:
5589N/A case TK_A_SECLABEL:
3988N/A case TK_M_EVENT_TIMEOUT:
3988N/A case TK_M_PARENTS_MIN:
3988N/A case TK_M_PARENTS_MAX:
4011N/Astatic int import_program_into_properties(struct udev_event *event, const char *program, const sigset_t *sigmask)
3988N/A log_debug("file '%s' appeared after %i loops\n", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
3988N/Astatic int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value)
4988N/A case TK_M_ACTION:
3988N/A case TK_M_DEVPATH:
3988N/A case TK_M_KERNEL:
3988N/A case TK_M_SUBSYSTEM:
3988N/A case TK_M_DRIVER:
4011N/A case TK_M_WAITFOR:
4988N/A case TK_M_DEVLINK:
4988N/A case TK_M_KERNELS:
3988N/A case TK_M_SUBSYSTEMS:
3988N/A case TK_M_DRIVERS:
3988N/A case TK_M_PROGRAM:
4988N/A case TK_M_IMPORT_FILE:
4988N/A case TK_M_IMPORT_PROG:
4988N/A case TK_M_IMPORT_DB:
3988N/A case TK_M_IMPORT_CMDLINE:
4988N/A case TK_M_IMPORT_PARENT:
4988N/A case TK_M_RESULT:
3988N/A case TK_A_OWNER:
4988N/A case TK_A_GROUP:
4988N/A case TK_A_DEVLINK:
4988N/A case TK_M_IMPORT_BUILTIN:
4988N/A case TK_M_ATTRS:
4988N/A case TK_A_SECLABEL:
4011N/A case TK_A_DB_PERSIST:
4011N/A case TK_A_RUN_BUILTIN:
3988N/A case TK_A_RUN_PROGRAM:
6756N/A case TK_A_INOTIFY_WATCH:
6756N/A case TK_A_DEVLINK_PRIO:
6756N/A case TK_A_OWNER_ID:
4011N/A case TK_A_GROUP_ID:
4011N/A case TK_A_MODE_ID:
6756N/A case TK_A_STATIC_NODE:
4011N/A case TK_M_EVENT_TIMEOUT:
3988N/A case TK_M_PARENTS_MIN:
3988N/A case TK_M_PARENTS_MAX:
6756N/A has_glob = (strchr(value, '*') != NULL || strchr(value, '?') != NULL || strchr(value, '[') != NULL);
3988N/A unsigned int first_token;
3988N/A unsigned int filename_off;
3988N/A rules->token_max * sizeof(struct token), rules->token_max, sizeof(struct token), rules->strbuf->len);
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_SECLABEL: {
case TK_A_ENV: {
if (value_old) {
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_TAG:
goto finish;
case TK_A_STATIC_NODE: {
goto next;
goto next;
goto next;
if (tags) {
return -errno;
goto next;
if (mode == 0) {
if (gid > 0)
return -errno;
return -errno;
case TK_END:
goto finish;
cur++;
next:
fflush(f);
r = -errno;
fclose(f);