/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

#include "alloc-util.h"
#include "fs-util.h"
#include "log.h"
#include "macro.h"
#include "nulstr-util.h"
#include "path-lookup.h"
#include "path-util.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "tmpfile-util.h"
#include "user-util.h"

int xdg_user_runtime_dir(char **ret, const char *suffix) {
        const char *e;
        char *j;

        assert(ret);
        assert(suffix);

        e = getenv("XDG_RUNTIME_DIR");
        if (!e)
                return -ENXIO;

        j = path_join(e, suffix);
        if (!j)
                return -ENOMEM;

        *ret = j;
        return 0;
}

int xdg_user_config_dir(char **ret, const char *suffix) {
        _cleanup_free_ char *j = NULL;
        const char *e;
        int r;

        assert(ret);

        e = getenv("XDG_CONFIG_HOME");
        if (e) {
                j = path_join(e, suffix);
                if (!j)
                        return -ENOMEM;
        } else {
                r = get_home_dir(&j);
                if (r < 0)
                        return r;

                if (!path_extend(&j, "/.config", suffix))
                        return -ENOMEM;
        }

        *ret = TAKE_PTR(j);
        return 0;
}

int xdg_user_data_dir(char **ret, const char *suffix) {
        _cleanup_free_ char *j = NULL;
        const char *e;
        int r;

        assert(ret);
        assert(suffix);

        /* We don't treat /etc/xdg/systemd here as the spec
         * suggests because we assume that is a link to
         * /etc/systemd/ anyway. */

        e = getenv("XDG_DATA_HOME");
        if (e) {
                j = path_join(e, suffix);
                if (!j)
                        return -ENOMEM;
        } else {
                r = get_home_dir(&j);
                if (r < 0)
                        return r;

                if (!path_extend(&j, "/.local/share", suffix))
                        return -ENOMEM;
        }

        *ret = TAKE_PTR(j);
        return 1;
}

static const char* const user_data_unit_paths[] = {
        "/usr/local/lib/systemd/user",
        "/usr/local/share/systemd/user",
        USER_DATA_UNIT_DIR,
        "/usr/lib/systemd/user",
        "/usr/share/systemd/user",
        NULL
};

static const char* const user_config_unit_paths[] = {
        USER_CONFIG_UNIT_DIR,
        "/etc/systemd/user",
        NULL
};

int xdg_user_dirs(char ***ret_config_dirs, char ***ret_data_dirs) {
        /* Implement the mechanisms defined in
         *
         * https://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
         *
         * We look in both the config and the data dirs because we
         * want to encourage that distributors ship their unit files
         * as data, and allow overriding as configuration.
         */
        const char *e;
        _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;

        e = getenv("XDG_CONFIG_DIRS");
        if (e)
                config_dirs = strv_split(e, ":");
        else
                config_dirs = strv_new("/etc/xdg");
        if (!config_dirs)
                return -ENOMEM;

        e = getenv("XDG_DATA_DIRS");
        if (e)
                data_dirs = strv_split(e, ":");
        else
                data_dirs = strv_new("/usr/local/share",
                                     "/usr/share");
        if (!data_dirs)
                return -ENOMEM;

        *ret_config_dirs = TAKE_PTR(config_dirs);
        *ret_data_dirs = TAKE_PTR(data_dirs);

        return 0;
}

