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

#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "alloc-util.h"
#include "chase-symlinks.h"
#include "conf-files.h"
#include "conf-parser.h"
#include "constants.h"
#include "dirent-util.h"
#include "errno-list.h"
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "hashmap.h"
#include "install-printf.h"
#include "install.h"
#include "locale-util.h"
#include "log.h"
#include "macro.h"
#include "mkdir-label.h"
#include "path-lookup.h"
#include "path-util.h"
#include "rm-rf.h"
#include "set.h"
#include "special.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "unit-file.h"

#define UNIT_FILE_FOLLOW_SYMLINK_MAX 64

typedef enum SearchFlags {
        SEARCH_LOAD                   = 1 << 0,
        SEARCH_FOLLOW_CONFIG_SYMLINKS = 1 << 1,
        SEARCH_DROPIN                 = 1 << 2,
} SearchFlags;

typedef struct {
        LookupScope scope;
        OrderedHashmap *will_process;
        OrderedHashmap *have_processed;
} InstallContext;

typedef enum {
        PRESET_UNKNOWN,
        PRESET_ENABLE,
        PRESET_DISABLE,
} PresetAction;

struct UnitFilePresetRule {
        char *pattern;
        PresetAction action;
        char **instances;
};

static bool install_info_has_rules(const InstallInfo *i) {
        assert(i);

        return !strv_isempty(i->aliases) ||
               !strv_isempty(i->wanted_by) ||
               !strv_isempty(i->required_by);
}

static bool install_info_has_also(const InstallInfo *i) {
        assert(i);

        return !strv_isempty(i->also);
}

void unit_file_presets_freep(UnitFilePresets *p) {
        if (!p)
                return;

        for (size_t i = 0; i < p->n_rules; i++) {
                free(p->rules[i].pattern);
                strv_free(p->rules[i].instances);
        }

        free(p->rules);
        p->n_rules = 0;
}

static const char *const install_mode_table[_INSTALL_MODE_MAX] = {
        [INSTALL_MODE_REGULAR] = "regular",
        [INSTALL_MODE_LINKED]  = "linked",
        [INSTALL_MODE_ALIAS]   = "alias",
        [INSTALL_MODE_MASKED]  = "masked",
};

DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(install_mode, InstallMode);

static int in_search_path(const LookupPaths *lp, const char *path) {
        _cleanup_free_ char *parent = NULL;
        int r;

        /* Check if 'path' is in lp->search_path. */

        r = path_extract_directory(ASSERT_PTR(path), &parent);
        if (r < 0)
                return r;

        return path_strv_contains(ASSERT_PTR(lp)->search_path, parent);
}

static int underneath_search_path(const LookupPaths *lp, const char *path) {
        /* Check if 'path' is underneath lp->search_path. */

        return !!path_startswith_strv(ASSERT_PTR(path), ASSERT_PTR(lp)->search_path);
}

static const char* skip_root(const char *root_dir, const char *path) {
        assert(path);

        if (!root_dir)
                return path;

        const char *e = path_startswith(path, root_dir);
        if (!e)
                return NULL;

        /* Make sure the returned path starts with a slash */
        if (e[0] != '/') {
                if (e == path || e[-1] != '/')
                        return NULL;

                e--;
        }

        return e;
}

static int path_is_generator(const LookupPaths *lp, const char *path) {
        _cleanup_free_ char *parent = NULL;
        int r;

        assert(lp);
        assert(path);

        r = path_extract_directory(path, &parent);
        if (r < 0)
                return r;

        return path_equal_ptr(parent, lp->generator) ||
               path_equal_ptr(parent, lp->generator_early) ||
               path_equal_ptr(parent, lp->generator_late);
}

static int path_is_transient(const LookupPaths *lp, const char *path) {
        _cleanup_free_ char *parent = NULL;
        int r;

        assert(lp);
        assert(path);

        r = path_extract_directory(path, &parent);
        if (r < 0)
                return r;

        return path_equal_ptr(parent, lp->transient);
}

static int path_is_control(const LookupPaths *lp, const char *path) {
        _cleanup_free_ char *parent = NULL;
        int r;

        assert(lp);
        assert(path);

        r = path_extract_directory(path, &parent);
        if (r < 0)
                return r;

        return path_equal_ptr(parent, lp->persistent_control) ||
               path_equal_ptr(parent, lp->runtime_control);
}

static int path_is_config(const LookupPaths *lp, const char *path, bool check_parent) {
        _cleanup_free_ char *parent = NULL;
        int r;

        assert(lp);
        assert(path);

        /* Note that we do *not* have generic checks for /etc or /run in place, since with
         * them we couldn't discern configuration from transient or generated units */

        if (check_parent) {
                r = path_extract_directory(path, &parent);
                if (r < 0)
                        return r;

                path = parent;
        }

        return path_equal_ptr(path, lp->persistent_config) ||
               path_equal_ptr(path, lp->runtime_config);
}

static int path_is_runtime(const LookupPaths *lp, const char *path, bool check_parent) {
        _cleanup_free_ char *parent = NULL;
        const char *rpath;
        int r;

        assert(lp);
        assert(path);

        /* Everything in /run is considered runtime. On top of that we also add
         * explicit checks for the various runtime directories, as safety net. */

        rpath = skip_root(lp->root_dir, path);
        if (rpath && path_startswith(rpath, "/run"))
                return true;

        if (check_parent) {
                r = path_extract_directory(path, &parent);
                if (r < 0)
                        return r;

                path = parent;
        }

        return path_equal_ptr(path, lp->runtime_config) ||
               path_equal_ptr(path, lp->generator) ||
               path_equal_ptr(path, lp->generator_early) ||
               path_equal_ptr(path, lp->generator_late) ||
               path_equal_ptr(path, lp->transient) ||
               path_equal_ptr(path, lp->runtime_control);
}

static int path_is_vendor_or_generator(const LookupPaths *lp, const char *path) {
        const char *rpath;

        assert(lp);
        assert(path);

        rpath = skip_root(lp->root_dir, path);
        if (!rpath)
                return 0;

        if (path_startswith(rpath, "/usr"))
                return true;

#if HAVE_SPLIT_USR
        if (path_startswith(rpath, "/lib"))
                return true;
#endif

        if (path_is_generator(lp, rpath))
                return true;

        return path_equal(rpath, SYSTEM_DATA_UNIT_DIR);
}

static const char* config_path_from_flags(const LookupPaths *lp, UnitFileFlags flags) {
        assert(lp);

        if (FLAGS_SET(flags, UNIT_FILE_PORTABLE))
                return FLAGS_SET(flags, UNIT_FILE_RUNTIME) ? lp->runtime_attached : lp->persistent_attached;
        else
                return FLAGS_SET(flags, UNIT_FILE_RUNTIME) ? lp->runtime_config : lp->persistent_config;
}

InstallChangeType install_changes_add(
                InstallChange **changes,
                size_t *n_changes,
                InstallChangeType type, /* INSTALL_CHANGE_SYMLINK, _UNLINK, _IS_MASKED, _IS_DANGLING, … if positive or errno if negative */
                const char *path,
                const char *source) {

        _cleanup_free_ char *p = NULL, *s = NULL;
        InstallChange *c;

        assert(!changes == !n_changes);
        assert(INSTALL_CHANGE_TYPE_VALID(type));

        /* Message formatting requires <path> to be set. */
        assert(path);

        /* Register a change or error. Note that the return value may be the error
         * that was passed in, or -ENOMEM generated internally. */

        if (!changes)
                return type;

        c = reallocarray(*changes, *n_changes + 1, sizeof(InstallChange));
        if (!c)
                return -ENOMEM;
        *changes = c;

        if (path) {
                p = strdup(path);
                if (!p)
                        return -ENOMEM;

                path_simplify(p);
        }

        if (source) {
                s = strdup(source);
                if (!s)
                        return -ENOMEM;

                path_simplify(s);
        }

        c[(*n_changes)++] = (InstallChange) {
                .type = type,
                .path = TAKE_PTR(p),
                .source = TAKE_PTR(s),
        };

        return type;
}

void install_changes_free(InstallChange *changes, size_t n_changes) {
        assert(changes || n_changes == 0);

        for (size_t i = 0; i < n_changes; i++) {
                free(changes[i].path);
                free(changes[i].source);
        }

        free(changes);
}

void install_changes_dump(int r, const char *verb, const InstallChange *changes, size_t n_changes, bool quiet) {
        int err = 0;

        assert(changes || n_changes == 0);
        /* If verb is not specified, errors are not allowed! */
        assert(verb || r >= 0);

        for (size_t i = 0; i < n_changes; i++) {
                if (changes[i].type < 0)
                        assert(verb);
                assert(changes[i].path);

                /* When making changes here, make sure to also change install_error() in dbus-manager.c. */

                switch (changes[i].type) {
                case INSTALL_CHANGE_SYMLINK:
                        if (!quiet)
                                log_info("Created symlink %s %s %s.",
                                         changes[i].path,
                                         special_glyph(SPECIAL_GLYPH_ARROW_RIGHT),
                                         changes[i].source);
                        break;
                case INSTALL_CHANGE_UNLINK:
                        if (!quiet)
                                log_info("Removed \"%s\".", changes[i].path);
                        break;
                case INSTALL_CHANGE_IS_MASKED:
                        if (!quiet)
                                log_info("Unit %s is masked, ignoring.", changes[i].path);
                        break;
                case INSTALL_CHANGE_IS_MASKED_GENERATOR:
                        if (!quiet)
                                log_info("Unit %s is masked via a generator and cannot be unmasked.",
                                         changes[i].path);
                        break;
                case INSTALL_CHANGE_IS_DANGLING:
                        if (!quiet)
                                log_info("Unit %s is an alias to a unit that is not present, ignoring.",
                                         changes[i].path);
                        break;
                case INSTALL_CHANGE_DESTINATION_NOT_PRESENT:
                        if (!quiet)
                                log_warning("Unit %s is added as a dependency to a non-existent unit %s.",
                                            changes[i].source, changes[i].path);
                        break;
                case INSTALL_CHANGE_AUXILIARY_FAILED:
                        if (!quiet)
                                log_warning("Failed to enable auxiliary unit %s, ignoring.", changes[i].path);
                        break;
                case -EEXIST:
                        if (changes[i].source)
                                err = log_error_errno(changes[i].type,
                                                      "Failed to %s unit, file \"%s\" already exists and is a symlink to \"%s\".",
                                                      verb, changes[i].path, changes[i].source);
                        else
                                err = log_error_errno(changes[i].type,
                                                      "Failed to %s unit, file \"%s\" already exists.",
                                                      verb, changes[i].path);
                        break;
                case -ERFKILL:
                        err = log_error_errno(changes[i].type, "Failed to %s unit, unit %s is masked.",
                                              verb, changes[i].path);
                        break;
                case -EADDRNOTAVAIL:
                        err = log_error_errno(changes[i].type, "Failed to %s unit, unit %s is transient or generated.",
                                              verb, changes[i].path);
                        break;
                case -ETXTBSY:
                        err = log_error_errno(changes[i].type, "Failed to %s unit, file %s is under the systemd unit hierarchy already.",
                                              verb, changes[i].path);
                        break;
                case -EBADSLT:
                        err = log_error_errno(changes[i].type, "Failed to %s unit, invalid specifier in \"%s\".",
                                              verb, changes[i].path);
                        break;
                case -EIDRM:
                        err = log_error_errno(changes[i].type, "Failed to %s %s, destination unit %s is a non-template unit.",
                                              verb, changes[i].source, changes[i].path);
                        break;
                case -EUCLEAN:
                        err = log_error_errno(changes[i].type,
                                              "Failed to %s unit, \"%s\" is not a valid unit name.",
                                              verb, changes[i].path);
                        break;
                case -ELOOP:
                        err = log_error_errno(changes[i].type, "Failed to %s unit, refusing to operate on linked unit file %s.",
                                              verb, changes[i].path);
                        break;
                case -EXDEV:
                        if (changes[i].source)
                                err = log_error_errno(changes[i].type, "Failed to %s unit, cannot alias %s as %s.",
                                                      verb, changes[i].source, changes[i].path);
                        else
                                err = log_error_errno(changes[i].type, "Failed to %s unit, invalid unit reference \"%s\".",
                                                      verb, changes[i].path);
                        break;
                case -ENOENT:
                        err = log_error_errno(changes[i].type, "Failed to %s unit, unit %s does not exist.",
                                              verb, changes[i].path);
                        break;
                case -EUNATCH:
                        err = log_error_errno(changes[i].type, "Failed to %s unit, cannot resolve specifiers in \"%s\".",
                                              verb, changes[i].path);
                        break;
                default:
                        assert(changes[i].type < 0);
                        err = log_error_errno(changes[i].type, "Failed to %s unit, file \"%s\": %m",
                                              verb, changes[i].path);
                }
        }

        if (r < 0 && err >= 0)
                log_error_errno(r, "Failed to %s: %m.", verb);
}

