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; }
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; }
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; }
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; }
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; }
int r; keymaps = set_new(&string_hash_ops); if (!keymaps) return -ENOMEM; NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) { r = nftw(dir, nftw_cb, 20, FTW_PHYS|FTW_ACTIONRETVAL); if (r == FTW_STOP) log_debug("Directory not found %s", dir); else if (r < 0) log_debug_errno(r, "Can't add keymap: %m"); } l = set_get_strv(keymaps); if (!l) { set_free_free(keymaps); return -ENOMEM; } set_free(keymaps); if (strv_isempty(l)) return -ENOENT; strv_sort(l); *ret = TAKE_PTR(l); return 0;