[systemd-commits] 2 commits - src/locale src/shared

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Mon Nov 18 17:47:56 PST 2013


 src/locale/localectl.c |    8 -
 src/locale/localed.c   |  229 ++++++++++++++++++++++++++-----------------------
 src/shared/def.h       |   13 ++
 3 files changed, 140 insertions(+), 110 deletions(-)

New commits:
commit 0732ef7acf37473847992888bcb6446726d9d877
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Nov 18 13:42:57 2013 -0500

    localed: match converted keymaps before legacy
    
    Before, X11 keymap fr-pc105-oss would be converted to fr,
    even though fr-oss exists. Now, if
    /usr/lib/kbd/keymaps/xkb/<layout>[-<variant>].map[.gz] exists,
    <layout>[-<variant>] will be used as the console keymap,
    falling back to the legacy mappings otherwise.
    
    % sudo localectl set-x11-keymap pl pc105
    % localectl
       System Locale: LANG=en_US.UTF-8
           VC Keymap: pl                      (was pl2 before)
          X11 Layout: pl
           X11 Model: pc105
    % sudo localectl set-x11-keymap fr pc105 oss
    % localectl
       System Locale: LANG=en_US.UTF-8
           VC Keymap: fr-oss                  (was fr before)
          X11 Layout: fr
           X11 Model: pc105
         X11 Variant: oss
    % sudo localectl set-x11-keymap fr pc105
    % localectl
       System Locale: LANG=en_US.UTF-8
           VC Keymap: fr
          X11 Layout: fr
           X11 Model: pc105
    % sudo localectl set-x11-keymap gb
    % localectl
       System Locale: LANG=en_US.UTF-8
           VC Keymap: gb                     (was uk before)
          X11 Layout: gb

diff --git a/src/locale/localectl.c b/src/locale/localectl.c
index f7fea48..76a53f6 100644
--- a/src/locale/localectl.c
+++ b/src/locale/localectl.c
@@ -42,6 +42,7 @@
 #include "set.h"
 #include "path-util.h"
 #include "utf8.h"
+#include "def.h"
 
 static bool arg_no_pager = false;
 static bool arg_ask_password = true;