/**
 * Checks if two symlink targets (starting from src) are equivalent as far as the unit enablement logic is
 * concerned. If the target is in the unit search path, then anything with the same name is equivalent.
 * If outside the unit search path, paths must be identical.
 */
static int chroot_unit_symlinks_equivalent(
                const LookupPaths *lp,
                const char *src,
                const char *target_a,
                const char *target_b) {

        assert(lp);
        assert(src);
        assert(target_a);
        assert(target_b);

        /* This will give incorrect results if the paths are relative and go outside
         * of the chroot. False negatives are possible. */

        const char *root = lp->root_dir ?: "/";
        _cleanup_free_ char *dirname = NULL;
        int r;

        if (!path_is_absolute(target_a) || !path_is_absolute(target_b)) {
                r = path_extract_directory(src, &dirname);
                if (r < 0)
                        return r;
        }

        _cleanup_free_ char *a = path_join(path_is_absolute(target_a) ? root : dirname, target_a);
        _cleanup_free_ char *b = path_join(path_is_absolute(target_b) ? root : dirname, target_b);
        if (!a || !b)
                return log_oom();

        r = path_equal_or_files_same(a, b, 0);
        if (r != 0)
                return r;

        _cleanup_free_ char *a_name = NULL, *b_name = NULL;
        r = path_extract_filename(a, &a_name);
        if (r < 0)
                return r;
        r = path_extract_filename(b, &b_name);
        if (r < 0)
                return r;

        return streq(a_name, b_name) &&
               path_startswith_strv(a, lp->search_path) &&
               path_startswith_strv(b, lp->search_path);
}

static int create_symlink(
                const LookupPaths *lp,
                const char *old_path,
                const char *new_path,
                bool force,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_free_ char *dest = NULL;
        const char *rp;
        int r;

        assert(old_path);
        assert(new_path);

        rp = skip_root(lp->root_dir, old_path);
        if (rp)
                old_path = rp;

        /* Actually create a symlink, and remember that we did. This function is
         * smart enough to check if there's already a valid symlink in place.
         *
         * Returns 1 if a symlink was created or already exists and points to the
         * right place, or negative on error.
         */

        (void) mkdir_parents_label(new_path, 0755);

        if (symlink(old_path, new_path) >= 0) {
                r = install_changes_add(changes, n_changes, INSTALL_CHANGE_SYMLINK, new_path, old_path);
                if (r < 0)
                        return r;
                return 1;
        }

        if (errno != EEXIST)
                return install_changes_add(changes, n_changes, -errno, new_path, NULL);

        r = readlink_malloc(new_path, &dest);
        if (r < 0) {
                /* translate EINVAL (non-symlink exists) to EEXIST */
                if (r == -EINVAL)
                        r = -EEXIST;

                return install_changes_add(changes, n_changes, r, new_path, NULL);
        }

        if (chroot_unit_symlinks_equivalent(lp, new_path, dest, old_path)) {
                log_debug("Symlink %s %s %s already exists",
                          new_path, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), dest);
                return 1;
        }

        if (!force)
                return install_changes_add(changes, n_changes, -EEXIST, new_path, dest);

        r = symlink_atomic(old_path, new_path);
        if (r < 0)
                return install_changes_add(changes, n_changes, r, new_path, NULL);

        r = install_changes_add(changes, n_changes, INSTALL_CHANGE_UNLINK, new_path, NULL);
        if (r < 0)
                return r;
        r = install_changes_add(changes, n_changes, INSTALL_CHANGE_SYMLINK, new_path, old_path);
        if (r < 0)
                return r;

        return 1;
}

static int mark_symlink_for_removal(
                Set **remove_symlinks_to,
                const char *p) {

        char *n;
        int r;

        assert(p);

        r = set_ensure_allocated(remove_symlinks_to, &path_hash_ops);
        if (r < 0)
                return r;

        n = strdup(p);
        if (!n)
                return -ENOMEM;

        path_simplify(n);

        r = set_consume(*remove_symlinks_to, n);
        if (r == -EEXIST)
                return 0;
        if (r < 0)
                return r;

        return 1;
}

static int remove_marked_symlinks_fd(
                Set *remove_symlinks_to,
                int fd,
                const char *path,
                const char *config_path,
                const LookupPaths *lp,
                bool dry_run,
                bool *restart,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_closedir_ DIR *d = NULL;
        int r = 0;

        assert(remove_symlinks_to);
        assert(fd >= 0);
        assert(path);
        assert(config_path);
        assert(lp);
        assert(restart);

        d = fdopendir(fd);
        if (!d) {
                safe_close(fd);
                return -errno;
        }

        rewinddir(d);

        FOREACH_DIRENT(de, d, return -errno)

                if (de->d_type == DT_DIR) {
                        _cleanup_free_ char *p = NULL;
                        int nfd, q;

                        nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
                        if (nfd < 0) {
                                if (errno == ENOENT)
                                        continue;

                                if (r == 0)
                                        r = -errno;
                                continue;
                        }

                        p = path_make_absolute(de->d_name, path);
                        if (!p) {
                                safe_close(nfd);
                                return -ENOMEM;
                        }

                        /* This will close nfd, regardless whether it succeeds or not */
                        q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, lp, dry_run, restart, changes, n_changes);
                        if (q < 0 && r == 0)
                                r = q;

                } else if (de->d_type == DT_LNK) {
                        _cleanup_free_ char *p = NULL;
                        bool found;
                        int q;

                        if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
                                continue;

                        p = path_make_absolute(de->d_name, path);
                        if (!p)
                                return -ENOMEM;
                        path_simplify(p);

                        /* We remove all links pointing to a file or path that is marked, as well as all
                         * files sharing the same name as a file that is marked, and files sharing the same
                         * name after the instance has been removed. Do path chasing only if we don't already
                         * know that we want to remove the symlink. */
                        found = set_contains(remove_symlinks_to, de->d_name);

                        if (!found) {
                                _cleanup_free_ char *template = NULL;

                                q = unit_name_template(de->d_name, &template);
                                if (q < 0 && q != -EINVAL)
                                        return q;
                                if (q >= 0)
                                        found = set_contains(remove_symlinks_to, template);
                        }

                        if (!found) {
                                _cleanup_free_ char *dest = NULL;

                                q = chase_symlinks(p, lp->root_dir, CHASE_NONEXISTENT, &dest, NULL);
                                if (q == -ENOENT)
                                        continue;
                                if (q < 0) {
                                        log_debug_errno(q, "Failed to resolve symlink \"%s\": %m", p);
                                        install_changes_add(changes, n_changes, q, p, NULL);

                                        if (r == 0)
                                                r = q;
                                        continue;
                                }

                                found = set_contains(remove_symlinks_to, dest) ||
                                        set_contains(remove_symlinks_to, basename(dest));

                        }


                        if (!found)
                                continue;

                        if (!dry_run) {
                                if (unlinkat(fd, de->d_name, 0) < 0 && errno != ENOENT) {
                                        if (r == 0)
                                                r = -errno;
                                        install_changes_add(changes, n_changes, -errno, p, NULL);
                                        continue;
                                }

                                (void) rmdir_parents(p, config_path);
                        }

                        q = install_changes_add(changes, n_changes, INSTALL_CHANGE_UNLINK, p, NULL);
                        if (q < 0)
                                return q;

                        /* Now, remember the full path (but with the root prefix removed) of
                         * the symlink we just removed, and remove any symlinks to it, too. */

                        const char *rp = skip_root(lp->root_dir, p);
                        q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: p);
                        if (q < 0)
                                return q;
                        if (q > 0 && !dry_run)
                                *restart = true;
                }

        return r;
}

static int remove_marked_symlinks(
                Set *remove_symlinks_to,
                const char *config_path,
                const LookupPaths *lp,
                bool dry_run,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_close_ int fd = -EBADF;
        bool restart;
        int r = 0;

        assert(config_path);
        assert(lp);

        if (set_size(remove_symlinks_to) <= 0)
                return 0;

        fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC);
        if (fd < 0)
                return errno == ENOENT ? 0 : -errno;

        do {
                int q, cfd;
                restart = false;

                cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
                if (cfd < 0)
                        return -errno;

                /* This takes possession of cfd and closes it */
                q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, lp, dry_run, &restart, changes, n_changes);
                if (r == 0)
                        r = q;
        } while (restart);

        return r;
}

static int is_symlink_with_known_name(const InstallInfo *i, const char *name) {
        int r;

        if (streq(name, i->name))
                return true;

        if (strv_contains(i->aliases, name))
                return true;

        /* Look for template symlink matching DefaultInstance */
        if (i->default_instance && unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE)) {
                _cleanup_free_ char *s = NULL;

                r = unit_name_replace_instance(i->name, i->default_instance, &s);
                if (r < 0) {
                        if (r != -EINVAL)
                                return r;

                } else if (streq(name, s))
                        return true;
        }

        return false;
}

static int find_symlinks_in_directory(
                DIR *dir,
                const char *dir_path,
                const char *root_dir,
                const InstallInfo *info,
                bool ignore_destination,
                bool match_name,
                bool ignore_same_name,
                const char *config_path,
                bool *same_name_link) {

        int r = 0;

        FOREACH_DIRENT(de, dir, return -errno) {
                bool found_path = false, found_dest = false, b = false;
                int q;

                if (de->d_type != DT_LNK)
                        continue;

                if (!ignore_destination) {
                        _cleanup_free_ char *dest = NULL;

                        /* Acquire symlink destination */
                        q = readlinkat_malloc(dirfd(dir), de->d_name, &dest);
                        if (q == -ENOENT)
                                continue;
                        if (q < 0) {
                                if (r == 0)
                                        r = q;
                                continue;
                        }

                        /* Make absolute */
                        if (!path_is_absolute(dest)) {
                                char *x;

                                x = path_join(dir_path, dest);
                                if (!x)
                                        return -ENOMEM;

                                free_and_replace(dest, x);
                        }

                        /* Check if what the symlink points to matches what we are looking for */
                        found_dest = streq(basename(dest), info->name);
                }

                assert(unit_name_is_valid(info->name, UNIT_NAME_ANY));

                /* Check if the symlink itself matches what we are looking for.
                 *
                 * If ignore_destination is specified, we only look at the source name.
                 *
                 * If ignore_same_name is specified, we are in one of the directories which
                 * have lower priority than the unit file, and even if a file or symlink with
                 * this name was found, we should ignore it. */

                if (ignore_destination || !ignore_same_name)
                        found_path = streq(de->d_name, info->name);

                if (!found_path && ignore_destination) {
                        _cleanup_free_ char *template = NULL;

                        q = unit_name_template(de->d_name, &template);
                        if (q < 0 && q != -EINVAL)
                                return q;
                        if (q >= 0)
                                found_dest = streq(template, info->name);
                }

                if (found_path && found_dest) {
                        _cleanup_free_ char *p = NULL, *t = NULL;

                        /* Filter out same name links in the main config path */
                        p = path_make_absolute(de->d_name, dir_path);
                        t = path_make_absolute(info->name, config_path);

                        if (!p || !t)
                                return -ENOMEM;

                        b = path_equal(p, t);
                }

                if (b)
                        *same_name_link = true;
                else if (found_path || found_dest) {
                        if (!match_name)
                                return 1;

                        /* Check if symlink name is in the set of names used by [Install] */
                        q = is_symlink_with_known_name(info, de->d_name);
                        if (q < 0)
                                return q;
                        if (q > 0)
                                return 1;
                }
        }

        return r;
}

static int find_symlinks(
                const char *root_dir,
                const InstallInfo *i,
                bool match_name,
                bool ignore_same_name,
                const char *config_path,
                bool *same_name_link) {

        _cleanup_closedir_ DIR *config_dir = NULL;
        int r = 0;

        assert(i);
        assert(config_path);
        assert(same_name_link);

        config_dir = opendir(config_path);
        if (!config_dir) {
                if (IN_SET(errno, ENOENT, ENOTDIR, EACCES))
                        return 0;
                return -errno;
        }

        FOREACH_DIRENT(de, config_dir, return -errno) {
                const char *suffix;
                _cleanup_free_ const char *path = NULL;
                _cleanup_closedir_ DIR *d = NULL;

                if (de->d_type != DT_DIR)
                        continue;

                suffix = strrchr(de->d_name, '.');
                if (!STRPTR_IN_SET(suffix, ".wants", ".requires"))
                        continue;

                path = path_join(config_path, de->d_name);
                if (!path)
                        return -ENOMEM;

                d = opendir(path);
                if (!d) {
                        log_error_errno(errno, "Failed to open directory \"%s\" while scanning for symlinks, ignoring: %m", path);
                        continue;
                }

                r = find_symlinks_in_directory(d, path, root_dir, i,
                                               /* ignore_destination= */ true,
                                               /* match_name= */ match_name,
                                               /* ignore_same_name= */ ignore_same_name,
                                               config_path,
                                               same_name_link);
                if (r > 0)
                        return 1;
                else if (r < 0)
                        log_debug_errno(r, "Failed to look up symlinks in \"%s\": %m", path);
        }

        /* We didn't find any suitable symlinks in .wants or .requires directories, let's look for linked unit files in this directory. */
        rewinddir(config_dir);
        return find_symlinks_in_directory(config_dir, config_path, root_dir, i,
                                          /* ignore_destination= */ false,
                                          /* match_name= */ match_name,
                                          /* ignore_same_name= */ ignore_same_name,
                                          config_path,
                                          same_name_link);
}

