locale-util.c revision bb15fafe9cd815fe5bf9eae84c08aead2eb98fd7
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek This file is part of systemd.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek Copyright 2014 Lennart Poettering
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek (at your option) any later version.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
cc3773810855956bad92337cee8fa193584ab62eLennart Poetteringstatic int add_locales_from_archive(Set *locales) {
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering /* Stolen from glibc... */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* Serial number. */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* Name hash table. */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* String table. */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* Table with locale records. */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* MD5 sum hash table. */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* Hash value of the name. */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* Offset of the name in the string table. */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek /* Offset of the locale record. */
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return errno == ENOENT ? 0 : -errno;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (st.st_size < (off_t) sizeof(struct locarhead))
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek h = (const struct locarhead *) p;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek h->namehash_offset + h->namehash_size > st.st_size ||
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek h->string_offset + h->string_size > st.st_size ||
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek h->locrectab_offset + h->locrectab_size > st.st_size ||
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek h->sumhash_offset + h->sumhash_size > st.st_size) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek e = (const struct namehashent*) ((const uint8_t*) p + h->namehash_offset);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek for (i = 0; i < h->namehash_size; i++) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (!utf8_is_valid((char*) p + e[i].name_offset))
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek z = strdup((char*) p + e[i].name_offset);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic int add_locales_from_libdir (Set *locales) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek _cleanup_closedir_ DIR *dir = NULL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek dir = opendir("/usr/lib/locale");
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek return errno == ENOENT ? 0 : -errno;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek FOREACH_DIRENT(entry, dir, return -errno) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (r < 0 && r != -EEXIST)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek _cleanup_set_free_ Set *locales = NULL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek _cleanup_strv_free_ char **l = NULL;
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek locales = set_new(&string_hash_ops);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek r = add_locales_from_archive(locales);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek if (r < 0 && r != -ENOENT)
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek r = add_locales_from_libdir(locales);
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekbool locale_is_valid(const char *name) {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmekstatic const char * const locale_variable_table[_VARIABLE_LC_MAX] = {
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LANGUAGE] = "LANGUAGE",
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LC_CTYPE] = "LC_CTYPE",
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LC_NUMERIC] = "LC_NUMERIC",
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LC_COLLATE] = "LC_COLLATE",
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LC_MONETARY] = "LC_MONETARY",
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LC_MESSAGES] = "LC_MESSAGES",
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LC_PAPER] = "LC_PAPER",
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE",
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT",
2b3ab29de466ae6bd7c3243a5a48c7291cc2af0aZbigniew Jędrzejewski-Szmek [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION"