Hello community, here is the log from the commit of package systemd for openSUSE:Factory checked in at 2017-10-28 14:19:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/systemd (Old) and /work/SRC/openSUSE:Factory/.systemd.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "systemd" Sat Oct 28 14:19:43 2017 rev:264 rq:536877 version:234 Changes: -------- --- /work/SRC/openSUSE:Factory/systemd/systemd-mini.changes 2017-10-10 11:37:43.057347484 +0200 +++ /work/SRC/openSUSE:Factory/.systemd.new/systemd-mini.changes 2017-10-28 14:19:46.111754726 +0200 @@ -1,0 +2,16 @@ +Thu Oct 26 12:29:29 UTC 2017 - f...@suse.com + +- Import commit e44237e76f6e133e62ff6c681d3fd06ebf12f66d + + a4e02c099 udev-rules: all values can contain escaped double quotes now (#6890) + d2b767a76 tmpfiles: remove old ICE and X11 sockets at boot (#6979) + +------------------------------------------------------------------- +Thu Oct 19 07:47:16 UTC 2017 - f...@suse.com + +- Add 0001-systemd-firstboot-add-vconsole-keymap-support.patch (bsc#1046436) + + Temporary patch until it's been merged by upstream, see + https://github.com/systemd/systemd/pull/7035 + +------------------------------------------------------------------- systemd.changes: same change New: ---- 0001-systemd-firstboot-add-vconsole-keymap-support.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ systemd-mini.spec ++++++ --- /var/tmp/diff_new_pack.SkjIcl/_old 2017-10-28 14:19:46.999722259 +0200 +++ /var/tmp/diff_new_pack.SkjIcl/_new 2017-10-28 14:19:47.003722113 +0200 @@ -163,6 +163,7 @@ # patches are temporary and should be removed as soon as a fix is # merged by upstream. Patch1: 0001-core-disable-session-keyring-per-system-sevice-entir.patch +Patch2: 0001-systemd-firstboot-add-vconsole-keymap-support.patch %description Systemd is a system and service manager, compatible with SysV and LSB ++++++ systemd.spec ++++++ --- /var/tmp/diff_new_pack.SkjIcl/_old 2017-10-28 14:19:47.027721235 +0200 +++ /var/tmp/diff_new_pack.SkjIcl/_new 2017-10-28 14:19:47.027721235 +0200 @@ -161,6 +161,7 @@ # patches are temporary and should be removed as soon as a fix is # merged by upstream. Patch1: 0001-core-disable-session-keyring-per-system-sevice-entir.patch +Patch2: 0001-systemd-firstboot-add-vconsole-keymap-support.patch %description Systemd is a system and service manager, compatible with SysV and LSB ++++++ 0001-systemd-firstboot-add-vconsole-keymap-support.patch ++++++ >From 349fd7b2fe35d2fd6c7ba6493d2e44ae93013804 Mon Sep 17 00:00:00 2001 From: Thomas Blume <thomas.bl...@suse.com> Date: Wed, 18 Oct 2017 12:30:03 +0200 Subject: [PATCH 1/1] systemd-firstboot: add vconsole keymap support yast installer needs systemd-firstboot support for setting the keymap This is a temporary patch to be superseded when upstream commit is available, see https://github.com/systemd/systemd/pull/7035 for the relevant PR. [tblume: fixes bsc#1046436] --- src/basic/locale-util.c | 95 +++++++++++++++++++++++++++++++++++ src/basic/locale-util.h | 3 ++ src/firstboot/firstboot.c | 117 ++++++++++++++++++++++++++++++++++++++++++-- src/locale/localectl.c | 65 +++--------------------- src/test/test-locale-util.c | 29 +++++++++++ 5 files changed, 247 insertions(+), 62 deletions(-) diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c index ada0a28cd..f3fa918b8 100644 --- a/src/basic/locale-util.c +++ b/src/basic/locale-util.c @@ -20,6 +20,7 @@ #include <dirent.h> #include <errno.h> #include <fcntl.h> +#include <ftw.h> #include <langinfo.h> #include <libintl.h> #include <locale.h> @@ -30,6 +31,7 @@ #include <sys/mman.h> #include <sys/stat.h> +#include "def.h" #include "dirent-util.h" #include "fd-util.h" #include "hashmap.h" @@ -270,6 +272,99 @@ out: return (bool) cached_answer; } +static thread_local Set *keymaps = NULL; + +static int nftw_cb( + const char *fpath, + const struct stat *sb, + int tflag, + struct FTW *ftwbuf) { + + char *p, *e; + int r; + + if (tflag != FTW_F) + return 0; + + if (!endswith(fpath, ".map") && + !endswith(fpath, ".map.gz")) + return 0; + + p = strdup(basename(fpath)); + if (!p) + return FTW_STOP; + + e = endswith(p, ".map"); + if (e) + *e = 0; + + e = endswith(p, ".map.gz"); + if (e) + *e = 0; + + r = set_consume(keymaps, p); + if (r < 0 && r != -EEXIST) + return r; + + return 0; +} + +int get_keymaps(char ***ret) { + _cleanup_strv_free_ char **l = NULL; + const char *dir; + 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_MOUNT|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 = l; + l = NULL; + + return 0; +} + +bool keymap_is_valid(const char *name) { + + if (isempty(name)) + return false; + + if (strlen(name) >= 128) + return false; + + if (!utf8_is_valid(name)) + return false; + + if (!filename_is_valid(name)) + return false; + + if (!string_is_safe(name)) + return false; + + return true; +} const char *special_glyph(SpecialGlyph code) { diff --git a/src/basic/locale-util.h b/src/basic/locale-util.h index 0630a034a..104864501 100644 --- a/src/basic/locale-util.h +++ b/src/basic/locale-util.h @@ -71,3 +71,6 @@ const char *special_glyph(SpecialGlyph code) _const_; const char* locale_variable_to_string(LocaleVariable i) _const_; LocaleVariable locale_variable_from_string(const char *s) _pure_; + +int get_keymaps(char ***l); +bool keymap_is_valid(const char *name); diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index b3578d3e1..fd60ee518 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -44,16 +44,19 @@ static char *arg_root = NULL; static char *arg_locale = NULL; /* $LANG */ +static char *arg_keymap = NULL; static char *arg_locale_messages = NULL; /* $LC_MESSAGES */ static char *arg_timezone = NULL; static char *arg_hostname = NULL; static sd_id128_t arg_machine_id = {}; static char *arg_root_password = NULL; static bool arg_prompt_locale = false; +static bool arg_prompt_keymap = false; static bool arg_prompt_timezone = false; static bool arg_prompt_hostname = false; static bool arg_prompt_root_password = false; static bool arg_copy_locale = false; +static bool arg_copy_keymap = false; static bool arg_copy_timezone = false; static bool arg_copy_root_password = false; @@ -285,6 +288,80 @@ static int process_locale(void) { return 0; } +static int prompt_keymap(void) { + _cleanup_strv_free_ char **kmaps = NULL; + int r; + + if (arg_keymap) + return 0; + + if (!arg_prompt_keymap) + return 0; + + r = get_keymaps(&kmaps); + if (r < 0) + return log_error_errno(r, "Cannot query keymap list: %m"); + + print_welcome(); + + printf("\nAvailable keymaps:\n\n"); + r = show_menu(kmaps, 3, 22, 60); + if (r < 0) + return r; + + putchar('\n'); + + r = prompt_loop("Please enter system keymap name or number", kmaps, keymap_is_valid, &arg_keymap); + if (r < 0) + return r; + + if (isempty(arg_keymap)) + return 0; + + return 0; +} + +static int process_keymap(void) { + const char *etc_vconsoleconf; + char **keymap; + int r; + + etc_vconsoleconf = prefix_roota(arg_root, "/etc/vconsole.conf"); + if (laccess(etc_vconsoleconf, F_OK) >= 0) + return 0; + + if (arg_copy_keymap && arg_root) { + + mkdir_parents(etc_vconsoleconf, 0755); + r = copy_file("/etc/vconsole.conf", etc_vconsoleconf, 0, 0644, 0, COPY_REFLINK); + if (r != -ENOENT) { + if (r < 0) + return log_error_errno(r, "Failed to copy %s: %m", etc_vconsoleconf); + + log_info("%s copied.", etc_vconsoleconf); + return 0; + } + } + + r = prompt_keymap(); + if (r < 0) + return r; + + if (!isempty(arg_keymap)) + keymap = STRV_MAKE(strjoina("KEYMAP=", arg_keymap)); + + if (!keymap) + return 0; + + mkdir_parents(etc_vconsoleconf, 0755); + r = write_env_file(etc_vconsoleconf, keymap); + if (r < 0) + return log_error_errno(r, "Failed to write %s: %m", etc_vconsoleconf); + + log_info("%s written.", etc_vconsoleconf); + return 0; +} + static int prompt_timezone(void) { _cleanup_strv_free_ char **zones = NULL; int r; @@ -611,20 +688,23 @@ static void help(void) { " --root=PATH Operate on an alternate filesystem root\n" " --locale=LOCALE Set primary locale (LANG=)\n" " --locale-messages=LOCALE Set message locale (LC_MESSAGES=)\n" + " --keymap=KEYMAP Set keymap\n" " --timezone=TIMEZONE Set timezone\n" " --hostname=NAME Set host name\n" " --machine-ID=ID Set machine ID\n" " --root-password=PASSWORD Set root password\n" " --root-password-file=FILE Set root password from file\n" " --prompt-locale Prompt the user for locale settings\n" + " --prompt-keymap Prompt the user for keymap settings\n" " --prompt-timezone Prompt the user for timezone\n" " --prompt-hostname Prompt the user for hostname\n" " --prompt-root-password Prompt the user for root password\n" " --prompt Prompt for all of the above\n" " --copy-locale Copy locale from host\n" + " --copy-keymap Copy keymap from host\n" " --copy-timezone Copy timezone from host\n" " --copy-root-password Copy root password from host\n" - " --copy Copy locale, timezone, root password\n" + " --copy Copy locale, keymap, timezone, root password\n" " --setup-machine-id Generate a new random machine ID\n" , program_invocation_short_name); } @@ -636,6 +716,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_ROOT, ARG_LOCALE, ARG_LOCALE_MESSAGES, + ARG_KEYMAP, ARG_TIMEZONE, ARG_HOSTNAME, ARG_MACHINE_ID, @@ -643,11 +724,13 @@ static int parse_argv(int argc, char *argv[]) { ARG_ROOT_PASSWORD_FILE, ARG_PROMPT, ARG_PROMPT_LOCALE, + ARG_PROMPT_KEYMAP, ARG_PROMPT_TIMEZONE, ARG_PROMPT_HOSTNAME, ARG_PROMPT_ROOT_PASSWORD, ARG_COPY, ARG_COPY_LOCALE, + ARG_COPY_KEYMAP, ARG_COPY_TIMEZONE, ARG_COPY_ROOT_PASSWORD, ARG_SETUP_MACHINE_ID, @@ -659,6 +742,7 @@ static int parse_argv(int argc, char *argv[]) { { "root", required_argument, NULL, ARG_ROOT }, { "locale", required_argument, NULL, ARG_LOCALE }, { "locale-messages", required_argument, NULL, ARG_LOCALE_MESSAGES }, + { "keymap", required_argument, NULL, ARG_KEYMAP }, { "timezone", required_argument, NULL, ARG_TIMEZONE }, { "hostname", required_argument, NULL, ARG_HOSTNAME }, { "machine-id", required_argument, NULL, ARG_MACHINE_ID }, @@ -666,11 +750,13 @@ static int parse_argv(int argc, char *argv[]) { { "root-password-file", required_argument, NULL, ARG_ROOT_PASSWORD_FILE }, { "prompt", no_argument, NULL, ARG_PROMPT }, { "prompt-locale", no_argument, NULL, ARG_PROMPT_LOCALE }, + { "prompt-keymap", no_argument, NULL, ARG_PROMPT_KEYMAP }, { "prompt-timezone", no_argument, NULL, ARG_PROMPT_TIMEZONE }, { "prompt-hostname", no_argument, NULL, ARG_PROMPT_HOSTNAME }, { "prompt-root-password", no_argument, NULL, ARG_PROMPT_ROOT_PASSWORD }, { "copy", no_argument, NULL, ARG_COPY }, { "copy-locale", no_argument, NULL, ARG_COPY_LOCALE }, + { "copy-keymap", no_argument, NULL, ARG_COPY_KEYMAP }, { "copy-timezone", no_argument, NULL, ARG_COPY_TIMEZONE }, { "copy-root-password", no_argument, NULL, ARG_COPY_ROOT_PASSWORD }, { "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID }, @@ -723,6 +809,18 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_KEYMAP: + if (!keymap_is_valid(optarg)) { + log_error("Keymap %s is not valid.", optarg); + return -EINVAL; + } + + r = free_and_strdup(&arg_keymap, optarg); + if (r < 0) + return log_oom(); + + break; + case ARG_TIMEZONE: if (!timezone_is_valid(optarg)) { log_error("Timezone %s is not valid.", optarg); @@ -772,13 +870,17 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_PROMPT: - arg_prompt_locale = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true; + arg_prompt_locale = arg_prompt_keymap = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true; break; case ARG_PROMPT_LOCALE: arg_prompt_locale = true; break; + case ARG_PROMPT_KEYMAP: + arg_prompt_keymap = true; + break; + case ARG_PROMPT_TIMEZONE: arg_prompt_timezone = true; break; @@ -792,13 +894,17 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_COPY: - arg_copy_locale = arg_copy_timezone = arg_copy_root_password = true; + arg_copy_locale = arg_copy_keymap = arg_copy_timezone = arg_copy_root_password = true; break; case ARG_COPY_LOCALE: arg_copy_locale = true; break; + case ARG_COPY_KEYMAP: + arg_copy_keymap = true; + break; + case ARG_COPY_TIMEZONE: arg_copy_timezone = true; break; @@ -853,6 +959,10 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; + r = process_keymap(); + if (r < 0) + goto finish; + r = process_timezone(); if (r < 0) goto finish; @@ -873,6 +983,7 @@ finish: free(arg_root); free(arg_locale); free(arg_locale_messages); + free(arg_keymap); free(arg_timezone); free(arg_hostname); string_erase(arg_root_password); diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 0bd18a5c0..efdd73a8f 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -273,68 +273,15 @@ static int set_vconsole_keymap(sd_bus *bus, char **args, unsigned n) { return r; } -static Set *keymaps = NULL; - -static int nftw_cb( - const char *fpath, - const struct stat *sb, - int tflag, - struct FTW *ftwbuf) { - - char *p, *e; - int r; - - if (tflag != FTW_F) - return 0; - - if (!endswith(fpath, ".map") && - !endswith(fpath, ".map.gz")) - return 0; - - p = strdup(basename(fpath)); - if (!p) - return log_oom(); - - e = endswith(p, ".map"); - if (e) - *e = 0; - - e = endswith(p, ".map.gz"); - if (e) - *e = 0; - - r = set_consume(keymaps, p); - if (r < 0 && r != -EEXIST) - return log_error_errno(r, "Can't add keymap: %m"); - - 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_ops); - 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); + _cleanup_strv_free_ char **l = NULL; + int r; - if (strv_isempty(l)) { - log_error("Couldn't find any console keymaps."); - return -ENOENT; - } + assert(args); - strv_sort(l); + r = get_keymaps(&l); + if (r < 0) + return log_error_errno(r, "Failed to read list of keymaps: %m"); pager_open(arg_no_pager, false); diff --git a/src/test/test-locale-util.c b/src/test/test-locale-util.c index 427c698d1..e6876c82e 100644 --- a/src/test/test-locale-util.c +++ b/src/test/test-locale-util.c @@ -50,9 +50,38 @@ static void test_locale_is_valid(void) { assert_se(!locale_is_valid("\x01gar\x02 bage\x03")); } +static void test_get_keymaps(void) { + _cleanup_strv_free_ char **kmaps = NULL; + char **p; + int r; + + r = get_keymaps(&kmaps); + assert_se(r >= 0); + assert_se(kmaps); + + STRV_FOREACH(p, kmaps) { + puts(*p); + assert_se(keymap_is_valid(*p)); + } +} + +static void test_keymap_is_valid(void) { + assert_se(keymap_is_valid("uk")); + assert_se(keymap_is_valid("de-nodeadkeys")); + assert_se(keymap_is_valid("ANSI-dvorak")); + assert_se(keymap_is_valid("unicode")); + + assert_se(!keymap_is_valid("")); + assert_se(!keymap_is_valid("/usr/bin/foo")); + assert_se(!keymap_is_valid("\x01gar\x02 bage\x03")); +} + int main(int argc, char *argv[]) { test_get_locales(); test_locale_is_valid(); + test_get_keymaps(); + test_keymap_is_valid(); + return 0; } -- 2.14.2 ++++++ systemd-234.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/systemd-234/src/udev/udev-event.c new/systemd-234/src/udev/udev-event.c --- old/systemd-234/src/udev/udev-event.c 2017-10-06 09:35:03.000000000 +0200 +++ new/systemd-234/src/udev/udev-event.c 2017-10-26 14:29:18.000000000 +0200 @@ -719,10 +719,12 @@ pos = cmd; while (pos != NULL && pos[0] != '\0') { - if (pos[0] == '\'') { - /* do not separate quotes */ + if (IN_SET(pos[0], '\'', '"')) { + /* do not separate quotes or double quotes */ + char delim[2] = { pos[0], '\0' }; + pos++; - argv[i] = strsep(&pos, "\'"); + argv[i] = strsep(&pos, delim); if (pos != NULL) while (pos[0] == ' ') pos++; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/systemd-234/src/udev/udev-rules.c new/systemd-234/src/udev/udev-rules.c --- old/systemd-234/src/udev/udev-rules.c 2017-10-06 09:35:03.000000000 +0200 +++ new/systemd-234/src/udev/udev-rules.c 2017-10-26 14:29:18.000000000 +0200 @@ -718,6 +718,7 @@ static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value) { char *linepos; char *temp; + unsigned i, j; linepos = *line; if (linepos == NULL || linepos[0] == '\0') @@ -793,14 +794,25 @@ *value = linepos; /* terminate */ - temp = strchr(linepos, '"'); - if (!temp) - return -1; - temp[0] = '\0'; - temp++; + for (i = 0, j = 0; ; i++, j++) { + + if (linepos[i] == '"') + break; + + if (linepos[i] == '\0') + return -1; + + /* double quotes can be escaped */ + if (linepos[i] == '\\') + if (linepos[i+1] == '"') + i++; + + linepos[j] = linepos[i]; + } + linepos[j] = '\0'; /* move line to next key */ - *line = temp; + *line = linepos + i + 1; return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/systemd-234/test/udev-test.pl new/systemd-234/test/udev-test.pl --- old/systemd-234/test/udev-test.pl 2017-10-06 09:35:03.000000000 +0200 +++ new/systemd-234/test/udev-test.pl 2017-10-26 14:29:18.000000000 +0200 @@ -333,6 +333,30 @@ EOF }, { + desc => "program arguments combined with escaped double quotes, part 1", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "foo2" , + rules => <<EOF +SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c 'printf %%s \\\"foo1 foo2\\\" | grep \\\"foo1 foo2\\\"'", KERNEL=="sda5", SYMLINK+="%c{2}" +EOF + }, + { + desc => "program arguments combined with escaped double quotes, part 2", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "foo2" , + rules => <<EOF +SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c \\\"printf %%s 'foo1 foo2' | grep 'foo1 foo2'\\\"", KERNEL=="sda5", SYMLINK+="%c{2}" +EOF + }, + { + desc => "program arguments combined with escaped double quotes, part 3", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", + exp_name => "foo2" , + rules => <<EOF +SUBSYSTEMS=="scsi", PROGRAM=="/bin/sh -c 'printf \\\"%%s %%s\\\" \\\"foo1 foo2\\\" \\\"foo3\\\"| grep \\\"foo1 foo2\\\"'", KERNEL=="sda5", SYMLINK+="%c{2}" +EOF + }, + { desc => "characters before the %c{N} substitution", devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5", exp_name => "my-foo9" , diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/systemd-234/tmpfiles.d/x11.conf new/systemd-234/tmpfiles.d/x11.conf --- old/systemd-234/tmpfiles.d/x11.conf 2017-10-06 09:35:03.000000000 +0200 +++ new/systemd-234/tmpfiles.d/x11.conf 2017-10-26 14:29:18.000000000 +0200 @@ -8,11 +8,12 @@ # See tmpfiles.d(5) for details # Make sure these are created by default so that nobody else can -d /tmp/.X11-unix 1777 root root 10d -d /tmp/.ICE-unix 1777 root root 10d -d /tmp/.XIM-unix 1777 root root 10d -d /tmp/.font-unix 1777 root root 10d -d /tmp/.Test-unix 1777 root root 10d +# or empty them at startup +D! /tmp/.X11-unix 1777 root root 10d +D! /tmp/.ICE-unix 1777 root root 10d +D! /tmp/.XIM-unix 1777 root root 10d +D! /tmp/.font-unix 1777 root root 10d +D! /tmp/.Test-unix 1777 root root 10d # Unlink the X11 lock files r! /tmp/.X[0-9]*-lock