static int find_symlinks_in_scope(
                LookupScope scope,
                const LookupPaths *lp,
                const InstallInfo *info,
                bool match_name,
                UnitFileState *state) {

        bool same_name_link_runtime = false, same_name_link_config = false;
        bool enabled_in_runtime = false, enabled_at_all = false;
        bool ignore_same_name = false;
        int r;

        assert(lp);
        assert(info);

        /* As we iterate over the list of search paths in lp->search_path, we may encounter "same name"
         * symlinks. The ones which are "below" (i.e. have lower priority) than the unit file itself are
         * effectively masked, so we should ignore them. */

        STRV_FOREACH(p, lp->search_path)  {
                bool same_name_link = false;

                r = find_symlinks(lp->root_dir, info, match_name, ignore_same_name, *p, &same_name_link);
                if (r < 0)
                        return r;
                if (r > 0) {
                        /* We found symlinks in this dir? Yay! Let's see where precisely it is enabled. */

                        if (path_equal_ptr(*p, lp->persistent_config)) {
                                /* This is the best outcome, let's return it immediately. */
                                *state = UNIT_FILE_ENABLED;
                                return 1;
                        }

                        /* look for global enablement of user units */
                        if (scope == LOOKUP_SCOPE_USER && path_is_user_config_dir(*p)) {
                                *state = UNIT_FILE_ENABLED;
                                return 1;
                        }

                        r = path_is_runtime(lp, *p, false);
                        if (r < 0)
                                return r;
                        if (r > 0)
                                enabled_in_runtime = true;
                        else
                                enabled_at_all = true;

                } else if (same_name_link) {
                        if (path_equal_ptr(*p, lp->persistent_config))
                                same_name_link_config = true;
                        else {
                                r = path_is_runtime(lp, *p, false);
                                if (r < 0)
                                        return r;
                                if (r > 0)
                                        same_name_link_runtime = true;
                        }
                }

                /* Check if next iteration will be "below" the unit file (either a regular file
                 * or a symlink), and hence should be ignored */
                if (!ignore_same_name && path_startswith(info->path, *p))
                        ignore_same_name = true;
        }

        if (enabled_in_runtime) {
                *state = UNIT_FILE_ENABLED_RUNTIME;
                return 1;
        }

        /* Here's a special rule: if the unit we are looking for is an instance, and it symlinked in the search path
         * outside of runtime and configuration directory, then we consider it statically enabled. Note we do that only
         * for instance, not for regular names, as those are merely aliases, while instances explicitly instantiate
         * something, and hence are a much stronger concept. */
        if (enabled_at_all && unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
                *state = UNIT_FILE_STATIC;
                return 1;
        }

        /* Hmm, we didn't find it, but maybe we found the same name
         * link? */
        if (same_name_link_config) {
                *state = UNIT_FILE_LINKED;
                return 1;
        }
        if (same_name_link_runtime) {
                *state = UNIT_FILE_LINKED_RUNTIME;
                return 1;
        }

        return 0;
}

static void install_info_clear(InstallInfo *i) {
        if (!i)
                return;

        i->name = mfree(i->name);
        i->path = mfree(i->path);
        i->root = mfree(i->root);
        i->aliases = strv_free(i->aliases);
        i->wanted_by = strv_free(i->wanted_by);
        i->required_by = strv_free(i->required_by);
        i->also = strv_free(i->also);
        i->default_instance = mfree(i->default_instance);
        i->symlink_target = mfree(i->symlink_target);
}

static InstallInfo* install_info_free(InstallInfo *i) {
        install_info_clear(i);
        return mfree(i);
}

DEFINE_TRIVIAL_CLEANUP_FUNC(InstallInfo*, install_info_free);

static void install_context_done(InstallContext *ctx) {
        assert(ctx);

        ctx->will_process = ordered_hashmap_free_with_destructor(ctx->will_process, install_info_free);
        ctx->have_processed = ordered_hashmap_free_with_destructor(ctx->have_processed, install_info_free);
}

static InstallInfo *install_info_find(InstallContext *ctx, const char *name) {
        InstallInfo *i;

        i = ordered_hashmap_get(ctx->have_processed, name);
        if (i)
                return i;

        return ordered_hashmap_get(ctx->will_process, name);
}

static int install_info_may_process(
                const InstallInfo *i,
                const LookupPaths *lp,
                InstallChange **changes,
                size_t *n_changes) {
        assert(i);
        assert(lp);

        /* Checks whether the loaded unit file is one we should process, or is masked,
         * transient or generated and thus not subject to enable/disable operations. */

        if (i->install_mode == INSTALL_MODE_MASKED)
                return install_changes_add(changes, n_changes, -ERFKILL, i->path, NULL);
        if (path_is_generator(lp, i->path) ||
            path_is_transient(lp, i->path))
                return install_changes_add(changes, n_changes, -EADDRNOTAVAIL, i->path, NULL);

        return 0;
}

/**
 * Adds a new InstallInfo entry under name in the InstallContext.will_process
 * hashmap, or retrieves the existing one if already present.
 *
 * Returns negative on error, 0 if the unit was already known, 1 otherwise.
 */
static int install_info_add(
                InstallContext *ctx,
                const char *name,
                const char *path,
                const char *root,
                bool auxiliary,
                InstallInfo **ret) {

        int r;

        assert(ctx);

        if (!name) {
                /* 'name' and 'path' must not both be null. Check here 'path' using assert_se() to
                 * workaround a bug in gcc that generates a -Wnonnull warning when calling basename(),
                 * but this cannot be possible in any code path (See #6119). */
                assert_se(path);
                name = basename(path);
        }

        if (!unit_name_is_valid(name, UNIT_NAME_ANY))
                return -EINVAL;

        InstallInfo *i = install_info_find(ctx, name);
        if (i) {
                i->auxiliary = i->auxiliary && auxiliary;

                if (ret)
                        *ret = i;
                return 0;
        }

        _cleanup_(install_info_freep) InstallInfo *alloc = new(InstallInfo, 1);
        if (!alloc)
                return -ENOMEM;

        *alloc = (InstallInfo) {
                .install_mode = _INSTALL_MODE_INVALID,
                .auxiliary = auxiliary,
        };

        alloc->name = strdup(name);
        if (!alloc->name)
                return -ENOMEM;

        if (root) {
                alloc->root = strdup(root);
                if (!alloc->root)
                        return -ENOMEM;
        }

        if (path) {
                alloc->path = strdup(path);
                if (!alloc->path)
                        return -ENOMEM;
        }

        r = ordered_hashmap_ensure_put(&ctx->will_process, &string_hash_ops, alloc->name, alloc);
        if (r < 0)
                return r;
        i = TAKE_PTR(alloc);

        if (ret)
                *ret = i;
        return 1;
}

static int config_parse_alias(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        UnitType type;

        assert(unit);
        assert(filename);
        assert(lvalue);
        assert(rvalue);

        type = unit_name_to_type(unit);
        if (!unit_type_may_alias(type))
                return log_syntax(unit, LOG_WARNING, filename, line, 0,
                                  "Alias= is not allowed for %s units, ignoring.",
                                  unit_type_to_string(type));

        return config_parse_strv(unit, filename, line, section, section_line,
                                 lvalue, ltype, rvalue, data, userdata);
}

static int config_parse_also(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        InstallInfo *info = ASSERT_PTR(userdata);
        InstallContext *ctx = ASSERT_PTR(data);
        int r;

        assert(unit);
        assert(filename);
        assert(lvalue);
        assert(rvalue);

        for (;;) {
                _cleanup_free_ char *word = NULL, *printed = NULL;

                r = extract_first_word(&rvalue, &word, NULL, 0);
                if (r < 0)
                        return r;
                if (r == 0)
                        break;

                r = install_name_printf(ctx->scope, info, word, &printed);
                if (r < 0)
                        return log_syntax(unit, LOG_WARNING, filename, line, r,
                                          "Failed to resolve unit name in Also=\"%s\": %m", word);

                r = install_info_add(ctx, printed, NULL, info->root, /* auxiliary= */ true, NULL);
                if (r < 0)
                        return r;

                r = strv_push(&info->also, printed);
                if (r < 0)
                        return r;

                printed = NULL;
        }

        return 0;
}

static int config_parse_default_instance(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        InstallContext *ctx = ASSERT_PTR(data);
        InstallInfo *info = ASSERT_PTR(userdata);
        _cleanup_free_ char *printed = NULL;
        int r;

        assert(unit);
        assert(filename);
        assert(lvalue);
        assert(rvalue);

        if (unit_name_is_valid(unit, UNIT_NAME_INSTANCE))
                /* When enabling an instance, we might be using a template unit file,
                 * but we should ignore DefaultInstance silently. */
                return 0;
        if (!unit_name_is_valid(unit, UNIT_NAME_TEMPLATE))
                return log_syntax(unit, LOG_WARNING, filename, line, 0,
                                  "DefaultInstance= only makes sense for template units, ignoring.");

        r = install_name_printf(ctx->scope, info, rvalue, &printed);
        if (r < 0)
                return log_syntax(unit, LOG_WARNING, filename, line, r,
                                  "Failed to resolve instance name in DefaultInstance=\"%s\": %m", rvalue);

        if (isempty(printed))
                printed = mfree(printed);

        if (printed && !unit_instance_is_valid(printed))
                return log_syntax(unit, LOG_WARNING, filename, line, SYNTHETIC_ERRNO(EINVAL),
                                  "Invalid DefaultInstance= value \"%s\".", printed);

        return free_and_replace(info->default_instance, printed);
}

static int unit_file_load(
                InstallContext *ctx,
                InstallInfo *info,
                const char *path,
                const char *root_dir,
                SearchFlags flags) {

        const ConfigTableItem items[] = {
                { "Install", "Alias",           config_parse_alias,            0, &info->aliases           },
                { "Install", "WantedBy",        config_parse_strv,             0, &info->wanted_by         },
                { "Install", "RequiredBy",      config_parse_strv,             0, &info->required_by       },
                { "Install", "DefaultInstance", config_parse_default_instance, 0, info                     },
                { "Install", "Also",            config_parse_also,             0, ctx                      },
                {}
        };

        UnitType type;
        _cleanup_fclose_ FILE *f = NULL;
        _cleanup_close_ int fd = -EBADF;
        struct stat st;
        int r;

        assert(info);
        assert(path);

        if (!(flags & SEARCH_DROPIN)) {
                /* Loading or checking for the main unit file… */

                type = unit_name_to_type(info->name);
                if (type < 0)
                        return -EINVAL;
                if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) && !unit_type_may_template(type))
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                               "%s: unit type %s cannot be templated, ignoring.", path, unit_type_to_string(type));

                if (!(flags & SEARCH_LOAD)) {
                        if (lstat(path, &st) < 0)
                                return -errno;

                        if (null_or_empty(&st))
                                info->install_mode = INSTALL_MODE_MASKED;
                        else if (S_ISREG(st.st_mode))
                                info->install_mode = INSTALL_MODE_REGULAR;
                        else if (S_ISLNK(st.st_mode))
                                return -ELOOP;
                        else if (S_ISDIR(st.st_mode))
                                return -EISDIR;
                        else
                                return -ENOTTY;

                        return 0;
                }

                fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
                if (fd < 0)
                        return -errno;
        } else {
                /* Operating on a drop-in file. If we aren't supposed to load the unit file drop-ins don't matter, let's hence shortcut this. */

                if (!(flags & SEARCH_LOAD))
                        return 0;

                fd = chase_symlinks_and_open(path, root_dir, 0, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
                if (fd < 0)
                        return fd;
        }

        if (fstat(fd, &st) < 0)
                return -errno;

        if (null_or_empty(&st)) {
                if ((flags & SEARCH_DROPIN) == 0)
                        info->install_mode = INSTALL_MODE_MASKED;

                return 0;
        }

        r = stat_verify_regular(&st);
        if (r < 0)
                return r;

        f = take_fdopen(&fd, "r");
        if (!f)
                return -errno;

        /* ctx is only needed if we actually load the file (it's referenced from items[] btw, in case you wonder.) */
        assert(ctx);

        r = config_parse(info->name, path, f,
                         "Install\0"
                         "-Unit\0"
                         "-Automount\0"
                         "-Device\0"
                         "-Mount\0"
                         "-Path\0"
                         "-Scope\0"
                         "-Service\0"
                         "-Slice\0"
                         "-Socket\0"
                         "-Swap\0"
                         "-Target\0"
                         "-Timer\0",
                         config_item_table_lookup, items,
                         0, info,
                         NULL);
        if (r < 0)
                return log_debug_errno(r, "Failed to parse \"%s\": %m", info->name);

        if ((flags & SEARCH_DROPIN) == 0)
                info->install_mode = INSTALL_MODE_REGULAR;

        return
                (int) strv_length(info->aliases) +
                (int) strv_length(info->wanted_by) +
                (int) strv_length(info->required_by);
}