@@ -437,15 +438,14 @@ static int nftw_cb(
 
 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();
 
-        nftw("/usr/share/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
-        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);
+        NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS)
+                nftw(dir, nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
 
         l = set_get_strv(keymaps);
         if (!l) {
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 5275ef3..1248f20 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -633,8 +633,114 @@ static int vconsole_convert_to_x11(Context *c, sd_bus *bus) {
         return 0;
 }
 
+static int find_converted_keymap(Context *c, char **new_keymap) {
+        const char *dir;
+        _cleanup_free_ char *n;
+
+        if (c->x11_variant)
+                n = strjoin(c->x11_layout, "-", c->x11_variant, NULL);
+        else
+                n = strdup(c->x11_layout);
+        if (!n)
+                return -ENOMEM;
+
+        NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
+                _cleanup_free_ char *p = NULL, *pz = NULL;
+
+                p = strjoin(dir, "xkb/", n, ".map", NULL);
+                pz = strjoin(dir, "xkb/", n, ".map.gz", NULL);
+                if (!p || !pz)
+                        return -ENOMEM;
+
+                if (access(p, F_OK) == 0 || access(pz, F_OK) == 0) {
+                        *new_keymap = n;
+                        n = NULL;
+                        return 1;
+                }
+        }
+
+        return 0;
+}
+
+static int find_legacy_keymap(Context *c, char **new_keymap) {
+        _cleanup_fclose_ FILE *f;
+        unsigned n = 0;
+        unsigned best_matching = 0;
+
+
+        f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
+        if (!f)
+                return -errno;
+
+        for (;;) {
+                _cleanup_strv_free_ char **a = NULL;
+                unsigned matching = 0;
+                int r;
+
+                r = read_next_mapping(f, &n, &a);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
+
+                /* Determine how well matching this entry is */
+                if (streq_ptr(c->x11_layout, a[1]))
+                        /* If we got an exact match, this is best */
+                        matching = 10;
+                else {
+                        size_t x;
+
+                        x = strcspn(c->x11_layout, ",");
+
+                        /* We have multiple X layouts, look for an
+                         * entry that matches our key with everything
+                         * but the first layout stripped off. */
+                        if (x > 0 &&
+                            strlen(a[1]) == x &&
+                            strneq(c->x11_layout, a[1], x))
+                                matching = 5;
+                        else  {
+                                size_t w;
+
+                                /* If that didn't work, strip off the
+                                 * other layouts from the entry, too */
+                                w = strcspn(a[1], ",");
+
+                                if (x > 0 && x == w &&
+                                    memcmp(c->x11_layout, a[1], x) == 0)
+                                        matching = 1;
+                        }
+                }
+
+                if (matching > 0 &&
+                    streq_ptr(c->x11_model, a[2])) {
+                        matching++;
+
+                        if (streq_ptr(c->x11_variant, a[3])) {
+                                matching++;
+
+                                if (streq_ptr(c->x11_options, a[4]))
+                                        matching++;
+                        }
+                }
+
+                /* The best matching entry so far, then let's save that */
+                if (matching > best_matching) {
+                        best_matching = matching;
+
+                        free(*new_keymap);
+                        *new_keymap = strdup(a[0]);
+                        if (!*new_keymap)
+                                return -ENOMEM;
+                }
+        }
+
+        return 0;
+}
+
 static int x11_convert_to_vconsole(Context *c, sd_bus *bus) {
         bool modified = false;
+        int r;
 
         assert(bus);
 
@@ -646,79 +752,15 @@ static int x11_convert_to_vconsole(Context *c, sd_bus *bus) {
 
                 context_free_x11(c);
         } else {
-                _cleanup_fclose_ FILE *f;
-                unsigned n = 0;
-                unsigned best_matching = 0;
                 char *new_keymap = NULL;
 
-                f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
-                if (!f)
-                        return -errno;
-
-                for (;;) {
-                        _cleanup_strv_free_ char **a = NULL;
-                        unsigned matching = 0;
-                        int r;
-
-                        r = read_next_mapping(f, &n, &a);
+                r = find_converted_keymap(c, &new_keymap);
+                if (r < 0)
+                        return r;
+                else if (r == 0) {
+                        r = find_legacy_keymap(c, &new_keymap);
                         if (r < 0)
                                 return r;
-                        if (r == 0)
-                                break;
-
-                        /* Determine how well matching this entry is */
-                        if (streq_ptr(c->x11_layout, a[1]))
-                                /* If we got an exact match, this is best */
-                                matching = 10;
-                        else {
-                                size_t x;
-
-                                x = strcspn(c->x11_layout, ",");
-
-                                /* We have multiple X layouts, look
-                                 * for an entry that matches our key
-                                 * with the everything but the first
-                                 * layout stripped off. */
-                                if (x > 0 &&
-                                    strlen(a[1]) == x &&
-                                    strneq(c->x11_layout, a[1], x))
-                                        matching = 5;
-                                else  {
-                                        size_t w;
-
-                                        /* If that didn't work, strip
-                                         * off the other layouts from
-                                         * the entry, too */
-                                        w = strcspn(a[1], ",");
-
-                                        if (x > 0 && x == w &&
-                                            memcmp(c->x11_layout, a[1], x) == 0)
-                                                matching = 1;
-                                }
-                        }
-
-                        if (matching > 0 &&
-                            streq_ptr(c->x11_model, a[2])) {
-                                matching++;
-
-                                if (streq_ptr(c->x11_variant, a[3])) {
-                                        matching++;
-
-                                        if (streq_ptr(c->x11_options, a[4]))
-                                                matching++;
-                                }
-                        }
-
-                        /* The best matching entry so far, then let's
-                         * save that */
-                        if (matching > best_matching) {
-                                best_matching = matching;
-
-                                free(new_keymap);
-                                new_keymap = strdup(a[0]);
-                                if (!new_keymap)
-                                        return -ENOMEM;
-                        }
                 }
 
                 if (!streq_ptr(c->vc_keymap, new_keymap)) {
@@ -730,8 +772,6 @@ static int x11_convert_to_vconsole(Context *c, sd_bus *bus) {
         }
 
         if (modified) {
-                int r;
-
                 r = vconsole_write_data(c);
                 if (r < 0)
                         log_error("Failed to set virtual console keymap: %s", strerror(-r));
diff --git a/src/shared/def.h b/src/shared/def.h
index d7e077a..825db95 100644
--- a/src/shared/def.h
+++ b/src/shared/def.h
@@ -43,3 +43,16 @@
 #define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS
 
 #define REBOOT_PARAM_FILE "/run/systemd/reboot-param"
+
+#ifdef HAVE_SPLIT_USR
+#define KBD_KEYMAP_DIRS                         \
+        "/usr/share/keymaps/\0"                 \
+        "/usr/share/kbd/keymaps/\0"             \
+        "/usr/lib/kbd/keymaps/\0"               \
+        "/lib/kbd/keymaps/\0"
+#else
+#define KBD_KEYMAP_DIRS                         \
+        "/usr/share/keymaps/\0"                 \
+        "/usr/share/kbd/keymaps/\0"             \
+        "/usr/lib/kbd/keymaps/\0"
+#endif

commit 98fce79dea6f653dead88638fc17a27280b1f250
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Nov 18 10:19:29 2013 -0500

    localed: use _cleanup_

diff --git a/src/locale/localed.c b/src/locale/localed.c
index 78250d6..5275ef3 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -391,7 +391,7 @@ static int locale_update_system_manager(Context *c, sd_bus *bus) {
 
 static int vconsole_write_data(Context *c) {
         int r;
-        char **l = NULL;
+        _cleanup_strv_free_ char **l = NULL;
 
         r = load_env_file("/etc/vconsole.conf", NULL, &l);
         if (r < 0 && r != -ENOENT)
@@ -403,10 +403,8 @@ static int vconsole_write_data(Context *c) {
                 char *s, **u;
 
                 s = strappend("KEYMAP=", c->vc_keymap);
-                if (!s) {
-                        strv_free(l);
+                if (!s)
                         return -ENOMEM;
-                }
 
                 u = strv_env_set(l, s);
                 free(s);
@@ -424,10 +422,8 @@ static int vconsole_write_data(Context *c) {
                 char *s, **u;
 
                 s = strappend("KEYMAP_TOGGLE=", c->vc_keymap_toggle);
-                if (!s) {
-                        strv_free(l);
+                if (!s)
                         return -ENOMEM;
-                }
 
                 u = strv_env_set(l, s);
                 free(s);
@@ -440,8 +436,6 @@ static int vconsole_write_data(Context *c) {
         }
 
         if (strv_isempty(l)) {
-                strv_free(l);
-
                 if (unlink("/etc/vconsole.conf") < 0)
                         return errno == ENOENT ? 0 : -errno;
 
@@ -449,14 +443,12 @@ static int vconsole_write_data(Context *c) {
         }
 
         r = write_env_file_label("/etc/vconsole.conf", l);
-        strv_free(l);
-
         return r;
 }
 
 static int write_data_x11(Context *c) {
-        FILE *f;
-        char *temp_path;
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *temp_path = NULL;
         int r;
 
         if (isempty(c->x11_layout) &&
@@ -503,13 +495,9 @@ static int write_data_x11(Context *c) {
                 r = -errno;
                 unlink("/etc/X11/xorg.conf.d/00-keyboard.conf");
                 unlink(temp_path);
+                return r;
         } else
-                r = 0;
-
-        fclose(f);
-        free(temp_path);
-
-        return r;
+                return 0;
 }
 
 static int vconsole_reload(sd_bus *bus) {
@@ -591,7 +579,7 @@ static int vconsole_convert_to_x11(Context *c, sd_bus *bus) {
 
                 context_free_x11(c);
         } else {
-                FILE *f;
+                _cleanup_fclose_ FILE *f = NULL;
                 unsigned n = 0;
 
                 f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
@@ -599,22 +587,17 @@ static int vconsole_convert_to_x11(Context *c, sd_bus *bus) {
                         return -errno;
 
                 for (;;) {
-                        char **a;
+                        _cleanup_strv_free_ char **a = NULL;
                         int r;
 
                         r = read_next_mapping(f, &n, &a);
-                        if (r < 0) {
-                                fclose(f);
+                        if (r < 0)
                                 return r;
-                        }
-
                         if (r == 0)
                                 break;
 
-                        if (!streq(c->vc_keymap, a[0])) {
-                                strv_free(a);
+                        if (!streq(c->vc_keymap, a[0]))
                                 continue;
-                        }
 
                         if (!streq_ptr(c->x11_layout, strnulldash(a[1])) ||
                             !streq_ptr(c->x11_model, strnulldash(a[2])) ||
@@ -624,20 +607,14 @@ static int vconsole_convert_to_x11(Context *c, sd_bus *bus) {
                                 if (free_and_copy(&c->x11_layout, strnulldash(a[1])) < 0 ||
                                     free_and_copy(&c->x11_model, strnulldash(a[2])) < 0 ||
                                     free_and_copy(&c->x11_variant, strnulldash(a[3])) < 0 ||
-                                    free_and_copy(&c->x11_options, strnulldash(a[4])) < 0) {
-                                        strv_free(a);
-                                        fclose(f);
+                                    free_and_copy(&c->x11_options, strnulldash(a[4])) < 0)
                                         return -ENOMEM;
-                                }
 
                                 modified = true;
                         }
 
-                        strv_free(a);
                         break;
                 }
-
-                fclose(f);
         }
 
         if (modified) {



More information about the systemd-commits mailing list