X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udev_rules.c;h=647875d9a93906e4a3612744a93df1858cbe0f29;hp=8587b0254989c4dfa8e42567df3dcc4aa2fe6d88;hb=5618b5611bccf64a1e22f8cbcebe8ecba9713c9c;hpb=27f877e60f1c1793d6fafdd888e7e367c44b2eb9 diff --git a/udev_rules.c b/udev_rules.c index 8587b0254..647875d9a 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -222,7 +222,7 @@ static int import_program_into_env(struct udevice *udev, const char *program) char result[1024]; size_t reslen; - if (run_program(program, udev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_DEBUG)) != 0) + if (run_program(program, udev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_INFO)) != 0) return -1; return import_keys_into_env(udev, result, reslen); } @@ -270,7 +270,7 @@ static int import_parent_into_env(struct udevice *udev, struct sysfs_class_devic /* finds the lowest positive N such that N isn't present in the udevdb * if doesn't exist, 0 is returned, N otherwise */ -static int find_free_number(struct udevice *udev, const char *name) +static int find_free_number(const char *name) { char devpath[PATH_SIZE]; char filename[PATH_SIZE]; @@ -397,7 +397,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, { .name = "root", .fmt = 'r', .type = SUBST_ROOT }, { .name = "modalias", .fmt = 'A', .type = SUBST_MODALIAS }, { .name = "env", .fmt = 'E', .type = SUBST_ENV }, - {} + { NULL, '\0', 0 } }; enum subst_type type; const struct subst_map *subst; @@ -546,7 +546,7 @@ found: dbg("substitute sysfs value '%s'", temp2); break; case SUBST_ENUM: - next_free_number = find_free_number(udev, string); + next_free_number = find_free_number(string); if (next_free_number > 0) { sprintf(temp2, "%d", next_free_number); strlcat(string, temp2, maxsize); @@ -667,6 +667,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { struct sysfs_device *parent_device = sysfs_device; + int i; if (match_key("ACTION", rule, &rule->action, udev->action)) goto exit; @@ -691,23 +692,21 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, goto exit; } - if (rule->env.count) { - int i; + for (i = 0; i < rule->env.count; i++) { + struct key_pair *pair = &rule->env.keys[i]; - dbg("check %i ENV keys", rule->env.count); - for (i = 0; i < rule->env.count; i++) { - struct key_pair *pair = &rule->env.keys[i]; + /* we only check for matches, assignments will be handled later */ + if (pair->key.operation != KEY_OP_ASSIGN) { const char *key_name = key_pair_name(rule, pair); const char *value = getenv(key_name); if (!value) { - dbg("ENV{'%s'} is not set", key_name); + dbg("ENV{'%s'} is not set, treat as empty", key_name); value = ""; } if (match_key("ENV", rule, &pair->key, value)) goto exit; } - dbg("all %i ENV keys matched", rule->env.count); } if (rule->wait_for_sysfs.operation != KEY_OP_UNSET) { @@ -760,8 +759,6 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, /* check for matching sysfs pairs */ if (rule->sysfs.count) { - int i; - dbg("check %i SYSFS keys", rule->sysfs.count); for (i = 0; i < rule->sysfs.count; i++) { struct key_pair *pair = &rule->sysfs.keys[i]; @@ -799,7 +796,36 @@ try_parent: dbg("look at sysfs_device->bus_id='%s'", parent_device->bus_id); } - /* import variables from file into environment */ + /* execute external program */ + if (rule->program.operation != KEY_OP_UNSET) { + char program[PATH_SIZE]; + char result[PATH_SIZE]; + + strlcpy(program, key_val(rule, &rule->program), sizeof(program)); + apply_format(udev, program, sizeof(program), class_dev, sysfs_device); + if (run_program(program, udev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_INFO)) != 0) { + dbg("PROGRAM is false"); + udev->program_result[0] = '\0'; + if (rule->program.operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg("PROGRAM matches"); + remove_trailing_char(result, '\n'); + replace_untrusted_chars(result); + dbg("result is '%s'", result); + strlcpy(udev->program_result, result, sizeof(udev->program_result)); + dbg("PROGRAM returned successful"); + if (rule->program.operation == KEY_OP_NOMATCH) + goto exit; + } + dbg("PROGRAM key is true"); + } + + /* check for matching result of external program */ + if (match_key("RESULT", rule, &rule->result, udev->program_result)) + goto exit; + + /* import variables returned from program or or file into environment */ if (rule->import.operation != KEY_OP_UNSET) { char import[PATH_SIZE]; int rc = -1; @@ -808,7 +834,6 @@ try_parent: apply_format(udev, import, sizeof(import), class_dev, sysfs_device); dbg("check for IMPORT import='%s'", import); if (rule->import_type == IMPORT_PROGRAM) { - dbg("run executable file import='%s'", import); rc = import_program_into_env(udev, import); } else if (rule->import_type == IMPORT_FILE) { dbg("import file import='%s'", import); @@ -826,37 +851,19 @@ try_parent: dbg("IMPORT key is true"); } - /* execute external program */ - if (rule->program.operation != KEY_OP_UNSET) { - char program[PATH_SIZE]; - char result[PATH_SIZE]; + /* rule matches, if we have ENV assignments export it */ + for (i = 0; i < rule->env.count; i++) { + struct key_pair *pair = &rule->env.keys[i]; - strlcpy(program, key_val(rule, &rule->program), sizeof(program)); - apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - dbg("check for PROGRAM program='%s", program); - if (run_program(program, udev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_DEBUG)) != 0) { - dbg("PROGRAM is false"); - udev->program_result[0] = '\0'; - if (rule->program.operation != KEY_OP_NOMATCH) - goto exit; - } else { - dbg("PROGRAM matches"); - remove_trailing_char(result, '\n'); - replace_untrusted_chars(result); - dbg("result is '%s'", result); - strlcpy(udev->program_result, result, sizeof(udev->program_result)); - dbg("PROGRAM returned successful"); - if (rule->program.operation == KEY_OP_NOMATCH) - goto exit; + if (pair->key.operation == KEY_OP_ASSIGN) { + const char *key_name = key_pair_name(rule, pair); + const char *value = key_val(rule, &pair->key); + + setenv(key_name, value, 1); + dbg("export ENV '%s=%s'", key_name, value); } - dbg("PROGRAM key is true"); } - /* check for matching result of external program */ - if (match_key("RESULT", rule, &rule->result, udev->program_result)) - goto exit; - - /* rule matches */ return 0; exit: @@ -964,7 +971,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s } strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp)); apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); - info("rule applied, added symlink '%s'", temp); + dbg("rule applied, added symlink '%s'", temp); /* add multiple symlinks separated by spaces */ pos = temp; @@ -1033,7 +1040,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s if (!name_set) { strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); - info("no rule found, will use kernel name '%s'", udev->name); + info("no node name set, will use kernel name '%s'", udev->name); } if (udev->tmp_node[0] != '\0') {