static int unit_file_load_or_readlink(
                InstallContext *ctx,
                InstallInfo *info,
                const char *path,
                const LookupPaths *lp,
                SearchFlags flags) {
        int r;

        r = unit_file_load(ctx, info, path, lp->root_dir, flags);
        if (r != -ELOOP || (flags & SEARCH_DROPIN))
                return r;

        /* This is a symlink, let's read and verify it. */
        r = unit_file_resolve_symlink(lp->root_dir, lp->search_path,
                                      NULL, AT_FDCWD, path,
                                      true, &info->symlink_target);
        if (r < 0)
                return r;
        bool outside_search_path = r > 0;

        r = null_or_empty_path_with_root(info->symlink_target, lp->root_dir);
        if (r < 0 && r != -ENOENT)
                return log_debug_errno(r, "Failed to stat %s: %m", info->symlink_target);
        if (r > 0)
                info->install_mode = INSTALL_MODE_MASKED;
        else if (outside_search_path)
                info->install_mode = INSTALL_MODE_LINKED;
        else
                info->install_mode = INSTALL_MODE_ALIAS;

        return 0;
}

static int unit_file_search(
                InstallContext *ctx,
                InstallInfo *info,
                const LookupPaths *lp,
                SearchFlags flags) {

        const char *dropin_dir_name = NULL, *dropin_template_dir_name = NULL;
        _cleanup_strv_free_ char **dirs = NULL, **files = NULL;
        _cleanup_free_ char *template = NULL;
        bool found_unit = false;
        int r, result;

        assert(info);
        assert(lp);

        /* Was this unit already loaded? */
        if (info->install_mode != _INSTALL_MODE_INVALID)
                return 0;

        if (info->path)
                return unit_file_load_or_readlink(ctx, info, info->path, lp, flags);

        assert(info->name);

        if (unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
                r = unit_name_template(info->name, &template);
                if (r < 0)
                        return r;
        }

        STRV_FOREACH(p, lp->search_path) {
                _cleanup_free_ char *path = NULL;

                path = path_join(*p, info->name);
                if (!path)
                        return -ENOMEM;

                r = unit_file_load_or_readlink(ctx, info, path, lp, flags);
                if (r >= 0) {
                        info->path = TAKE_PTR(path);
                        result = r;
                        found_unit = true;
                        break;
                } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
                        return r;
        }

        if (!found_unit && template) {

                /* Unit file doesn't exist, however instance
                 * enablement was requested.  We will check if it is
                 * possible to load template unit file. */

                STRV_FOREACH(p, lp->search_path) {
                        _cleanup_free_ char *path = NULL;

                        path = path_join(*p, template);
                        if (!path)
                                return -ENOMEM;

                        r = unit_file_load_or_readlink(ctx, info, path, lp, flags);
                        if (r >= 0) {
                                info->path = TAKE_PTR(path);
                                result = r;
                                found_unit = true;
                                break;
                        } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
                                return r;
                }
        }

        if (!found_unit)
                return log_debug_errno(SYNTHETIC_ERRNO(ENOENT),
                                       "Cannot find unit %s%s%s.",
                                       info->name, template ? " or " : "", strempty(template));

        if (info->install_mode == INSTALL_MODE_MASKED)
                return result;

        /* Search for drop-in directories */

        dropin_dir_name = strjoina(info->name, ".d");
        STRV_FOREACH(p, lp->search_path) {
                char *path;

                path = path_join(*p, dropin_dir_name);
                if (!path)
                        return -ENOMEM;

                r = strv_consume(&dirs, path);
                if (r < 0)
                        return r;
        }

        if (template) {
                dropin_template_dir_name = strjoina(template, ".d");
                STRV_FOREACH(p, lp->search_path) {
                        char *path;

                        path = path_join(*p, dropin_template_dir_name);
                        if (!path)
                                return -ENOMEM;

                        r = strv_consume(&dirs, path);
                        if (r < 0)
                                return r;
                }
        }

        /* Load drop-in conf files */

        r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) dirs);
        if (r < 0)
                return log_debug_errno(r, "Failed to get list of conf files: %m");

        STRV_FOREACH(p, files) {
                r = unit_file_load_or_readlink(ctx, info, *p, lp, flags | SEARCH_DROPIN);
                if (r < 0)
                        return log_debug_errno(r, "Failed to load conf file \"%s\": %m", *p);
        }

        return result;
}

static int install_info_follow(
                InstallContext *ctx,
                InstallInfo *info,
                const LookupPaths *lp,
                SearchFlags flags,
                bool ignore_different_name) {

        assert(ctx);
        assert(info);

        if (!IN_SET(info->install_mode, INSTALL_MODE_ALIAS, INSTALL_MODE_LINKED))
                return -EINVAL;
        if (!info->symlink_target)
                return -EINVAL;

        /* If the basename doesn't match, the caller should add a complete new entry for this. */

        if (!ignore_different_name && !streq(basename(info->symlink_target), info->name))
                return -EXDEV;

        free_and_replace(info->path, info->symlink_target);
        info->install_mode = _INSTALL_MODE_INVALID;

        return unit_file_load_or_readlink(ctx, info, info->path, lp, flags);
}

/**
 * Search for the unit file. If the unit name is a symlink, follow the symlink to the
 * target, maybe more than once. Propagate the instance name if present.
 */
static int install_info_traverse(
                InstallContext *ctx,
                const LookupPaths *lp,
                InstallInfo *start,
                SearchFlags flags,
                InstallInfo **ret) {

        InstallInfo *i;
        unsigned k = 0;
        int r;

        assert(lp);
        assert(start);
        assert(ctx);

        r = unit_file_search(ctx, start, lp, flags);
        if (r < 0)
                return r;

        i = start;
        while (IN_SET(i->install_mode, INSTALL_MODE_ALIAS, INSTALL_MODE_LINKED)) {
                /* Follow the symlink */

                if (++k > UNIT_FILE_FOLLOW_SYMLINK_MAX)
                        return -ELOOP;

                if (!(flags & SEARCH_FOLLOW_CONFIG_SYMLINKS)) {
                        r = path_is_config(lp, i->path, true);
                        if (r < 0)
                                return r;
                        if (r > 0)
                                return -ELOOP;
                }

                r = install_info_follow(ctx, i, lp, flags,
                                        /* If linked, don't look at the target name */
                                        /* ignore_different_name= */ i->install_mode == INSTALL_MODE_LINKED);
                if (r == -EXDEV && i->symlink_target) {
                        _cleanup_free_ char *buffer = NULL;
                        const char *bn;

                        /* Target is an alias, create a new install info object and continue with that. */

                        bn = basename(i->symlink_target);

                        if (unit_name_is_valid(i->name, UNIT_NAME_INSTANCE) &&
                            unit_name_is_valid(bn, UNIT_NAME_TEMPLATE)) {

                                _cleanup_free_ char *instance = NULL;

                                r = unit_name_to_instance(i->name, &instance);
                                if (r < 0)
                                        return r;

                                r = unit_name_replace_instance(bn, instance, &buffer);
                                if (r < 0)
                                        return r;

                                if (streq(buffer, i->name)) {

                                        /* We filled in the instance, and the target stayed the same? If so,
                                         * then let's honour the link as it is. */

                                        r = install_info_follow(ctx, i, lp, flags, true);
                                        if (r < 0)
                                                return r;

                                        continue;
                                }

                                bn = buffer;
                        }

                        r = install_info_add(ctx, bn, NULL, lp->root_dir, /* auxiliary= */ false, &i);
                        if (r < 0)
                                return r;

                        /* Try again, with the new target we found. */
                        r = unit_file_search(ctx, i, lp, flags);
                        if (r == -ENOENT)
                                /* Translate error code to highlight this specific case */
                                return -ENOLINK;
                }

                if (r < 0)
                        return r;
        }

        if (ret)
                *ret = i;

        return 0;
}

/**
 * Call install_info_add() with name_or_path as the path (if name_or_path starts with "/")
 * or the name (otherwise). root_dir is prepended to the path.
 */
static int install_info_add_auto(
                InstallContext *ctx,
                const LookupPaths *lp,
                const char *name_or_path,
                InstallInfo **ret) {

        assert(ctx);
        assert(name_or_path);

        if (path_is_absolute(name_or_path)) {
                const char *pp;

                pp = prefix_roota(lp->root_dir, name_or_path);

                return install_info_add(ctx, NULL, pp, lp->root_dir, /* auxiliary= */ false, ret);
        } else
                return install_info_add(ctx, name_or_path, NULL, lp->root_dir, /* auxiliary= */ false, ret);
}

static int install_info_discover(
                InstallContext *ctx,
                const LookupPaths *lp,
                const char *name_or_path,
                SearchFlags flags,
                InstallInfo **ret,
                InstallChange **changes,
                size_t *n_changes) {

        InstallInfo *info;
        int r;

        assert(ctx);
        assert(lp);
        assert(name_or_path);

        r = install_info_add_auto(ctx, lp, name_or_path, &info);
        if (r >= 0)
                r = install_info_traverse(ctx, lp, info, flags, ret);

        if (r < 0)
                install_changes_add(changes, n_changes, r, name_or_path, NULL);
        return r;
}

static int install_info_discover_and_check(
                InstallContext *ctx,
                const LookupPaths *lp,
                const char *name_or_path,
                SearchFlags flags,
                InstallInfo **ret,
                InstallChange **changes,
                size_t *n_changes) {

        int r;

        r = install_info_discover(ctx, lp, name_or_path, flags, ret, changes, n_changes);
        if (r < 0)
                return r;

        return install_info_may_process(ret ? *ret : NULL, lp, changes, n_changes);
}

int unit_file_verify_alias(
                const InstallInfo *info,
                const char *dst,
                char **ret_dst,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_free_ char *dst_updated = NULL;
        int r;

        /* Verify that dst is a valid either a valid alias or a valid .wants/.requires symlink for the target
         * unit *i. Return negative on error or if not compatible, zero on success.
         *
         * ret_dst is set in cases where "instance propagation" happens, i.e. when the instance part is
         * inserted into dst. It is not normally set, even on success, so that the caller can easily
         * distinguish the case where instance propagation occurred.
         *
         * Returns:
         * -EXDEV when the alias doesn't match the unit,
         * -EUCLEAN when the name is invalid,
         * -ELOOP when the alias it to the unit itself.
         */

        const char *path_alias = strrchr(dst, '/');
        if (path_alias) {
                /* This branch covers legacy Alias= function of creating .wants and .requires symlinks. */
                _cleanup_free_ char *dir = NULL;
                char *p;

                path_alias ++; /* skip over slash */

                r = path_extract_directory(dst, &dir);
                if (r < 0)
                        return log_error_errno(r, "Failed to extract parent directory from '%s': %m", dst);

                p = endswith(dir, ".wants");
                if (!p)
                        p = endswith(dir, ".requires");
                if (!p) {
                        install_changes_add(changes, n_changes, -EXDEV, dst, NULL);
                        return log_debug_errno(SYNTHETIC_ERRNO(EXDEV), "Invalid path \"%s\" in alias.", dir);
                }

                *p = '\0'; /* dir should now be a unit name */

                UnitNameFlags type = unit_name_classify(dir);
                if (type < 0) {
                        install_changes_add(changes, n_changes, -EXDEV, dst, NULL);
                        return log_debug_errno(SYNTHETIC_ERRNO(EXDEV),
                                               "Invalid unit name component \"%s\" in alias.", dir);
                }

                const bool instance_propagation = type == UNIT_NAME_TEMPLATE;

                /* That's the name we want to use for verification. */
                r = unit_symlink_name_compatible(path_alias, info->name, instance_propagation);
                if (r < 0)
                        return log_error_errno(r, "Failed to verify alias validity: %m");
                if (r == 0) {
                        install_changes_add(changes, n_changes, -EXDEV, dst, info->name);
                        return log_debug_errno(SYNTHETIC_ERRNO(EXDEV),
                                               "Invalid unit \"%s\" symlink \"%s\".",
                                               info->name, dst);
                }

        } else {
                /* If the symlink target has an instance set and the symlink source doesn't, we "propagate
                 * the instance", i.e. instantiate the symlink source with the target instance. */
                if (unit_name_is_valid(dst, UNIT_NAME_TEMPLATE)) {
                        _cleanup_free_ char *inst = NULL;

                        UnitNameFlags type = unit_name_to_instance(info->name, &inst);
                        if (type < 0) {
                                install_changes_add(changes, n_changes, -EUCLEAN, info->name, NULL);
                                return log_debug_errno(type, "Failed to extract instance name from \"%s\": %m", info->name);
                        }

                        if (type == UNIT_NAME_INSTANCE) {
                                r = unit_name_replace_instance(dst, inst, &dst_updated);
                                if (r < 0)
                                        return log_error_errno(r, "Failed to build unit name from %s+%s: %m",
                                                               dst, inst);
                        }
                }

                r = unit_validate_alias_symlink_or_warn(LOG_DEBUG, dst_updated ?: dst, info->name);
                if (r == -ELOOP)  /* -ELOOP means self-alias, which we (quietly) ignore */
                        return r;
                if (r < 0)
                        return install_changes_add(changes, n_changes,
                                                   r == -EINVAL ? -EXDEV : r,
                                                   dst_updated ?: dst,
                                                   info->name);
        }

        *ret_dst = TAKE_PTR(dst_updated);
        return 0;
}

