Пример #1
0
static int network_get_link_strv(const char *key, int ifindex, char ***ret) {
        _cleanup_free_ char *p = NULL, *s = NULL;
        _cleanup_strv_free_ char **a = NULL;
        int r;

        assert_return(ifindex > 0, -EINVAL);
        assert_return(ret, -EINVAL);

        if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
                return -ENOMEM;

        r = parse_env_file(p, NEWLINE, key, &s, NULL);
        if (r == -ENOENT)
                return -ENODATA;
        if (r < 0)
                return r;
        if (isempty(s)) {
                *ret = NULL;
                return 0;
        }

        a = strv_split(s, " ");
        if (!a)
                return -ENOMEM;

        strv_uniq(a);
        r = strv_length(a);

        *ret = a;
        a = NULL;

        return r;
}
Пример #2
0
static int network_get_strv(const char *key, char ***ret) {
        _cleanup_strv_free_ char **a = NULL;
        _cleanup_free_ char *s = NULL;
        int r;

        assert_return(ret, -EINVAL);

        r = parse_env_file("/run/systemd/netif/state", NEWLINE, key, &s, NULL);
        if (r == -ENOENT)
                return -ENODATA;
        if (r < 0)
                return r;
        if (isempty(s)) {
                *ret = NULL;
                return 0;
        }

        a = strv_split(s, " ");
        if (!a)
                return -ENOMEM;

        strv_uniq(a);
        r = strv_length(a);

        *ret = a;
        a = NULL;

        return r;
}
Пример #3
0
static int network_link_get_strv(int ifindex, const char *key, char ***ret) {
        char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
        _cleanup_strv_free_ char **a = NULL;
        _cleanup_free_ char *s = NULL;
        int r;

        assert_return(ifindex > 0, -EINVAL);
        assert_return(ret, -EINVAL);

        xsprintf(path, "/run/systemd/netif/links/%i", ifindex);
        r = parse_env_file(path, NEWLINE, key, &s, NULL);
        if (r == -ENOENT)
                return -ENODATA;
        if (r < 0)
                return r;
        if (isempty(s)) {
                *ret = NULL;
                return 0;
        }

        a = strv_split(s, " ");
        if (!a)
                return -ENOMEM;

        strv_uniq(a);
        r = strv_length(a);

        *ret = TAKE_PTR(a);

        return r;
}
Пример #4
0
static int uid_get_array(uid_t uid, const char *variable, char ***array) {
        _cleanup_free_ char *p = NULL, *s = NULL;
        char **a;
        int r;

        assert(variable);

        r = file_of_uid(uid, &p);
        if (r < 0)
                return r;

        r = parse_env_file(p, NEWLINE, variable, &s, NULL);
        if (r == -ENOENT || (r >= 0 && isempty(s))) {
                if (array)
                        *array = NULL;
                return 0;
        }
        if (r < 0)
                return r;

        a = strv_split(s, " ");
        if (!a)
                return -ENOMEM;

        strv_uniq(a);
        r = strv_length(a);

        if (array)
                *array = a;
        else
                strv_free(a);

        return r;
}
Пример #5
0
int sd_bus_list_names(sd_bus *bus, char ***l) {
        _cleanup_bus_message_unref_ sd_bus_message *reply1 = NULL, *reply2 = NULL;
        char **x = NULL;
        int r;

        if (!bus)
                return -EINVAL;
        if (!l)
                return -EINVAL;

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.DBus",
                        "/",
                        "org.freedesktop.DBus",
                        "ListNames",
                        NULL,
                        &reply1,
                        NULL);
        if (r < 0)
                return r;

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.DBus",
                        "/",
                        "org.freedesktop.DBus",
                        "ListActivatableNames",
                        NULL,
                        &reply2,
                        NULL);
        if (r < 0)
                return r;

        r = bus_message_read_strv_extend(reply1, &x);
        if (r < 0) {
                strv_free(x);
                return r;
        }

        r = bus_message_read_strv_extend(reply2, &x);
        if (r < 0) {
                strv_free(x);
                return r;
        }

        *l = strv_uniq(x);
        return 0;
}
Пример #6
0
static int uid_get_array(uid_t uid, const char *variable, char ***array) {
        _cleanup_free_ char *p = NULL, *s = NULL;
        char **a;
        int r;

        if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0)
                return -ENOMEM;

        r = parse_env_file(p, NEWLINE,
                           variable, &s,
                           NULL);
        if (r < 0) {
                if (r == -ENOENT) {
                        if (array)
                                *array = NULL;
                        return 0;
                }

                return r;
        }

        if (!s) {
                if (array)
                        *array = NULL;
                return 0;
        }

        a = strv_split(s, " ");

        if (!a)
                return -ENOMEM;

        strv_uniq(a);
        r = strv_length(a);

        if (array)
                *array = a;
        else
                strv_free(a);

        return r;
}
Пример #7
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;
}
Пример #8
0
int main(int argc, char *argv[]) {
    _cleanup_strv_free_ char **disks_done = NULL;
    _cleanup_fclose_ FILE *f = NULL;
    unsigned n = 0;
    int r = EXIT_FAILURE, r2 = EXIT_FAILURE;
    char **i;

    if (argc > 1 && argc != 4) {
        log_error("This program takes three or no arguments.");
        return EXIT_FAILURE;
    }

    if (argc > 1)
        arg_dest = argv[1];

    log_set_target(LOG_TARGET_SAFE);
    log_parse_environment();
    log_open();

    umask(0022);

    if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
        goto cleanup;

    if (!arg_enabled) {
        r = r2 = EXIT_SUCCESS;
        goto cleanup;
    }

    strv_uniq(arg_disks);

    if (arg_read_crypttab) {
        struct stat st;

        f = fopen("/etc/crypttab", "re");
        if (!f) {
            if (errno == ENOENT)
                r = EXIT_SUCCESS;
            else
                log_error("Failed to open /etc/crypttab: %m");

            goto next;
        }

        if (fstat(fileno(f), &st) < 0) {
            log_error("Failed to stat /etc/crypttab: %m");
            goto next;
        }

        /* If we readd support for specifying passphrases
         * directly in crypttabe we should upgrade the warning
         * below, though possibly only if a passphrase is
         * specified directly. */
        if (st.st_mode & 0005)
            log_debug("/etc/crypttab is world-readable. This is usually not a good idea.");

        for (;;) {
            char line[LINE_MAX], *l;
            _cleanup_free_ char *name = NULL, *device = NULL, *password = NULL, *options = NULL;
            int k;

            if (!fgets(line, sizeof(line), f))
                break;

            n++;

            l = strstrip(line);
            if (*l == '#' || *l == 0)
                continue;

            k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options);
            if (k < 2 || k > 4) {
                log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);
                continue;
            }

            /*
              If options are specified on the kernel commandline, let them override
              the ones from crypttab.
            */
            STRV_FOREACH(i, arg_options) {
                _cleanup_free_ char *proc_uuid = NULL, *proc_options = NULL;
                const char *p = *i;

                k = sscanf(p, "%m[0-9a-fA-F-]=%ms", &proc_uuid, &proc_options);
                if (k == 2 && streq(proc_uuid, device + 5)) {
                    free(options);
                    options = strdup(p);
                    if (!proc_options) {
                        log_oom();
                        goto cleanup;
                    }
                }
            }

            if (arg_disks) {
                /*
                  If luks UUIDs are specified on the kernel command line, use them as a filter
                  for /etc/crypttab and only generate units for those.
                */
                STRV_FOREACH(i, arg_disks) {
                    _cleanup_free_ char *proc_device = NULL, *proc_name = NULL;
                    const char *p = *i;

                    if (startswith(p, "luks-"))
                        p += 5;

                    proc_name = strappend("luks-", p);
                    proc_device = strappend("UUID=", p);

                    if (!proc_name || !proc_device) {
                        log_oom();
                        goto cleanup;
                    }

                    if (streq(proc_device, device) || streq(proc_name, name)) {
                        if (create_disk(name, device, password, options) < 0)
                            goto cleanup;

                        if (strv_extend(&disks_done, p) < 0) {
                            log_oom();
                            goto cleanup;
                        }
                    }
                }
            } else if (create_disk(name, device, password, options) < 0)
Пример #9
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;
}