diff --git a/gdm-sysconfig-settings.patch b/gdm-sysconfig-settings.patch index d48d878..2bacf51 100644 --- a/gdm-sysconfig-settings.patch +++ b/gdm-sysconfig-settings.patch @@ -1,5 +1,5 @@ diff --git a/common/Makefile.am b/common/Makefile.am -index 101b3f4..705c6de 100644 +index 101b3f4..5e9e9d1 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -83,6 +83,8 @@ libgdmcommon_la_SOURCES = \ @@ -11,12 +11,21 @@ index 101b3f4..705c6de 100644 gdm-settings-keys.h \ gdm-settings-utils.h \ gdm-settings-utils.c \ +@@ -90,6 +92,8 @@ libgdmcommon_la_SOURCES = \ + gdm-settings-direct.h \ + gdm-settings-client.h \ + gdm-settings-client.c \ ++ gdm-sysconfig.c \ ++ gdm-sysconfig.h \ + gdm-log.h \ + gdm-log.c \ + gdm-md5.h \ diff --git a/common/gdm-settings-system-backend.c b/common/gdm-settings-system-backend.c new file mode 100644 -index 0000000..eb7f883 +index 0000000..036c28c --- /dev/null +++ b/common/gdm-settings-system-backend.c -@@ -0,0 +1,619 @@ +@@ -0,0 +1,283 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Hans Petter Jansson @@ -53,6 +62,7 @@ index 0000000..eb7f883 +#include +#include + ++#include "gdm-sysconfig.h" +#include "gdm-settings-keys.h" +#include "gdm-settings-system-backend.h" + @@ -80,343 +90,6 @@ index 0000000..eb7f883 + +G_DEFINE_TYPE (GdmSettingsSystemBackend, gdm_settings_system_backend, GDM_TYPE_SETTINGS_BACKEND) + -+static gchar ** -+load_settings_file (gchar *file_name) -+{ -+ GIOChannel *channel; -+ GPtrArray *lines; -+ gchar *str; -+ -+ g_debug ("Loading settings from %s", file_name); -+ -+ channel = g_io_channel_new_file (file_name, "r", NULL); -+ if (!channel) { -+ g_debug ("Failed to open %s", file_name); -+ return NULL; -+ } -+ -+ lines = g_ptr_array_new (); -+ -+ while (g_io_channel_read_line (channel, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) { -+ if (str) { -+ gchar *p0; -+ -+ /* Remove line separators */ -+ -+ for (p0 = str + strlen (str) - 1; p0 >= str && strchr ("\r\n", *p0); p0--) -+ *p0 = '\0'; -+ -+ g_ptr_array_add (lines, str); -+ g_debug ("%s", str); -+ } else { -+ g_ptr_array_add (lines, g_strdup ("")); -+ g_debug ("", str); -+ } -+ } -+ -+ g_io_channel_shutdown (channel, FALSE, NULL); -+ g_io_channel_unref (channel); -+ -+ g_ptr_array_add (lines, NULL); -+ -+ return (gchar **) g_ptr_array_free (lines, FALSE); -+} -+ -+static gboolean -+save_settings_file (gchar *file_name, gchar **lines) -+{ -+ GIOStatus last_status = G_IO_STATUS_ERROR; -+ GIOChannel *channel = NULL; -+ gchar *temp_file_name; -+ gint i; -+ -+ temp_file_name = g_strdup_printf ("%s.new.%u", file_name, g_random_int ()); -+ -+ channel = g_io_channel_new_file (temp_file_name, "w", NULL); -+ if (!channel) -+ goto out; -+ -+ if (!lines) -+ goto out; -+ -+ for (i = 0; lines [i]; i++) { -+ gsize bytes_written; -+ -+ if (lines [i] [0] != '\0') -+ last_status = g_io_channel_write_chars (channel, -+ lines [i], strlen (lines [i]), -+ &bytes_written, -+ NULL); -+ -+ if (last_status != G_IO_STATUS_NORMAL) -+ break; -+ -+ last_status = g_io_channel_write_unichar (channel, '\n', NULL); -+ -+ if (last_status != G_IO_STATUS_NORMAL) -+ break; -+ } -+ -+out: -+ if (channel) { -+ g_io_channel_shutdown (channel, FALSE, NULL); -+ g_io_channel_unref (channel); -+ } -+ -+ if (last_status == G_IO_STATUS_NORMAL && g_rename (temp_file_name, file_name) != 0) -+ last_status = G_IO_STATUS_ERROR; -+ -+ g_free (temp_file_name); -+ return last_status == G_IO_STATUS_NORMAL ? TRUE : FALSE; -+} -+ -+/* Parser for shell-script-like key-value files. Far from complete, but -+ * deals with a couple of common shell oddities. For instance, the following -+ * are parsed correctly: -+ * -+ * KEY=value\0 -+ * KEY = value#comment\0 -+ * KEY = " value with spaces" \0 -+ * KEY = ' it\'s a value with "embedded" quotes'\0 -+ * KEY = "if quotes aren't closed, we assume the string ends at EOL\0 -+ * -+ * It should be good enough for the config files in /etc/sysconfig/. -+ */ -+ -+#define SPACE_CHARS " \t" -+#define KEY_ALLOW_CHARS "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" -+ -+static const gchar * -+skip_from_start_to_key (const gchar *line) -+{ -+ const gchar *p0; -+ -+ /* Skip initial space */ -+ -+ p0 = line + strspn (line, SPACE_CHARS); -+ -+ /* Ignore comments and other junk */ -+ -+ if (*p0 && strchr (KEY_ALLOW_CHARS, *p0)) -+ return p0; -+ -+ return NULL; -+} -+ -+static const gchar * -+skip_from_start_to_value_of_key (const gchar *line, const gchar *key_normal, gint key_len) -+{ -+ const gchar *p0, *p1; -+ gchar *potential_key_normal; -+ gboolean result; -+ -+ p0 = skip_from_start_to_key (line); -+ if (!p0) -+ return NULL; -+ -+ /* There's at least one key-like character, figure out how many */ -+ -+ p1 = p0 + strspn (p0, KEY_ALLOW_CHARS); -+ -+ /* Is this the key we're looking for? */ -+ -+ if (p1 - p0 != key_len) -+ return NULL; -+ -+ potential_key_normal = g_ascii_strdown (p0, p1 - p0); -+ result = strcmp (key_normal, potential_key_normal) == 0 ? TRUE : FALSE; -+ g_free (potential_key_normal); -+ -+ if (!result) -+ return NULL; -+ -+ /* It's the right key; skip over key-value separator */ -+ -+ p0 = p1 + strspn (p1, SPACE_CHARS); -+ if (*p0 != '=') -+ return NULL; -+ -+ p0++; -+ p0 += strspn (p0, SPACE_CHARS); -+ -+ return p0; -+} -+ -+static const gchar * -+skip_over_value (const gchar *value_start, gchar *quotes_out) -+{ -+ const gchar *p0 = value_start; -+ const gchar *p1; -+ gchar quotes; -+ -+ /* Is the value quoted? */ -+ -+ quotes = *p0; -+ if (quotes == '\'' || quotes == '"') { -+ /* Quoted sequence opened; find closing quote, but skip over escaped ones. If -+ * there's no closing quote on this line, assume the EOL closes it. */ -+ -+ *quotes_out = quotes; -+ -+ p1 = p0; -+ do { -+ p1++; -+ p1 = strchr (p1, quotes); -+ if (!p1) { -+ /* Hit EOL */ -+ -+ p1 = p0 + strlen (p0) - 1; -+ break; -+ } -+ } while (*(p1 - 1) == '\\'); -+ } else { -+ /* No quotes; look for comment or EOL */ -+ -+ *quotes_out = 0; -+ -+ p1 = strchr (p0, '#'); -+ if (!p1) -+ p1 = p0 + strlen (p0); -+ -+ for (p1--; p1 >= p0; p1--) -+ if (!strchr (SPACE_CHARS, *p1)) -+ break; -+ } -+ -+ return p1 + 1; -+} -+ -+static gchar * -+get_value_of_key (const gchar *line, const gchar *key_normal, gint key_len) -+{ -+ const gchar *p0, *p1; -+ gchar quotes; -+ gchar *value; -+ gchar *temp; -+ -+ p0 = skip_from_start_to_value_of_key (line, key_normal, key_len); -+ if (!p0) -+ return NULL; -+ -+ p1 = skip_over_value (p0, "es); -+ -+ if (quotes != 0) { -+ if (p1 - p0 > 2) { -+ temp = g_strndup (p0 + 1, p1 - p0 - 2); -+ value = g_strcompress (temp); -+ g_free (temp); -+ } else { -+ value = g_strdup (""); -+ } -+ } else { -+ temp = g_strndup (p0, p1 - p0); -+ value = g_strcompress (temp); -+ g_free (temp); -+ g_strchomp (value); -+ } -+ -+ return value; -+} -+ -+static gchar * -+get_value (const gchar **lines, const gchar *key) -+{ -+ gchar *value = NULL; -+ gchar *key_normal; -+ gint key_len; -+ gint i; -+ -+ g_return_val_if_fail (key != NULL, NULL); -+ -+ g_debug ("Getting value of %s", key); -+ -+ if (!lines) { -+ g_debug ("Missing configuration data"); -+ return NULL; -+ } -+ -+ key_normal = g_ascii_strdown (key, -1); -+ key_len = strlen (key_normal); -+ -+ for (i = 0; lines [i]; i++) { -+ value = get_value_of_key (lines [i], key_normal, key_len); -+ if (value) -+ break; -+ } -+ -+ g_free (key_normal); -+ -+ g_debug ("Got value of %s: %s", key, value); -+ -+ return value; -+} -+ -+static gchar * -+set_value_of_key (const gchar *line, const gchar *key_normal, gint key_len, const gchar *key, const gchar *value) -+{ -+ const gchar *p0, *p1, *p2; -+ gchar quotes; -+ gchar *escaped_value; -+ gint escaped_value_len; -+ gchar *new_line; -+ gint len; -+ -+ p0 = skip_from_start_to_value_of_key (line, key_normal, key_len); -+ if (!p0) -+ return NULL; -+ -+ escaped_value = g_strescape (value, ""); -+ escaped_value_len = strlen (escaped_value); -+ -+ p1 = skip_over_value (p0, "es); -+ p2 = p1 + strlen (p1); -+ len = (p0 - line) + escaped_value_len + (p2 - p1); -+ -+ new_line = g_malloc (len + 1); -+ memcpy (new_line, line, p0 - line); -+ memcpy (new_line + (p0 - line), escaped_value, escaped_value_len); -+ memcpy (new_line + (p0 - line) + escaped_value_len, p1, p2 - p1); -+ -+ *(new_line + len - 1) = '\0'; -+ -+ g_free (escaped_value); -+ -+ return new_line; -+} -+ -+static gboolean -+set_value (gchar **lines, const gchar *key, const gchar *value) -+{ -+ gboolean result = FALSE; -+ gchar *key_normal; -+ gint key_len; -+ gint i; -+ -+ g_return_val_if_fail (key != NULL, FALSE); -+ -+ if (!lines) -+ return FALSE; -+ -+ key_normal = g_ascii_strdown (key, -1); -+ key_len = strlen (key_normal); -+ -+ for (i = 0; lines [i]; i++) { -+ gchar *new_line; -+ -+ new_line = set_value_of_key (lines [i], key_normal, key_len, key, value); -+ if (new_line) { -+ g_free (lines [i]); -+ lines [i] = new_line; -+ result = TRUE; -+ break; -+ } -+ } -+ -+ g_free (key_normal); -+ -+ return result; -+} -+ +static gboolean +gdm_settings_system_backend_get_value (GdmSettingsBackend *backend, + const char *key, @@ -450,7 +123,7 @@ index 0000000..eb7f883 + } else { + const gchar *new_val; + -+ val = get_value ((const gchar **) priv->lines, SYSCONFIG_AUTOLOGIN_KEY); ++ val = gdm_sysconfig_get_value ((const gchar **) priv->lines, SYSCONFIG_AUTOLOGIN_KEY); + + new_val = (val && *val) ? "true" : "false"; + g_free (val); @@ -460,7 +133,7 @@ index 0000000..eb7f883 + if (priv->dirty && priv->set_autologin_user) { + val = g_strdup (priv->set_autologin_user); + } else { -+ val = get_value ((const gchar **) priv->lines, SYSCONFIG_AUTOLOGIN_KEY); ++ val = gdm_sysconfig_get_value ((const gchar **) priv->lines, SYSCONFIG_AUTOLOGIN_KEY); + } + } + @@ -494,11 +167,11 @@ index 0000000..eb7f883 + backend->priv->set_autologin_user = g_strdup (""); + } + -+ if (!set_value (backend->priv->lines, SYSCONFIG_AUTOLOGIN_KEY, backend->priv->set_autologin_user)) ++ if (!gdm_sysconfig_set_value (backend->priv->lines, SYSCONFIG_AUTOLOGIN_KEY, backend->priv->set_autologin_user)) + g_warning ("Unable to set key %s to '%s'.", SYSCONFIG_AUTOLOGIN_KEY, + backend->priv->set_autologin_user); + -+ if (!save_settings_file (backend->priv->filename, backend->priv->lines)) ++ if (!gdm_sysconfig_save_file (backend->priv->filename, backend->priv->lines)) + g_warning ("Unable to save settings to %s.", backend->priv->filename); + + backend->priv->dirty = FALSE; @@ -600,7 +273,7 @@ index 0000000..eb7f883 + backend->priv = GDM_SETTINGS_SYSTEM_BACKEND_GET_PRIVATE (backend); + + backend->priv->filename = g_strdup ("/etc/sysconfig/displaymanager"); -+ backend->priv->lines = load_settings_file (backend->priv->filename); ++ backend->priv->lines = gdm_sysconfig_load_file (backend->priv->filename); + + if (!backend->priv->lines) { + g_warning ("Unable to load file '%s'", backend->priv->filename); @@ -829,3 +502,522 @@ index 00fe73e..4c31394 100644 G_OBJECT_CLASS (gdm_settings_parent_class)->finalize (object); } +diff --git a/common/gdm-sysconfig.c b/common/gdm-sysconfig.c +new file mode 100644 +index 0000000..0e9e754 +--- /dev/null ++++ b/common/gdm-sysconfig.c +@@ -0,0 +1,439 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2008 Hans Petter Jansson ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ */ ++ ++/* Parser for shell-script-like key-value files. Far from complete, but ++ * deals with a couple of common shell oddities. For instance, the following ++ * are parsed correctly: ++ * ++ * KEY=value\0 ++ * KEY = value#comment\0 ++ * KEY = " value with spaces" \0 ++ * KEY = ' it\'s a value with "embedded" quotes'\0 ++ * KEY = "if quotes aren't closed, we assume the string ends at EOL\0 ++ * ++ * It should be good enough for the config files in /etc/sysconfig/. ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++ ++#include ++#include ++ ++#include "gdm-sysconfig.h" ++ ++#define SPACE_CHARS " \t" ++#define KEY_ALLOW_CHARS "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ++ ++static gchar ** ++load_settings_file (const gchar *file_name) ++{ ++ GIOChannel *channel; ++ GPtrArray *lines; ++ gchar *str; ++ ++ g_debug ("Loading settings from %s", file_name); ++ ++ channel = g_io_channel_new_file (file_name, "r", NULL); ++ if (!channel) { ++ g_debug ("Failed to open %s", file_name); ++ return NULL; ++ } ++ ++ lines = g_ptr_array_new (); ++ ++ while (g_io_channel_read_line (channel, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) { ++ if (str) { ++ gchar *p0; ++ ++ /* Remove line separators */ ++ ++ for (p0 = str + strlen (str) - 1; p0 >= str && strchr ("\r\n", *p0); p0--) ++ *p0 = '\0'; ++ ++ g_ptr_array_add (lines, str); ++ g_debug ("%s", str); ++ } else { ++ g_ptr_array_add (lines, g_strdup ("")); ++ g_debug ("", str); ++ } ++ } ++ ++ g_io_channel_shutdown (channel, FALSE, NULL); ++ g_io_channel_unref (channel); ++ ++ g_ptr_array_add (lines, NULL); ++ ++ return (gchar **) g_ptr_array_free (lines, FALSE); ++} ++ ++static gboolean ++save_settings_file (const gchar *file_name, gchar **lines) ++{ ++ GIOStatus last_status = G_IO_STATUS_ERROR; ++ GIOChannel *channel = NULL; ++ gchar *temp_file_name; ++ gint i; ++ ++ temp_file_name = g_strdup_printf ("%s.new.%u", file_name, g_random_int ()); ++ ++ channel = g_io_channel_new_file (temp_file_name, "w", NULL); ++ if (!channel) ++ goto out; ++ ++ if (!lines) ++ goto out; ++ ++ for (i = 0; lines [i]; i++) { ++ gsize bytes_written; ++ ++ if (lines [i] [0] != '\0') ++ last_status = g_io_channel_write_chars (channel, ++ lines [i], strlen (lines [i]), ++ &bytes_written, ++ NULL); ++ ++ if (last_status != G_IO_STATUS_NORMAL) ++ break; ++ ++ last_status = g_io_channel_write_unichar (channel, '\n', NULL); ++ ++ if (last_status != G_IO_STATUS_NORMAL) ++ break; ++ } ++ ++out: ++ if (channel) { ++ g_io_channel_shutdown (channel, FALSE, NULL); ++ g_io_channel_unref (channel); ++ } ++ ++ if (last_status == G_IO_STATUS_NORMAL && g_rename (temp_file_name, file_name) != 0) ++ last_status = G_IO_STATUS_ERROR; ++ ++ g_free (temp_file_name); ++ return last_status == G_IO_STATUS_NORMAL ? TRUE : FALSE; ++} ++ ++static const gchar * ++skip_from_start_to_key (const gchar *line) ++{ ++ const gchar *p0; ++ ++ /* Skip initial space */ ++ ++ p0 = line + strspn (line, SPACE_CHARS); ++ ++ /* Ignore comments and other junk */ ++ ++ if (*p0 && strchr (KEY_ALLOW_CHARS, *p0)) ++ return p0; ++ ++ return NULL; ++} ++ ++static const gchar * ++skip_from_start_to_value_of_key (const gchar *line, const gchar *key_normal, gint key_len) ++{ ++ const gchar *p0, *p1; ++ gchar *potential_key_normal; ++ gboolean result; ++ ++ p0 = skip_from_start_to_key (line); ++ if (!p0) ++ return NULL; ++ ++ /* There's at least one key-like character, figure out how many */ ++ ++ p1 = p0 + strspn (p0, KEY_ALLOW_CHARS); ++ ++ /* Is this the key we're looking for? */ ++ ++ if (p1 - p0 != key_len) ++ return NULL; ++ ++ potential_key_normal = g_ascii_strdown (p0, p1 - p0); ++ result = strcmp (key_normal, potential_key_normal) == 0 ? TRUE : FALSE; ++ g_free (potential_key_normal); ++ ++ if (!result) ++ return NULL; ++ ++ /* It's the right key; skip over key-value separator */ ++ ++ p0 = p1 + strspn (p1, SPACE_CHARS); ++ if (*p0 != '=') ++ return NULL; ++ ++ p0++; ++ p0 += strspn (p0, SPACE_CHARS); ++ ++ return p0; ++} ++ ++static const gchar * ++skip_over_value (const gchar *value_start, gchar *quotes_out) ++{ ++ const gchar *p0 = value_start; ++ const gchar *p1; ++ gchar quotes; ++ ++ /* Is the value quoted? */ ++ ++ quotes = *p0; ++ if (quotes == '\'' || quotes == '"') { ++ /* Quoted sequence opened; find closing quote, but skip over escaped ones. If ++ * there's no closing quote on this line, assume the EOL closes it. */ ++ ++ *quotes_out = quotes; ++ ++ p1 = p0; ++ do { ++ p1++; ++ p1 = strchr (p1, quotes); ++ if (!p1) { ++ /* Hit EOL */ ++ ++ p1 = p0 + strlen (p0) - 1; ++ break; ++ } ++ } while (*(p1 - 1) == '\\'); ++ } else { ++ /* No quotes; look for comment or EOL */ ++ ++ *quotes_out = 0; ++ ++ p1 = strchr (p0, '#'); ++ if (!p1) ++ p1 = p0 + strlen (p0); ++ ++ for (p1--; p1 >= p0; p1--) ++ if (!strchr (SPACE_CHARS, *p1)) ++ break; ++ } ++ ++ return p1 + 1; ++} ++ ++static gchar * ++get_value_of_key (const gchar *line, const gchar *key_normal, gint key_len) ++{ ++ const gchar *p0, *p1; ++ gchar quotes; ++ gchar *value; ++ gchar *temp; ++ ++ p0 = skip_from_start_to_value_of_key (line, key_normal, key_len); ++ if (!p0) ++ return NULL; ++ ++ p1 = skip_over_value (p0, "es); ++ ++ if (quotes != 0) { ++ if (p1 - p0 > 2) { ++ temp = g_strndup (p0 + 1, p1 - p0 - 2); ++ value = g_strcompress (temp); ++ g_free (temp); ++ } else { ++ value = g_strdup (""); ++ } ++ } else { ++ temp = g_strndup (p0, p1 - p0); ++ value = g_strcompress (temp); ++ g_free (temp); ++ g_strchomp (value); ++ } ++ ++ return value; ++} ++ ++static gchar * ++get_value (const gchar **lines, const gchar *key) ++{ ++ gchar *value = NULL; ++ gchar *key_normal; ++ gint key_len; ++ gint i; ++ ++ g_debug ("Getting value of %s", key); ++ ++ if (!lines) { ++ g_debug ("Missing configuration data"); ++ return NULL; ++ } ++ ++ key_normal = g_ascii_strdown (key, -1); ++ key_len = strlen (key_normal); ++ ++ for (i = 0; lines [i]; i++) { ++ value = get_value_of_key (lines [i], key_normal, key_len); ++ if (value) ++ break; ++ } ++ ++ g_free (key_normal); ++ ++ g_debug ("Got value of %s: %s", key, value); ++ ++ return value; ++} ++ ++static gchar * ++set_value_of_key (const gchar *line, const gchar *key_normal, gint key_len, const gchar *key, const gchar *value) ++{ ++ const gchar *p0, *p1, *p2; ++ gchar quotes; ++ gchar *escaped_value; ++ gint escaped_value_len; ++ gchar *new_line; ++ gint len; ++ ++ p0 = skip_from_start_to_value_of_key (line, key_normal, key_len); ++ if (!p0) ++ return NULL; ++ ++ escaped_value = g_strescape (value, ""); ++ escaped_value_len = strlen (escaped_value); ++ ++ p1 = skip_over_value (p0, "es); ++ p2 = p1 + strlen (p1); ++ len = (p0 - line) + escaped_value_len + (p2 - p1); ++ ++ new_line = g_malloc (len + 1); ++ memcpy (new_line, line, p0 - line); ++ memcpy (new_line + (p0 - line), escaped_value, escaped_value_len); ++ memcpy (new_line + (p0 - line) + escaped_value_len, p1, p2 - p1); ++ ++ *(new_line + len - 1) = '\0'; ++ ++ g_free (escaped_value); ++ ++ return new_line; ++} ++ ++static gboolean ++set_value (gchar **lines, const gchar *key, const gchar *value) ++{ ++ gboolean result = FALSE; ++ gchar *key_normal; ++ gint key_len; ++ gint i; ++ ++ if (!lines) ++ return FALSE; ++ ++ key_normal = g_ascii_strdown (key, -1); ++ key_len = strlen (key_normal); ++ ++ for (i = 0; lines [i]; i++) { ++ gchar *new_line; ++ ++ new_line = set_value_of_key (lines [i], key_normal, key_len, key, value); ++ if (new_line) { ++ g_free (lines [i]); ++ lines [i] = new_line; ++ result = TRUE; ++ break; ++ } ++ } ++ ++ g_free (key_normal); ++ ++ return result; ++} ++ ++gchar ** ++gdm_sysconfig_load_file (const gchar *file_name) ++{ ++ g_return_val_if_fail (file_name != NULL, NULL); ++ ++ return load_settings_file (file_name); ++} ++ ++gboolean ++gdm_sysconfig_save_file (const gchar *file_name, const gchar **sysconfig) ++{ ++ g_return_val_if_fail (file_name != NULL, FALSE); ++ g_return_val_if_fail (sysconfig != NULL, FALSE); ++ ++ return save_settings_file (file_name, sysconfig); ++} ++ ++gchar * ++gdm_sysconfig_get_value (const gchar **sysconfig, const gchar *key) ++{ ++ g_return_val_if_fail (sysconfig != NULL, NULL); ++ g_return_val_if_fail (key != NULL, NULL); ++ ++ return get_value (sysconfig, key); ++} ++ ++gboolean ++gdm_sysconfig_set_value (gchar **sysconfig, const gchar *key, const gchar *value) ++{ ++ g_return_val_if_fail (sysconfig != NULL, FALSE); ++ g_return_val_if_fail (key != NULL, FALSE); ++ g_return_val_if_fail (value != NULL, FALSE); ++ ++ return set_value (sysconfig, key, value); ++} ++ ++gchar * ++gdm_sysconfig_load_value (const gchar *file_name, const gchar *key) ++{ ++ gchar **lines; ++ gchar *value; ++ ++ g_return_val_if_fail (file_name != NULL, NULL); ++ g_return_val_if_fail (key != NULL, NULL); ++ ++ lines = load_settings_file (file_name); ++ if (!lines) ++ return NULL; ++ ++ value = get_value (lines, key); ++ ++ g_strfreev (lines); ++ return value; ++} ++ ++gboolean ++gdm_sysconfig_save_value (const gchar *file_name, const gchar *key, const gchar *value) ++{ ++ gchar **lines; ++ gboolean result; ++ ++ g_return_val_if_fail (file_name != NULL, FALSE); ++ g_return_val_if_fail (key != NULL, FALSE); ++ g_return_val_if_fail (value != NULL, FALSE); ++ ++ lines = load_settings_file (file_name); ++ if (!lines) ++ return FALSE; ++ ++ result = set_value (lines, key, value); ++ if (result) ++ result = save_settings_file (file_name, lines); ++ ++ g_strfreev (lines); ++ return result; ++} +diff --git a/common/gdm-sysconfig.h b/common/gdm-sysconfig.h +new file mode 100644 +index 0000000..9bc21ec +--- /dev/null ++++ b/common/gdm-sysconfig.h +@@ -0,0 +1,40 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2008 Hans Petter Jansson ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ */ ++ ++ ++#ifndef __GDM_SYSCONFIG_H ++#define __GDM_SYSCONFIG_H ++ ++#include ++ ++G_BEGIN_DECLS ++ ++gchar **gdm_sysconfig_load_file (const gchar *file_name); ++gboolean gdm_sysconfig_save_file (const gchar *file_name, const gchar **sysconfig); ++ ++gchar *gdm_sysconfig_get_value (const gchar **sysconfig, const gchar *key); ++gboolean gdm_sysconfig_set_value (gchar **sysconfig, const gchar *key, const gchar *value); ++ ++gchar *gdm_sysconfig_load_value (const gchar *file_name, const gchar *key); ++gboolean gdm_sysconfig_save_value (const gchar *file_name, const gchar *key, const gchar *value); ++ ++G_END_DECLS ++ ++#endif /* __GDM_SYSCONFIG_H */ +diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c +index 75a1cec..8b74dea 100644 +--- a/daemon/gdm-session-direct.c ++++ b/daemon/gdm-session-direct.c +@@ -45,6 +45,8 @@ + #include + #include + ++#include "gdm-sysconfig.h" ++ + #include "gdm-session-direct.h" + #include "gdm-session.h" + #include "gdm-session-private.h" +@@ -600,9 +602,11 @@ get_default_language_name (GdmSessionDirect *session) + static const char * + get_default_layout_name (GdmSessionDirect *session) + { +- if (session->priv->saved_layout != NULL) { +- return session->priv->saved_layout; +- } ++ if (!session->priv->saved_layout) ++ session->priv->saved_layout = gdm_sysconfig_load_value ("/etc/sysconfig/keyboard", "KEYTABLE"); ++ ++ if (session->priv->saved_layout) ++ return session->priv->saved_layout; + + return "us"; + } diff --git a/gdm.changes b/gdm.changes index 4f6a096..bf04b2d 100644 --- a/gdm.changes +++ b/gdm.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Nov 11 01:11:27 CST 2008 - hpj@novell.com + +- Update gdm-sysconfig-settings.patch, fixing bnc#440863. + ------------------------------------------------------------------- Sun Nov 9 13:47:59 EST 2008 - jpr@novell.com diff --git a/gdm.spec b/gdm.spec index f68cf00..a1b0c85 100644 --- a/gdm.spec +++ b/gdm.spec @@ -57,7 +57,7 @@ PreReq: %insserv_prereq License: GPL v2 or later Group: System/GUI/GNOME Version: 2.24.0 -Release: 8 +Release: 9 Summary: The GNOME 2.x Display Manager Source: %{name}-%{version}.tar.bz2 Source1: gdm.pamd @@ -271,6 +271,8 @@ fi %files lang -f %{name}.lang %changelog +* Tue Nov 11 2008 hpj@novell.com +- Update gdm-sysconfig-settings.patch, fixing bnc#440863. * Sun Nov 09 2008 jpr@novell.com - Add gdm-autologin.patch so the greeter is not created for autologin and improve startup time (bnc#436524) @@ -612,7 +614,7 @@ fi - Split off a -lang subpackag - Fix variable expansion in gdm-conf.patch (#255685) - Remove earlygdm, replaced by earlyxdm (#285813) -* Sat Aug 04 2007 maw@suse.de +* Fri Aug 03 2007 maw@suse.de - Use %%fdupes - Uncomment out the rm in %%clean. * Fri Aug 03 2007 hpj@suse.de @@ -1071,7 +1073,7 @@ fi - Cache gdm help and show gdm in khelpcenter. * Mon Aug 16 2004 ro@suse.de - fixed specfile -* Mon Aug 16 2004 shprasad@suse.de +* Sun Aug 15 2004 shprasad@suse.de - Fixes bug #60020 Invalid username/passwd input doen't bring the password dialog for timed login user.