static int install_info_symlink_alias(
                LookupScope scope,
                InstallInfo *info,
                const LookupPaths *lp,
                const char *config_path,
                bool force,
                InstallChange **changes,
                size_t *n_changes) {

        int r = 0, q;

        assert(info);
        assert(lp);
        assert(config_path);

        STRV_FOREACH(s, info->aliases) {
                _cleanup_free_ char *alias_path = NULL, *dst = NULL, *dst_updated = NULL;
                bool broken;

                q = install_name_printf(scope, info, *s, &dst);
                if (q < 0) {
                        install_changes_add(changes, n_changes, q, *s, NULL);
                        r = r < 0 ? r : q;
                        continue;
                }

                q = unit_file_verify_alias(info, dst, &dst_updated, changes, n_changes);
                if (q == -ELOOP)
                        continue;
                if (q < 0) {
                        r = r < 0 ? r : q;
                        continue;
                }

                alias_path = path_make_absolute(dst_updated ?: dst, config_path);
                if (!alias_path)
                        return -ENOMEM;

                q = chase_symlinks(alias_path, lp->root_dir, CHASE_NONEXISTENT, NULL, NULL);
                if (q < 0 && q != -ENOENT) {
                        r = r < 0 ? r : q;
                        continue;
                }
                broken = q == 0; /* symlink target does not exist? */

                q = create_symlink(lp, info->path, alias_path, force || broken, changes, n_changes);
                r = r < 0 ? r : q;
        }

        return r;
}

static int install_info_symlink_wants(
                LookupScope scope,
                UnitFileFlags file_flags,
                InstallInfo *info,
                const LookupPaths *lp,
                const char *config_path,
                char **list,
                const char *suffix,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(install_info_clear) InstallInfo instance = {
                .install_mode = _INSTALL_MODE_INVALID,
        };

        UnitNameFlags valid_dst_type = UNIT_NAME_ANY;
        const char *n;
        int r = 0, q;

        assert(info);
        assert(lp);
        assert(config_path);

        if (strv_isempty(list))
                return 0;

        if (unit_name_is_valid(info->name, UNIT_NAME_PLAIN | UNIT_NAME_INSTANCE))
                /* Not a template unit. Use the name directly. */
                n = info->name;

        else if (info->default_instance) {
                /* If this is a template, and we have a default instance, use it. */

                r = unit_name_replace_instance(info->name, info->default_instance, &instance.name);
                if (r < 0)
                        return r;

                r = unit_file_search(NULL, &instance, lp, SEARCH_FOLLOW_CONFIG_SYMLINKS);
                if (r < 0)
                        return r;

                if (instance.install_mode == INSTALL_MODE_MASKED)
                        return install_changes_add(changes, n_changes, -ERFKILL, instance.path, NULL);

                n = instance.name;

        } else {
                /* We have a template, but no instance yet. When used with an instantiated unit, we will get
                 * the instance from that unit. Cannot be used with non-instance units. */

                valid_dst_type = UNIT_NAME_INSTANCE | UNIT_NAME_TEMPLATE;
                n = info->name;
        }

        r = 0;
        STRV_FOREACH(s, list) {
                _cleanup_free_ char *path = NULL, *dst = NULL;

                q = install_name_printf(scope, info, *s, &dst);
                if (q < 0) {
                        install_changes_add(changes, n_changes, q, *s, NULL);
                        if (r >= 0)
                                r = q;

                        continue;
                }

                if (!unit_name_is_valid(dst, valid_dst_type)) {
                        /* Generate a proper error here: EUCLEAN if the name is generally bad, EIDRM if the
                         * template status doesn't match. If we are doing presets don't bother reporting the
                         * error. This also covers cases like 'systemctl preset serial-getty@.service', which
                         * has no DefaultInstance, so there is nothing we can do. At the same time,
                         * 'systemctl enable serial-getty@.service' should fail, the user should specify an
                         * instance like in 'systemctl enable serial-getty@ttyS0.service'.
                         */
                        if (file_flags & UNIT_FILE_IGNORE_AUXILIARY_FAILURE)
                                continue;

                        if (unit_name_is_valid(dst, UNIT_NAME_ANY))
                                q = install_changes_add(changes, n_changes, -EIDRM, dst, n);
                        else
                                q = install_changes_add(changes, n_changes, -EUCLEAN, dst, NULL);
                        if (r >= 0)
                                r = q;

                        continue;
                }

                path = strjoin(config_path, "/", dst, suffix, n);
                if (!path)
                        return -ENOMEM;

                q = create_symlink(lp, info->path, path, true, changes, n_changes);
                if ((q < 0 && r >= 0) || r == 0)
                        r = q;

                if (unit_file_exists(scope, lp, dst) == 0) {
                        q = install_changes_add(changes, n_changes, INSTALL_CHANGE_DESTINATION_NOT_PRESENT, dst, info->path);
                        if (q < 0)
                                return q;
                }
        }

        return r;
}

static int install_info_symlink_link(
                InstallInfo *info,
                const LookupPaths *lp,
                const char *config_path,
                bool force,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_free_ char *path = NULL;
        int r;

        assert(info);
        assert(lp);
        assert(config_path);
        assert(info->path);

        r = in_search_path(lp, info->path);
        if (r < 0)
                return r;
        if (r > 0)
                return 0;

        path = path_join(config_path, info->name);
        if (!path)
                return -ENOMEM;

        return create_symlink(lp, info->path, path, force, changes, n_changes);
}

static int install_info_apply(
                LookupScope scope,
                UnitFileFlags file_flags,
                InstallInfo *info,
                const LookupPaths *lp,
                const char *config_path,
                InstallChange **changes,
                size_t *n_changes) {

        int r, q;

        assert(info);
        assert(lp);
        assert(config_path);

        if (info->install_mode != INSTALL_MODE_REGULAR)
                return 0;

        bool force = file_flags & UNIT_FILE_FORCE;

        r = install_info_symlink_link(info, lp, config_path, force, changes, n_changes);
        /* Do not count links to the unit file towards the "carries_install_info" count */
        if (r < 0)
                /* If linking of the file failed, do not try to create other symlinks,
                 * because they might would pointing to a non-existent or wrong unit. */
                return r;

        r = install_info_symlink_alias(scope, info, lp, config_path, force, changes, n_changes);

        q = install_info_symlink_wants(scope, file_flags, info, lp, config_path, info->wanted_by, ".wants/", changes, n_changes);
        if (r == 0)
                r = q;

        q = install_info_symlink_wants(scope, file_flags, info, lp, config_path, info->required_by, ".requires/", changes, n_changes);
        if (r == 0)
                r = q;

        return r;
}

static int install_context_apply(
                InstallContext *ctx,
                const LookupPaths *lp,
                UnitFileFlags file_flags,
                const char *config_path,
                SearchFlags flags,
                InstallChange **changes,
                size_t *n_changes) {

        InstallInfo *i;
        int r;

        assert(ctx);
        assert(lp);
        assert(config_path);

        if (ordered_hashmap_isempty(ctx->will_process))
                return 0;

        r = ordered_hashmap_ensure_allocated(&ctx->have_processed, &string_hash_ops);
        if (r < 0)
                return r;

        r = 0;
        while ((i = ordered_hashmap_first(ctx->will_process))) {
                int q;

                q = ordered_hashmap_move_one(ctx->have_processed, ctx->will_process, i->name);
                if (q < 0)
                        return q;

                q = install_info_traverse(ctx, lp, i, flags, NULL);
                if (q < 0) {
                        if (i->auxiliary) {
                                q = install_changes_add(changes, n_changes, INSTALL_CHANGE_AUXILIARY_FAILED, i->name, NULL);
                                if (q < 0)
                                        return q;
                                continue;
                        }

                        return install_changes_add(changes, n_changes, q, i->name, NULL);
                }

                /* We can attempt to process a masked unit when a different unit
                 * that we were processing specifies it in Also=. */
                if (i->install_mode == INSTALL_MODE_MASKED) {
                        q = install_changes_add(changes, n_changes, INSTALL_CHANGE_IS_MASKED, i->path, NULL);
                        if (q < 0)
                                return q;
                        if (r >= 0)
                                /* Assume that something *could* have been enabled here,
                                 * avoid "empty [Install] section" warning. */
                                r += 1;
                        continue;
                }

                if (i->install_mode != INSTALL_MODE_REGULAR)
                        continue;

                q = install_info_apply(ctx->scope, file_flags, i, lp, config_path, changes, n_changes);
                if (r >= 0) {
                        if (q < 0)
                                r = q;
                        else
                                r += q;
                }
        }

        return r;
}

static int install_context_mark_for_removal(
                InstallContext *ctx,
                const LookupPaths *lp,
                Set **remove_symlinks_to,
                const char *config_path,
                InstallChange **changes,
                size_t *n_changes) {

        InstallInfo *i;
        int r;

        assert(ctx);
        assert(lp);
        assert(config_path);

        /* Marks all items for removal */

        if (ordered_hashmap_isempty(ctx->will_process))
                return 0;

        r = ordered_hashmap_ensure_allocated(&ctx->have_processed, &string_hash_ops);
        if (r < 0)
                return r;

        while ((i = ordered_hashmap_first(ctx->will_process))) {

                r = ordered_hashmap_move_one(ctx->have_processed, ctx->will_process, i->name);
                if (r < 0)
                        return r;

                r = install_info_traverse(ctx, lp, i, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL);
                if (r == -ENOLINK) {
                        log_debug_errno(r, "Name %s leads to a dangling symlink, removing name.", i->name);
                        r = install_changes_add(changes, n_changes, INSTALL_CHANGE_IS_DANGLING, i->path ?: i->name, NULL);
                        if (r < 0)
                                return r;
                } else if (r == -ENOENT) {
                        if (i->auxiliary)  /* some unit specified in Also= or similar is missing */
                                log_debug_errno(r, "Auxiliary unit of %s not found, removing name.", i->name);
                        else {
                                log_debug_errno(r, "Unit %s not found, removing name.", i->name);
                                r = install_changes_add(changes, n_changes, r, i->path ?: i->name, NULL);
                                if (r < 0)
                                        return r;
                        }
                } else if (r < 0) {
                        log_debug_errno(r, "Failed to find unit %s, removing name: %m", i->name);
                        install_changes_add(changes, n_changes, r, i->path ?: i->name, NULL);
                } else if (i->install_mode == INSTALL_MODE_MASKED) {
                        log_debug("Unit file %s is masked, ignoring.", i->name);
                        install_changes_add(changes, n_changes, INSTALL_CHANGE_IS_MASKED, i->path ?: i->name, NULL);
                        continue;
                } else if (i->install_mode != INSTALL_MODE_REGULAR) {
                        log_debug("Unit %s has install mode %s, ignoring.",
                                  i->name, install_mode_to_string(i->install_mode) ?: "invalid");
                        continue;
                }

                r = mark_symlink_for_removal(remove_symlinks_to, i->name);
                if (r < 0)
                        return r;
        }

        return 0;
}

int unit_file_mask(
                LookupScope scope,
                UnitFileFlags flags,
                const char *root_dir,
                char **names,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        const char *config_path;
        int r;

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

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        config_path = (flags & UNIT_FILE_RUNTIME) ? lp.runtime_config : lp.persistent_config;
        if (!config_path)
                return -ENXIO;

        STRV_FOREACH(name, names) {
                _cleanup_free_ char *path = NULL;
                int q;

                if (!unit_name_is_valid(*name, UNIT_NAME_ANY)) {
                        if (r == 0)
                                r = -EINVAL;
                        continue;
                }

                path = path_make_absolute(*name, config_path);
                if (!path)
                        return -ENOMEM;

                q = create_symlink(&lp, "/dev/null", path, flags & UNIT_FILE_FORCE, changes, n_changes);
                if (q < 0 && r >= 0)
                        r = q;
        }

        return r;
}