static char** user_dirs(
                const char *persistent_config,
                const char *runtime_config,
                const char *global_persistent_config,
                const char *global_runtime_config,
                const char *generator,
                const char *generator_early,
                const char *generator_late,
                const char *transient,
                const char *persistent_control,
                const char *runtime_control) {

        _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
        _cleanup_free_ char *data_home = NULL;
        _cleanup_strv_free_ char **res = NULL;
        int r;

        r = xdg_user_dirs(&config_dirs, &data_dirs);
        if (r < 0)
                return NULL;

        r = xdg_user_data_dir(&data_home, "/systemd/user");
        if (r < 0 && r != -ENXIO)
                return NULL;

        /* Now merge everything we found. */
        if (strv_extend(&res, persistent_control) < 0)
                return NULL;

        if (strv_extend(&res, runtime_control) < 0)
                return NULL;

        if (strv_extend(&res, transient) < 0)
                return NULL;

        if (strv_extend(&res, generator_early) < 0)
                return NULL;

        if (strv_extend(&res, persistent_config) < 0)
                return NULL;

        if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0)
                return NULL;

        /* global config has lower priority than the user config of the same type */
        if (strv_extend(&res, global_persistent_config) < 0)
                return NULL;

        if (strv_extend_strv(&res, (char**) user_config_unit_paths, false) < 0)
                return NULL;

        if (strv_extend(&res, runtime_config) < 0)
                return NULL;

        if (strv_extend(&res, global_runtime_config) < 0)
                return NULL;

        if (strv_extend(&res, generator) < 0)
                return NULL;

        if (strv_extend(&res, data_home) < 0)
                return NULL;

        if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0)
                return NULL;

        if (strv_extend_strv(&res, (char**) user_data_unit_paths, false) < 0)
                return NULL;

        if (strv_extend(&res, generator_late) < 0)
                return NULL;

        if (path_strv_make_absolute_cwd(res) < 0)
                return NULL;

        return TAKE_PTR(res);
}

bool path_is_user_data_dir(const char *path) {
        assert(path);

        return strv_contains((char**) user_data_unit_paths, path);
}

bool path_is_user_config_dir(const char *path) {
        assert(path);

        return strv_contains((char**) user_config_unit_paths, path);
}

static int acquire_generator_dirs(
                LookupScope scope,
                const char *tempdir,
                char **generator,
                char **generator_early,
                char **generator_late) {

        _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *p = NULL;
        const char *prefix;

        assert(generator);
        assert(generator_early);
        assert(generator_late);
        assert(IN_SET(scope, LOOKUP_SCOPE_SYSTEM, LOOKUP_SCOPE_USER, LOOKUP_SCOPE_GLOBAL));

        if (scope == LOOKUP_SCOPE_GLOBAL)
                return -EOPNOTSUPP;

        if (tempdir)
                prefix = tempdir;
        else if (scope == LOOKUP_SCOPE_SYSTEM)
                prefix = "/run/systemd";
        else {
                /* LOOKUP_SCOPE_USER */
                const char *e;

                e = getenv("XDG_RUNTIME_DIR");
                if (!e)
                        return -ENXIO;

                p = path_join(e, "/systemd");
                if (!p)
                        return -ENOMEM;

                prefix = p;
        }

        x = path_join(prefix, "generator");
        if (!x)
                return -ENOMEM;

        y = path_join(prefix, "generator.early");
        if (!y)
                return -ENOMEM;

        z = path_join(prefix, "generator.late");
        if (!z)
                return -ENOMEM;

        *generator = TAKE_PTR(x);
        *generator_early = TAKE_PTR(y);
        *generator_late = TAKE_PTR(z);

        return 0;
}

static int acquire_transient_dir(
                LookupScope scope,
                const char *tempdir,
                char **ret) {

        char *transient;

        assert(ret);
        assert(IN_SET(scope, LOOKUP_SCOPE_SYSTEM, LOOKUP_SCOPE_USER, LOOKUP_SCOPE_GLOBAL));

        if (scope == LOOKUP_SCOPE_GLOBAL)
                return -EOPNOTSUPP;

        if (tempdir)
                transient = path_join(tempdir, "transient");
        else if (scope == LOOKUP_SCOPE_SYSTEM)
                transient = strdup("/run/systemd/transient");
        else
                return xdg_user_runtime_dir(ret, "/systemd/transient");

        if (!transient)
                return -ENOMEM;
        *ret = transient;
        return 0;
}

static int acquire_config_dirs(LookupScope scope, char **persistent, char **runtime) {
        _cleanup_free_ char *a = NULL, *b = NULL;
        int r;

        assert(persistent);
        assert(runtime);

        switch (scope) {

        case LOOKUP_SCOPE_SYSTEM:
                a = strdup(SYSTEM_CONFIG_UNIT_DIR);
                b = strdup("/run/systemd/system");
                break;

        case LOOKUP_SCOPE_GLOBAL:
                a = strdup(USER_CONFIG_UNIT_DIR);
                b = strdup("/run/systemd/user");
                break;

        case LOOKUP_SCOPE_USER:
                r = xdg_user_config_dir(&a, "/systemd/user");
                if (r < 0 && r != -ENXIO)
                        return r;

                r = xdg_user_runtime_dir(runtime, "/systemd/user");
                if (r < 0) {
                        if (r != -ENXIO)
                                return r;

                        /* If XDG_RUNTIME_DIR is not set, don't consider that fatal, simply initialize the runtime
                         * directory to NULL */
                        *runtime = NULL;
                }

                *persistent = TAKE_PTR(a);

                return 0;

        default:
                assert_not_reached();
        }

        if (!a || !b)
                return -ENOMEM;

        *persistent = TAKE_PTR(a);
        *runtime = TAKE_PTR(b);

        return 0;
}

