diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/fs-util.c | 23 | ||||
-rw-r--r-- | src/basic/khash.c | 2 | ||||
-rw-r--r-- | src/basic/socket-util.c | 2 | ||||
-rw-r--r-- | src/core/dbus-execute.c | 2 | ||||
-rw-r--r-- | src/coredump/coredump.c | 6 | ||||
-rw-r--r-- | src/hostname/hostnamed.c | 4 | ||||
-rw-r--r-- | src/journal-remote/journal-gatewayd.c | 3 | ||||
-rw-r--r-- | src/libudev/libudev-util.c | 14 | ||||
-rw-r--r-- | src/network/networkd-address.c | 4 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 21 | ||||
-rw-r--r-- | src/test/test-fs-util.c | 7 | ||||
-rw-r--r-- | src/test/test-socket-util.c | 3 | ||||
-rw-r--r-- | src/udev/udev-event.c | 449 |
13 files changed, 282 insertions, 258 deletions
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index e31fa2711a..8fe19ee4e4 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -723,6 +723,8 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, return -errno; if (S_ISLNK(st.st_mode)) { + char *joined; + _cleanup_free_ char *destination = NULL; /* This is a symlink, in this case read the destination. But let's make sure we don't follow @@ -746,9 +748,6 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, if (fd < 0) return -errno; - free_and_replace(buffer, destination); - - todo = buffer; free(done); /* Note that we do not revalidate the root, we take it as is. */ @@ -760,19 +759,17 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, return -ENOMEM; } - } else { - char *joined; + } - /* A relative destination. If so, this is what we'll prefix what's left to do with what - * we just read, and start the loop again, but remain in the current directory. */ + /* Prefix what's left to do with what we just read, and start the loop again, + * but remain in the current directory. */ - joined = strjoin("/", destination, todo); - if (!joined) - return -ENOMEM; + joined = strjoin("/", destination, todo); + if (!joined) + return -ENOMEM; - free(buffer); - todo = buffer = joined; - } + free(buffer); + todo = buffer = joined; continue; } diff --git a/src/basic/khash.c b/src/basic/khash.c index 9a2a3edb75..84648dc1c9 100644 --- a/src/basic/khash.c +++ b/src/basic/khash.c @@ -143,7 +143,7 @@ int khash_dup(khash *h, khash **ret) { copy->fd = -1; copy->algorithm = strdup(h->algorithm); - if (!copy) + if (!copy->algorithm) return -ENOMEM; copy->fd = accept4(h->fd, NULL, 0, SOCK_CLOEXEC); diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index c882b8a12a..77f81a60ba 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -887,7 +887,7 @@ bool ifname_valid(const char *p) { if ((unsigned char) *p <= 32U) return false; - if (*p == '/') + if (*p == ':' || *p == '/') return false; numeric = numeric && (*p >= '0' && *p <= '9'); diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 3ae894d59c..cc10e2d8e7 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -1698,7 +1698,7 @@ int bus_exec_context_set_transient_property( if (!path_is_absolute(source)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source); if (!path_is_absolute(destination)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", source); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination); if (!IN_SET(mount_flags, 0, MS_REC)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags."); diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index d55d896df4..1f6fb5de1e 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -642,7 +642,11 @@ static int get_process_container_parent_cmdline(pid_t pid, char** cmdline) { if (r < 0) return r; - return get_process_cmdline(container_pid, 0, false, cmdline); + r = get_process_cmdline(container_pid, 0, false, cmdline); + if (r < 0) + return r; + + return 1; } static int change_uid_gid(const char *context[]) { diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 74256e4444..4657cf8c77 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -283,7 +283,7 @@ static int context_update_kernel_hostname(Context *c) { /* ... and the ultimate fallback */ else - hn = "localhost"; + hn = FALLBACK_HOSTNAME; if (sethostname_idempotent(hn) < 0) return -errno; @@ -419,7 +419,7 @@ static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error * name = c->data[PROP_STATIC_HOSTNAME]; if (isempty(name)) - name = "localhost"; + name = FALLBACK_HOSTNAME; if (!hostname_is_valid(name, false)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", name); diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c index b7c4257f49..9a1c5b76ca 100644 --- a/src/journal-remote/journal-gatewayd.c +++ b/src/journal-remote/journal-gatewayd.c @@ -912,7 +912,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "hD:", options, NULL)) >= 0) switch(c) { @@ -958,6 +958,7 @@ static int parse_argv(int argc, char *argv[]) { break; #else log_error("Option --trust is not available."); + return -EINVAL; #endif case 'D': arg_directory = optarg; diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c index a9819b9db3..1d73d8f090 100644 --- a/src/libudev/libudev-util.c +++ b/src/libudev/libudev-util.c @@ -161,6 +161,20 @@ void util_remove_trailing_chars(char *path, char c) path[--len] = '\0'; } +/* + * Copy from 'str' to 'to', while removing all leading and trailing whitespace, + * and replacing each run of consecutive whitespace with a single underscore. + * The chars from 'str' are copied up to the \0 at the end of the string, or + * at most 'len' chars. This appends \0 to 'to', at the end of the copied + * characters. + * + * If 'len' chars are copied into 'to', the final \0 is placed at len+1 + * (i.e. 'to[len] = \0'), so the 'to' buffer must have at least len+1 + * chars available. + * + * Note this may be called with 'str' == 'to', i.e. to replace whitespace + * in-place in a buffer. This function can handle that situation. + */ int util_replace_whitespace(const char *str, char *to, size_t len) { size_t i, j; diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 2b698d9531..ffd2e18a45 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -809,8 +809,8 @@ int config_parse_label( if (r < 0) return r; - if (!ifname_valid(rvalue)) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is not valid or too long, ignoring assignment: %s", rvalue); + if (strlen(rvalue) >= IFNAMSIZ) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Interface label is too long, ignoring assignment: %s", rvalue); return 0; } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 41e8d6075a..a20ca1bcb5 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -5655,16 +5655,22 @@ static int switch_root(int argc, char *argv[], void *userdata) { } /* Instruct PID1 to exclude us from its killing spree applied during - * the transition from the initrd to the main system otherwise we would - * exit with a failure status even though the switch to the new root - * has succeed. */ - if (in_initrd()) - argv_cmdline[0] = '@'; + * the transition. Otherwise we would exit with a failure status even + * though the switch to the new root has succeed. */ + argv_cmdline[0] = '@'; r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) return r; + /* If we are slow to exit after the root switch, the new systemd instance + * will send us a signal to terminate. Just ignore it and exit normally. + * This way the unit does not end up as failed. + */ + r = ignore_signals(SIGTERM, -1); + if (r < 0) + log_warning_errno(r, "Failed to change disposition of SIGTERM to ignore: %m"); + log_debug("Switching root - root: %s; init: %s", root, strna(init)); r = sd_bus_call_method( @@ -5676,8 +5682,11 @@ static int switch_root(int argc, char *argv[], void *userdata) { &error, NULL, "ss", root, init); - if (r < 0) + if (r < 0) { + (void) default_signals(SIGTERM, -1); + return log_error_errno(r, "Failed to switch root: %s", bus_error_message(&error, r)); + } return 0; } diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index ae68587be9..4cb465d0d2 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -186,6 +186,13 @@ static void test_chase_symlinks(void) { r = chase_symlinks(p, NULL, CHASE_NONEXISTENT, &result); assert_se(r == -ENOENT); + p = strjoina(temp, "/target"); + q = strjoina(temp, "/top"); + assert_se(symlink(q, p) >= 0); + p = strjoina(temp, "/target/idontexist"); + r = chase_symlinks(p, NULL, 0, &result); + assert_se(r == -ENOENT); + assert_se(rm_rf(temp, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0); } diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index e1f5fd5084..d80613dc84 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -30,7 +30,6 @@ static void test_ifname_valid(void) { assert(ifname_valid("foo")); assert(ifname_valid("eth0")); - assert(ifname_valid("eth0:0")); assert(!ifname_valid("0")); assert(!ifname_valid("99")); @@ -45,7 +44,7 @@ static void test_ifname_valid(void) { assert(!ifname_valid(".")); assert(!ifname_valid("..")); assert(ifname_valid("foo.bar")); - assert(ifname_valid("x:y")); + assert(!ifname_valid("x:y")); assert(ifname_valid("xxxxxxxxxxxxxxx")); assert(!ifname_valid("xxxxxxxxxxxxxxxx")); diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index deffefd60b..3f9c3ed0cf 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -73,29 +73,219 @@ void udev_event_unref(struct udev_event *event) { free(event); } +enum subst_type { + SUBST_UNKNOWN, + SUBST_DEVNODE, + SUBST_ATTR, + SUBST_ENV, + SUBST_KERNEL, + SUBST_KERNEL_NUMBER, + SUBST_DRIVER, + SUBST_DEVPATH, + SUBST_ID, + SUBST_MAJOR, + SUBST_MINOR, + SUBST_RESULT, + SUBST_PARENT, + SUBST_NAME, + SUBST_LINKS, + SUBST_ROOT, + SUBST_SYS, +}; + +static size_t subst_format_var(struct udev_event *event, struct udev_device *dev, + enum subst_type type, char *attr, + char *dest, size_t l) { + char *s = dest; + + switch (type) { + case SUBST_DEVPATH: + l = strpcpy(&s, l, udev_device_get_devpath(dev)); + break; + case SUBST_KERNEL: + l = strpcpy(&s, l, udev_device_get_sysname(dev)); + break; + case SUBST_KERNEL_NUMBER: + if (udev_device_get_sysnum(dev) == NULL) + break; + l = strpcpy(&s, l, udev_device_get_sysnum(dev)); + break; + case SUBST_ID: + if (event->dev_parent == NULL) + break; + l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent)); + break; + case SUBST_DRIVER: { + const char *driver; + + if (event->dev_parent == NULL) + break; + + driver = udev_device_get_driver(event->dev_parent); + if (driver == NULL) + break; + l = strpcpy(&s, l, driver); + break; + } + case SUBST_MAJOR: { + char num[UTIL_PATH_SIZE]; + + sprintf(num, "%u", major(udev_device_get_devnum(dev))); + l = strpcpy(&s, l, num); + break; + } + case SUBST_MINOR: { + char num[UTIL_PATH_SIZE]; + + sprintf(num, "%u", minor(udev_device_get_devnum(dev))); + l = strpcpy(&s, l, num); + break; + } + case SUBST_RESULT: { + char *rest; + int i; + + if (event->program_result == NULL) + break; + /* get part of the result string */ + i = 0; + if (attr != NULL) + i = strtoul(attr, &rest, 10); + if (i > 0) { + char result[UTIL_PATH_SIZE]; + char tmp[UTIL_PATH_SIZE]; + char *cpos; + + strscpy(result, sizeof(result), event->program_result); + cpos = result; + while (--i) { + while (cpos[0] != '\0' && !isspace(cpos[0])) + cpos++; + while (isspace(cpos[0])) + cpos++; + if (cpos[0] == '\0') + break; + } + if (i > 0) { + log_error("requested part of result string not found"); + break; + } + strscpy(tmp, sizeof(tmp), cpos); + /* %{2+}c copies the whole string from the second part on */ + if (rest[0] != '+') { + cpos = strchr(tmp, ' '); + if (cpos) + cpos[0] = '\0'; + } + l = strpcpy(&s, l, tmp); + } else { + l = strpcpy(&s, l, event->program_result); + } + break; + } + case SUBST_ATTR: { + const char *value = NULL; + char vbuf[UTIL_NAME_SIZE]; + size_t len; + int count; + + if (attr == NULL) { + log_error("missing file parameter for attr"); + break; + } + + /* try to read the value specified by "[dmi/id]product_name" */ + if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0) + value = vbuf; + + /* try to read the attribute the device */ + if (value == NULL) + value = udev_device_get_sysattr_value(event->dev, attr); + + /* try to read the attribute of the parent device, other matches have selected */ + if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev) + value = udev_device_get_sysattr_value(event->dev_parent, attr); + + if (value == NULL) + break; + + /* strip trailing whitespace, and replace unwanted characters */ + if (value != vbuf) + strscpy(vbuf, sizeof(vbuf), value); + len = strlen(vbuf); + while (len > 0 && isspace(vbuf[--len])) + vbuf[len] = '\0'; + count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT); + if (count > 0) + log_debug("%i character(s) replaced" , count); + l = strpcpy(&s, l, vbuf); + break; + } + case SUBST_PARENT: { + struct udev_device *dev_parent; + const char *devnode; + + dev_parent = udev_device_get_parent(event->dev); + if (dev_parent == NULL) + break; + devnode = udev_device_get_devnode(dev_parent); + if (devnode != NULL) + l = strpcpy(&s, l, devnode + strlen("/dev/")); + break; + } + case SUBST_DEVNODE: + if (udev_device_get_devnode(dev) != NULL) + l = strpcpy(&s, l, udev_device_get_devnode(dev)); + break; + case SUBST_NAME: + if (event->name != NULL) + l = strpcpy(&s, l, event->name); + else if (udev_device_get_devnode(dev) != NULL) + l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/")); + else + l = strpcpy(&s, l, udev_device_get_sysname(dev)); + break; + case SUBST_LINKS: { + struct udev_list_entry *list_entry; + + list_entry = udev_device_get_devlinks_list_entry(dev); + if (list_entry == NULL) + break; + l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/")); + udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry)) + l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL); + break; + } + case SUBST_ROOT: + l = strpcpy(&s, l, "/dev"); + break; + case SUBST_SYS: + l = strpcpy(&s, l, "/sys"); + break; + case SUBST_ENV: + if (attr == NULL) { + break; + } else { + const char *value; + + value = udev_device_get_property_value(event->dev, attr); + if (value == NULL) + break; + l = strpcpy(&s, l, value); + break; + } + default: + log_error("unknown substitution type=%i", type); + break; + } + + return s - dest; +} + 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, - SUBST_DEVNODE, - SUBST_ATTR, - SUBST_ENV, - SUBST_KERNEL, - SUBST_KERNEL_NUMBER, - SUBST_DRIVER, - SUBST_DEVPATH, - SUBST_ID, - SUBST_MAJOR, - SUBST_MINOR, - SUBST_RESULT, - SUBST_PARENT, - SUBST_NAME, - SUBST_LINKS, - SUBST_ROOT, - SUBST_SYS, - }; static const struct subst_map { const char *name; const char fmt; @@ -132,10 +322,9 @@ size_t udev_event_apply_format(struct udev_event *event, for (;;) { enum subst_type type = SUBST_UNKNOWN; - char attrbuf[UTIL_PATH_SIZE], sbuf[UTIL_PATH_SIZE]; - char *attr = NULL, *_s; - size_t _l; - bool replws = replace_whitespace; + char attrbuf[UTIL_PATH_SIZE]; + char *attr = NULL; + size_t subst_len; while (from[0] != '\0') { if (from[0] == '$') { @@ -204,213 +393,17 @@ 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)); - break; - case SUBST_KERNEL: - l = strpcpy(&s, l, udev_device_get_sysname(dev)); - break; - case SUBST_KERNEL_NUMBER: - if (udev_device_get_sysnum(dev) == NULL) - break; - l = strpcpy(&s, l, udev_device_get_sysnum(dev)); - break; - case SUBST_ID: - if (event->dev_parent == NULL) - break; - l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent)); - break; - case SUBST_DRIVER: { - const char *driver; - - if (event->dev_parent == NULL) - break; - - driver = udev_device_get_driver(event->dev_parent); - if (driver == NULL) - break; - l = strpcpy(&s, l, driver); - break; - } - case SUBST_MAJOR: { - char num[UTIL_PATH_SIZE]; - - sprintf(num, "%u", major(udev_device_get_devnum(dev))); - l = strpcpy(&s, l, num); - break; - } - case SUBST_MINOR: { - char num[UTIL_PATH_SIZE]; - - sprintf(num, "%u", minor(udev_device_get_devnum(dev))); - l = strpcpy(&s, l, num); - break; - } - case SUBST_RESULT: { - char *rest; - int i; - - if (event->program_result == NULL) - break; - /* get part of the result string */ - i = 0; - if (attr != NULL) - i = strtoul(attr, &rest, 10); - if (i > 0) { - char result[UTIL_PATH_SIZE]; - char tmp[UTIL_PATH_SIZE]; - char *cpos; - - strscpy(result, sizeof(result), event->program_result); - cpos = result; - while (--i) { - while (cpos[0] != '\0' && !isspace(cpos[0])) - cpos++; - while (isspace(cpos[0])) - cpos++; - if (cpos[0] == '\0') - break; - } - if (i > 0) { - log_error("requested part of result string not found"); - break; - } - strscpy(tmp, sizeof(tmp), cpos); - /* %{2+}c copies the whole string from the second part on */ - if (rest[0] != '+') { - cpos = strchr(tmp, ' '); - if (cpos) - cpos[0] = '\0'; - } - l = strpcpy(&s, l, tmp); - } else { - l = strpcpy(&s, l, event->program_result); - } - break; - } - case SUBST_ATTR: { - const char *value = NULL; - char vbuf[UTIL_NAME_SIZE]; - size_t len; - int count; - - if (attr == NULL) { - log_error("missing file parameter for attr"); - break; - } - - /* try to read the value specified by "[dmi/id]product_name" */ - if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0) - value = vbuf; - - /* try to read the attribute the device */ - if (value == NULL) - value = udev_device_get_sysattr_value(event->dev, attr); - - /* try to read the attribute of the parent device, other matches have selected */ - if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev) - value = udev_device_get_sysattr_value(event->dev_parent, attr); - - if (value == NULL) - break; + subst_len = subst_format_var(event, dev, type, attr, s, l); - /* strip trailing whitespace, and replace unwanted characters */ - if (value != vbuf) - strscpy(vbuf, sizeof(vbuf), value); - len = strlen(vbuf); - while (len > 0 && isspace(vbuf[--len])) - vbuf[len] = '\0'; - count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT); - if (count > 0) - log_debug("%i character(s) replaced" , count); - l = strpcpy(&s, l, vbuf); - break; - } - case SUBST_PARENT: { - struct udev_device *dev_parent; - const char *devnode; - - dev_parent = udev_device_get_parent(event->dev); - if (dev_parent == NULL) - break; - devnode = udev_device_get_devnode(dev_parent); - if (devnode != NULL) - l = strpcpy(&s, l, devnode + strlen("/dev/")); - break; - } - case SUBST_DEVNODE: - if (udev_device_get_devnode(dev) != NULL) - l = strpcpy(&s, l, udev_device_get_devnode(dev)); - break; - case SUBST_NAME: - if (event->name != NULL) - l = strpcpy(&s, l, event->name); - else if (udev_device_get_devnode(dev) != NULL) - l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/")); - else - l = strpcpy(&s, l, udev_device_get_sysname(dev)); - break; - case SUBST_LINKS: { - struct udev_list_entry *list_entry; + /* SUBST_RESULT handles spaces itself */ + if (replace_whitespace && type != SUBST_RESULT) + /* util_replace_whitespace can replace in-place, + * and does nothing if subst_len == 0 + */ + subst_len = util_replace_whitespace(s, s, subst_len); - list_entry = udev_device_get_devlinks_list_entry(dev); - if (list_entry == NULL) - break; - l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/")); - udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry)) - l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL); - break; - } - case SUBST_ROOT: - l = strpcpy(&s, l, "/dev"); - break; - case SUBST_SYS: - l = strpcpy(&s, l, "/sys"); - break; - case SUBST_ENV: - if (attr == NULL) { - break; - } else { - const char *value; - - value = udev_device_get_property_value(event->dev, attr); - if (value == NULL) - break; - l = strpcpy(&s, l, value); - break; - } - default: - 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; - } + s += subst_len; + l -= subst_len; } out: |