int unit_file_unmask(
                LookupScope scope,
                UnitFileFlags flags,
                const char *root_dir,
                char **names,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
        _cleanup_strv_free_ char **todo = NULL;
        const char *config_path;
        size_t n_todo = 0;
        int r, q;

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

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        config_path = (flags & UNIT_FILE_RUNTIME) ? lp.runtime_config : lp.persistent_config;
        if (!config_path)
                return -ENXIO;

        bool dry_run = flags & UNIT_FILE_DRY_RUN;

        STRV_FOREACH(name, names) {
                if (!unit_name_is_valid(*name, UNIT_NAME_ANY))
                        return -EINVAL;

                /* If root_dir is set, we don't care about kernel commandline or generators.
                 * But if it is not set, we need to check for interference. */
                if (!root_dir) {
                        _cleanup_(install_info_clear) InstallInfo info = {
                                .name = *name,  /* We borrow *name temporarily… */
                                .install_mode = _INSTALL_MODE_INVALID,
                        };

                        r = unit_file_search(NULL, &info, &lp, 0);
                        if (r < 0) {
                                if (r != -ENOENT)
                                        log_debug_errno(r, "Failed to look up unit %s, ignoring: %m", info.name);
                        } else if (info.install_mode == INSTALL_MODE_MASKED &&
                                   path_is_generator(&lp, info.path)) {
                                r = install_changes_add(changes, n_changes,
                                                        INSTALL_CHANGE_IS_MASKED_GENERATOR, info.name, info.path);
                                if (r < 0)
                                        return r;
                        }

                        TAKE_PTR(info.name);  /* … and give it back here */
                }

                _cleanup_free_ char *path = path_make_absolute(*name, config_path);
                if (!path)
                        return -ENOMEM;

                r = null_or_empty_path(path);
                if (r == -ENOENT)
                        continue;
                if (r < 0)
                        return r;
                if (r == 0)
                        continue;

                if (!GREEDY_REALLOC0(todo, n_todo + 2))
                        return -ENOMEM;

                todo[n_todo] = strdup(*name);
                if (!todo[n_todo])
                        return -ENOMEM;

                n_todo++;
        }

        strv_uniq(todo);

        r = 0;
        STRV_FOREACH(i, todo) {
                _cleanup_free_ char *path = NULL;
                const char *rp;

                path = path_make_absolute(*i, config_path);
                if (!path)
                        return -ENOMEM;

                if (!dry_run && unlink(path) < 0) {
                        if (errno != ENOENT) {
                                if (r >= 0)
                                        r = -errno;
                                install_changes_add(changes, n_changes, -errno, path, NULL);
                        }

                        continue;
                }

                q = install_changes_add(changes, n_changes, INSTALL_CHANGE_UNLINK, path, NULL);
                if (q < 0)
                        return q;

                rp = skip_root(lp.root_dir, path);
                q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
                if (q < 0)
                        return q;
        }

        q = remove_marked_symlinks(remove_symlinks_to, config_path, &lp, dry_run, changes, n_changes);
        if (r >= 0)
                r = q;

        return r;
}

int unit_file_link(
                LookupScope scope,
                UnitFileFlags flags,
                const char *root_dir,
                char **files,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        _cleanup_strv_free_ char **todo = NULL;
        const char *config_path;
        size_t n_todo = 0;
        int r, q;

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

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        config_path = (flags & UNIT_FILE_RUNTIME) ? lp.runtime_config : lp.persistent_config;
        if (!config_path)
                return -ENXIO;

        STRV_FOREACH(file, files) {
                _cleanup_free_ char *full = NULL;
                struct stat st;
                char *fn;

                if (!path_is_absolute(*file))
                        return install_changes_add(changes, n_changes, -EINVAL, *file, NULL);

                fn = basename(*file);
                if (!unit_name_is_valid(fn, UNIT_NAME_ANY))
                        return install_changes_add(changes, n_changes, -EUCLEAN, *file, NULL);

                full = path_join(lp.root_dir, *file);
                if (!full)
                        return -ENOMEM;

                if (lstat(full, &st) < 0)
                        return install_changes_add(changes, n_changes, -errno, *file, NULL);

                r = stat_verify_regular(&st);
                if (r < 0)
                        return install_changes_add(changes, n_changes, r, *file, NULL);

                r = in_search_path(&lp, *file);
                if (r < 0)
                        return install_changes_add(changes, n_changes, r, *file, NULL);
                if (r > 0)
                        /* A silent noop if the file is already in the search path. */
                        continue;

                r = underneath_search_path(&lp, *file);
                if (r > 0)
                        r = -ETXTBSY;
                if (r < 0)
                        return install_changes_add(changes, n_changes, r, *file, NULL);

                if (!GREEDY_REALLOC0(todo, n_todo + 2))
                        return -ENOMEM;

                todo[n_todo] = strdup(*file);
                if (!todo[n_todo])
                        return -ENOMEM;

                n_todo++;
        }

        strv_uniq(todo);

        r = 0;
        STRV_FOREACH(i, todo) {
                _cleanup_free_ char *new_path = NULL;

                new_path = path_make_absolute(basename(*i), config_path);
                if (!new_path)
                        return -ENOMEM;

                q = create_symlink(&lp, *i, new_path, flags & UNIT_FILE_FORCE, changes, n_changes);
                if (q < 0 && r >= 0)
                        r = q;
        }

        return r;
}

static int path_shall_revert(const LookupPaths *lp, const char *path) {
        int r;

        assert(lp);
        assert(path);

        /* Checks whether the path is one where the drop-in directories shall be removed. */

        r = path_is_config(lp, path, true);
        if (r != 0)
                return r;

        r = path_is_control(lp, path);
        if (r != 0)
                return r;

        return path_is_transient(lp, path);
}

int unit_file_revert(
                LookupScope scope,
                const char *root_dir,
                char **names,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        _cleanup_strv_free_ char **todo = NULL;
        size_t n_todo = 0;
        int r, q;

        /* Puts a unit file back into vendor state. This means:
         *
         * a) we remove all drop-in snippets added by the user ("config"), add to transient units
         *    ("transient"), and added via "systemctl set-property" ("control"), but not if the drop-in is
         *    generated ("generated").
         *
         * c) if there's a vendor unit file (i.e. one in /usr) we remove any configured overriding unit files
         *    (i.e. in "config", but not in "transient" or "control" or even "generated").
         *
         * We remove all that in both the runtime and the persistent directories, if that applies.
         */

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        STRV_FOREACH(name, names) {
                bool has_vendor = false;

                if (!unit_name_is_valid(*name, UNIT_NAME_ANY))
                        return -EINVAL;

                STRV_FOREACH(p, lp.search_path) {
                        _cleanup_free_ char *path = NULL, *dropin = NULL;
                        struct stat st;

                        path = path_make_absolute(*name, *p);
                        if (!path)
                                return -ENOMEM;

                        r = RET_NERRNO(lstat(path, &st));
                        if (r < 0) {
                                if (r != -ENOENT)
                                        return install_changes_add(changes, n_changes, r, path, NULL);
                        } else if (S_ISREG(st.st_mode)) {
                                /* Check if there's a vendor version */
                                r = path_is_vendor_or_generator(&lp, path);
                                if (r < 0)
                                        return install_changes_add(changes, n_changes, r, path, NULL);
                                if (r > 0)
                                        has_vendor = true;
                        }

                        dropin = strjoin(path, ".d");
                        if (!dropin)
                                return -ENOMEM;

                        r = RET_NERRNO(lstat(dropin, &st));
                        if (r < 0) {
                                if (r != -ENOENT)
                                        return install_changes_add(changes, n_changes, r, dropin, NULL);
                        } else if (S_ISDIR(st.st_mode)) {
                                /* Remove the drop-ins */
                                r = path_shall_revert(&lp, dropin);
                                if (r < 0)
                                        return install_changes_add(changes, n_changes, r, dropin, NULL);
                                if (r > 0) {
                                        if (!GREEDY_REALLOC0(todo, n_todo + 2))
                                                return -ENOMEM;

                                        todo[n_todo++] = TAKE_PTR(dropin);
                                }
                        }
                }

                if (!has_vendor)
                        continue;

                /* OK, there's a vendor version, hence drop all configuration versions */
                STRV_FOREACH(p, lp.search_path) {
                        _cleanup_free_ char *path = NULL;
                        struct stat st;

                        path = path_make_absolute(*name, *p);
                        if (!path)
                                return -ENOMEM;

                        r = RET_NERRNO(lstat(path, &st));
                        if (r < 0) {
                                if (r != -ENOENT)
                                        return install_changes_add(changes, n_changes, r, path, NULL);
                        } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
                                r = path_is_config(&lp, path, true);
                                if (r < 0)
                                        return install_changes_add(changes, n_changes, r, path, NULL);
                                if (r > 0) {
                                        if (!GREEDY_REALLOC0(todo, n_todo + 2))
                                                return -ENOMEM;

                                        todo[n_todo++] = TAKE_PTR(path);
                                }
                        }
                }
        }

        strv_uniq(todo);

        r = 0;
        STRV_FOREACH(i, todo) {
                _cleanup_strv_free_ char **fs = NULL;
                const char *rp;

                (void) get_files_in_directory(*i, &fs);

                q = rm_rf(*i, REMOVE_ROOT|REMOVE_PHYSICAL);
                if (q < 0 && q != -ENOENT && r >= 0) {
                        r = q;
                        continue;
                }

                STRV_FOREACH(j, fs) {
                        _cleanup_free_ char *t = NULL;

                        t = path_join(*i, *j);
                        if (!t)
                                return -ENOMEM;

                        q = install_changes_add(changes, n_changes, INSTALL_CHANGE_UNLINK, t, NULL);
                        if (q < 0)
                                return q;
                }

                q = install_changes_add(changes, n_changes, INSTALL_CHANGE_UNLINK, *i, NULL);
                if (q < 0)
                        return q;

                rp = skip_root(lp.root_dir, *i);
                q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: *i);
                if (q < 0)
                        return q;
        }

        q = remove_marked_symlinks(remove_symlinks_to, lp.runtime_config, &lp, false, changes, n_changes);
        if (r >= 0)
                r = q;

        q = remove_marked_symlinks(remove_symlinks_to, lp.persistent_config, &lp, false, changes, n_changes);
        if (r >= 0)
                r = q;

        return r;
}