static int acquire_control_dirs(LookupScope scope, char **persistent, char **runtime) {
        _cleanup_free_ char *a = NULL;
        int r;

        assert(persistent);
        assert(runtime);

        switch (scope) {

        case LOOKUP_SCOPE_SYSTEM:  {
                _cleanup_free_ char *b = NULL;

                a = strdup("/etc/systemd/system.control");
                if (!a)
                        return -ENOMEM;

                b = strdup("/run/systemd/system.control");
                if (!b)
                        return -ENOMEM;

                *runtime = TAKE_PTR(b);

                break;
        }

        case LOOKUP_SCOPE_USER:
                r = xdg_user_config_dir(&a, "/systemd/user.control");
                if (r < 0 && r != -ENXIO)
                        return r;

                r = xdg_user_runtime_dir(runtime, "/systemd/user.control");
                if (r < 0) {
                        if (r != -ENXIO)
                                return r;

                        /* If XDG_RUNTIME_DIR is not set, don't consider this fatal, simply initialize the directory to
                         * NULL */
                        *runtime = NULL;
                }

                break;

        case LOOKUP_SCOPE_GLOBAL:
                return -EOPNOTSUPP;

        default:
                assert_not_reached();
        }

        *persistent = TAKE_PTR(a);

        return 0;
}

static int acquire_attached_dirs(
                LookupScope scope,
                char **ret_persistent,
                char **ret_runtime) {

        _cleanup_free_ char *a = NULL, *b = NULL;

        assert(ret_persistent);
        assert(ret_runtime);

        /* Portable services are not available to regular users for now. */
        if (scope != LOOKUP_SCOPE_SYSTEM)
                return -EOPNOTSUPP;

        a = strdup("/etc/systemd/system.attached");
        if (!a)
                return -ENOMEM;

        b = strdup("/run/systemd/system.attached");
        if (!b)
                return -ENOMEM;

        *ret_persistent = TAKE_PTR(a);
        *ret_runtime = TAKE_PTR(b);

        return 0;
}

static int patch_root_prefix(char **p, const char *root_dir) {
        char *c;

        assert(p);

        if (!*p)
                return 0;

        c = path_join(root_dir, *p);
        if (!c)
                return -ENOMEM;

        free_and_replace(*p, c);
        return 0;
}

static int patch_root_prefix_strv(char **l, const char *root_dir) {
        int r;

        if (!root_dir)
                return 0;

        STRV_FOREACH(i, l) {
                r = patch_root_prefix(i, root_dir);
                if (r < 0)
                        return r;
        }

        return 0;
}

static int get_paths_from_environ(const char *var, char ***paths, bool *append) {
        const char *e;
        int r;

        assert(var);
        assert(paths);
        assert(append);

        *append = false;

        e = getenv(var);
        if (e) {
                const char *k;

                k = endswith(e, ":");
                if (k) {
                        e = strndupa_safe(e, k - e);
                        *append = true;
                }

                /* FIXME: empty components in other places should be rejected. */

                r = path_split_and_make_absolute(e, paths);
                if (r < 0)
                        return r;
        }

        return 0;
}

