Пример #1
0
int can_sleep_disk(char **types) {
        char **type;
        int r;
        _cleanup_free_ char *p = NULL;

        if (strv_isempty(types))
                return true;

        /* If /sys is read-only we cannot sleep */
        if (access("/sys/power/disk", W_OK) < 0)
                return false;

        r = read_one_line_file("/sys/power/disk", &p);
        if (r < 0)
                return false;

        STRV_FOREACH(type, types) {
                const char *word, *state;
                size_t l, k;

                k = strlen(*type);
                FOREACH_WORD_SEPARATOR(word, l, p, WHITESPACE, state) {
                        if (l == k && memcmp(word, *type, l) == 0)
                                return true;

                        if (l == k + 2 &&
                            word[0] == '[' &&
                            memcmp(word + 1, *type, l - 2) == 0 &&
                            word[l-1] == ']')
                                return true;
                }
        }

        return false;
}
Пример #2
0
int safe_glob(const char *path, int flags, glob_t *pglob) {
        int k;

        /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
        assert(!(flags & GLOB_ALTDIRFUNC));

        if (!pglob->gl_closedir)
                pglob->gl_closedir = closedir_wrapper;
        if (!pglob->gl_readdir)
                pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot;
        if (!pglob->gl_opendir)
                pglob->gl_opendir = (void *(*)(const char *)) opendir;
        if (!pglob->gl_lstat)
                pglob->gl_lstat = lstat;
        if (!pglob->gl_stat)
                pglob->gl_stat = stat;

        errno = 0;
        k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob);

        if (k == GLOB_NOMATCH)
                return -ENOENT;
        if (k == GLOB_NOSPACE)
                return -ENOMEM;
        if (k != 0)
                return errno > 0 ? -errno : -EIO;
        if (strv_isempty(pglob->gl_pathv))
                return -ENOENT;

        return 0;
}
Пример #3
0
static void print_status_info(StatusInfo *i) {
        assert(i);

        if (strv_isempty(i->locale))
                puts("   System Locale: n/a\n");
        else {
                char **j;

                printf("   System Locale: %s\n", i->locale[0]);
                STRV_FOREACH(j, i->locale + 1)
                        printf("                  %s\n", *j);
        }

        printf("       VC Keymap: %s\n", strna(i->vconsole_keymap));
        if (!isempty(i->vconsole_keymap_toggle))
                printf("VC Toggle Keymap: %s\n", i->vconsole_keymap_toggle);

        printf("      X11 Layout: %s\n", strna(i->x11_layout));
        if (!isempty(i->x11_model))
                printf("       X11 Model: %s\n", i->x11_model);
        if (!isempty(i->x11_variant))
                printf("     X11 Variant: %s\n", i->x11_variant);
        if (!isempty(i->x11_options))
                printf("     X11 Options: %s\n", i->x11_options);
}
Пример #4
0
static int list_vconsole_keymaps(sd_bus *bus, char **args, unsigned n) {
        _cleanup_strv_free_ char **l = NULL;
        const char *dir;

        keymaps = set_new(string_hash_func, string_compare_func);
        if (!keymaps)
                return log_oom();

        NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS)
                nftw(dir, nftw_cb, 20, FTW_MOUNT|FTW_PHYS);

        l = set_get_strv(keymaps);
        if (!l) {
                set_free_free(keymaps);
                return log_oom();
        }

        set_free(keymaps);

        if (strv_isempty(l)) {
                log_error("Couldn't find any console keymaps.");
                return -ENOENT;
        }

        strv_sort(l);

        pager_open_if_enabled();

        strv_print(l);

        return 0;
}
Пример #5
0
int vconsole_write_data(Context *c) {
        _cleanup_strv_free_ char **l = NULL;
        struct stat st;
        int r;

        r = load_env_file(NULL, "/etc/vconsole.conf", NULL, &l);
        if (r < 0 && r != -ENOENT)
                return r;

        if (isempty(c->vc_keymap))
                l = strv_env_unset(l, "KEYMAP");
        else {
                _cleanup_free_ char *s = NULL;
                char **u;

                s = strappend("KEYMAP=", c->vc_keymap);
                if (!s)
                        return -ENOMEM;

                u = strv_env_set(l, s);
                if (!u)
                        return -ENOMEM;

                strv_free_and_replace(l, u);
        }

        if (isempty(c->vc_keymap_toggle))
                l = strv_env_unset(l, "KEYMAP_TOGGLE");
        else  {
                _cleanup_free_ char *s = NULL;
                char **u;

                s = strappend("KEYMAP_TOGGLE=", c->vc_keymap_toggle);
                if (!s)
                        return -ENOMEM;

                u = strv_env_set(l, s);
                if (!u)
                        return -ENOMEM;

                strv_free_and_replace(l, u);
        }

        if (strv_isempty(l)) {
                if (unlink("/etc/vconsole.conf") < 0)
                        return errno == ENOENT ? 0 : -errno;

                c->vc_mtime = USEC_INFINITY;
                return 0;
        }

        r = write_env_file_label("/etc/vconsole.conf", l);
        if (r < 0)
                return r;

        if (stat("/etc/vconsole.conf", &st) >= 0)
                c->vc_mtime = timespec_load(&st.st_mtim);

        return 0;
}
Пример #6
0
static int list_vconsole_keymaps(DBusConnection *bus, char **args, unsigned n) {
        char _cleanup_strv_free_ **l = NULL;
        char **i;

        keymaps = set_new(string_hash_func, string_compare_func);
        if (!keymaps)
                return log_oom();

        nftw("/usr/share/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
        nftw("/usr/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
        nftw("/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);

        l = set_get_strv(keymaps);
        if (!l) {
                set_free_free(keymaps);
                return log_oom();
        }

        set_free(keymaps);

        if (strv_isempty(l)) {
                log_error("Couldn't find any console keymaps.");
                return -ENOENT;
        }

        strv_sort(l);

        pager_open_if_enabled();

        STRV_FOREACH(i, l)
                puts(*i);


        return 0;
}
Пример #7
0
static int status_entries(const char *esp_path, sd_id128_t partition) {
        int r;

        _cleanup_(boot_config_free) BootConfig config = {};

        printf("Default Boot Entry:\n");

        r = boot_entries_load_config(esp_path, &config);
        if (r < 0)
                return log_error_errno(r, "Failed to load bootspec config from \"%s/loader\": %m",
                                       esp_path);

        if (config.default_entry < 0)
                printf("%zu entries, no entry suitable as default", config.n_entries);
        else {
                const BootEntry *e = &config.entries[config.default_entry];

                printf("        title: %s\n", boot_entry_title(e));
                if (e->version)
                        printf("      version: %s\n", e->version);
                if (e->kernel)
                        printf("        linux: %s\n", e->kernel);
                if (!strv_isempty(e->initrd)) {
                        _cleanup_free_ char *t;

                        t = strv_join(e->initrd, " ");
                        if (!t)
                                return log_oom();

                        printf("       initrd: %s\n", t);
                }
                if (!strv_isempty(e->options)) {
                        _cleanup_free_ char *t;

                        t = strv_join(e->options, " ");
                        if (!t)
                                return log_oom();

                        printf("      options: %s\n", t);
                }
                if (e->device_tree)
                        printf("   devicetree: %s\n", e->device_tree);
                puts("");
        }

        return 0;
}
Пример #8
0
static const char *dkr_pull_current_layer(DkrPull *i) {
        assert(i);

        if (strv_isempty(i->ancestry))
                return NULL;

        return i->ancestry[i->current_ancestry];
}
Пример #9
0
static int vconsole_write_data(Context *c) {
        int r;
        _cleanup_strv_free_ char **l = NULL;

        r = load_env_file("/etc/vconsole.conf", NULL, &l);
        if (r < 0 && r != -ENOENT)
                return r;

        if (isempty(c->vc_keymap))
                l = strv_env_unset(l, "KEYMAP");
        else {
                char *s, **u;

                s = strappend("KEYMAP=", c->vc_keymap);
                if (!s)
                        return -ENOMEM;

                u = strv_env_set(l, s);
                free(s);
                strv_free(l);

                if (!u)
                        return -ENOMEM;

                l = u;
        }

        if (isempty(c->vc_keymap_toggle))
                l = strv_env_unset(l, "KEYMAP_TOGGLE");
        else  {
                char *s, **u;

                s = strappend("KEYMAP_TOGGLE=", c->vc_keymap_toggle);
                if (!s)
                        return -ENOMEM;

                u = strv_env_set(l, s);
                free(s);
                strv_free(l);

                if (!u)
                        return -ENOMEM;

                l = u;
        }

        if (strv_isempty(l)) {
                if (unlink("/etc/vconsole.conf") < 0)
                        return errno == ENOENT ? 0 : -errno;

                return 0;
        }

        r = write_env_file_label("/etc/vconsole.conf", l);
        return r;
}
Пример #10
0
static char *strdup_structured_data(struct structured_data *sd)
{
	char *res, *tmp;

	if (strv_isempty(sd->params))
		return NULL;

	xasprintf(&res, "[%s %s]", sd->id,
			(tmp = strv_join(sd->params, " ")));
	free(tmp);
	return res;
}
Пример #11
0
static int determine_matches(const char *image, char **l, bool allow_any, char ***ret) {
        _cleanup_strv_free_ char **k = NULL;
        int r;

        /* Determine the matches to apply. If the list is empty we derive the match from the image name. If the list
         * contains exactly the "-" we return a wildcard list (which is the empty list), but only if this is expressly
         * permitted. */

        if (strv_isempty(l)) {
                char *prefix;

                r = extract_prefix(image, &prefix);
                if (r < 0)
                        return log_error_errno(r, "Failed to extract prefix of image name '%s': %m", image);

                if (!arg_quiet)
                        log_info("(Matching unit files with prefix '%s'.)", prefix);

                r = strv_consume(&k, prefix);
                if (r < 0)
                        return log_oom();

        } else if (strv_equal(l, STRV_MAKE("-"))) {

                if (!allow_any)
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                               "Refusing all unit file match.");

                if (!arg_quiet)
                        log_info("(Matching all unit files.)");
        } else {

                k = strv_copy(l);
                if (!k)
                        return log_oom();

                if (!arg_quiet) {
                        _cleanup_free_ char *joined = NULL;

                        joined = strv_join(k, "', '");
                        if (!joined)
                                return log_oom();

                        log_info("(Matching unit files with prefixes '%s'.)", joined);
                }
        }

        *ret = TAKE_PTR(k);

        return 0;
}
Пример #12
0
static int context_write_data_machine_info(Context *c) {

    static const char * const name[_PROP_MAX] = {
        [PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME",
        [PROP_ICON_NAME] = "ICON_NAME",
        [PROP_CHASSIS] = "CHASSIS",
        [PROP_DEPLOYMENT] = "DEPLOYMENT",
        [PROP_LOCATION] = "LOCATION",
    };

    _cleanup_strv_free_ char **l = NULL;
    int r, p;

    assert(c);

    r = load_env_file(NULL, "/etc/machine-info", NULL, &l);
    if (r < 0 && r != -ENOENT)
        return r;

    for (p = PROP_PRETTY_HOSTNAME; p <= PROP_LOCATION; p++) {
        _cleanup_free_ char *t = NULL;
        char **u;

        assert(name[p]);

        if (isempty(c->data[p]))  {
            strv_env_unset(l, name[p]);
            continue;
        }

        t = strjoin(name[p], "=", c->data[p], NULL);
        if (!t)
            return -ENOMEM;

        u = strv_env_set(l, t);
        if (!u)
            return -ENOMEM;

        strv_free(l);
        l = u;
    }

    if (strv_isempty(l)) {
        if (unlink("/etc/machine-info") < 0)
            return errno == ENOENT ? 0 : -errno;

        return 0;
    }

    return write_env_file_label("/etc/machine-info", l);
}
Пример #13
0
int locale_write_data(Context *c, char ***settings) {
        int r, p;
        _cleanup_strv_free_ char **l = NULL;

        /* Set values will be returned as strv in *settings on success. */

        r = load_env_file(NULL, "/etc/locale.conf", NULL, &l);
        if (r < 0 && r != -ENOENT)
                return r;

        for (p = 0; p < _VARIABLE_LC_MAX; p++) {
                _cleanup_free_ char *t = NULL;
                char **u;
                const char *name;

                name = locale_variable_to_string(p);
                assert(name);

                if (isempty(c->locale[p])) {
                        l = strv_env_unset(l, name);
                        continue;
                }

                if (asprintf(&t, "%s=%s", name, c->locale[p]) < 0)
                        return -ENOMEM;

                u = strv_env_set(l, t);
                if (!u)
                        return -ENOMEM;

                strv_free(l);
                l = u;
        }

        if (strv_isempty(l)) {
                if (unlink("/etc/locale.conf") < 0)
                        return errno == ENOENT ? 0 : -errno;

                return 0;
        }

        r = write_env_file_label("/etc/locale.conf", l);
        if (r < 0)
                return r;

        *settings = TAKE_PTR(l);
        return 0;
}
Пример #14
0
int locale_write_data(Context *c, char ***settings) {
        _cleanup_strv_free_ char **l = NULL;
        struct stat st;
        int r, p;

        /* Set values will be returned as strv in *settings on success. */

        for (p = 0; p < _VARIABLE_LC_MAX; p++) {
                _cleanup_free_ char *t = NULL;
                char **u;
                const char *name;

                name = locale_variable_to_string(p);
                assert(name);

                if (isempty(c->locale[p]))
                        continue;

                if (asprintf(&t, "%s=%s", name, c->locale[p]) < 0)
                        return -ENOMEM;

                u = strv_env_set(l, t);
                if (!u)
                        return -ENOMEM;

                strv_free_and_replace(l, u);
        }

        if (strv_isempty(l)) {
                if (unlink("/etc/locale.conf") < 0)
                        return errno == ENOENT ? 0 : -errno;

                c->locale_mtime = USEC_INFINITY;
                return 0;
        }

        r = write_env_file_label("/etc/locale.conf", l);
        if (r < 0)
                return r;

        *settings = TAKE_PTR(l);

        if (stat("/etc/locale.conf", &st) >= 0)
                c->locale_mtime = timespec_load(&st.st_mtim);

        return 0;
}
Пример #15
0
static int locale_write_data(Context *c) {
        int r, p;
        char **l = NULL;

        r = load_env_file("/etc/locale.conf", NULL, &l);
        if (r < 0 && r != -ENOENT)
                return r;

        for (p = 0; p < _LOCALE_MAX; p++) {
                char *t, **u;

                assert(names[p]);

                if (isempty(c->locale[p])) {
                        l = strv_env_unset(l, names[p]);
                        continue;
                }

                if (asprintf(&t, "%s=%s", names[p], c->locale[p]) < 0) {
                        strv_free(l);
                        return -ENOMEM;
                }

                u = strv_env_set(l, t);
                free(t);
                strv_free(l);

                if (!u)
                        return -ENOMEM;

                l = u;
        }

        if (strv_isempty(l)) {
                strv_free(l);

                if (unlink("/etc/locale.conf") < 0)
                        return errno == ENOENT ? 0 : -errno;

                return 0;
        }

        r = write_env_file_label("/etc/locale.conf", l);
        strv_free(l);

        return r;
}
Пример #16
0
static int generate_mask_symlinks(void) {
        char **u;
        int r = 0;

        if (strv_isempty(arg_mask))
                return 0;

        STRV_FOREACH(u, arg_mask) {
                _cleanup_free_ char *p = NULL;

                p = strjoin(arg_dest, "/", *u, NULL);
                if (!p)
                        return log_oom();

                if (symlink("/dev/null", p) < 0)
                        r = log_error_errno(errno,
                                            "Failed to create mask symlink %s: %m",
                                            p);
        }
Пример #17
0
static void test_config_parse_pass_environ(void) {
        /* int config_parse_pass_environ(
                 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) */
        int r;
        _cleanup_strv_free_ char **passenv = NULL;

        r = config_parse_pass_environ(NULL, "fake", 1, "section", 1,
                              "PassEnvironment", 0, "A B",
                              &passenv, NULL);
        assert_se(r >= 0);
        assert_se(strv_length(passenv) == 2);
        assert_se(streq(passenv[0], "A"));
        assert_se(streq(passenv[1], "B"));

        r = config_parse_pass_environ(NULL, "fake", 1, "section", 1,
                              "PassEnvironment", 0, "",
                              &passenv, NULL);
        assert_se(r >= 0);
        assert_se(strv_isempty(passenv));

        r = config_parse_pass_environ(NULL, "fake", 1, "section", 1,
                              "PassEnvironment", 0, "'invalid name' 'normal_name' A=1 \\",
                              &passenv, NULL);
        assert_se(r >= 0);
        assert_se(strv_length(passenv) == 1);
        assert_se(streq(passenv[0], "normal_name"));

}
Пример #18
0
int can_sleep_state(char **types) {
        char *w, *state, **type;
        int r;
        _cleanup_free_ char *p = NULL;

        if (strv_isempty(types))
                return true;

        /* If /sys is read-only we cannot sleep */
        if (access("/sys/power/state", W_OK) < 0)
                return false;

        r = read_one_line_file("/sys/power/state", &p);
        if (r < 0)
                return false;

        STRV_FOREACH(type, types) {
                size_t l, k;

                k = strlen(*type);
                FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state)
                        if (l == k && memcmp(w, *type, l) == 0)
                                return true;
        }
Пример #19
0
static int transient_service_set_properties(sd_bus_message *m, char **argv, const char *pty_path) {
    int r;

    assert(m);

    r = transient_unit_set_properties(m, arg_property);
    if (r < 0)
        return r;

    r = transient_kill_set_properties(m);
    if (r < 0)
        return r;

    r = transient_cgroup_set_properties(m);
    if (r < 0)
        return r;

    if (arg_wait) {
        r = sd_bus_message_append(m, "(sv)", "AddRef", "b", 1);
        if (r < 0)
            return r;
    }

    if (arg_remain_after_exit) {
        r = sd_bus_message_append(m, "(sv)", "RemainAfterExit", "b", arg_remain_after_exit);
        if (r < 0)
            return r;
    }

    if (arg_service_type) {
        r = sd_bus_message_append(m, "(sv)", "Type", "s", arg_service_type);
        if (r < 0)
            return r;
    }

    if (arg_exec_user) {
        r = sd_bus_message_append(m, "(sv)", "User", "s", arg_exec_user);
        if (r < 0)
            return r;
    }

    if (arg_exec_group) {
        r = sd_bus_message_append(m, "(sv)", "Group", "s", arg_exec_group);
        if (r < 0)
            return r;
    }

    if (arg_nice_set) {
        r = sd_bus_message_append(m, "(sv)", "Nice", "i", arg_nice);
        if (r < 0)
            return r;
    }

    if (pty_path) {
        const char *e;

        r = sd_bus_message_append(m,
                                  "(sv)(sv)(sv)(sv)",
                                  "StandardInput", "s", "tty",
                                  "StandardOutput", "s", "tty",
                                  "StandardError", "s", "tty",
                                  "TTYPath", "s", pty_path);
        if (r < 0)
            return r;

        e = getenv("TERM");
        if (e) {
            char *n;

            n = strjoina("TERM=", e);
            r = sd_bus_message_append(m,
                                      "(sv)",
                                      "Environment", "as", 1, n);
            if (r < 0)
                return r;
        }
    }

    if (!strv_isempty(arg_environment)) {
        r = sd_bus_message_open_container(m, 'r', "sv");
        if (r < 0)
            return r;

        r = sd_bus_message_append(m, "s", "Environment");
        if (r < 0)
            return r;

        r = sd_bus_message_open_container(m, 'v', "as");
        if (r < 0)
            return r;

        r = sd_bus_message_append_strv(m, arg_environment);
        if (r < 0)
            return r;

        r = sd_bus_message_close_container(m);
        if (r < 0)
            return r;

        r = sd_bus_message_close_container(m);
        if (r < 0)
            return r;
    }

    /* Exec container */
    {
        r = sd_bus_message_open_container(m, 'r', "sv");
        if (r < 0)
            return r;

        r = sd_bus_message_append(m, "s", "ExecStart");
        if (r < 0)
            return r;

        r = sd_bus_message_open_container(m, 'v', "a(sasb)");
        if (r < 0)
            return r;

        r = sd_bus_message_open_container(m, 'a', "(sasb)");
        if (r < 0)
            return r;

        r = sd_bus_message_open_container(m, 'r', "sasb");
        if (r < 0)
            return r;

        r = sd_bus_message_append(m, "s", argv[0]);
        if (r < 0)
            return r;

        r = sd_bus_message_append_strv(m, argv);
        if (r < 0)
            return r;

        r = sd_bus_message_append(m, "b", false);
        if (r < 0)
            return r;

        r = sd_bus_message_close_container(m);
        if (r < 0)
            return r;

        r = sd_bus_message_close_container(m);
        if (r < 0)
            return r;

        r = sd_bus_message_close_container(m);
        if (r < 0)
            return r;

        r = sd_bus_message_close_container(m);
        if (r < 0)
            return r;
    }

    return 0;
}
Пример #20
0
int locale_setup(char ***environment) {
        char **add;
        char *variables[_VARIABLE_MAX] = {};
        int r = 0, i;

        if (detect_container(NULL) <= 0) {
                r = parse_env_file("/proc/cmdline", WHITESPACE,
                                   "locale.LANG",              &variables[VARIABLE_LANG],
                                   "locale.LANGUAGE",          &variables[VARIABLE_LANGUAGE],
                                   "locale.LC_CTYPE",          &variables[VARIABLE_LC_CTYPE],
                                   "locale.LC_NUMERIC",        &variables[VARIABLE_LC_NUMERIC],
                                   "locale.LC_TIME",           &variables[VARIABLE_LC_TIME],
                                   "locale.LC_COLLATE",        &variables[VARIABLE_LC_COLLATE],
                                   "locale.LC_MONETARY",       &variables[VARIABLE_LC_MONETARY],
                                   "locale.LC_MESSAGES",       &variables[VARIABLE_LC_MESSAGES],
                                   "locale.LC_PAPER",          &variables[VARIABLE_LC_PAPER],
                                   "locale.LC_NAME",           &variables[VARIABLE_LC_NAME],
                                   "locale.LC_ADDRESS",        &variables[VARIABLE_LC_ADDRESS],
                                   "locale.LC_TELEPHONE",      &variables[VARIABLE_LC_TELEPHONE],
                                   "locale.LC_MEASUREMENT",    &variables[VARIABLE_LC_MEASUREMENT],
                                   "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
                                   NULL);

                if (r < 0 && r != -ENOENT)
                        log_warning("Failed to read /proc/cmdline: %s", strerror(-r));
        }

        /* Hmm, nothing set on the kernel cmd line? Then let's
         * try /etc/locale.conf */
        if (r <= 0) {
                r = parse_env_file("/etc/locale.conf", NEWLINE,
                                   "LANG",              &variables[VARIABLE_LANG],
                                   "LANGUAGE",          &variables[VARIABLE_LANGUAGE],
                                   "LC_CTYPE",          &variables[VARIABLE_LC_CTYPE],
                                   "LC_NUMERIC",        &variables[VARIABLE_LC_NUMERIC],
                                   "LC_TIME",           &variables[VARIABLE_LC_TIME],
                                   "LC_COLLATE",        &variables[VARIABLE_LC_COLLATE],
                                   "LC_MONETARY",       &variables[VARIABLE_LC_MONETARY],
                                   "LC_MESSAGES",       &variables[VARIABLE_LC_MESSAGES],
                                   "LC_PAPER",          &variables[VARIABLE_LC_PAPER],
                                   "LC_NAME",           &variables[VARIABLE_LC_NAME],
                                   "LC_ADDRESS",        &variables[VARIABLE_LC_ADDRESS],
                                   "LC_TELEPHONE",      &variables[VARIABLE_LC_TELEPHONE],
                                   "LC_MEASUREMENT",    &variables[VARIABLE_LC_MEASUREMENT],
                                   "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
                                   NULL);

                if (r < 0 && r != -ENOENT)
                        log_warning("Failed to read /etc/locale.conf: %s", strerror(-r));
        }

        if (r <= 0) {
                r = parse_env_file("/etc/default/locale", NEWLINE,
                                   "LANG",              &variables[VARIABLE_LANG],
                                   "LANGUAGE",          &variables[VARIABLE_LANGUAGE],
                                   "LC_CTYPE",          &variables[VARIABLE_LC_CTYPE],
                                   "LC_NUMERIC",        &variables[VARIABLE_LC_NUMERIC],
                                   "LC_TIME",           &variables[VARIABLE_LC_TIME],
                                   "LC_COLLATE",        &variables[VARIABLE_LC_COLLATE],
                                   "LC_MONETARY",       &variables[VARIABLE_LC_MONETARY],
                                   "LC_MESSAGES",       &variables[VARIABLE_LC_MESSAGES],
                                   "LC_PAPER",          &variables[VARIABLE_LC_PAPER],
                                   "LC_NAME",           &variables[VARIABLE_LC_NAME],
                                   "LC_ADDRESS",        &variables[VARIABLE_LC_ADDRESS],
                                   "LC_TELEPHONE",      &variables[VARIABLE_LC_TELEPHONE],
                                   "LC_MEASUREMENT",    &variables[VARIABLE_LC_MEASUREMENT],
                                   "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
                                   NULL);

                if (r < 0 && r != -ENOENT)
                        log_warning("Failed to read /etc/default/locale: %s", strerror(-r));
        }

        add = NULL;
        for (i = 0; i < _VARIABLE_MAX; i++) {
                char *s;

                if (!variables[i])
                        continue;

                s = strjoin(variable_names[i], "=", variables[i], NULL);
                if (!s) {
                        r = -ENOMEM;
                        goto finish;
                }

                if (strv_consume(&add, s) < 0) {
                        r = -ENOMEM;
                        goto finish;
                }
        }

        if (!strv_isempty(add)) {
                char **e;

                e = strv_env_merge(2, *environment, add);
                if (!e) {
                        r = -ENOMEM;
                        goto finish;
                }

                strv_free(*environment);
                *environment = e;
        }

        r = 0;

finish:
        strv_free(add);

        for (i = 0; i < _VARIABLE_MAX; i++)
                free(variables[i]);

        return r;
}
Пример #21
0
static void test_strv_split_empty(void) {
        _cleanup_strv_free_ char **l = NULL;

        l = strv_split("", WHITESPACE);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split("", NULL);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", NULL, 0);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", NULL, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", WHITESPACE, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", WHITESPACE, SPLIT_QUOTES | SPLIT_RELAX);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split("    ", WHITESPACE);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split("    ", NULL);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", NULL, 0);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", WHITESPACE, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", NULL, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", NULL, SPLIT_QUOTES | SPLIT_RELAX);
        assert_se(l);
        assert_se(strv_isempty(l));
}
Пример #22
0
int lookup_paths_init(
                LookupPaths *p,
                SystemdRunningAs running_as,
                bool personal,
                const char *generator,
                const char *generator_early,
                const char *generator_late) {

        const char *e;

        assert(p);

        /* First priority is whatever has been passed to us via env
         * vars */
        e = getenv("SYSTEMD_UNIT_PATH");
        if (e) {
                p->unit_path = path_split_and_make_absolute(e);
                if (!p->unit_path)
                        return -ENOMEM;
        } else
                p->unit_path = NULL;

        if (strv_isempty(p->unit_path)) {
                /* Nothing is set, so let's figure something out. */
                strv_free(p->unit_path);

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

                if (running_as == SYSTEMD_USER) {

                        if (personal)
                                p->unit_path = user_dirs(generator, generator_early, generator_late);
                        else
                                p->unit_path = strv_new(
                                                /* If you modify this you also want to modify
                                                 * systemduserunitpath= in systemd.pc.in, and
                                                 * the arrays in user_dirs() above! */
                                                STRV_IFNOTNULL(generator_early),
                                                USER_CONFIG_UNIT_PATH,
                                                "/etc/systemd/user",
                                                "/run/systemd/user",
                                                STRV_IFNOTNULL(generator),
                                                "/usr/local/lib/systemd/user",
                                                "/usr/local/share/systemd/user",
                                                USER_DATA_UNIT_PATH,
                                                "/usr/lib/systemd/user",
                                                "/usr/share/systemd/user",
                                                STRV_IFNOTNULL(generator_late),
                                                NULL);

                        if (!p->unit_path)
                                return -ENOMEM;

                } else {
                        p->unit_path = strv_new(
                                        /* If you modify this you also want to modify
                                         * systemdsystemunitpath= in systemd.pc.in! */
                                        STRV_IFNOTNULL(generator_early),
                                        SYSTEM_CONFIG_UNIT_PATH,
                                        "/etc/systemd/system",
                                        "/run/systemd/system",
                                        STRV_IFNOTNULL(generator),
                                        "/usr/local/lib/systemd/system",
                                        SYSTEM_DATA_UNIT_PATH,
                                        "/usr/lib/systemd/system",
#ifdef HAVE_SPLIT_USR
                                        "/lib/systemd/system",
#endif
                                        STRV_IFNOTNULL(generator_late),
                                        NULL);

                        if (!p->unit_path)
                                return -ENOMEM;
                }
        }

        if (!path_strv_canonicalize(p->unit_path))
                return -ENOMEM;

        strv_uniq(p->unit_path);

        if (!strv_isempty(p->unit_path)) {
                _cleanup_free_ char *t = strv_join(p->unit_path, "\n\t");
                if (!t)
                        return -ENOMEM;
                log_debug("Looking for unit files in (higher priority first):\n\t%s", t);
        } else {
                log_debug("Ignoring unit files.");
                strv_free(p->unit_path);
                p->unit_path = NULL;
        }

        if (running_as == SYSTEMD_SYSTEM) {
#ifdef HAVE_SYSV_COMPAT
                /* /etc/init.d/ compatibility does not matter to users */

                e = getenv("SYSTEMD_SYSVINIT_PATH");
                if (e) {
                        p->sysvinit_path = path_split_and_make_absolute(e);
                        if (!p->sysvinit_path)
                                return -ENOMEM;
                } else
                        p->sysvinit_path = NULL;

                if (strv_isempty(p->sysvinit_path)) {
                        strv_free(p->sysvinit_path);

                        p->sysvinit_path = strv_new(
                                        SYSTEM_SYSVINIT_PATH,     /* /etc/init.d/ */
                                        NULL);
                        if (!p->sysvinit_path)
                                return -ENOMEM;
                }

                e = getenv("SYSTEMD_SYSVRCND_PATH");
                if (e) {
                        p->sysvrcnd_path = path_split_and_make_absolute(e);
                        if (!p->sysvrcnd_path)
                                return -ENOMEM;
                } else
                        p->sysvrcnd_path = NULL;

                if (strv_isempty(p->sysvrcnd_path)) {
                        strv_free(p->sysvrcnd_path);

                        p->sysvrcnd_path = strv_new(
                                        SYSTEM_SYSVRCND_PATH,     /* /etc/rcN.d/ */
                                        NULL);
                        if (!p->sysvrcnd_path)
                                return -ENOMEM;
                }

                if (!path_strv_canonicalize(p->sysvinit_path))
                        return -ENOMEM;

                if (!path_strv_canonicalize(p->sysvrcnd_path))
                        return -ENOMEM;

                strv_uniq(p->sysvinit_path);
                strv_uniq(p->sysvrcnd_path);

                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;
}
Пример #23
0
int main(int argc, char *argv[]) {
        _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
        _cleanup_(decrypted_image_unrefp) DecryptedImage *di = NULL;
        _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
        int r;

        log_parse_environment();
        log_open();

        r = parse_argv(argc, argv);
        if (r <= 0)
                goto finish;

        r = loop_device_make_by_path(arg_image, (arg_flags & DISSECT_IMAGE_READ_ONLY) ? O_RDONLY : O_RDWR, &d);
        if (r < 0) {
                log_error_errno(r, "Failed to set up loopback device: %m");
                goto finish;
        }

        if (!arg_root_hash) {
                r = root_hash_load(arg_image, &arg_root_hash, &arg_root_hash_size);
                if (r < 0) {
                        log_error_errno(r, "Failed to read root hash file for %s: %m", arg_image);
                        goto finish;
                }
        }

        r = dissect_image(d->fd, arg_root_hash, arg_root_hash_size, arg_flags, &m);
        if (r == -ENOPKG) {
                log_error_errno(r, "Couldn't identify a suitable partition table or file system in %s.", arg_image);
                goto finish;
        }
        if (r == -EADDRNOTAVAIL) {
                log_error_errno(r, "No root partition for specified root hash found in %s.", arg_image);
                goto finish;
        }
        if (r == -ENOTUNIQ) {
                log_error_errno(r, "Multiple suitable root partitions found in image %s.", arg_image);
                goto finish;
        }
        if (r == -ENXIO) {
                log_error_errno(r, "No suitable root partition found in image %s.", arg_image);
                goto finish;
        }
        if (r == -EPROTONOSUPPORT) {
                log_error_errno(r, "Device %s is loopback block device with partition scanning turned off, please turn it on.", arg_image);
                goto finish;
        }
        if (r < 0) {
                log_error_errno(r, "Failed to dissect image: %m");
                goto finish;
        }

        switch (arg_action) {

        case ACTION_DISSECT: {
                unsigned i;

                for (i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
                        DissectedPartition *p = m->partitions + i;
                        int k;

                        if (!p->found)
                                continue;

                        printf("Found %s '%s' partition",
                               p->rw ? "writable" : "read-only",
                               partition_designator_to_string(i));

                        if (!sd_id128_is_null(p->uuid))
                                printf(" (UUID " SD_ID128_FORMAT_STR ")", SD_ID128_FORMAT_VAL(p->uuid));

                        if (p->fstype)
                                printf(" of type %s", p->fstype);

                        if (p->architecture != _ARCHITECTURE_INVALID)
                                printf(" for %s", architecture_to_string(p->architecture));

                        k = PARTITION_VERITY_OF(i);
                        if (k >= 0)
                                printf(" %s verity", m->partitions[k].found ? "with" : "without");

                        if (p->partno >= 0)
                                printf(" on partition #%i", p->partno);

                        if (p->node)
                                printf(" (%s)", p->node);

                        putchar('\n');
                }

                r = dissected_image_acquire_metadata(m);
                if (r < 0) {
                        log_error_errno(r, "Failed to acquire image metadata: %m");
                        goto finish;
                }

                if (m->hostname)
                        printf("  Hostname: %s\n", m->hostname);

                if (!sd_id128_is_null(m->machine_id))
                        printf("Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->machine_id));

                if (!strv_isempty(m->machine_info)) {
                        char **p, **q;

                        STRV_FOREACH_PAIR(p, q, m->machine_info)
                                printf("%s %s=%s\n",
                                       p == m->machine_info ? "Mach. Info:" : "           ",
                                       *p, *q);
                }

                if (!strv_isempty(m->os_release)) {
                        char **p, **q;

                        STRV_FOREACH_PAIR(p, q, m->os_release)
                                printf("%s %s=%s\n",
                                       p == m->os_release ? "OS Release:" : "           ",
                                       *p, *q);
                }

                break;
        }

        case ACTION_MOUNT:
                r = dissected_image_decrypt_interactively(m, NULL, arg_root_hash, arg_root_hash_size, arg_flags, &di);
                if (r < 0)
                        goto finish;

                r = dissected_image_mount(m, arg_path, UID_INVALID, arg_flags);
                if (r < 0) {
                        log_error_errno(r, "Failed to mount image: %m");
                        goto finish;
                }

                if (di) {
                        r = decrypted_image_relinquish(di);
                        if (r < 0) {
                                log_error_errno(r, "Failed to relinquish DM devices: %m");
                                goto finish;
                        }
                }

                loop_device_relinquish(d);
                break;

        default:
                assert_not_reached("Unknown action.");
        }

finish:
        free(arg_root_hash);
        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
Пример #24
0
static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) {
        _cleanup_fclose_ FILE *f = NULL;
        _cleanup_strv_free_ char **list = NULL;
        char line[LINE_MAX];
        enum {
                NONE,
                MODELS,
                LAYOUTS,
                VARIANTS,
                OPTIONS
        } state = NONE, look_for;
        int r;

        if (n > 2) {
                log_error("Too many arguments.");
                return -EINVAL;
        }

        f = fopen("/usr/share/X11/xkb/rules/base.lst", "re");
        if (!f) {
                log_error("Failed to open keyboard mapping list. %m");
                return -errno;
        }

        if (streq(args[0], "list-x11-keymap-models"))
                look_for = MODELS;
        else if (streq(args[0], "list-x11-keymap-layouts"))
                look_for = LAYOUTS;
        else if (streq(args[0], "list-x11-keymap-variants"))
                look_for = VARIANTS;
        else if (streq(args[0], "list-x11-keymap-options"))
                look_for = OPTIONS;
        else
                assert_not_reached("Wrong parameter");

        FOREACH_LINE(line, f, break) {
                char *l, *w;

                l = strstrip(line);

                if (isempty(l))
                        continue;

                if (l[0] == '!') {
                        if (startswith(l, "! model"))
                                state = MODELS;
                        else if (startswith(l, "! layout"))
                                state = LAYOUTS;
                        else if (startswith(l, "! variant"))
                                state = VARIANTS;
                        else if (startswith(l, "! option"))
                                state = OPTIONS;
                        else
                                state = NONE;

                        continue;
                }

                if (state != look_for)
                        continue;

                w = l + strcspn(l, WHITESPACE);

                if (n > 1) {
                        char *e;

                        if (*w == 0)
                                continue;

                        *w = 0;
                        w++;
                        w += strspn(w, WHITESPACE);

                        e = strchr(w, ':');
                        if (!e)
                                continue;

                        *e = 0;

                        if (!streq(w, args[1]))
                                continue;
                } else
                        *w = 0;

                 r = strv_extend(&list, l);
                 if (r < 0)
                         return log_oom();
        }

        if (strv_isempty(list)) {
                log_error("Couldn't find any entries.");
                return -ENOENT;
        }

        strv_sort(list);
        strv_uniq(list);

        pager_open_if_enabled();

        strv_print(list);
        return 0;
}
Пример #25
0
static int write_data_vconsole(void) {
        int r;
        char **l = NULL;

        r = load_env_file("/etc/vconsole.conf", &l);
        if (r < 0 && r != -ENOENT)
                return r;

        if (isempty(state.vc_keymap))
                l = strv_env_unset(l, "KEYMAP");
        else {
                char *s, **u;

                s = strappend("KEYMAP=", state.vc_keymap);
                if (!s) {
                        strv_free(l);
                        return -ENOMEM;
                }

                u = strv_env_set(l, s);
                free(s);
                strv_free(l);

                if (!u)
                        return -ENOMEM;

                l = u;
        }

        if (isempty(state.vc_keymap_toggle))
                l = strv_env_unset(l, "KEYMAP_TOGGLE");
        else  {
                char *s, **u;

                s = strappend("KEYMAP_TOGGLE=", state.vc_keymap_toggle);
                if (!s) {
                        strv_free(l);
                        return -ENOMEM;
                }

                u = strv_env_set(l, s);
                free(s);
                strv_free(l);

                if (!u)
                        return -ENOMEM;

                l = u;
        }

        if (strv_isempty(l)) {
                strv_free(l);

                if (unlink("/etc/vconsole.conf") < 0)
                        return errno == ENOENT ? 0 : -errno;

                return 0;
        }

        r = write_env_file("/etc/vconsole.conf", l);
        strv_free(l);

        return r;
}
Пример #26
0
static int parse_ancestry(const void *payload, size_t size, char ***ret) {
        _cleanup_free_ char *buf = NULL;
        void *json_state = NULL;
        const char *p;
        enum {
                STATE_BEGIN,
                STATE_ITEM,
                STATE_COMMA,
                STATE_END,
        } state = STATE_BEGIN;
        _cleanup_strv_free_ char **l = NULL;
        size_t n = 0, allocated = 0;

        if (size <= 0)
                return -EBADMSG;

        if (memchr(payload, 0, size))
                return -EBADMSG;

        buf = strndup(payload, size);
        if (!buf)
                return -ENOMEM;

        p = buf;
        for (;;) {
                _cleanup_free_ char *str;
                union json_value v = {};
                int t;

                t = json_tokenize(&p, &str, &v, &json_state, NULL);
                if (t < 0)
                        return t;

                switch (state) {

                case STATE_BEGIN:
                        if (t == JSON_ARRAY_OPEN)
                                state = STATE_ITEM;
                        else
                                return -EBADMSG;

                        break;

                case STATE_ITEM:
                        if (t == JSON_STRING) {
                                if (!dkr_id_is_valid(str))
                                        return -EBADMSG;

                                if (n+1 > LAYERS_MAX)
                                        return -EFBIG;

                                if (!GREEDY_REALLOC(l, allocated, n + 2))
                                        return -ENOMEM;

                                l[n++] = str;
                                str = NULL;
                                l[n] = NULL;

                                state = STATE_COMMA;

                        } else if (t == JSON_ARRAY_CLOSE)
                                state = STATE_END;
                        else
                                return -EBADMSG;

                        break;

                case STATE_COMMA:
                        if (t == JSON_COMMA)
                                state = STATE_ITEM;
                        else if (t == JSON_ARRAY_CLOSE)
                                state = STATE_END;
                        else
                                return -EBADMSG;
                        break;

                case STATE_END:
                        if (t == JSON_END) {

                                if (strv_isempty(l))
                                        return -EBADMSG;

                                if (!strv_is_uniq(l))
                                        return -EBADMSG;

                                l = strv_reverse(l);

                                *ret = l;
                                l = NULL;
                                return 0;
                        } else
                                return -EBADMSG;
                }

        }
}
Пример #27
0
static int start_transient_timer(
    sd_bus *bus,
    char **argv) {

    _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
    _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
    _cleanup_free_ char *timer = NULL, *service = NULL;
    const char *object = NULL;
    int r;

    assert(bus);
    assert(argv);

    r = bus_wait_for_jobs_new(bus, &w);
    if (r < 0)
        return log_oom();

    if (arg_unit) {
        switch (unit_name_to_type(arg_unit)) {

        case UNIT_SERVICE:
            service = strdup(arg_unit);
            if (!service)
                return log_oom();

            r = unit_name_change_suffix(service, ".timer", &timer);
            if (r < 0)
                return log_error_errno(r, "Failed to change unit suffix: %m");
            break;

        case UNIT_TIMER:
            timer = strdup(arg_unit);
            if (!timer)
                return log_oom();

            r = unit_name_change_suffix(timer, ".service", &service);
            if (r < 0)
                return log_error_errno(r, "Failed to change unit suffix: %m");
            break;

        default:
            r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".service", &service);
            if (r < 0)
                return log_error_errno(r, "Failed to mangle unit name: %m");

            r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".timer", &timer);
            if (r < 0)
                return log_error_errno(r, "Failed to mangle unit name: %m");

            break;
        }
    } else {
        r = make_unit_name(bus, UNIT_SERVICE, &service);
        if (r < 0)
            return r;

        r = unit_name_change_suffix(service, ".timer", &timer);
        if (r < 0)
            return log_error_errno(r, "Failed to change unit suffix: %m");
    }

    r = sd_bus_message_new_method_call(
            bus,
            &m,
            "org.freedesktop.systemd1",
            "/org/freedesktop/systemd1",
            "org.freedesktop.systemd1.Manager",
            "StartTransientUnit");
    if (r < 0)
        return bus_log_create_error(r);

    r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
    if (r < 0)
        return bus_log_create_error(r);

    /* Name and Mode */
    r = sd_bus_message_append(m, "ss", timer, "fail");
    if (r < 0)
        return bus_log_create_error(r);

    /* Properties */
    r = sd_bus_message_open_container(m, 'a', "(sv)");
    if (r < 0)
        return bus_log_create_error(r);

    r = transient_timer_set_properties(m);
    if (r < 0)
        return bus_log_create_error(r);

    r = sd_bus_message_close_container(m);
    if (r < 0)
        return bus_log_create_error(r);

    r = sd_bus_message_open_container(m, 'a', "(sa(sv))");
    if (r < 0)
        return bus_log_create_error(r);

    if (!strv_isempty(argv)) {
        r = sd_bus_message_open_container(m, 'r', "sa(sv)");
        if (r < 0)
            return bus_log_create_error(r);

        r = sd_bus_message_append(m, "s", service);
        if (r < 0)
            return bus_log_create_error(r);

        r = sd_bus_message_open_container(m, 'a', "(sv)");
        if (r < 0)
            return bus_log_create_error(r);

        r = transient_service_set_properties(m, argv, NULL);
        if (r < 0)
            return bus_log_create_error(r);

        r = sd_bus_message_close_container(m);
        if (r < 0)
            return bus_log_create_error(r);

        r = sd_bus_message_close_container(m);
        if (r < 0)
            return bus_log_create_error(r);
    }

    r = sd_bus_message_close_container(m);
    if (r < 0)
        return bus_log_create_error(r);

    polkit_agent_open_if_enabled();

    r = sd_bus_call(bus, m, 0, &error, &reply);
    if (r < 0) {
        log_error("Failed to start transient timer unit: %s", bus_error_message(&error, -r));
        return r;
    }

    r = sd_bus_message_read(reply, "o", &object);
    if (r < 0)
        return bus_log_parse_error(r);

    r = bus_wait_for_jobs_one(w, object, arg_quiet);
    if (r < 0)
        return r;

    if (!arg_quiet) {
        log_info("Running timer as unit: %s", timer);
        if (argv[0])
            log_info("Will run service as unit: %s", service);
    }

    return 0;
}
Пример #28
0
int lookup_paths_init(
                LookupPaths *p,
                SystemdRunningAs running_as,
                bool personal,
                const char *root_dir,
                const char *generator,
                const char *generator_early,
                const char *generator_late) {

        const char *e;
        bool append = false; /* Add items from SYSTEMD_UNIT_PATH before normal directories */

        assert(p);

        /* First priority is whatever has been passed to us via env
         * vars */
        e = getenv("SYSTEMD_UNIT_PATH");
        if (e) {
                if (endswith(e, ":")) {
                        e = strndupa(e, strlen(e) - 1);
                        append = true;
                }

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

                p->unit_path = path_split_and_make_absolute(e);
                if (!p->unit_path)
                        return -ENOMEM;
        } else
                p->unit_path = NULL;

        if (!p->unit_path || append) {
                /* Let's figure something out. */

                _cleanup_strv_free_ char **unit_path;
                int r;

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

                if (running_as == SYSTEMD_USER) {
                        if (personal)
                                unit_path = user_dirs(generator, generator_early, generator_late);
                        else
                                unit_path = strv_new(
                                        /* If you modify this you also want to modify
                                         * systemduserunitpath= in systemd.pc.in, and
                                         * the arrays in user_dirs() above! */
                                        STRV_IFNOTNULL(generator_early),
                                        USER_CONFIG_UNIT_PATH,
                                        "/etc/systemd/user",
                                        "/run/systemd/user",
                                        STRV_IFNOTNULL(generator),
                                        "/usr/local/lib/systemd/user",
                                        "/usr/local/share/systemd/user",
                                        USER_DATA_UNIT_PATH,
                                        "/usr/lib/systemd/user",
                                        "/usr/share/systemd/user",
                                        STRV_IFNOTNULL(generator_late),
                                        NULL);
                } else
                        unit_path = strv_new(
                                /* If you modify this you also want to modify
                                 * systemdsystemunitpath= in systemd.pc.in! */
                                STRV_IFNOTNULL(generator_early),
                                SYSTEM_CONFIG_UNIT_PATH,
                                "/etc/systemd/system",
                                "/run/systemd/system",
                                STRV_IFNOTNULL(generator),
                                "/usr/local/lib/systemd/system",
                                SYSTEM_DATA_UNIT_PATH,
                                "/usr/lib/systemd/system",
#ifdef HAVE_SPLIT_USR
                                "/lib/systemd/system",
#endif
                                STRV_IFNOTNULL(generator_late),
                                NULL);

                if (!unit_path)
                        return -ENOMEM;

                r = strv_extend_strv(&p->unit_path, unit_path);
                if (r < 0)
                        return r;
        }

        if (!path_strv_resolve_uniq(p->unit_path, root_dir))
                return -ENOMEM;

        if (!strv_isempty(p->unit_path)) {
                _cleanup_free_ char *t = strv_join(p->unit_path, "\n\t");
                if (!t)
                        return -ENOMEM;
                log_debug("Looking for unit files in (higher priority first):\n\t%s", t);
        } else {
                log_debug("Ignoring unit files.");
                strv_free(p->unit_path);
                p->unit_path = NULL;
        }

        if (running_as == SYSTEMD_SYSTEM) {
#ifdef HAVE_SYSV_COMPAT
                /* /etc/init.d/ compatibility does not matter to users */

                e = getenv("SYSTEMD_SYSVINIT_PATH");
                if (e) {
                        p->sysvinit_path = path_split_and_make_absolute(e);
                        if (!p->sysvinit_path)
                                return -ENOMEM;
                } else
                        p->sysvinit_path = NULL;

                if (strv_isempty(p->sysvinit_path)) {
                        strv_free(p->sysvinit_path);

                        p->sysvinit_path = strv_new(
                                        SYSTEM_SYSVINIT_PATH,     /* /etc/init.d/ */
                                        NULL);
                        if (!p->sysvinit_path)
                                return -ENOMEM;
                }

                e = getenv("SYSTEMD_SYSVRCND_PATH");
                if (e) {
                        p->sysvrcnd_path = path_split_and_make_absolute(e);
                        if (!p->sysvrcnd_path)
                                return -ENOMEM;
                } else
                        p->sysvrcnd_path = NULL;

                if (strv_isempty(p->sysvrcnd_path)) {
                        strv_free(p->sysvrcnd_path);

                        p->sysvrcnd_path = strv_new(
                                        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;
}