int unit_file_add_dependency(
                LookupScope scope,
                UnitFileFlags file_flags,
                const char *root_dir,
                char **names,
                const char *target,
                UnitDependency dep,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        _cleanup_(install_context_done) InstallContext ctx = { .scope = scope };
        InstallInfo *info, *target_info;
        const char *config_path;
        int r;

        assert(scope >= 0);
        assert(scope < _LOOKUP_SCOPE_MAX);
        assert(target);
        assert(IN_SET(dep, UNIT_WANTS, UNIT_REQUIRES));

        if (!unit_name_is_valid(target, UNIT_NAME_ANY))
                return install_changes_add(changes, n_changes, -EUCLEAN, target, NULL);

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        config_path = (file_flags & UNIT_FILE_RUNTIME) ? lp.runtime_config : lp.persistent_config;
        if (!config_path)
                return -ENXIO;

        r = install_info_discover_and_check(&ctx, &lp, target, SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                            &target_info, changes, n_changes);
        if (r < 0)
                return r;

        assert(target_info->install_mode == INSTALL_MODE_REGULAR);

        STRV_FOREACH(name, names) {
                char ***l;

                r = install_info_discover_and_check(&ctx, &lp, *name,
                                                    SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                                    &info, changes, n_changes);
                if (r < 0)
                        return r;

                assert(info->install_mode == INSTALL_MODE_REGULAR);

                /* We didn't actually load anything from the unit
                 * file, but instead just add in our new symlink to
                 * create. */

                if (dep == UNIT_WANTS)
                        l = &info->wanted_by;
                else
                        l = &info->required_by;

                strv_free(*l);
                *l = strv_new(target_info->name);
                if (!*l)
                        return -ENOMEM;
        }

        return install_context_apply(&ctx, &lp, file_flags, config_path,
                                     SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
}

static int do_unit_file_enable(
                const LookupPaths *lp,
                LookupScope scope,
                UnitFileFlags flags,
                const char *config_path,
                char **names_or_paths,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(install_context_done) InstallContext ctx = { .scope = scope };
        InstallInfo *info;
        int r;

        STRV_FOREACH(name, names_or_paths) {
                r = install_info_discover_and_check(&ctx, lp, *name,
                                                    SEARCH_LOAD | SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                                    &info, changes, n_changes);
                if (r < 0)
                        return r;

                assert(info->install_mode == INSTALL_MODE_REGULAR);
        }

        /* This will return the number of symlink rules that were
           supposed to be created, not the ones actually created. This
           is useful to determine whether the passed units had any
           installation data at all. */

        return install_context_apply(&ctx, lp, flags, config_path,
                                     SEARCH_LOAD, changes, n_changes);
}

int unit_file_enable(
                LookupScope scope,
                UnitFileFlags flags,
                const char *root_dir,
                char **names_or_paths,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        int r;

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

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        const char *config_path = config_path_from_flags(&lp, flags);
        if (!config_path)
                return -ENXIO;

        return do_unit_file_enable(&lp, scope, flags, config_path, names_or_paths, changes, n_changes);
}

static int do_unit_file_disable(
                const LookupPaths *lp,
                LookupScope scope,
                UnitFileFlags flags,
                const char *config_path,
                char **names,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(install_context_done) InstallContext ctx = { .scope = scope };
        _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
        InstallInfo *info;
        bool has_install_info = false;
        int r;

        STRV_FOREACH(name, names) {
                if (!unit_name_is_valid(*name, UNIT_NAME_ANY))
                        return install_changes_add(changes, n_changes, -EUCLEAN, *name, NULL);

                r = install_info_add(&ctx, *name, NULL, lp->root_dir, /* auxiliary= */ false, &info);
                if (r >= 0)
                        r = install_info_traverse(&ctx, lp, info, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL);

                if (r < 0)
                        return install_changes_add(changes, n_changes, r, *name, NULL);

                /* If we enable multiple units, some with install info and others without,
                 * the "empty [Install] section" warning is not shown. Let's make the behavior
                 * of disable align with that. */
                has_install_info = has_install_info || install_info_has_rules(info) || install_info_has_also(info);
        }

        r = install_context_mark_for_removal(&ctx, lp, &remove_symlinks_to, config_path, changes, n_changes);
        if (r >= 0)
                r = remove_marked_symlinks(remove_symlinks_to, config_path, lp, flags & UNIT_FILE_DRY_RUN, changes, n_changes);

        if (r < 0)
                return r;

        /* The warning is shown only if it's a no-op */
        return install_changes_have_modification(*changes, *n_changes) || has_install_info;
}

int unit_file_disable(
                LookupScope scope,
                UnitFileFlags flags,
                const char *root_dir,
                char **files,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        int r;

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

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        const char *config_path = config_path_from_flags(&lp, flags);
        if (!config_path)
                return -ENXIO;

        return do_unit_file_disable(&lp, scope, flags, config_path, files, changes, n_changes);
}

static int normalize_linked_files(
                LookupScope scope,
                const LookupPaths *lp,
                char **names_or_paths,
                char ***ret_names,
                char ***ret_files) {

        /* This is similar to normalize_filenames()/normalize_names() in src/systemctl/,
         * but operates on real unit names. For each argument we look up the actual path
         * where the unit is found. This way linked units can be re-enabled successfully. */

        _cleanup_strv_free_ char **files = NULL, **names = NULL;
        int r;

        STRV_FOREACH(a, names_or_paths) {
                _cleanup_(install_context_done) InstallContext ctx = { .scope = scope };
                InstallInfo *i = NULL;
                _cleanup_free_ char *n = NULL;

                r = path_extract_filename(*a, &n);
                if (r < 0)
                        return r;
                if (r == O_DIRECTORY)
                        return log_debug_errno(SYNTHETIC_ERRNO(EISDIR),
                                               "Unexpected path to a directory \"%s\", refusing.", *a);

                if (!is_path(*a)) {
                        r = install_info_discover(&ctx, lp, n, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, &i, NULL, NULL);
                        if (r < 0)
                                log_debug_errno(r, "Failed to discover unit \"%s\", operating on name: %m", n);
                }

                r = strv_consume(&names, TAKE_PTR(n));
                if (r < 0)
                        return r;

                const char *p = NULL;
                if (i && i->path && i->root)
                        /* Use startswith here, because we know that paths are normalized, and
                         * path_startswith() would give us a relative path, but we need an absolute path
                         * relative to i->root.
                         *
                         * In other words: /var/tmp/instroot.1234/etc/systemd/system/frobnicator.service
                         * is replaced by /etc/systemd/system/frobnicator.service, which is "absolute"
                         * in a sense, but only makes sense "relative" to /var/tmp/instroot.1234/.
                         */
                        p = startswith(i->path, i->root);

                r = strv_extend(&files, p ?: *a);
                if (r < 0)
                        return r;
        }

        *ret_names = TAKE_PTR(names);
        *ret_files = TAKE_PTR(files);
        return 0;
}

int unit_file_reenable(
                LookupScope scope,
                UnitFileFlags flags,
                const char *root_dir,
                char **names_or_paths,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        _cleanup_strv_free_ char **names = NULL, **files = NULL;
        int r;

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

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        const char *config_path = config_path_from_flags(&lp, flags);
        if (!config_path)
                return -ENXIO;

        r = normalize_linked_files(scope, &lp, names_or_paths, &names, &files);
        if (r < 0)
                return r;

        /* First, we invoke the disable command with only the basename... */
        r = do_unit_file_disable(&lp, scope, flags, config_path, names, changes, n_changes);
        if (r < 0)
                return r;

        /* But the enable command with the full name */
        return do_unit_file_enable(&lp, scope, flags, config_path, files, changes, n_changes);
}

int unit_file_set_default(
                LookupScope scope,
                UnitFileFlags flags,
                const char *root_dir,
                const char *name,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        _cleanup_(install_context_done) InstallContext ctx = { .scope = scope };
        InstallInfo *info;
        const char *new_path;
        int r;

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

        if (unit_name_to_type(name) != UNIT_TARGET) /* this also validates the name */
                return -EINVAL;
        if (streq(name, SPECIAL_DEFAULT_TARGET))
                return -EINVAL;

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        r = install_info_discover_and_check(&ctx, &lp, name, 0, &info, changes, n_changes);
        if (r < 0)
                return r;

        new_path = strjoina(lp.persistent_config, "/" SPECIAL_DEFAULT_TARGET);
        return create_symlink(&lp, info->path, new_path, flags & UNIT_FILE_FORCE, changes, n_changes);
}

int unit_file_get_default(
                LookupScope scope,
                const char *root_dir,
                char **name) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        _cleanup_(install_context_done) InstallContext ctx = { .scope = scope };
        InstallInfo *info;
        char *n;
        int r;

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

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        r = install_info_discover(&ctx, &lp, SPECIAL_DEFAULT_TARGET, SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                  &info, NULL, NULL);
        if (r < 0)
                return r;
        r = install_info_may_process(info, &lp, NULL, 0);
        if (r < 0)
                return r;

        n = strdup(info->name);
        if (!n)
                return -ENOMEM;

        *name = n;
        return 0;
}

int unit_file_lookup_state(
                LookupScope scope,
                const LookupPaths *lp,
                const char *name,
                UnitFileState *ret) {

        _cleanup_(install_context_done) InstallContext ctx = { .scope = scope };
        InstallInfo *info;
        UnitFileState state;
        int r;

        assert(lp);
        assert(name);

        if (!unit_name_is_valid(name, UNIT_NAME_ANY))
                return -EINVAL;

        r = install_info_discover(&ctx, lp, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                  &info, NULL, NULL);
        if (r < 0)
                return log_debug_errno(r, "Failed to discover unit %s: %m", name);

        assert(IN_SET(info->install_mode, INSTALL_MODE_REGULAR, INSTALL_MODE_MASKED));
        log_debug("Found unit %s at %s (%s)", name, strna(info->path),
                  info->install_mode == INSTALL_MODE_REGULAR ? "regular file" : "mask");

        /* Shortcut things, if the caller just wants to know if this unit exists. */
        if (!ret)
                return 0;

        switch (info->install_mode) {

        case INSTALL_MODE_MASKED:
                r = path_is_runtime(lp, info->path, true);
                if (r < 0)
                        return r;

                state = r > 0 ? UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
                break;

        case INSTALL_MODE_REGULAR:
                /* Check if the name we were querying is actually an alias */
                if (!streq(name, basename(info->path)) && !unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
                        state = UNIT_FILE_ALIAS;
                        break;
                }

                r = path_is_generator(lp, info->path);
                if (r < 0)
                        return r;
                if (r > 0) {
                        state = UNIT_FILE_GENERATED;
                        break;
                }

                r = path_is_transient(lp, info->path);
                if (r < 0)
                        return r;
                if (r > 0) {
                        state = UNIT_FILE_TRANSIENT;
                        break;
                }

                /* Check if any of the Alias= symlinks have been created.
                 * We ignore other aliases, and only check those that would
                 * be created by systemctl enable for this unit. */
                r = find_symlinks_in_scope(scope, lp, info, true, &state);
                if (r < 0)
                        return r;
                if (r > 0)
                        break;

                /* Check if the file is known under other names. If it is,
                 * it might be in use. Report that as UNIT_FILE_INDIRECT. */
                r = find_symlinks_in_scope(scope, lp, info, false, &state);
                if (r < 0)
                        return r;
                if (r > 0)
                        state = UNIT_FILE_INDIRECT;
                else {
                        if (install_info_has_rules(info))
                                state = UNIT_FILE_DISABLED;
                        else if (install_info_has_also(info))
                                state = UNIT_FILE_INDIRECT;
                        else
                                state = UNIT_FILE_STATIC;
                }

                break;

        default:
                assert_not_reached();
        }

        *ret = state;
        return 0;
}

int unit_file_get_state(
                LookupScope scope,
                const char *root_dir,
                const char *name,
                UnitFileState *ret) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        int r;

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

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        return unit_file_lookup_state(scope, &lp, name, ret);
}

int unit_file_exists(LookupScope scope, const LookupPaths *lp, const char *name) {
        _cleanup_(install_context_done) InstallContext c = { .scope = scope };
        int r;

        assert(lp);
        assert(name);

        if (!unit_name_is_valid(name, UNIT_NAME_ANY))
                return -EINVAL;

        r = install_info_discover(&c, lp, name, 0, NULL, NULL, NULL);
        if (r == -ENOENT)
                return 0;
        if (r < 0)
                return r;

        return 1;
}

static int split_pattern_into_name_and_instances(const char *pattern, char **out_unit_name, char ***out_instances) {
        _cleanup_strv_free_ char **instances = NULL;
        _cleanup_free_ char *unit_name = NULL;
        int r;

        assert(pattern);
        assert(out_instances);
        assert(out_unit_name);

        r = extract_first_word(&pattern, &unit_name, NULL, EXTRACT_RETAIN_ESCAPE);
        if (r < 0)
                return r;

        /* We handle the instances logic when unit name is extracted */
        if (pattern) {
                /* We only create instances when a rule of templated unit
                 * is seen. A rule like enable foo@.service a b c will
                 * result in an array of (a, b, c) as instance names */
                if (!unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE))
                        return -EINVAL;

                instances = strv_split(pattern, WHITESPACE);
                if (!instances)
                        return -ENOMEM;

                *out_instances = TAKE_PTR(instances);
        }

        *out_unit_name = TAKE_PTR(unit_name);

        return 0;
}

static int presets_find_config(LookupScope scope, const char *root_dir, char ***files) {
        static const char* const system_dirs[] = {CONF_PATHS("systemd/system-preset"), NULL};
        static const char* const user_dirs[] = {CONF_PATHS_USR("systemd/user-preset"), NULL};
        const char* const* dirs;

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

        if (scope == LOOKUP_SCOPE_SYSTEM)
                dirs = system_dirs;
        else if (IN_SET(scope, LOOKUP_SCOPE_GLOBAL, LOOKUP_SCOPE_USER))
                dirs = user_dirs;
        else
                assert_not_reached();

        return conf_files_list_strv(files, ".preset", root_dir, 0, dirs);
}

static int read_presets(LookupScope scope, const char *root_dir, UnitFilePresets *presets) {
        _cleanup_(unit_file_presets_freep) UnitFilePresets ps = {};
        _cleanup_strv_free_ char **files = NULL;
        int r;

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

        r = presets_find_config(scope, root_dir, &files);
        if (r < 0)
                return r;

        STRV_FOREACH(p, files) {
                _cleanup_fclose_ FILE *f = NULL;
                int n = 0;

                f = fopen(*p, "re");
                if (!f) {
                        if (errno == ENOENT)
                                continue;

                        return -errno;
                }

                for (;;) {
                        _cleanup_free_ char *line = NULL;
                        UnitFilePresetRule rule = {};
                        const char *parameter;
                        char *l;

                        r = read_line(f, LONG_LINE_MAX, &line);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                break;

                        l = strstrip(line);
                        n++;

                        if (isempty(l))
                                continue;
                        if (strchr(COMMENTS, *l))
                                continue;

                        parameter = first_word(l, "enable");
                        if (parameter) {
                                char *unit_name;
                                char **instances = NULL;

                                /* Unit_name will remain the same as parameter when no instances are specified */
                                r = split_pattern_into_name_and_instances(parameter, &unit_name, &instances);
                                if (r < 0) {
                                        log_syntax(NULL, LOG_WARNING, *p, n, r, "Couldn't parse line '%s'. Ignoring.", line);
                                        continue;
                                }

                                rule = (UnitFilePresetRule) {
                                        .pattern = unit_name,
                                        .action = PRESET_ENABLE,
                                        .instances = instances,
                                };
                        }

                        parameter = first_word(l, "disable");
                        if (parameter) {
                                char *pattern;

                                pattern = strdup(parameter);
                                if (!pattern)
                                        return -ENOMEM;

                                rule = (UnitFilePresetRule) {
                                        .pattern = pattern,
                                        .action = PRESET_DISABLE,
                                };
                        }

                        if (rule.action) {
                                if (!GREEDY_REALLOC(ps.rules, ps.n_rules + 1))
                                        return -ENOMEM;

                                ps.rules[ps.n_rules++] = rule;
                                continue;
                        }

                        log_syntax(NULL, LOG_WARNING, *p, n, 0, "Couldn't parse line '%s'. Ignoring.", line);
                }
        }

        ps.initialized = true;
        *presets = ps;
        ps = (UnitFilePresets){};

        return 0;
}