int lookup_paths_init(
                LookupPaths *lp,
                LookupScope scope,
                LookupPathsFlags flags,
                const char *root_dir) {

        _cleanup_(rmdir_and_freep) char *tempdir = NULL;
        _cleanup_free_ char
                *root = NULL,
                *persistent_config = NULL, *runtime_config = NULL,
                *global_persistent_config = NULL, *global_runtime_config = NULL,
                *generator = NULL, *generator_early = NULL, *generator_late = NULL,
                *transient = NULL,
                *persistent_control = NULL, *runtime_control = NULL,
                *persistent_attached = NULL, *runtime_attached = NULL;
        bool append = false; /* Add items from SYSTEMD_UNIT_PATH before normal directories */
        _cleanup_strv_free_ char **paths = NULL;
        int r;

        assert(lp);
        assert(scope >= 0);
        assert(scope < _LOOKUP_SCOPE_MAX);

#if HAVE_SPLIT_USR
        flags |= LOOKUP_PATHS_SPLIT_USR;
#endif

        if (!empty_or_root(root_dir)) {
                if (scope == LOOKUP_SCOPE_USER)
                        return -EINVAL;

                r = is_dir(root_dir, true);
                if (r < 0)
                        return r;
                if (r == 0)
                        return -ENOTDIR;

                root = strdup(root_dir);
                if (!root)
                        return -ENOMEM;
        }

        if (flags & LOOKUP_PATHS_TEMPORARY_GENERATED) {
                r = mkdtemp_malloc("/tmp/systemd-temporary-XXXXXX", &tempdir);
                if (r < 0)
                        return log_debug_errno(r, "Failed to create temporary directory: %m");
        }

        /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_config to NULL */
        r = acquire_config_dirs(scope, &persistent_config, &runtime_config);
        if (r < 0)
                return r;

        if (scope == LOOKUP_SCOPE_USER) {
                r = acquire_config_dirs(LOOKUP_SCOPE_GLOBAL, &global_persistent_config, &global_runtime_config);
                if (r < 0)
                        return r;
        }

        if ((flags & LOOKUP_PATHS_EXCLUDE_GENERATED) == 0) {
                /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */
                r = acquire_generator_dirs(scope, tempdir,
                                           &generator, &generator_early, &generator_late);
                if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENXIO))
                        return r;
        }

        /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */
        r = acquire_transient_dir(scope, tempdir, &transient);
        if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENXIO))
                return r;

        /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_control to NULL */
        r = acquire_control_dirs(scope, &persistent_control, &runtime_control);
        if (r < 0 && r != -EOPNOTSUPP)
                return r;

        r = acquire_attached_dirs(scope, &persistent_attached, &runtime_attached);
        if (r < 0 && r != -EOPNOTSUPP)
                return r;

        /* First priority is whatever has been passed to us via env vars */
        r = get_paths_from_environ("SYSTEMD_UNIT_PATH", &paths, &append);
        if (r < 0)
                return r;

        if (!paths || append) {
                /* Let's figure something out. */

                _cleanup_strv_free_ char **add = NULL;

                /* For the user units we include share/ in the search
                 * path in order to comply with the XDG basedir spec.
                 * For the system stuff we avoid such nonsense. OTOH
                 * we include /lib in the search path for the system
                 * stuff but avoid it for user stuff. */

                switch (scope) {

                case LOOKUP_SCOPE_SYSTEM:
                        add = strv_new(
                                        /* If you modify this you also want to modify
                                         * systemdsystemunitpath= in systemd.pc.in! */
                                        STRV_IFNOTNULL(persistent_control),
                                        STRV_IFNOTNULL(runtime_control),
                                        STRV_IFNOTNULL(transient),
                                        STRV_IFNOTNULL(generator_early),
                                        persistent_config,
                                        SYSTEM_CONFIG_UNIT_DIR,
                                        "/etc/systemd/system",
                                        STRV_IFNOTNULL(persistent_attached),
                                        runtime_config,
                                        "/run/systemd/system",
                                        STRV_IFNOTNULL(runtime_attached),
                                        STRV_IFNOTNULL(generator),
                                        "/usr/local/lib/systemd/system",
                                        SYSTEM_DATA_UNIT_DIR,
                                        "/usr/lib/systemd/system",
                                        STRV_IFNOTNULL(flags & LOOKUP_PATHS_SPLIT_USR ? "/lib/systemd/system" : NULL),
                                        STRV_IFNOTNULL(generator_late));
                        break;

                case LOOKUP_SCOPE_GLOBAL:
                        add = strv_new(
                                        /* If you modify this you also want to modify
                                         * systemduserunitpath= in systemd.pc.in, and
                                         * the arrays in user_dirs() above! */
                                        STRV_IFNOTNULL(persistent_control),
                                        STRV_IFNOTNULL(runtime_control),
                                        STRV_IFNOTNULL(transient),
                                        STRV_IFNOTNULL(generator_early),
                                        persistent_config,
                                        USER_CONFIG_UNIT_DIR,
                                        "/etc/systemd/user",
                                        runtime_config,
                                        "/run/systemd/user",
                                        STRV_IFNOTNULL(generator),
                                        "/usr/local/share/systemd/user",
                                        "/usr/share/systemd/user",
                                        "/usr/local/lib/systemd/user",
                                        USER_DATA_UNIT_DIR,
                                        "/usr/lib/systemd/user",
                                        STRV_IFNOTNULL(generator_late));
                        break;

                case LOOKUP_SCOPE_USER:
                        add = user_dirs(persistent_config, runtime_config,
                                        global_persistent_config, global_runtime_config,
                                        generator, generator_early, generator_late,
                                        transient,
                                        persistent_control, runtime_control);
                        break;

                default:
                        assert_not_reached();
                }

                if (!add)
                        return -ENOMEM;

                if (paths) {
                        r = strv_extend_strv(&paths, add, true);
                        if (r < 0)
                                return r;
                } else
                        /* Small optimization: if paths is NULL (and it usually is), we can simply assign 'add' to it,
                         * and don't have to copy anything */
                        paths = TAKE_PTR(add);
        }

        r = patch_root_prefix(&persistent_config, root);
        if (r < 0)
                return r;
        r = patch_root_prefix(&runtime_config, root);
        if (r < 0)
                return r;

        r = patch_root_prefix(&generator, root);
        if (r < 0)
                return r;
        r = patch_root_prefix(&generator_early, root);
        if (r < 0)
                return r;
        r = patch_root_prefix(&generator_late, root);
        if (r < 0)
                return r;

        r = patch_root_prefix(&transient, root);
        if (r < 0)
                return r;

        r = patch_root_prefix(&persistent_control, root);
        if (r < 0)
                return r;
        r = patch_root_prefix(&runtime_control, root);
        if (r < 0)
                return r;

        r = patch_root_prefix(&persistent_attached, root);
        if (r < 0)
                return r;
        r = patch_root_prefix(&runtime_attached, root);
        if (r < 0)
                return r;

        r = patch_root_prefix_strv(paths, root);
        if (r < 0)
                return -ENOMEM;

        *lp = (LookupPaths) {
                .search_path = strv_uniq(TAKE_PTR(paths)),

                .persistent_config = TAKE_PTR(persistent_config),
                .runtime_config = TAKE_PTR(runtime_config),

                .generator = TAKE_PTR(generator),
                .generator_early = TAKE_PTR(generator_early),
                .generator_late = TAKE_PTR(generator_late),

                .transient = TAKE_PTR(transient),

                .persistent_control = TAKE_PTR(persistent_control),
                .runtime_control = TAKE_PTR(runtime_control),

                .persistent_attached = TAKE_PTR(persistent_attached),
                .runtime_attached = TAKE_PTR(runtime_attached),

                .root_dir = TAKE_PTR(root),
                .temporary_dir = TAKE_PTR(tempdir),
        };

        return 0;
}

