This commit is contained in:
parent
a8433b4ddc
commit
4ee251b690
@ -1,5 +1,5 @@
|
|||||||
diff --git a/common/Makefile.am b/common/Makefile.am
|
diff --git a/common/Makefile.am b/common/Makefile.am
|
||||||
index 101b3f4..705c6de 100644
|
index 101b3f4..5e9e9d1 100644
|
||||||
--- a/common/Makefile.am
|
--- a/common/Makefile.am
|
||||||
+++ b/common/Makefile.am
|
+++ b/common/Makefile.am
|
||||||
@@ -83,6 +83,8 @@ libgdmcommon_la_SOURCES = \
|
@@ -83,6 +83,8 @@ libgdmcommon_la_SOURCES = \
|
||||||
@ -11,12 +11,21 @@ index 101b3f4..705c6de 100644
|
|||||||
gdm-settings-keys.h \
|
gdm-settings-keys.h \
|
||||||
gdm-settings-utils.h \
|
gdm-settings-utils.h \
|
||||||
gdm-settings-utils.c \
|
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
|
diff --git a/common/gdm-settings-system-backend.c b/common/gdm-settings-system-backend.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000..eb7f883
|
index 0000000..036c28c
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/common/gdm-settings-system-backend.c
|
+++ 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 -*-
|
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
+ *
|
+ *
|
||||||
+ * Copyright (C) 2008 Hans Petter Jansson <hpj@copyleft.no>
|
+ * Copyright (C) 2008 Hans Petter Jansson <hpj@copyleft.no>
|
||||||
@ -53,6 +62,7 @@ index 0000000..eb7f883
|
|||||||
+#include <glib/gstdio.h>
|
+#include <glib/gstdio.h>
|
||||||
+#include <glib-object.h>
|
+#include <glib-object.h>
|
||||||
+
|
+
|
||||||
|
+#include "gdm-sysconfig.h"
|
||||||
+#include "gdm-settings-keys.h"
|
+#include "gdm-settings-keys.h"
|
||||||
+#include "gdm-settings-system-backend.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)
|
+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
|
+static gboolean
|
||||||
+gdm_settings_system_backend_get_value (GdmSettingsBackend *backend,
|
+gdm_settings_system_backend_get_value (GdmSettingsBackend *backend,
|
||||||
+ const char *key,
|
+ const char *key,
|
||||||
@ -450,7 +123,7 @@ index 0000000..eb7f883
|
|||||||
+ } else {
|
+ } else {
|
||||||
+ const gchar *new_val;
|
+ 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";
|
+ new_val = (val && *val) ? "true" : "false";
|
||||||
+ g_free (val);
|
+ g_free (val);
|
||||||
@ -460,7 +133,7 @@ index 0000000..eb7f883
|
|||||||
+ if (priv->dirty && priv->set_autologin_user) {
|
+ if (priv->dirty && priv->set_autologin_user) {
|
||||||
+ val = g_strdup (priv->set_autologin_user);
|
+ val = g_strdup (priv->set_autologin_user);
|
||||||
+ } else {
|
+ } 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 ("");
|
+ 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,
|
+ g_warning ("Unable to set key %s to '%s'.", SYSCONFIG_AUTOLOGIN_KEY,
|
||||||
+ backend->priv->set_autologin_user);
|
+ 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);
|
+ g_warning ("Unable to save settings to %s.", backend->priv->filename);
|
||||||
+
|
+
|
||||||
+ backend->priv->dirty = FALSE;
|
+ backend->priv->dirty = FALSE;
|
||||||
@ -600,7 +273,7 @@ index 0000000..eb7f883
|
|||||||
+ backend->priv = GDM_SETTINGS_SYSTEM_BACKEND_GET_PRIVATE (backend);
|
+ backend->priv = GDM_SETTINGS_SYSTEM_BACKEND_GET_PRIVATE (backend);
|
||||||
+
|
+
|
||||||
+ backend->priv->filename = g_strdup ("/etc/sysconfig/displaymanager");
|
+ 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) {
|
+ if (!backend->priv->lines) {
|
||||||
+ g_warning ("Unable to load file '%s'", backend->priv->filename);
|
+ 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);
|
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 <hpj@novell.com>
|
||||||
|
+ *
|
||||||
|
+ * 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 <unistd.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+#include <glib.h>
|
||||||
|
+#include <glib/gi18n.h>
|
||||||
|
+
|
||||||
|
+#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 <hpj@novell.com>
|
||||||
|
+ *
|
||||||
|
+ * 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 <glib-object.h>
|
||||||
|
+
|
||||||
|
+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 <dbus/dbus-glib.h>
|
||||||
|
#include <dbus/dbus-glib-lowlevel.h>
|
||||||
|
|
||||||
|
+#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";
|
||||||
|
}
|
||||||
|
@ -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
|
Sun Nov 9 13:47:59 EST 2008 - jpr@novell.com
|
||||||
|
|
||||||
|
8
gdm.spec
8
gdm.spec
@ -57,7 +57,7 @@ PreReq: %insserv_prereq
|
|||||||
License: GPL v2 or later
|
License: GPL v2 or later
|
||||||
Group: System/GUI/GNOME
|
Group: System/GUI/GNOME
|
||||||
Version: 2.24.0
|
Version: 2.24.0
|
||||||
Release: 8
|
Release: 9
|
||||||
Summary: The GNOME 2.x Display Manager
|
Summary: The GNOME 2.x Display Manager
|
||||||
Source: %{name}-%{version}.tar.bz2
|
Source: %{name}-%{version}.tar.bz2
|
||||||
Source1: gdm.pamd
|
Source1: gdm.pamd
|
||||||
@ -271,6 +271,8 @@ fi
|
|||||||
%files lang -f %{name}.lang
|
%files lang -f %{name}.lang
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Nov 11 2008 hpj@novell.com
|
||||||
|
- Update gdm-sysconfig-settings.patch, fixing bnc#440863.
|
||||||
* Sun Nov 09 2008 jpr@novell.com
|
* Sun Nov 09 2008 jpr@novell.com
|
||||||
- Add gdm-autologin.patch so the greeter is not created for
|
- Add gdm-autologin.patch so the greeter is not created for
|
||||||
autologin and improve startup time (bnc#436524)
|
autologin and improve startup time (bnc#436524)
|
||||||
@ -612,7 +614,7 @@ fi
|
|||||||
- Split off a -lang subpackag
|
- Split off a -lang subpackag
|
||||||
- Fix variable expansion in gdm-conf.patch (#255685)
|
- Fix variable expansion in gdm-conf.patch (#255685)
|
||||||
- Remove earlygdm, replaced by earlyxdm (#285813)
|
- Remove earlygdm, replaced by earlyxdm (#285813)
|
||||||
* Sat Aug 04 2007 maw@suse.de
|
* Fri Aug 03 2007 maw@suse.de
|
||||||
- Use %%fdupes
|
- Use %%fdupes
|
||||||
- Uncomment out the rm in %%clean.
|
- Uncomment out the rm in %%clean.
|
||||||
* Fri Aug 03 2007 hpj@suse.de
|
* Fri Aug 03 2007 hpj@suse.de
|
||||||
@ -1071,7 +1073,7 @@ fi
|
|||||||
- Cache gdm help and show gdm in khelpcenter.
|
- Cache gdm help and show gdm in khelpcenter.
|
||||||
* Mon Aug 16 2004 ro@suse.de
|
* Mon Aug 16 2004 ro@suse.de
|
||||||
- fixed specfile
|
- fixed specfile
|
||||||
* Mon Aug 16 2004 shprasad@suse.de
|
* Sun Aug 15 2004 shprasad@suse.de
|
||||||
- Fixes bug #60020
|
- Fixes bug #60020
|
||||||
Invalid username/passwd input doen't bring the password dialog
|
Invalid username/passwd input doen't bring the password dialog
|
||||||
for timed login user.
|
for timed login user.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user