static int pattern_match_multiple_instances(
                        const UnitFilePresetRule rule,
                        const char *unit_name,
                        char ***ret) {

        _cleanup_free_ char *templated_name = NULL;
        int r;

        /* If no ret is needed or the rule itself does not have instances
         * initialized, we return not matching */
        if (!ret || !rule.instances)
                return 0;

        r = unit_name_template(unit_name, &templated_name);
        if (r < 0)
                return r;
        if (!streq(rule.pattern, templated_name))
                return 0;

        /* Compose a list of specified instances when unit name is a template  */
        if (unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
                _cleanup_strv_free_ char **out_strv = NULL;

                STRV_FOREACH(iter, rule.instances) {
                        _cleanup_free_ char *name = NULL;

                        r = unit_name_replace_instance(unit_name, *iter, &name);
                        if (r < 0)
                                return r;

                        r = strv_consume(&out_strv, TAKE_PTR(name));
                        if (r < 0)
                                return r;
                }

                *ret = TAKE_PTR(out_strv);
                return 1;
        } else {
                /* We now know the input unit name is an instance name */
                _cleanup_free_ char *instance_name = NULL;

                r = unit_name_to_instance(unit_name, &instance_name);
                if (r < 0)
                        return r;

                if (strv_find(rule.instances, instance_name))
                        return 1;
        }
        return 0;
}

static int query_presets(const char *name, const UnitFilePresets *presets, char ***instance_name_list) {
        PresetAction action = PRESET_UNKNOWN;

        if (!unit_name_is_valid(name, UNIT_NAME_ANY))
                return -EINVAL;

        for (size_t i = 0; i < presets->n_rules; i++)
                if (pattern_match_multiple_instances(presets->rules[i], name, instance_name_list) > 0 ||
                    fnmatch(presets->rules[i].pattern, name, FNM_NOESCAPE) == 0) {
                        action = presets->rules[i].action;
                        break;
                }

        switch (action) {
        case PRESET_UNKNOWN:
                log_debug("Preset files don't specify rule for %s. Enabling.", name);
                return 1;
        case PRESET_ENABLE:
                if (instance_name_list && *instance_name_list)
                        STRV_FOREACH(s, *instance_name_list)
                                log_debug("Preset files say enable %s.", *s);
                else
                        log_debug("Preset files say enable %s.", name);
                return 1;
        case PRESET_DISABLE:
                log_debug("Preset files say disable %s.", name);
                return 0;
        default:
                assert_not_reached();
        }
}

int unit_file_query_preset(LookupScope scope, const char *root_dir, const char *name, UnitFilePresets *cached) {
        _cleanup_(unit_file_presets_freep) UnitFilePresets tmp = {};
        int r;

        if (!cached)
                cached = &tmp;
        if (!cached->initialized) {
                r = read_presets(scope, root_dir, cached);
                if (r < 0)
                        return r;
        }

        return query_presets(name, cached, NULL);
}

static int execute_preset(
                UnitFileFlags file_flags,
                InstallContext *plus,
                InstallContext *minus,
                const LookupPaths *lp,
                const char *config_path,
                char **files,
                UnitFilePresetMode mode,
                InstallChange **changes,
                size_t *n_changes) {

        int r;

        assert(plus);
        assert(minus);
        assert(lp);
        assert(config_path);

        if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
                _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;

                r = install_context_mark_for_removal(minus, lp, &remove_symlinks_to, config_path, changes, n_changes);
                if (r < 0)
                        return r;

                r = remove_marked_symlinks(remove_symlinks_to, config_path, lp, false, changes, n_changes);
        } else
                r = 0;

        if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
                int q;

                /* Returns number of symlinks that where supposed to be installed. */
                q = install_context_apply(plus, lp,
                                          file_flags | UNIT_FILE_IGNORE_AUXILIARY_FAILURE,
                                          config_path,
                                          SEARCH_LOAD, changes, n_changes);
                if (r >= 0) {
                        if (q < 0)
                                r = q;
                        else
                                r += q;
                }
        }

        return r;
}

static int preset_prepare_one(
                LookupScope scope,
                InstallContext *plus,
                InstallContext *minus,
                LookupPaths *lp,
                const char *name,
                const UnitFilePresets *presets,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(install_context_done) InstallContext tmp = { .scope = scope };
        _cleanup_strv_free_ char **instance_name_list = NULL;
        InstallInfo *info;
        int r;

        if (install_info_find(plus, name) || install_info_find(minus, name))
                return 0;

        r = install_info_discover(&tmp, lp, name, SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                  &info, changes, n_changes);
        if (r < 0)
                return r;
        if (!streq(name, info->name)) {
                log_debug("Skipping %s because it is an alias for %s.", name, info->name);
                return 0;
        }

        r = query_presets(name, presets, &instance_name_list);
        if (r < 0)
                return r;

        if (r > 0) {
                if (instance_name_list)
                        STRV_FOREACH(s, instance_name_list) {
                                r = install_info_discover_and_check(plus, lp, *s, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                                                    &info, changes, n_changes);
                                if (r < 0)
                                        return r;
                        }
                else {
                        r = install_info_discover_and_check(plus, lp, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                                            &info, changes, n_changes);
                        if (r < 0)
                                return r;
                }

        } else
                r = install_info_discover(minus, lp, name, SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                          &info, changes, n_changes);

        return r;
}

int unit_file_preset(
                LookupScope scope,
                UnitFileFlags file_flags,
                const char *root_dir,
                char **names,
                UnitFilePresetMode mode,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        _cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
        const char *config_path;
        int r;

        assert(scope >= 0);
        assert(scope < _LOOKUP_SCOPE_MAX);
        assert(mode < _UNIT_FILE_PRESET_MODE_MAX);

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        config_path = (file_flags & UNIT_FILE_RUNTIME) ? lp.runtime_config : lp.persistent_config;
        if (!config_path)
                return -ENXIO;

        r = read_presets(scope, root_dir, &presets);
        if (r < 0)
                return r;

        STRV_FOREACH(name, names) {
                r = preset_prepare_one(scope, &plus, &minus, &lp, *name, &presets, changes, n_changes);
                if (r < 0)
                        return r;
        }

        return execute_preset(file_flags, &plus, &minus, &lp, config_path, names, mode, changes, n_changes);
}

int unit_file_preset_all(
                LookupScope scope,
                UnitFileFlags file_flags,
                const char *root_dir,
                UnitFilePresetMode mode,
                InstallChange **changes,
                size_t *n_changes) {

        _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        _cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
        const char *config_path = NULL;
        int r;

        assert(scope >= 0);
        assert(scope < _LOOKUP_SCOPE_MAX);
        assert(mode < _UNIT_FILE_PRESET_MODE_MAX);

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        config_path = (file_flags & UNIT_FILE_RUNTIME) ? lp.runtime_config : lp.persistent_config;
        if (!config_path)
                return -ENXIO;

        r = read_presets(scope, root_dir, &presets);
        if (r < 0)
                return r;

        STRV_FOREACH(i, lp.search_path) {
                _cleanup_closedir_ DIR *d = NULL;

                d = opendir(*i);
                if (!d) {
                        if (errno == ENOENT)
                                continue;

                        return -errno;
                }

                FOREACH_DIRENT(de, d, return -errno) {

                        if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
                                continue;

                        if (!IN_SET(de->d_type, DT_LNK, DT_REG))
                                continue;

                        r = preset_prepare_one(scope, &plus, &minus, &lp, de->d_name, &presets, changes, n_changes);
                        if (r < 0 &&
                            !IN_SET(r, -EEXIST, -ERFKILL, -EADDRNOTAVAIL, -EBADSLT, -EIDRM, -EUCLEAN, -ELOOP, -ENOENT, -EUNATCH, -EXDEV))
                                /* Ignore generated/transient/missing/invalid units when applying preset, propagate other errors.
                                 * Coordinate with install_changes_dump() above. */
                                return r;
                }
        }

        return execute_preset(file_flags, &plus, &minus, &lp, config_path, NULL, mode, changes, n_changes);
}

static UnitFileList* unit_file_list_free_one(UnitFileList *f) {
        if (!f)
                return NULL;

        free(f->path);
        return mfree(f);
}

Hashmap* unit_file_list_free(Hashmap *h) {
        return hashmap_free_with_destructor(h, unit_file_list_free_one);
}

DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);

int unit_file_get_list(
                LookupScope scope,
                const char *root_dir,
                Hashmap *h,
                char **states,
                char **patterns) {

        _cleanup_(lookup_paths_free) LookupPaths lp = {};
        int r;

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

        r = lookup_paths_init(&lp, scope, 0, root_dir);
        if (r < 0)
                return r;

        STRV_FOREACH(dirname, lp.search_path) {
                _cleanup_closedir_ DIR *d = NULL;

                d = opendir(*dirname);
                if (!d) {
                        if (errno == ENOENT)
                                continue;
                        if (IN_SET(errno, ENOTDIR, EACCES)) {
                                log_debug_errno(errno, "Failed to open \"%s\": %m", *dirname);
                                continue;
                        }

                        return -errno;
                }

                FOREACH_DIRENT(de, d, return -errno) {
                        _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;

                        if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
                                continue;

                        if (!strv_fnmatch_or_empty(patterns, de->d_name, FNM_NOESCAPE))
                                continue;

                        if (hashmap_get(h, de->d_name))
                                continue;

                        if (!IN_SET(de->d_type, DT_LNK, DT_REG))
                                continue;

                        f = new0(UnitFileList, 1);
                        if (!f)
                                return -ENOMEM;

                        f->path = path_make_absolute(de->d_name, *dirname);
                        if (!f->path)
                                return -ENOMEM;

                        r = unit_file_lookup_state(scope, &lp, de->d_name, &f->state);
                        if (r < 0)
                                f->state = UNIT_FILE_BAD;

                        if (!strv_isempty(states) &&
                            !strv_contains(states, unit_file_state_to_string(f->state)))
                                continue;

                        r = hashmap_put(h, basename(f->path), f);
                        if (r < 0)
                                return r;

                        f = NULL; /* prevent cleanup */
                }
        }

        return 0;
}

static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
        [UNIT_FILE_ENABLED]         = "enabled",
        [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
        [UNIT_FILE_LINKED]          = "linked",
        [UNIT_FILE_LINKED_RUNTIME]  = "linked-runtime",
        [UNIT_FILE_ALIAS]           = "alias",
        [UNIT_FILE_MASKED]          = "masked",
        [UNIT_FILE_MASKED_RUNTIME]  = "masked-runtime",
        [UNIT_FILE_STATIC]          = "static",
        [UNIT_FILE_DISABLED]        = "disabled",
        [UNIT_FILE_INDIRECT]        = "indirect",
        [UNIT_FILE_GENERATED]       = "generated",
        [UNIT_FILE_TRANSIENT]       = "transient",
        [UNIT_FILE_BAD]             = "bad",
};

DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);

static const char* const install_change_type_table[_INSTALL_CHANGE_TYPE_MAX] = {
        [INSTALL_CHANGE_SYMLINK]                 = "symlink",
        [INSTALL_CHANGE_UNLINK]                  = "unlink",
        [INSTALL_CHANGE_IS_MASKED]               = "masked",
        [INSTALL_CHANGE_IS_MASKED_GENERATOR]     = "masked by generator",
        [INSTALL_CHANGE_IS_DANGLING]             = "dangling",
        [INSTALL_CHANGE_DESTINATION_NOT_PRESENT] = "destination not present",
        [INSTALL_CHANGE_AUXILIARY_FAILED]        = "auxiliary unit failed",
};

DEFINE_STRING_TABLE_LOOKUP(install_change_type, InstallChangeType);

static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MODE_MAX] = {
        [UNIT_FILE_PRESET_FULL]         = "full",
        [UNIT_FILE_PRESET_ENABLE_ONLY]  = "enable-only",
        [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
};

DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);