int lookup_paths_init_or_warn(LookupPaths *lp, LookupScope scope, LookupPathsFlags flags, const char *root_dir) {
        int r;

        r = lookup_paths_init(lp, scope, flags, root_dir);
        if (r < 0)
                return log_error_errno(r, "Failed to initialize unit search paths%s%s: %m",
                                       isempty(root_dir) ? "" : " for root directory ", strempty(root_dir));
        return r;
}

void lookup_paths_free(LookupPaths *lp) {
        if (!lp)
                return;

        lp->search_path = strv_free(lp->search_path);

        lp->persistent_config = mfree(lp->persistent_config);
        lp->runtime_config = mfree(lp->runtime_config);

        lp->persistent_attached = mfree(lp->persistent_attached);
        lp->runtime_attached = mfree(lp->runtime_attached);

        lp->generator = mfree(lp->generator);
        lp->generator_early = mfree(lp->generator_early);
        lp->generator_late = mfree(lp->generator_late);

        lp->transient = mfree(lp->transient);

        lp->persistent_control = mfree(lp->persistent_control);
        lp->runtime_control = mfree(lp->runtime_control);

        lp->root_dir = mfree(lp->root_dir);
        lp->temporary_dir = mfree(lp->temporary_dir);
}

void lookup_paths_log(LookupPaths *lp) {
        assert(lp);

        if (strv_isempty(lp->search_path)) {
                log_debug("Ignoring unit files.");
                lp->search_path = strv_free(lp->search_path);
        } else {
                _cleanup_free_ char *t = NULL;

                t = strv_join(lp->search_path, "\n\t");
                log_debug("Looking for unit files in (higher priority first):\n\t%s", strna(t));
        }
}

