path-lookup.c revision aa08982d62cf45b59ea6a06c915391f5db1fb86e
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2010 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <assert.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <stdlib.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <stdio.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <string.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <unistd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "mkdir.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "strv.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "path-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "path-lookup.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringint user_config_home(char **config_home) {
c34255bdb217c2a1d3ac6348252437ab8be9ca46Lennart Poettering const char *e;
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering char *r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering e = getenv("XDG_CONFIG_HOME");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (e) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = strappend(e, "/systemd/user");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!r)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *config_home = r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt } else {
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt const char *home;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering home = getenv("HOME");
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poettering if (home) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = strappend(home, "/.config/systemd/user");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (!r)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return -ENOMEM;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
afc6adb5ec7e73bc13156c43f52fb015cd80cc68Lennart Poettering *config_home = r;
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering return 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
cde93897cdefdd7c7f66c400a61e42ceee5f6a46Lennart Poettering}
cde93897cdefdd7c7f66c400a61e42ceee5f6a46Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint user_runtime_dir(char **runtime_dir) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *e;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char *r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering e = getenv("XDG_RUNTIME_DIR");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (e) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = strappend(e, "/systemd/user");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!r)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *runtime_dir = r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering}
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringstatic char** user_dirs(
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *generator,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *generator_early,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *generator_late) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char * const config_unit_paths[] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering USER_CONFIG_UNIT_PATH,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/etc/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char * const runtime_unit_path = "/run/systemd/user";
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char * const data_unit_paths[] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/usr/local/lib/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/usr/local/share/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering USER_DATA_UNIT_PATH,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/usr/lib/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/usr/share/systemd/user",
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt NULL
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *home, *e;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *config_home = NULL, *runtime_dir = NULL, *data_home = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char **r = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Implement the mechanisms defined in
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering *
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering * We look in both the config and the data dirs because we
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering * want to encourage that distributors ship their unit files
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering * as data, and allow overriding as configuration.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt if (user_config_home(&config_home) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto fail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (user_runtime_dir(&runtime_dir) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto fail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering home = getenv("HOME");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering e = getenv("XDG_CONFIG_DIRS");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (e) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering config_dirs = strv_split(e, ":");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!config_dirs)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto fail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* We don't treat /etc/xdg/systemd here as the spec
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * suggests because we assume that that is a link to
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering * /etc/systemd/ anyway. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering e = getenv("XDG_DATA_HOME");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (e) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (asprintf(&data_home, "%s/systemd/user", e) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto fail;
76b543756ef69ce69784d571aefe8de65eaeb331Lennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt } else if (home) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (asprintf(&data_home, "%s/.local/share/systemd/user", home) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto fail;
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering }
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt e = getenv("XDG_DATA_DIRS");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (e)
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering data_dirs = strv_split(e, ":");
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt else
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt data_dirs = strv_new("/usr/local/share",
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "/usr/share",
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering NULL);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (!data_dirs)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt goto fail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering /* Now merge everything we found. */
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering if (generator_early)
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering if (strv_extend(&r, generator_early) < 0)
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering goto fail;
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering if (config_home)
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering if (strv_extend(&r, config_home) < 0)
ebeccf9eecf5939a2ef772c3160e89efcad96194Lennart Poettering goto fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering if (!strv_isempty(config_dirs))
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (strv_extend_strv_concat(&r, config_dirs, "/systemd/user") < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (strv_extend_strv(&r, (char**) config_unit_paths) < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (runtime_dir)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (strv_extend(&r, runtime_dir) < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt goto fail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (strv_extend(&r, runtime_unit_path) < 0)
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering goto fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (generator)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (strv_extend(&r, generator) < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (data_home)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (strv_extend(&r, data_home) < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt goto fail;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
943aca8efb39453e3994ccdd1e08534b788c5aeeLennart Poettering if (!strv_isempty(data_dirs))
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (strv_extend_strv_concat(&r, data_dirs, "/systemd/user") < 0)
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering goto fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (strv_extend_strv(&r, (char**) data_unit_paths) < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (generator_late)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (strv_extend(&r, generator_late) < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt goto fail;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!path_strv_make_absolute_cwd(r))
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto fail;
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringfail:
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering strv_free(r);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return NULL;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidtint lookup_paths_init(
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt LookupPaths *p,
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering SystemdRunningAs running_as,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering bool personal,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *root_dir,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *generator,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *generator_early,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *generator_late) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *e;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering bool append = false; /* Add items from SYSTEMD_UNIT_PATH before normal directories */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(p);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* First priority is whatever has been passed to us via env
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * vars */
5bb658a1784a0fd4f0f32adb4b1fb636ff503f7dKay Sievers e = getenv("SYSTEMD_UNIT_PATH");
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (e) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (endswith(e, ":")) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering e = strndupa(e, strlen(e) - 1);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering append = true;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt }
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* FIXME: empty components in other places should be
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * rejected. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->unit_path = path_split_and_make_absolute(e);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!p->unit_path)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->unit_path = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!p->unit_path || append) {
71fda00f320379f5cbee8e118848de98caaa229dLennart Poettering /* Let's figure something out. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_strv_free_ char **unit_path;
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* For the user units we include share/ in the search
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * path in order to comply with the XDG basedir spec.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * For the system stuff we avoid such nonsense. OTOH
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * we include /lib in the search path for the system
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * stuff but avoid it for user stuff. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (running_as == SYSTEMD_USER) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (personal)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering unit_path = user_dirs(generator, generator_early, generator_late);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unit_path = strv_new(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* If you modify this you also want to modify
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * systemduserunitpath= in systemd.pc.in, and
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * the arrays in user_dirs() above! */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering STRV_IFNOTNULL(generator_early),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering USER_CONFIG_UNIT_PATH,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/etc/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/run/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering STRV_IFNOTNULL(generator),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/usr/local/lib/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/usr/local/share/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering USER_DATA_UNIT_PATH,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/usr/lib/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/usr/share/systemd/user",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering STRV_IFNOTNULL(generator_late),
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unit_path = strv_new(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* If you modify this you also want to modify
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * systemdsystemunitpath= in systemd.pc.in! */
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering STRV_IFNOTNULL(generator_early),
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering SYSTEM_CONFIG_UNIT_PATH,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/etc/systemd/system",
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering "/run/systemd/system",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering STRV_IFNOTNULL(generator),
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering "/usr/local/lib/systemd/system",
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering SYSTEM_DATA_UNIT_PATH,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/usr/lib/systemd/system",
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering#ifdef HAVE_SPLIT_USR
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering "/lib/systemd/system",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#endif
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering STRV_IFNOTNULL(generator_late),
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering NULL);
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering if (!unit_path)
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering return -ENOMEM;
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = strv_extend_strv(&p->unit_path, unit_path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!path_strv_resolve_uniq(p->unit_path, root_dir))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!strv_isempty(p->unit_path)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *t = strv_join(p->unit_path, "\n\t");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!t)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_debug("Looking for unit files in (higher priority first):\n\t%s", t);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_debug("Ignoring unit files.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering strv_free(p->unit_path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->unit_path = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (running_as == SYSTEMD_SYSTEM) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#ifdef HAVE_SYSV_COMPAT
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* /etc/init.d/ compatibility does not matter to users */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering e = getenv("SYSTEMD_SYSVINIT_PATH");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (e) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->sysvinit_path = path_split_and_make_absolute(e);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!p->sysvinit_path)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->sysvinit_path = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (strv_isempty(p->sysvinit_path)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering strv_free(p->sysvinit_path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt p->sysvinit_path = strv_new(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering SYSTEM_SYSVINIT_PATH, /* /etc/init.d/ */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!p->sysvinit_path)
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek return -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering e = getenv("SYSTEMD_SYSVRCND_PATH");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (e) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->sysvrcnd_path = path_split_and_make_absolute(e);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!p->sysvrcnd_path)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek } else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->sysvrcnd_path = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (strv_isempty(p->sysvrcnd_path)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering strv_free(p->sysvrcnd_path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p->sysvrcnd_path = strv_new(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering SYSTEM_SYSVRCND_PATH, /* /etc/rcN.d/ */
NULL);
if (!p->sysvrcnd_path)
return -ENOMEM;
}
if (!path_strv_resolve_uniq(p->sysvinit_path, root_dir))
return -ENOMEM;
if (!path_strv_resolve_uniq(p->sysvrcnd_path, root_dir))
return -ENOMEM;
if (!strv_isempty(p->sysvinit_path)) {
_cleanup_free_ char *t = strv_join(p->sysvinit_path, "\n\t");
if (!t)
return -ENOMEM;
log_debug("Looking for SysV init scripts in:\n\t%s", t);
} else {
log_debug("Ignoring SysV init scripts.");
strv_free(p->sysvinit_path);
p->sysvinit_path = NULL;
}
if (!strv_isempty(p->sysvrcnd_path)) {
_cleanup_free_ char *t =
strv_join(p->sysvrcnd_path, "\n\t");
if (!t)
return -ENOMEM;
log_debug("Looking for SysV rcN.d links in:\n\t%s", t);
} else {
log_debug("Ignoring SysV rcN.d links.");
strv_free(p->sysvrcnd_path);
p->sysvrcnd_path = NULL;
}
#else
log_debug("SysV init scripts and rcN.d links support disabled");
#endif
}
return 0;
}
void lookup_paths_free(LookupPaths *p) {
assert(p);
strv_free(p->unit_path);
p->unit_path = NULL;
#ifdef HAVE_SYSV_COMPAT
strv_free(p->sysvinit_path);
strv_free(p->sysvrcnd_path);
p->sysvinit_path = p->sysvrcnd_path = NULL;
#endif
}