Exemple #1
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;
}
Exemple #2
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;
}
Exemple #3
0
int get_locales(char ***ret) {
        _cleanup_set_free_ Set *locales = NULL;
        _cleanup_strv_free_ char **l = NULL;
        int r;

        locales = set_new(&string_hash_ops);
        if (!locales)
                return -ENOMEM;

        r = add_locales_from_archive(locales);
        if (r < 0 && r != -ENOENT)
                return r;

        r = add_locales_from_libdir(locales);
        if (r < 0)
                return r;

        l = set_get_strv(locales);
        if (!l)
                return -ENOMEM;

        strv_sort(l);

        *ret = TAKE_PTR(l);

        return 0;
}
Exemple #4
0
static int list_locales(sd_bus *bus, char **args, unsigned n) {
        _cleanup_set_free_ Set *locales;
        _cleanup_strv_free_ char **l = NULL;
        int r;

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

        r = add_locales_from_archive(locales);
        if (r < 0 && r != -ENOENT)
                return r;

        r = add_locales_from_libdir(locales);
        if (r < 0)
                return r;

        l = set_get_strv(locales);
        if (!l)
                return log_oom();

        strv_sort(l);

        pager_open_if_enabled();

        strv_print(l);

        return 0;
}
Exemple #5
0
int get_timezones(char ***ret) {
        _cleanup_fclose_ FILE *f = NULL;
        _cleanup_strv_free_ char **zones = NULL;
        size_t n_zones = 0, n_allocated = 0;

        assert(ret);

        zones = strv_new("UTC", NULL);
        if (!zones)
                return -ENOMEM;

        n_allocated = 2;
        n_zones = 1;

        f = fopen("/usr/share/zoneinfo/zone.tab", "re");
        if (f) {
                char l[LINE_MAX];

                FOREACH_LINE(l, f, return -errno) {
                        char *p, *w;
                        size_t k;

                        p = strstrip(l);

                        if (isempty(p) || *p == '#')
                                continue;

                        /* Skip over country code */
                        p += strcspn(p, WHITESPACE);
                        p += strspn(p, WHITESPACE);

                        /* Skip over coordinates */
                        p += strcspn(p, WHITESPACE);
                        p += strspn(p, WHITESPACE);

                        /* Found timezone name */
                        k = strcspn(p, WHITESPACE);
                        if (k <= 0)
                                continue;

                        w = strndup(p, k);
                        if (!w)
                                return -ENOMEM;

                        if (!GREEDY_REALLOC(zones, n_allocated, n_zones + 2)) {
                                free(w);
                                return -ENOMEM;
                        }

                        zones[n_zones++] = w;
                        zones[n_zones] = NULL;
                }

                strv_sort(zones);

        } else if (errno != ENOENT)
Exemple #6
0
static int driver_list_activatable_names(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
        _cleanup_strv_free_ char **names = NULL;
        int r;

        r = sd_bus_list_names(bus, NULL, &names);
        if (r < 0)
                return r;

        /* Let's sort the names list to make it stable */
        strv_sort(names);

        return return_strv(bus, m, names);
}
Exemple #7
0
static void test_hashmap_get_strv(void) {
        Hashmap *m;
        char **strv;
        char *val1, *val2, *val3, *val4;

        log_info("%s", __func__);

        val1 = strdup("val1");
        assert_se(val1);
        val2 = strdup("val2");
        assert_se(val2);
        val3 = strdup("val3");
        assert_se(val3);
        val4 = strdup("val4");
        assert_se(val4);

        m = hashmap_new(&string_hash_ops);

        hashmap_put(m, "key 1", val1);
        hashmap_put(m, "key 2", val2);
        hashmap_put(m, "key 3", val3);
        hashmap_put(m, "key 4", val4);

        strv = hashmap_get_strv(m);

#ifndef ORDERED
        strv = strv_sort(strv);
#endif

        assert_se(streq(strv[0], "val1"));
        assert_se(streq(strv[1], "val2"));
        assert_se(streq(strv[2], "val3"));
        assert_se(streq(strv[3], "val4"));

        strv_free(strv);

        hashmap_free(m);
}
Exemple #8
0
static int list_locales(DBusConnection *bus, char **args, unsigned n) {
        /* Stolen from glibc... */

        struct locarhead {
                uint32_t magic;
                /* Serial number.  */
                uint32_t serial;
                /* Name hash table.  */
                uint32_t namehash_offset;
                uint32_t namehash_used;
                uint32_t namehash_size;
                /* String table.  */
                uint32_t string_offset;
                uint32_t string_used;
                uint32_t string_size;
                /* Table with locale records.  */
                uint32_t locrectab_offset;
                uint32_t locrectab_used;
                uint32_t locrectab_size;
                /* MD5 sum hash table.  */
                uint32_t sumhash_offset;
                uint32_t sumhash_used;
                uint32_t sumhash_size;
        };

        struct namehashent {
                /* Hash value of the name.  */
                uint32_t hashval;
                /* Offset of the name in the string table.  */
                uint32_t name_offset;
                /* Offset of the locale record.  */
                uint32_t locrec_offset;
        };

        const struct locarhead *h;
        const struct namehashent *e;
        const void *p = MAP_FAILED;
        _cleanup_close_ int fd = -1;
        _cleanup_strv_free_ char **l = NULL;
        char **j;
        Set *locales;
        size_t sz = 0;
        struct stat st;
        unsigned i;
        int r;

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

        fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC);
        if (fd < 0) {
                log_error("Failed to open locale archive: %m");
                r = -errno;
                goto finish;
        }

        if (fstat(fd, &st) < 0) {
                log_error("fstat() failed: %m");
                r = -errno;
                goto finish;
        }

        if (!S_ISREG(st.st_mode)) {
                log_error("Archive file is not regular");
                r = -EBADMSG;
                goto finish;
        }

        if (st.st_size < (off_t) sizeof(struct locarhead)) {
                log_error("Archive has invalid size");
                r = -EBADMSG;
                goto finish;
        }

        p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
        if (p == MAP_FAILED) {
                log_error("Failed to map archive: %m");
                r = -errno;
                goto finish;
        }

        h = (const struct locarhead *) p;
        if (h->magic != 0xde020109 ||
            h->namehash_offset + h->namehash_size > st.st_size ||
            h->string_offset + h->string_size > st.st_size ||
            h->locrectab_offset + h->locrectab_size > st.st_size ||
            h->sumhash_offset + h->sumhash_size > st.st_size) {
                log_error("Invalid archive file.");
                r = -EBADMSG;
                goto finish;
        }

        e = (const struct namehashent*) ((const uint8_t*) p + h->namehash_offset);
        for (i = 0; i < h->namehash_size; i++) {
                char *z;

                if (e[i].locrec_offset == 0)
                        continue;

                z = strdup((char*) p + e[i].name_offset);
                if (!z) {
                        r = log_oom();
                        goto finish;
                }

                r = set_put(locales, z);
                if (r < 0) {
                        free(z);
                        log_error("Failed to add locale: %s", strerror(-r));
                        goto finish;
                }
        }

        l = set_get_strv(locales);
        if (!l) {
                r = log_oom();
                goto finish;
        }

        set_free(locales);
        locales = NULL;

        strv_sort(l);

        pager_open_if_enabled();

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

        r = 0;

finish:
        if (p != MAP_FAILED)
                munmap((void*) p, sz);

        set_free_free(locales);

        return r;
}
Exemple #9
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;
}
Exemple #10
0
static int list_timezones(DBusConnection *bus, char **args, unsigned n) {
        _cleanup_fclose_ FILE *f = NULL;
        _cleanup_strv_free_ char **zones = NULL;
        size_t n_zones = 0;
        char **i;

        assert(args);
        assert(n == 1);

        f = fopen("/usr/share/zoneinfo/zone.tab", "re");
        if (!f) {
                log_error("Failed to open timezone database: %m");
                return -errno;
        }

        for (;;) {
                char l[LINE_MAX], *p, **z, *w;
                size_t k;

                if (!fgets(l, sizeof(l), f)) {
                        if (feof(f))
                                break;

                        log_error("Failed to read timezone database: %m");
                        return -errno;
                }

                p = strstrip(l);

                if (isempty(p) || *p == '#')
                        continue;


                /* Skip over country code */
                p += strcspn(p, WHITESPACE);
                p += strspn(p, WHITESPACE);

                /* Skip over coordinates */
                p += strcspn(p, WHITESPACE);
                p += strspn(p, WHITESPACE);

                /* Found timezone name */
                k = strcspn(p, WHITESPACE);
                if (k <= 0)
                        continue;

                w = strndup(p, k);
                if (!w)
                        return log_oom();

                z = realloc(zones, sizeof(char*) * (n_zones + 2));
                if (!z) {
                        free(w);
                        return log_oom();
                }

                zones = z;
                zones[n_zones++] = w;
        }

        if (zones)
                zones[n_zones] = NULL;

        pager_open_if_enabled();

        strv_sort(zones);
        STRV_FOREACH(i, zones)
                puts(*i);

        return 0;
}
Exemple #11
0
static int enumerate_dir_d(
                OrderedHashmap *top,
                OrderedHashmap *bottom,
                OrderedHashmap *drops,
                const char *toppath, const char *drop) {

        _cleanup_free_ char *unit = NULL;
        _cleanup_free_ char *path = NULL;
        _cleanup_strv_free_ char **list = NULL;
        char **file;
        char *c;
        int r;

        assert(!endswith(drop, "/"));

        path = strjoin(toppath, "/", drop);
        if (!path)
                return -ENOMEM;

        log_debug("Looking at %s", path);

        unit = strdup(drop);
        if (!unit)
                return -ENOMEM;

        c = strrchr(unit, '.');
        if (!c)
                return -EINVAL;
        *c = 0;

        r = get_files_in_directory(path, &list);
        if (r < 0)
                return log_error_errno(r, "Failed to enumerate %s: %m", path);

        strv_sort(list);

        STRV_FOREACH(file, list) {
                OrderedHashmap *h;
                int k;
                char *p;
                char *d;

                if (!endswith(*file, ".conf"))
                        continue;

                p = strjoin(path, "/", *file);
                if (!p)
                        return -ENOMEM;
                d = p + strlen(toppath) + 1;

                log_debug("Adding at top: %s %s %s", d, special_glyph(ARROW), p);
                k = ordered_hashmap_put(top, d, p);
                if (k >= 0) {
                        p = strdup(p);
                        if (!p)
                                return -ENOMEM;
                        d = p + strlen(toppath) + 1;
                } else if (k != -EEXIST) {
                        free(p);
                        return k;
                }

                log_debug("Adding at bottom: %s %s %s", d, special_glyph(ARROW), p);
                free(ordered_hashmap_remove(bottom, d));
                k = ordered_hashmap_put(bottom, d, p);
                if (k < 0) {
                        free(p);
                        return k;
                }

                h = ordered_hashmap_get(drops, unit);
                if (!h) {
                        h = ordered_hashmap_new(&string_hash_ops);
                        if (!h)
                                return -ENOMEM;
                        ordered_hashmap_put(drops, unit, h);
                        unit = strdup(unit);
                        if (!unit)
                                return -ENOMEM;
                }

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

                log_debug("Adding to drops: %s %s %s %s %s",
                          unit, special_glyph(ARROW), basename(p), special_glyph(ARROW), p);
                k = ordered_hashmap_put(h, basename(p), p);
                if (k < 0) {
                        free(p);
                        if (k != -EEXIST)
                                return k;
                }
        }