char **generator_binary_paths(LookupScope scope) {
        bool append = false; /* Add items from SYSTEMD_GENERATOR_PATH before normal directories */
        _cleanup_strv_free_ char **paths = NULL;
        int r;

        /* First priority is whatever has been passed to us via env vars */
        r = get_paths_from_environ("SYSTEMD_GENERATOR_PATH", &paths, &append);
        if (r < 0)
                return NULL;

        if (!paths || append) {
                _cleanup_strv_free_ char **add = NULL;

                switch (scope) {

                case LOOKUP_SCOPE_SYSTEM:
                        add = strv_new("/run/systemd/system-generators",
                                       "/etc/systemd/system-generators",
                                       "/usr/local/lib/systemd/system-generators",
                                       SYSTEM_GENERATOR_DIR);
                        break;

                case LOOKUP_SCOPE_GLOBAL:
                case LOOKUP_SCOPE_USER:
                        add = strv_new("/run/systemd/user-generators",
                                       "/etc/systemd/user-generators",
                                       "/usr/local/lib/systemd/user-generators",
                                       USER_GENERATOR_DIR);
                        break;

                default:
                        assert_not_reached();
                }

                if (!add)
                        return NULL;

                if (paths) {
                        r = strv_extend_strv(&paths, add, true);
                        if (r < 0)
                                return NULL;
                } else
                        /* Small optimization: if paths is NULL (and it usually is), we can simply assign 'add' to it,
                         * and don't have to copy anything */
                        paths = TAKE_PTR(add);
        }

        return TAKE_PTR(paths);
}

char **env_generator_binary_paths(bool is_system) {
        bool append = false; /* Add items from SYSTEMD_ENVIRONMENT_GENERATOR_PATH before normal directories */
        _cleanup_strv_free_ char **paths = NULL;
        _cleanup_strv_free_ char **add = NULL;
        int r;

        /* First priority is whatever has been passed to us via env vars */
        r = get_paths_from_environ("SYSTEMD_ENVIRONMENT_GENERATOR_PATH", &paths, &append);
        if (r < 0)
                return NULL;

        if (!paths || append) {
                if (is_system)
                        add = strv_new("/run/systemd/system-environment-generators",
                                        "/etc/systemd/system-environment-generators",
                                        "/usr/local/lib/systemd/system-environment-generators",
                                        SYSTEM_ENV_GENERATOR_DIR);
                else
                        add = strv_new("/run/systemd/user-environment-generators",
                                       "/etc/systemd/user-environment-generators",
                                       "/usr/local/lib/systemd/user-environment-generators",
                                       USER_ENV_GENERATOR_DIR);

                if (!add)
                        return NULL;
        }

        if (paths) {
                r = strv_extend_strv(&paths, add, true);
                if (r < 0)
                        return NULL;
        } else
                /* Small optimization: if paths is NULL (and it usually is), we can simply assign 'add' to it,
                 * and don't have to copy anything */
                paths = TAKE_PTR(add);

        return TAKE_PTR(paths);
}

int find_portable_profile(const char *name, const char *unit, char **ret_path) {
        const char *dot;

        assert(name);
        assert(ret_path);

        assert_se(dot = strrchr(unit, '.'));

        NULSTR_FOREACH(p, PORTABLE_PROFILE_DIRS) {
                _cleanup_free_ char *joined = NULL;

                joined = strjoin(p, "/", name, "/", dot + 1, ".conf");
                if (!joined)
                        return -ENOMEM;

                if (laccess(joined, F_OK) >= 0) {
                        *ret_path = TAKE_PTR(joined);
                        return 0;
                }

                if (errno != ENOENT)
                        return -errno;
        }

        return -ENOENT;
}
