diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-01-11 16:40:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-11 16:40:04 -0500 |
commit | 5aac0be024349b488a6ca9fb9e871fbd5aef7df4 (patch) | |
tree | 3fe35d098e0c2e2a0fd0e23aa4e84c19e3e75b32 | |
parent | 374e69225215aa25ea67b166ec4b61ad628d5021 (diff) | |
parent | 0a10235ed4538a80f5fc7dbbf79e3a1c178f5179 (diff) |
Merge pull request #4837 from ddstreet/master
Replace spaces in expanded fields in SYMLINK properties by default.
-rw-r--r-- | src/libudev/libudev-util.c | 2 | ||||
-rw-r--r-- | src/udev/udev-event.c | 39 | ||||
-rw-r--r-- | src/udev/udev-rules.c | 40 | ||||
-rw-r--r-- | src/udev/udev.h | 4 | ||||
-rw-r--r-- | src/udev/udevadm-test.c | 2 |
5 files changed, 60 insertions, 27 deletions
diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c index 574cfeac85..a9819b9db3 100644 --- a/src/libudev/libudev-util.c +++ b/src/libudev/libudev-util.c @@ -186,7 +186,7 @@ int util_replace_whitespace(const char *str, char *to, size_t len) to[j++] = str[i++]; } to[j] = '\0'; - return 0; + return j; } /* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */ diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 304a28777b..be7c7367ff 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -73,7 +73,9 @@ void udev_event_unref(struct udev_event *event) { free(event); } -size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size) { +size_t udev_event_apply_format(struct udev_event *event, + const char *src, char *dest, size_t size, + bool replace_whitespace) { struct udev_device *dev = event->dev; enum subst_type { SUBST_UNKNOWN, @@ -130,8 +132,10 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char * for (;;) { enum subst_type type = SUBST_UNKNOWN; - char attrbuf[UTIL_PATH_SIZE]; - char *attr = NULL; + char attrbuf[UTIL_PATH_SIZE], sbuf[UTIL_PATH_SIZE]; + char *attr = NULL, *_s; + size_t _l; + bool replws = replace_whitespace; while (from[0] != '\0') { if (from[0] == '$') { @@ -200,6 +204,19 @@ subst: attr = NULL; } + /* result subst handles space as field separator */ + if (type == SUBST_RESULT) + replws = false; + + if (replws) { + /* store dest string ptr and remaining len */ + _s = s; + _l = l; + /* temporarily use sbuf */ + s = &sbuf; + l = UTIL_PATH_SIZE; + } + switch (type) { case SUBST_DEVPATH: l = strpcpy(&s, l, udev_device_get_devpath(dev)); @@ -380,6 +397,20 @@ subst: log_error("unknown substitution type=%i", type); break; } + + /* replace whitespace in sbuf and copy to dest */ + if (replws) { + size_t tmplen = UTIL_PATH_SIZE - l; + + /* restore s and l to dest string values */ + s = _s; + l = _l; + + /* copy ws-replaced value to s */ + tmplen = util_replace_whitespace(sbuf, s, MIN(tmplen, l)); + l -= tmplen; + s += tmplen; + } } out: @@ -927,7 +958,7 @@ void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_ const char *cmd = udev_list_entry_get_name(list_entry); enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry); - udev_event_apply_format(event, cmd, command, sizeof(command)); + udev_event_apply_format(event, cmd, command, sizeof(command), false); if (builtin_cmd < UDEV_BUILTIN_MAX) udev_builtin_run(event->dev, builtin_cmd, command, false); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index b0238220e4..4d07b8fce0 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1676,7 +1676,7 @@ static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct name = rules_str(rules, cur->key.attr_off); switch (cur->key.attrsubst) { case SB_FORMAT: - udev_event_apply_format(event, name, nbuf, sizeof(nbuf)); + udev_event_apply_format(event, name, nbuf, sizeof(nbuf), false); name = nbuf; /* fall through */ case SB_NONE: @@ -1838,7 +1838,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, _cleanup_free_ char *value = NULL; size_t len; - udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename)); + udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename), false); sysctl_normalize(filename); if (sysctl_read(filename, &value) < 0) goto nomatch; @@ -1916,7 +1916,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, struct stat statbuf; int match; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename), false); if (util_resolve_subsys_kernel(event->udev, filename, filename, sizeof(filename), 0) != 0) { if (filename[0] != '/') { char tmp[UTIL_PATH_SIZE]; @@ -1942,7 +1942,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, char result[UTIL_LINE_SIZE]; event->program_result = mfree(event->program_result); - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program), false); log_debug("PROGRAM '%s' %s:%u", program, rules_str(rules, rule->rule.filename_off), @@ -1969,7 +1969,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, case TK_M_IMPORT_FILE: { char import[UTIL_PATH_SIZE]; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false); if (import_file_into_properties(event->dev, import) != 0) if (cur->key.op != OP_NOMATCH) goto nomatch; @@ -1978,7 +1978,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, case TK_M_IMPORT_PROG: { char import[UTIL_PATH_SIZE]; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false); log_debug("IMPORT '%s' %s:%u", import, rules_str(rules, rule->rule.filename_off), @@ -2009,7 +2009,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, event->builtin_run |= (1 << cur->key.builtin_cmd); } - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command), false); log_debug("IMPORT builtin '%s' %s:%u", udev_builtin_name(cur->key.builtin_cmd), rules_str(rules, rule->rule.filename_off), @@ -2077,7 +2077,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, case TK_M_IMPORT_PARENT: { char import[UTIL_PATH_SIZE]; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false); if (import_parent_into_properties(event->dev, import) != 0) if (cur->key.op != OP_NOMATCH) goto nomatch; @@ -2115,7 +2115,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, break; if (cur->key.op == OP_ASSIGN_FINAL) event->owner_final = true; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner), false); event->owner_set = true; r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL); if (r < 0) { @@ -2141,7 +2141,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, break; if (cur->key.op == OP_ASSIGN_FINAL) event->group_final = true; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group), false); event->group_set = true; r = get_group_creds(&gr, &event->gid); if (r < 0) { @@ -2165,7 +2165,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, if (event->mode_final) break; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str), false); mode = strtol(mode_str, &endptr, 8); if (endptr[0] != '\0') { log_error("ignoring invalid mode '%s'", mode_str); @@ -2222,7 +2222,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, const char *name, *label; name = rules_str(rules, cur->key.attr_off); - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), label_str, sizeof(label_str)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), label_str, sizeof(label_str), false); if (label_str[0] != '\0') label = label_str; else @@ -2256,10 +2256,10 @@ void udev_rules_apply_to_event(struct udev_rules *rules, char temp[UTIL_NAME_SIZE]; /* append value separated by space */ - udev_event_apply_format(event, value, temp, sizeof(temp)); + udev_event_apply_format(event, value, temp, sizeof(temp), false); strscpyl(value_new, sizeof(value_new), value_old, " ", temp, NULL); } else - udev_event_apply_format(event, value, value_new, sizeof(value_new)); + udev_event_apply_format(event, value, value_new, sizeof(value_new), false); udev_device_add_property(event->dev, name, value_new); break; @@ -2268,7 +2268,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, char tag[UTIL_PATH_SIZE]; const char *p; - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), tag, sizeof(tag)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), tag, sizeof(tag), false); if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL) udev_device_cleanup_tags_list(event->dev); for (p = tag; *p != '\0'; p++) { @@ -2296,7 +2296,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, break; if (cur->key.op == OP_ASSIGN_FINAL) event->name_final = true; - udev_event_apply_format(event, name, name_str, sizeof(name_str)); + udev_event_apply_format(event, name, name_str, sizeof(name_str), false); if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) { count = util_replace_chars(name_str, "/"); if (count > 0) @@ -2336,7 +2336,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, udev_device_cleanup_devlinks_list(event->dev); /* allow multiple symlinks separated by spaces */ - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), temp, sizeof(temp)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), temp, sizeof(temp), esc != ESCAPE_NONE); if (esc == ESCAPE_UNSET) count = util_replace_chars(temp, "/ "); else if (esc == ESCAPE_REPLACE) @@ -2376,7 +2376,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, strscpyl(attr, sizeof(attr), udev_device_get_syspath(event->dev), "/", key_name, NULL); attr_subst_subdir(attr, sizeof(attr)); - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value), false); log_debug("ATTR '%s' writing '%s' %s:%u", attr, value, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2392,9 +2392,9 @@ void udev_rules_apply_to_event(struct udev_rules *rules, char value[UTIL_NAME_SIZE]; int r; - udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename)); + udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename), false); sysctl_normalize(filename); - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value)); + udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value), false); log_debug("SYSCTL '%s' writing '%s' %s:%u", filename, value, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); r = sysctl_write(filename, value); diff --git a/src/udev/udev.h b/src/udev/udev.h index 8433e8d9f2..c0cb7eae84 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -80,7 +80,9 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules); /* udev-event.c */ struct udev_event *udev_event_new(struct udev_device *dev); void udev_event_unref(struct udev_event *event); -size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size); +size_t udev_event_apply_format(struct udev_event *event, + const char *src, char *dest, size_t size, + bool replace_whitespace); int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string, char *result, size_t maxsize, int read_value); int udev_event_spawn(struct udev_event *event, diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index 702dbe5282..07b667f131 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -144,7 +144,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) { udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) { char program[UTIL_PATH_SIZE]; - udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program)); + udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program), false); printf("run: '%s'\n", program); } out: |