action = argv[1];
devpath = argv[2];
- rules = udev_rules_new(1);
+ rules = udev_rules_new(RESOLVE_NAME_EARLY);
const char *syspath = strjoina("/sys", devpath);
r = device_new_from_synthetic_event(&dev, syspath, action);
#include "stat-util.h"
#include "stdio-util.h"
#include "strbuf.h"
+#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "sysctl-util.h"
struct udev_rules {
usec_t dirs_ts_usec;
- int resolve_names;
+ ResolveNameTiming resolve_name_timing;
/* every key in the rules file becomes a token */
struct token *tokens;
uid = strtoul(value, &endptr, 10);
if (endptr[0] == '\0')
rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
- else if (rules->resolve_names > 0 && strchr("$%", value[0]) == NULL) {
+ else if (rules->resolve_name_timing == RESOLVE_NAME_EARLY && strchr("$%", value[0]) == NULL) {
uid = add_uid(rules, value);
rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
- } else if (rules->resolve_names >= 0)
+ } else if (rules->resolve_name_timing != RESOLVE_NAME_NEVER)
rule_add_key(&rule_tmp, TK_A_OWNER, op, value, NULL);
rule_tmp.rule.rule.can_set_name = true;
gid = strtoul(value, &endptr, 10);
if (endptr[0] == '\0')
rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
- else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
+ else if ((rules->resolve_name_timing == RESOLVE_NAME_EARLY) && strchr("$%", value[0]) == NULL) {
gid = add_gid(rules, value);
rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
- } else if (rules->resolve_names >= 0)
+ } else if (rules->resolve_name_timing != RESOLVE_NAME_NEVER)
rule_add_key(&rule_tmp, TK_A_GROUP, op, value, NULL);
rule_tmp.rule.rule.can_set_name = true;
return 0;
}
-struct udev_rules *udev_rules_new(int resolve_names) {
+struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing) {
struct udev_rules *rules;
struct token end_token;
char **files, **f;
int r;
+ assert(resolve_name_timing >= 0 && resolve_name_timing < _RESOLVE_NAME_TIMING_MAX);
+
rules = new(struct udev_rules, 1);
if (!rules)
return NULL;
*rules = (struct udev_rules) {
- .resolve_names = resolve_names,
+ .resolve_name_timing = resolve_name_timing,
};
/* init token array and string buffer */
return 0;
}
+
+static const char* const resolve_name_timing_table[_RESOLVE_NAME_TIMING_MAX] = {
+ [RESOLVE_NAME_NEVER] = "never",
+ [RESOLVE_NAME_LATE] = "late",
+ [RESOLVE_NAME_EARLY] = "early",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(resolve_name_timing, ResolveNameTiming);
bool run_final;
};
+typedef enum ResolveNameTiming {
+ RESOLVE_NAME_NEVER,
+ RESOLVE_NAME_LATE,
+ RESOLVE_NAME_EARLY,
+ _RESOLVE_NAME_TIMING_MAX,
+ _RESOLVE_NAME_TIMING_INVALID = -1,
+} ResolveNameTiming;
+
/* udev-rules.c */
struct udev_rules;
-struct udev_rules *udev_rules_new(int resolve_names);
+struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing);
struct udev_rules *udev_rules_unref(struct udev_rules *rules);
bool udev_rules_check_timestamp(struct udev_rules *rules);
int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
Hashmap *properties_list);
int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
+ResolveNameTiming resolve_name_timing_from_string(const char *s) _pure_;
+const char *resolve_name_timing_to_string(ResolveNameTiming i) _const_;
+
/* udev-event.c */
struct udev_event *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl);
struct udev_event *udev_event_free(struct udev_event *event);
#include "udevadm.h"
static const char *arg_action = "add";
-static int arg_resolve_names = 1;
+static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY;
static char arg_syspath[UTIL_PATH_SIZE] = {};
static int help(void) {
arg_action = optarg;
break;
case 'N':
- if (streq (optarg, "early")) {
- arg_resolve_names = 1;
- } else if (streq (optarg, "late")) {
- arg_resolve_names = 0;
- } else if (streq (optarg, "never")) {
- arg_resolve_names = -1;
- } else {
- log_error("resolve-names must be early, late or never");
+ arg_resolve_name_timing = resolve_name_timing_from_string(optarg);
+ if (arg_resolve_name_timing < 0) {
+ log_error("--resolve-names= must be early, late or never");
return -EINVAL;
}
break;
udev_builtin_init();
- rules = udev_rules_new(arg_resolve_names);
+ rules = udev_rules_new(arg_resolve_name_timing);
if (!rules) {
log_error("Failed to read udev rules.");
r = -ENOMEM;
static bool arg_debug = false;
static int arg_daemonize = false;
-static int arg_resolve_names = 1;
+static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY;
static unsigned arg_children_max = 0;
static usec_t arg_exec_delay_usec = 0;
static usec_t arg_event_timeout_usec = 180 * USEC_PER_SEC;
udev_builtin_init();
if (!manager->rules) {
- manager->rules = udev_rules_new(arg_resolve_names);
+ manager->rules = udev_rules_new(arg_resolve_name_timing);
if (!manager->rules)
return;
}
case 'D':
arg_debug = true;
break;
- case 'N':
- if (streq(optarg, "early")) {
- arg_resolve_names = 1;
- } else if (streq(optarg, "late")) {
- arg_resolve_names = 0;
- } else if (streq(optarg, "never")) {
- arg_resolve_names = -1;
- } else {
- log_error("resolve-names must be early, late or never");
- return 0;
- }
+ case 'N': {
+ ResolveNameTiming t;
+
+ t = resolve_name_timing_from_string(optarg);
+ if (t < 0)
+ log_warning("Invalid --resolve-names= value '%s', ignoring.", optarg);
+ else
+ arg_resolve_name_timing = t;
break;
+ }
case 'h':
return help();
case 'V':
udev_builtin_init();
- manager->rules = udev_rules_new(arg_resolve_names);
+ manager->rules = udev_rules_new(arg_resolve_name_timing);
if (!manager->rules)
return log_error_errno(ENOMEM, "error reading rules");