/*
- * Copyright (C) 2003-2010 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2003-2012 Kay Sievers <kay.sievers@vrfy.org>
* Copyright (C) 2008 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
*
* This program is free software: you can redistribute it and/or modify
#include <time.h>
#include "udev.h"
+#include "path-util.h"
+#include "conf-files.h"
#define PREALLOC_TOKEN 2048
#define PREALLOC_STRBUF 32 * 1024
struct udev_rules {
struct udev *udev;
+ char **dirs;
+ unsigned long long *dirs_ts_usec;
int resolve_names;
/* every key in the rules file becomes a token */
size_t buf_max;
unsigned int buf_count;
- /* during rule parsing, strings are indexed to find duplicates */
+ /* during rule parsing, strings are indexed and de-duplicated */
struct trie_node *trie_nodes;
unsigned int trie_nodes_cur;
unsigned int trie_nodes_max;
/* lookup, if we know it already */
for (i = 0; i < rules->uids_cur; i++) {
off = rules->uids[i].name_off;
- if (strcmp(&rules->buf[off], owner) == 0) {
+ if (streq(&rules->buf[off], owner)) {
uid = rules->uids[i].uid;
return uid;
}
/* lookup, if we know it already */
for (i = 0; i < rules->gids_cur; i++) {
off = rules->gids[i].name_off;
- if (strcmp(&rules->buf[off], group) == 0) {
+ if (streq(&rules->buf[off], group)) {
gid = rules->gids[i].gid;
return gid;
}
static int import_property_from_string(struct udev_device *dev, char *line)
{
- struct udev *udev = udev_device_get_udev(dev);
char *key;
char *val;
size_t len;
}
/* handle device, renamed by external tool, returning new path */
- if (strcmp(key, "DEVPATH") == 0) {
+ if (streq(key, "DEVPATH")) {
char syspath[UTIL_PATH_SIZE];
log_debug("updating devpath from '%s' to '%s'\n",
udev_device_get_devpath(dev), val);
- util_strscpyl(syspath, sizeof(syspath), udev_get_sys_path(udev), val, NULL);
+ util_strscpyl(syspath, sizeof(syspath), "/sys", val, NULL);
udev_device_set_syspath(dev, syspath);
} else {
struct udev_list_entry *entry;
FILE *f;
char line[UTIL_LINE_SIZE];
- f = fopen(filename, "r");
+ f = fopen(filename, "re");
if (f == NULL)
return -1;
while (fgets(line, sizeof(line), f) != NULL)
#define WAIT_LOOP_PER_SECOND 50
static int wait_for_file(struct udev_device *dev, const char *file, int timeout)
{
- struct udev *udev = udev_device_get_udev(dev);
char filepath[UTIL_PATH_SIZE];
char devicepath[UTIL_PATH_SIZE];
struct stat stats;
/* a relative path is a device attribute */
devicepath[0] = '\0';
if (file[0] != '/') {
- util_strscpyl(devicepath, sizeof(devicepath),
- udev_get_sys_path(udev), udev_device_get_devpath(dev), NULL);
+ util_strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL);
util_strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL);
file = filepath;
}
} else if (has_split) {
glob = GL_SPLIT;
} else if (has_glob) {
- if (strcmp(value, "?*") == 0)
+ if (streq(value, "?*"))
glob = GL_SOMETHING;
else
glob = GL_GLOB;
memset(&rule_tmp, 0x00, sizeof(struct rule_tmp));
rule_tmp.rules = rules;
rule_tmp.rule.type = TK_RULE;
- rule_tmp.rule.rule.filename_off = filename_off;
+ /* the offset in the rule is limited to unsigned short */
+ if (filename_off < USHRT_MAX)
+ rule_tmp.rule.rule.filename_off = filename_off;
rule_tmp.rule.rule.filename_line = lineno;
linepos = line;
if (get_key(rules->udev, &linepos, &key, &op, &value) != 0)
break;
- if (strcmp(key, "ACTION") == 0) {
+ if (streq(key, "ACTION")) {
if (op > OP_MATCH_MAX) {
log_error("invalid ACTION operation\n");
goto invalid;
continue;
}
- if (strcmp(key, "DEVPATH") == 0) {
+ if (streq(key, "DEVPATH")) {
if (op > OP_MATCH_MAX) {
log_error("invalid DEVPATH operation\n");
goto invalid;
continue;
}
- if (strcmp(key, "KERNEL") == 0) {
+ if (streq(key, "KERNEL")) {
if (op > OP_MATCH_MAX) {
log_error("invalid KERNEL operation\n");
goto invalid;
continue;
}
- if (strcmp(key, "SUBSYSTEM") == 0) {
+ if (streq(key, "SUBSYSTEM")) {
if (op > OP_MATCH_MAX) {
log_error("invalid SUBSYSTEM operation\n");
goto invalid;
}
/* bus, class, subsystem events should all be the same */
- if (strcmp(value, "subsystem") == 0 ||
- strcmp(value, "bus") == 0 ||
- strcmp(value, "class") == 0) {
- if (strcmp(value, "bus") == 0 || strcmp(value, "class") == 0)
+ if (streq(value, "subsystem") ||
+ streq(value, "bus") ||
+ streq(value, "class")) {
+ if (streq(value, "bus") || streq(value, "class"))
log_error("'%s' must be specified as 'subsystem' \n"
"please fix it in %s:%u", value, filename, lineno);
rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, "subsystem|class|bus", NULL);
continue;
}
- if (strcmp(key, "DRIVER") == 0) {
+ if (streq(key, "DRIVER")) {
if (op > OP_MATCH_MAX) {
log_error("invalid DRIVER operation\n");
goto invalid;
continue;
}
- if (strncmp(key, "ATTR{", sizeof("ATTR{")-1) == 0) {
+ if (startswith(key, "ATTR{")) {
attr = get_key_attribute(rules->udev, key + sizeof("ATTR")-1);
if (attr == NULL) {
log_error("error parsing ATTR attribute\n");
continue;
}
- if (strcmp(key, "KERNELS") == 0) {
+ if (streq(key, "KERNELS")) {
if (op > OP_MATCH_MAX) {
log_error("invalid KERNELS operation\n");
goto invalid;
continue;
}
- if (strcmp(key, "SUBSYSTEMS") == 0) {
+ if (streq(key, "SUBSYSTEMS")) {
if (op > OP_MATCH_MAX) {
log_error("invalid SUBSYSTEMS operation\n");
goto invalid;
continue;
}
- if (strcmp(key, "DRIVERS") == 0) {
+ if (streq(key, "DRIVERS")) {
if (op > OP_MATCH_MAX) {
log_error("invalid DRIVERS operation\n");
goto invalid;
continue;
}
- if (strncmp(key, "ATTRS{", sizeof("ATTRS{")-1) == 0) {
+ if (startswith(key, "ATTRS{")) {
if (op > OP_MATCH_MAX) {
log_error("invalid ATTRS operation\n");
goto invalid;
log_error("error parsing ATTRS attribute\n");
goto invalid;
}
- if (strncmp(attr, "device/", 7) == 0)
+ if (startswith(attr, "device/"))
log_error("the 'device' link may not be available in a future kernel, "
"please fix it in %s:%u", filename, lineno);
else if (strstr(attr, "../") != NULL)
continue;
}
- if (strcmp(key, "TAGS") == 0) {
+ if (streq(key, "TAGS")) {
if (op > OP_MATCH_MAX) {
log_error("invalid TAGS operation\n");
goto invalid;
continue;
}
- if (strncmp(key, "ENV{", sizeof("ENV{")-1) == 0) {
+ if (startswith(key, "ENV{")) {
attr = get_key_attribute(rules->udev, key + sizeof("ENV")-1);
if (attr == NULL) {
log_error("error parsing ENV attribute\n");
};
unsigned int i;
- for (i = 0; i < ELEMENTSOF(blacklist); i++)
- if (strcmp(attr, blacklist[i]) == 0) {
- log_error("invalid ENV attribute, '%s' can not be set %s:%u\n", attr, filename, lineno);
+ for (i = 0; i < ELEMENTSOF(blacklist); i++) {
+ if (!streq(attr, blacklist[i]))
continue;
- }
+ log_error("invalid ENV attribute, '%s' can not be set %s:%u\n", attr, filename, lineno);
+ goto invalid;
+ }
if (rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr) != 0)
goto invalid;
}
continue;
}
- if (strcmp(key, "TAG") == 0) {
+ if (streq(key, "TAG")) {
if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL);
else
continue;
}
- if (strcmp(key, "PROGRAM") == 0) {
+ if (streq(key, "PROGRAM")) {
rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL);
continue;
}
- if (strcmp(key, "RESULT") == 0) {
+ if (streq(key, "RESULT")) {
if (op > OP_MATCH_MAX) {
log_error("invalid RESULT operation\n");
goto invalid;
continue;
}
- if (strncmp(key, "IMPORT", sizeof("IMPORT")-1) == 0) {
+ if (startswith(key, "IMPORT")) {
attr = get_key_attribute(rules->udev, key + sizeof("IMPORT")-1);
if (attr == NULL) {
log_error("IMPORT{} type missing, ignoring IMPORT %s:%u\n", filename, lineno);
continue;
}
- if (strcmp(attr, "program") == 0) {
+ if (streq(attr, "program")) {
/* find known built-in command */
if (value[0] != '/') {
enum udev_builtin_cmd cmd;
}
}
rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL);
- } else if (strcmp(attr, "builtin") == 0) {
+ } else if (streq(attr, "builtin")) {
enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
if (cmd < UDEV_BUILTIN_MAX)
rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
else
log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno);
- } else if (strcmp(attr, "file") == 0) {
+ } else if (streq(attr, "file")) {
rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL);
- } else if (strcmp(attr, "db") == 0) {
+ } else if (streq(attr, "db")) {
rule_add_key(&rule_tmp, TK_M_IMPORT_DB, op, value, NULL);
- } else if (strcmp(attr, "cmdline") == 0) {
+ } else if (streq(attr, "cmdline")) {
rule_add_key(&rule_tmp, TK_M_IMPORT_CMDLINE, op, value, NULL);
- } else if (strcmp(attr, "parent") == 0) {
+ } else if (streq(attr, "parent")) {
rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL);
} else
log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u\n", filename, lineno);
continue;
}
- if (strncmp(key, "TEST", sizeof("TEST")-1) == 0) {
+ if (startswith(key, "TEST")) {
mode_t mode = 0;
if (op > OP_MATCH_MAX) {
continue;
}
- if (strncmp(key, "RUN", sizeof("RUN")-1) == 0) {
+ if (startswith(key, "RUN")) {
attr = get_key_attribute(rules->udev, key + sizeof("RUN")-1);
if (attr == NULL)
attr = "program";
- if (strcmp(attr, "builtin") == 0) {
+ if (streq(attr, "builtin")) {
enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
if (cmd < UDEV_BUILTIN_MAX)
rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd);
else
log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno);
- } else if (strcmp(attr, "program") == 0) {
+ } else if (streq(attr, "program")) {
enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX;
rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd);
continue;
}
- if (strcmp(key, "WAIT_FOR") == 0 || strcmp(key, "WAIT_FOR_SYSFS") == 0) {
+ if (streq(key, "WAIT_FOR") || streq(key, "WAIT_FOR_SYSFS")) {
rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL);
continue;
}
- if (strcmp(key, "LABEL") == 0) {
+ if (streq(key, "LABEL")) {
rule_tmp.rule.rule.label_off = add_string(rules, value);
continue;
}
- if (strcmp(key, "GOTO") == 0) {
+ if (streq(key, "GOTO")) {
rule_add_key(&rule_tmp, TK_A_GOTO, 0, value, NULL);
continue;
}
- if (strncmp(key, "NAME", sizeof("NAME")-1) == 0) {
+ if (startswith(key, "NAME")) {
if (op < OP_MATCH_MAX) {
rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL);
} else {
- if (strcmp(value, "%k") == 0) {
+ if (streq(value, "%k")) {
log_error("NAME=\"%%k\" is ignored, because it breaks kernel supplied names, "
"please remove it from %s:%u\n", filename, lineno);
continue;
continue;
}
- if (strncmp(key, "SYMLINK", sizeof("SYMLINK")-1) == 0) {
+ if (startswith(key, "SYMLINK")) {
if (op < OP_MATCH_MAX) {
rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL);
} else {
continue;
}
- if (strcmp(key, "OWNER") == 0) {
+ if (streq(key, "OWNER")) {
uid_t uid;
char *endptr;
continue;
}
- if (strcmp(key, "GROUP") == 0) {
+ if (streq(key, "GROUP")) {
gid_t gid;
char *endptr;
continue;
}
- if (strcmp(key, "MODE") == 0) {
+ if (streq(key, "MODE")) {
mode_t mode;
char *endptr;
continue;
}
- if (strcmp(key, "OPTIONS") == 0) {
+ if (streq(key, "OPTIONS")) {
const char *pos;
pos = strstr(value, "link_priority=");
pos = strstr(value, "string_escape=");
if (pos != NULL) {
pos = &pos[strlen("string_escape=")];
- if (strncmp(pos, "none", strlen("none")) == 0)
+ if (startswith(pos, "none"))
rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_NONE, op, NULL, NULL);
- else if (strncmp(pos, "replace", strlen("replace")) == 0)
+ else if (startswith(pos, "replace"))
rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_REPLACE, op, NULL, NULL);
}
return -1;
}
-static int parse_file(struct udev_rules *rules, const char *filename, unsigned short filename_off)
+static int parse_file(struct udev_rules *rules, const char *filename)
{
FILE *f;
unsigned int first_token;
+ unsigned int filename_off;
char line[UTIL_LINE_SIZE];
int line_nr = 0;
unsigned int i;
- log_debug("reading '%s' as rules file\n", filename);
+ if (null_or_empty_path(filename)) {
+ log_debug("skip empty file: %s\n", filename);
+ return 0;
+ }
+ log_debug("read rules file: %s\n", filename);
- f = fopen(filename, "r");
+ f = fopen(filename, "re");
if (f == NULL)
return -1;
first_token = rules->token_cur;
+ filename_off = add_string(rules, filename);
while (fgets(line, sizeof(line), f) != NULL) {
char *key;
continue;
if (rules->tokens[j].rule.label_off == 0)
continue;
- if (strcmp(label, &rules->buf[rules->tokens[j].rule.label_off]) != 0)
+ if (!streq(label, &rules->buf[rules->tokens[j].rule.label_off]))
continue;
rules->tokens[i].key.rule_goto = j;
break;
return 0;
}
-static int add_matching_files(struct udev *udev, struct udev_list *file_list, const char *dirname, const char *suffix)
-{
- DIR *dir;
- struct dirent *dent;
- char filename[UTIL_PATH_SIZE];
-
- dir = opendir(dirname);
- if (dir == NULL) {
- log_debug("unable to open '%s': %m\n", dirname);
- return -1;
- }
-
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
- if (dent->d_name[0] == '.')
- continue;
-
- /* look for file matching with specified suffix */
- if (suffix != NULL) {
- const char *ext;
-
- ext = strrchr(dent->d_name, '.');
- if (ext == NULL)
- continue;
- if (strcmp(ext, suffix) != 0)
- continue;
- }
- util_strscpyl(filename, sizeof(filename), dirname, "/", dent->d_name, NULL);
- /*
- * the basename is the key, the filename the value
- * identical basenames from different directories override each other
- * entries are sorted after basename
- */
- udev_list_entry_add(file_list, dent->d_name, filename);
- }
-
- closedir(dir);
- return 0;
-}
-
struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
{
struct udev_rules *rules;
struct udev_list file_list;
- struct udev_list_entry *file_loop;
struct token end_token;
- char **s;
+ char **files, **f;
+ int r;
rules = calloc(1, sizeof(struct udev_rules));
if (rules == NULL)
/* init token array and string buffer */
rules->tokens = malloc(PREALLOC_TOKEN * sizeof(struct token));
- if (rules->tokens == NULL) {
- free(rules);
- return NULL;
- }
+ if (rules->tokens == NULL)
+ return udev_rules_unref(rules);
+
rules->token_max = PREALLOC_TOKEN;
rules->buf = malloc(PREALLOC_STRBUF);
- if (rules->buf == NULL) {
- free(rules->tokens);
- free(rules);
- return NULL;
- }
+ if (rules->buf == NULL)
+ return udev_rules_unref(rules);
+
rules->buf_max = PREALLOC_STRBUF;
/* offset 0 is always '\0' */
rules->buf[0] = '\0';
rules->buf_cur = 1;
rules->trie_nodes = malloc(PREALLOC_TRIE * sizeof(struct trie_node));
- if (rules->trie_nodes == NULL) {
- free(rules->buf);
- free(rules->tokens);
- free(rules);
- return NULL;
- }
+ if (rules->trie_nodes == NULL)
+ return udev_rules_unref(rules);
+
rules->trie_nodes_max = PREALLOC_TRIE;
/* offset 0 is the trie root, with an empty string */
memset(rules->trie_nodes, 0x00, sizeof(struct trie_node));
rules->trie_nodes_cur = 1;
- for (udev_get_rules_path(udev, &s, NULL); *s != NULL; s++)
- add_matching_files(udev, &file_list, *s, ".rules");
+ rules->dirs = strv_new(SYSCONFDIR "/udev/rules.d",
+ "/run/udev/rules.d",
+ UDEVLIBEXECDIR "/rules.d",
+ NULL);
+ if (!rules->dirs) {
+ log_error("failed to build config directory array");
+ return udev_rules_unref(rules);
+ }
+ if (!path_strv_canonicalize(rules->dirs)) {
+ log_error("failed to canonicalize config directories\n");
+ return udev_rules_unref(rules);
+ }
+ strv_uniq(rules->dirs);
- /* add all filenames to the string buffer */
- udev_list_entry_foreach(file_loop, udev_list_get_entry(&file_list)) {
- const char *filename = udev_list_entry_get_value(file_loop);
- unsigned int filename_off;
+ rules->dirs_ts_usec = calloc(strv_length(rules->dirs), sizeof(long long));
+ if(!rules->dirs_ts_usec)
+ return udev_rules_unref(rules);
+ udev_rules_check_timestamp(rules);
- filename_off = add_string(rules, filename);
- /* the offset in the rule is limited to unsigned short */
- if (filename_off < USHRT_MAX)
- udev_list_entry_set_num(file_loop, filename_off);
+ r = conf_files_list_strv(&files, ".rules", (const char **)rules->dirs);
+ if (r < 0) {
+ log_error("failed to enumerate rules files: %s\n", strerror(-r));
+ return udev_rules_unref(rules);
}
- /* parse all rules files */
- udev_list_entry_foreach(file_loop, udev_list_get_entry(&file_list)) {
- const char *filename = udev_list_entry_get_value(file_loop);
- unsigned int filename_off = udev_list_entry_get_num(file_loop);
- struct stat st;
+ /*
+ * The offset value in the rules strct is limited; add all
+ * rules file names to the beginning of the string buffer.
+ */
+ STRV_FOREACH(f, files)
+ add_string(rules, *f);
- if (stat(filename, &st) != 0) {
- log_error("can not find '%s': %m\n", filename);
- continue;
- }
- if (S_ISREG(st.st_mode) && st.st_size <= 0) {
- log_debug("ignore empty '%s'\n", filename);
- continue;
- }
- if (S_ISCHR(st.st_mode)) {
- log_debug("ignore masked '%s'\n", filename);
- continue;
- }
- parse_file(rules, filename, filename_off);
- }
- udev_list_cleanup(&file_list);
+ STRV_FOREACH(f, files)
+ parse_file(rules, *f);
+
+ strv_free(files);
memset(&end_token, 0x00, sizeof(struct token));
end_token.type = TK_END;
free(rules->trie_nodes);
free(rules->uids);
free(rules->gids);
+ strv_free(rules->dirs);
+ free(rules->dirs_ts_usec);
free(rules);
return NULL;
}
+bool udev_rules_check_timestamp(struct udev_rules *rules)
+{
+ unsigned int i;
+ bool changed = false;
+
+ if (rules == NULL)
+ goto out;
+
+ for (i = 0; rules->dirs[i]; i++) {
+ struct stat stats;
+
+ if (stat(rules->dirs[i], &stats) < 0)
+ continue;
+
+ if (rules->dirs_ts_usec[i] == ts_usec(&stats.st_mtim))
+ continue;
+
+ /* first check */
+ if (rules->dirs_ts_usec[i] != 0) {
+ log_debug("reload - timestamp of '%s' changed\n", rules->dirs[i]);
+ changed = true;
+ }
+
+ /* update timestamp */
+ rules->dirs_ts_usec[i] = ts_usec(&stats.st_mtim);
+ }
+out:
+ return changed;
+}
+
static int match_key(struct udev_rules *rules, struct token *token, const char *val)
{
char *key_value = &rules->buf[token->key.value_off];
switch (token->key.glob) {
case GL_PLAIN:
- match = (strcmp(key_value, val) == 0);
+ match = (streq(key_value, val));
break;
case GL_GLOB:
match = (fnmatch(key_value, val, 0) == 0);
break;
case GL_SPLIT:
{
- const char *split;
+ const char *s;
size_t len;
- split = &rules->buf[token->key.value_off];
+ s = &rules->buf[token->key.value_off];
len = strlen(val);
for (;;) {
const char *next;
- next = strchr(split, '|');
+ next = strchr(s, '|');
if (next != NULL) {
- size_t matchlen = (size_t)(next - split);
+ size_t matchlen = (size_t)(next - s);
- match = (matchlen == len && strncmp(split, val, matchlen) == 0);
+ match = (matchlen == len && strncmp(s, val, matchlen) == 0);
if (match)
break;
} else {
- match = (strcmp(split, val) == 0);
+ match = (streq(s, val));
break;
}
- split = &next[1];
+ s = &next[1];
}
break;
}
if (rules->tokens == NULL)
return -1;
- can_set_name = ((strcmp(udev_device_get_action(event->dev), "remove") != 0) &&
+ can_set_name = ((!streq(udev_device_get_action(event->dev), "remove")) &&
(major(udev_device_get_devnum(event->dev)) > 0 ||
udev_device_get_ifindex(event->dev) > 0));
goto nomatch;
break;
case TK_M_DEVLINK: {
- size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
struct udev_list_entry *list_entry;
bool match = false;
udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(event->dev)) {
const char *devlink;
- devlink = &udev_list_entry_get_name(list_entry)[devlen];
+ devlink = udev_list_entry_get_name(list_entry) + strlen("/dev/");
if (match_key(rules, cur, devlink) == 0) {
match = true;
break;
bool match = false;
udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(event->dev)) {
- if (strcmp(&rules->buf[cur->key.value_off], udev_list_entry_get_name(list_entry)) == 0) {
+ if (streq(&rules->buf[cur->key.value_off], udev_list_entry_get_name(list_entry))) {
match = true;
break;
}
FILE *f;
bool imported = false;
- f = fopen("/proc/cmdline", "r");
+ f = fopen("/proc/cmdline", "re");
if (f != NULL) {
char cmdline[4096];
if (count > 0)
log_debug("%i character(s) replaced\n", count);
}
- if (major(udev_device_get_devnum(event->dev))) {
- size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
-
- if (strcmp(name_str, &udev_device_get_devnode(event->dev)[devlen]) != 0) {
- log_error("NAME=\"%s\" ignored, kernel device nodes "
- "can not be renamed; please fix it in %s:%u\n", name,
- &rules->buf[rule->rule.filename_off], rule->rule.filename_line);
- break;
- }
+ if (major(udev_device_get_devnum(event->dev)) &&
+ (!streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/")))) {
+ log_error("NAME=\"%s\" ignored, kernel device nodes "
+ "can not be renamed; please fix it in %s:%u\n", name,
+ &rules->buf[rule->rule.filename_off], rule->rule.filename_line);
+ break;
}
free(event->name);
event->name = strdup(name_str);
next[0] = '\0';
log_debug("LINK '%s' %s:%u\n", pos,
&rules->buf[rule->rule.filename_off], rule->rule.filename_line);
- util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", pos, NULL);
+ util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL);
udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique);
while (isspace(next[1]))
next++;
if (pos[0] != '\0') {
log_debug("LINK '%s' %s:%u\n", pos,
&rules->buf[rule->rule.filename_off], rule->rule.filename_line);
- util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", pos, NULL);
+ util_strscpyl(filename, sizeof(filename), "/dev/", pos, NULL);
udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique);
}
break;
log_debug("ATTR '%s' writing '%s' %s:%u\n", attr, value,
&rules->buf[rule->rule.filename_off],
rule->rule.filename_line);
- f = fopen(attr, "w");
+ f = fopen(attr, "we");
if (f != NULL) {
if (fprintf(f, "%s", value) <= 0)
log_error("error writing ATTR{%s}: %m\n", attr);
/* we assure, that the permissions tokens are sorted before the static token */
if (mode == 0 && uid == 0 && gid == 0)
goto next;
- util_strscpyl(filename, sizeof(filename), udev_get_dev_path(rules->udev), "/",
+ util_strscpyl(filename, sizeof(filename), "/dev/",
&rules->buf[cur->key.value_off], NULL);
if (stat(filename, &stats) != 0)
goto next;