This commit is contained in:
parent
05add83ce4
commit
895a59d356
831
gdm-sysconfig-settings.patch
Normal file
831
gdm-sysconfig-settings.patch
Normal file
@ -0,0 +1,831 @@
|
||||
diff --git a/common/Makefile.am b/common/Makefile.am
|
||||
index 101b3f4..705c6de 100644
|
||||
--- a/common/Makefile.am
|
||||
+++ b/common/Makefile.am
|
||||
@@ -83,6 +83,8 @@ libgdmcommon_la_SOURCES = \
|
||||
gdm-settings-backend.h \
|
||||
gdm-settings-desktop-backend.c \
|
||||
gdm-settings-desktop-backend.h \
|
||||
+ gdm-settings-system-backend.c \
|
||||
+ gdm-settings-system-backend.h \
|
||||
gdm-settings-keys.h \
|
||||
gdm-settings-utils.h \
|
||||
gdm-settings-utils.c \
|
||||
diff --git a/common/gdm-settings-system-backend.c b/common/gdm-settings-system-backend.c
|
||||
new file mode 100644
|
||||
index 0000000..eb7f883
|
||||
--- /dev/null
|
||||
+++ b/common/gdm-settings-system-backend.c
|
||||
@@ -0,0 +1,619 @@
|
||||
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
+ *
|
||||
+ * Copyright (C) 2008 Hans Petter Jansson <hpj@copyleft.no>
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+#include <string.h>
|
||||
+#include <signal.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
+#include <glib.h>
|
||||
+#include <glib/gi18n.h>
|
||||
+#include <glib/gstdio.h>
|
||||
+#include <glib-object.h>
|
||||
+
|
||||
+#include "gdm-settings-keys.h"
|
||||
+#include "gdm-settings-system-backend.h"
|
||||
+
|
||||
+#include "gdm-marshal.h"
|
||||
+#include "gdm-log.h"
|
||||
+
|
||||
+#define SYSCONFIG_AUTOLOGIN_KEY "DISPLAYMANAGER_AUTOLOGIN"
|
||||
+
|
||||
+#define GDM_SETTINGS_SYSTEM_BACKEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SETTINGS_SYSTEM_BACKEND, GdmSettingsSystemBackendPrivate))
|
||||
+
|
||||
+struct GdmSettingsSystemBackendPrivate
|
||||
+{
|
||||
+ char *filename;
|
||||
+ gchar **lines;
|
||||
+ gboolean dirty;
|
||||
+ guint save_id;
|
||||
+
|
||||
+ gchar *set_autologin_user;
|
||||
+ gboolean set_autologin_enabled;
|
||||
+};
|
||||
+
|
||||
+static void gdm_settings_system_backend_class_init (GdmSettingsSystemBackendClass *klass);
|
||||
+static void gdm_settings_system_backend_init (GdmSettingsSystemBackend *settings_system_backend);
|
||||
+static void gdm_settings_system_backend_finalize (GObject *object);
|
||||
+
|
||||
+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,
|
||||
+ char **value,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ GdmSettingsSystemBackend *system_backend = (GdmSettingsSystemBackend *) backend;
|
||||
+ GdmSettingsSystemBackendPrivate *priv;
|
||||
+ gchar *val;
|
||||
+ gboolean ret;
|
||||
+
|
||||
+ g_return_val_if_fail (GDM_IS_SETTINGS_BACKEND (backend), FALSE);
|
||||
+ g_return_val_if_fail (key != NULL, FALSE);
|
||||
+
|
||||
+ priv = system_backend->priv;
|
||||
+ ret = FALSE;
|
||||
+
|
||||
+ if (value != NULL) {
|
||||
+ *value = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (strcasecmp (key, GDM_KEY_AUTO_LOGIN_ENABLE) &&
|
||||
+ strcasecmp (key, GDM_KEY_AUTO_LOGIN_USER)) {
|
||||
+ g_set_error (error, GDM_SETTINGS_BACKEND_ERROR, GDM_SETTINGS_BACKEND_ERROR_KEY_NOT_FOUND, "Key not found");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (!strcasecmp (key, GDM_KEY_AUTO_LOGIN_ENABLE)) {
|
||||
+ if (priv->dirty) {
|
||||
+ val = g_strdup (priv->set_autologin_enabled ? "true" : "false");
|
||||
+ } else {
|
||||
+ const gchar *new_val;
|
||||
+
|
||||
+ val = get_value ((const gchar **) priv->lines, SYSCONFIG_AUTOLOGIN_KEY);
|
||||
+
|
||||
+ new_val = (val && *val) ? "true" : "false";
|
||||
+ g_free (val);
|
||||
+ val = g_strdup (new_val);
|
||||
+ }
|
||||
+ } else {
|
||||
+ 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);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (value != NULL && val != NULL && *val != '\0') {
|
||||
+ *value = val;
|
||||
+ } else {
|
||||
+ g_free (val);
|
||||
+ }
|
||||
+
|
||||
+ ret = TRUE;
|
||||
+
|
||||
+ out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+save_settings (GdmSettingsSystemBackend *backend)
|
||||
+{
|
||||
+ GError *local_error;
|
||||
+ char *contents;
|
||||
+ gsize length;
|
||||
+
|
||||
+ if (! backend->priv->dirty) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ g_debug ("Saving settings to %s", backend->priv->filename);
|
||||
+
|
||||
+ if (!backend->priv->set_autologin_enabled) {
|
||||
+ g_free (backend->priv->set_autologin_user);
|
||||
+ backend->priv->set_autologin_user = g_strdup ("");
|
||||
+ }
|
||||
+
|
||||
+ if (!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))
|
||||
+ g_warning ("Unable to save settings to %s.", backend->priv->filename);
|
||||
+
|
||||
+ backend->priv->dirty = FALSE;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+save_settings_timer (GdmSettingsSystemBackend *backend)
|
||||
+{
|
||||
+ save_settings (backend);
|
||||
+ backend->priv->save_id = 0;
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+queue_save (GdmSettingsSystemBackend *backend)
|
||||
+{
|
||||
+ if (! backend->priv->dirty) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (backend->priv->save_id != 0) {
|
||||
+ /* already pending */
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ backend->priv->save_id = g_timeout_add_seconds (5, (GSourceFunc)save_settings_timer, backend);
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+gdm_settings_system_backend_set_value (GdmSettingsBackend *backend,
|
||||
+ const char *key,
|
||||
+ const char *value,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ GdmSettingsSystemBackend *system_backend = (GdmSettingsSystemBackend *) backend;
|
||||
+ GdmSettingsSystemBackendPrivate *priv;
|
||||
+ gchar *old_val = NULL;
|
||||
+
|
||||
+ g_return_val_if_fail (GDM_IS_SETTINGS_BACKEND (backend), FALSE);
|
||||
+ g_return_val_if_fail (key != NULL, FALSE);
|
||||
+
|
||||
+ priv = system_backend->priv;
|
||||
+
|
||||
+ if (strcasecmp ("key", GDM_KEY_AUTO_LOGIN_ENABLE) &&
|
||||
+ strcasecmp ("key", GDM_KEY_AUTO_LOGIN_USER)) {
|
||||
+ g_set_error (error, GDM_SETTINGS_BACKEND_ERROR, GDM_SETTINGS_BACKEND_ERROR_KEY_NOT_FOUND, "Key not found");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ gdm_settings_system_backend_get_value (backend, key, &old_val, NULL);
|
||||
+
|
||||
+ if (!strcasecmp ("key", GDM_KEY_AUTO_LOGIN_ENABLE)) {
|
||||
+ gchar t = 0;
|
||||
+
|
||||
+ if (value)
|
||||
+ t = g_ascii_tolower (*value);
|
||||
+
|
||||
+ if (t == 'y' || t == 't')
|
||||
+ priv->set_autologin_enabled = TRUE;
|
||||
+ else
|
||||
+ priv->set_autologin_enabled = FALSE;
|
||||
+ } else {
|
||||
+ g_free (priv->set_autologin_user);
|
||||
+ priv->set_autologin_user = g_strdup (value);
|
||||
+ }
|
||||
+
|
||||
+ GDM_SETTINGS_SYSTEM_BACKEND (backend)->priv->dirty = TRUE;
|
||||
+ queue_save (GDM_SETTINGS_SYSTEM_BACKEND (backend));
|
||||
+
|
||||
+ gdm_settings_backend_value_changed (backend, key, old_val, value);
|
||||
+
|
||||
+ g_free (old_val);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+gdm_settings_system_backend_class_init (GdmSettingsSystemBackendClass *klass)
|
||||
+{
|
||||
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
+ GdmSettingsBackendClass *backend_class = GDM_SETTINGS_BACKEND_CLASS (klass);
|
||||
+
|
||||
+ object_class->finalize = gdm_settings_system_backend_finalize;
|
||||
+
|
||||
+ backend_class->get_value = gdm_settings_system_backend_get_value;
|
||||
+ backend_class->set_value = gdm_settings_system_backend_set_value;
|
||||
+
|
||||
+ g_type_class_add_private (klass, sizeof (GdmSettingsSystemBackendPrivate));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+gdm_settings_system_backend_init (GdmSettingsSystemBackend *backend)
|
||||
+{
|
||||
+ gboolean res;
|
||||
+ GError *error;
|
||||
+
|
||||
+ gdm_log_set_debug (TRUE);
|
||||
+
|
||||
+ 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);
|
||||
+
|
||||
+ if (!backend->priv->lines) {
|
||||
+ g_warning ("Unable to load file '%s'", backend->priv->filename);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+gdm_settings_system_backend_finalize (GObject *object)
|
||||
+{
|
||||
+ GdmSettingsSystemBackend *backend;
|
||||
+
|
||||
+ g_return_if_fail (object != NULL);
|
||||
+ g_return_if_fail (GDM_IS_SETTINGS_SYSTEM_BACKEND (object));
|
||||
+
|
||||
+ backend = GDM_SETTINGS_SYSTEM_BACKEND (object);
|
||||
+
|
||||
+ g_return_if_fail (backend->priv != NULL);
|
||||
+
|
||||
+ save_settings (backend);
|
||||
+ g_strfreev (backend->priv->lines);
|
||||
+ g_free (backend->priv->filename);
|
||||
+ g_free (backend->priv->set_autologin_user);
|
||||
+
|
||||
+ G_OBJECT_CLASS (gdm_settings_system_backend_parent_class)->finalize (object);
|
||||
+}
|
||||
+
|
||||
+GdmSettingsBackend *
|
||||
+gdm_settings_system_backend_new (void)
|
||||
+{
|
||||
+ GObject *object;
|
||||
+
|
||||
+ object = g_object_new (GDM_TYPE_SETTINGS_SYSTEM_BACKEND, NULL);
|
||||
+
|
||||
+ return GDM_SETTINGS_BACKEND (object);
|
||||
+}
|
||||
diff --git a/common/gdm-settings-system-backend.h b/common/gdm-settings-system-backend.h
|
||||
new file mode 100644
|
||||
index 0000000..3cd16b7
|
||||
--- /dev/null
|
||||
+++ b/common/gdm-settings-system-backend.h
|
||||
@@ -0,0 +1,56 @@
|
||||
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||
+ *
|
||||
+ * Copyright (C) 2008 Hans Petter Jansson <hpj@copyleft.no>
|
||||
+ *
|
||||
+ * 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_SETTINGS_SYSTEM_BACKEND_H
|
||||
+#define __GDM_SETTINGS_SYSTEM_BACKEND_H
|
||||
+
|
||||
+#include <glib-object.h>
|
||||
+#include "gdm-settings-backend.h"
|
||||
+
|
||||
+G_BEGIN_DECLS
|
||||
+
|
||||
+#define GDM_TYPE_SETTINGS_SYSTEM_BACKEND (gdm_settings_system_backend_get_type ())
|
||||
+#define GDM_SETTINGS_SYSTEM_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_SETTINGS_SYSTEM_BACKEND, GdmSettingsSystemBackend))
|
||||
+#define GDM_SETTINGS_SYSTEM_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_SETTINGS_SYSTEM_BACKEND, GdmSettingsSystemBackendClass))
|
||||
+#define GDM_IS_SETTINGS_SYSTEM_BACKEND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_SETTINGS_SYSTEM_BACKEND))
|
||||
+#define GDM_IS_SETTINGS_SYSTEM_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_SETTINGS_SYSTEM_BACKEND))
|
||||
+#define GDM_SETTINGS_SYSTEM_BACKEND_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_SETTINGS_SYSTEM_BACKEND, GdmSettingsSystemBackendClass))
|
||||
+
|
||||
+typedef struct GdmSettingsSystemBackendPrivate GdmSettingsSystemBackendPrivate;
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ GdmSettingsBackend parent;
|
||||
+ GdmSettingsSystemBackendPrivate *priv;
|
||||
+} GdmSettingsSystemBackend;
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ GdmSettingsBackendClass parent_class;
|
||||
+} GdmSettingsSystemBackendClass;
|
||||
+
|
||||
+GType gdm_settings_system_backend_get_type (void);
|
||||
+
|
||||
+GdmSettingsBackend *gdm_settings_system_backend_new (void);
|
||||
+
|
||||
+G_END_DECLS
|
||||
+
|
||||
+#endif /* __GDM_SETTINGS_SYSTEM_BACKEND_H */
|
||||
diff --git a/common/gdm-settings.c b/common/gdm-settings.c
|
||||
index 00fe73e..4c31394 100644
|
||||
--- a/common/gdm-settings.c
|
||||
+++ b/common/gdm-settings.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "gdm-settings-glue.h"
|
||||
|
||||
#include "gdm-settings-desktop-backend.h"
|
||||
+#include "gdm-settings-system-backend.h"
|
||||
|
||||
#include "gdm-marshal.h"
|
||||
|
||||
@@ -53,7 +54,7 @@
|
||||
struct GdmSettingsPrivate
|
||||
{
|
||||
DBusGConnection *connection;
|
||||
- GdmSettingsBackend *backend;
|
||||
+ GList *backends;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -94,15 +95,29 @@ gdm_settings_get_value (GdmSettings *settings,
|
||||
{
|
||||
GError *local_error;
|
||||
gboolean res;
|
||||
+ GList *l;
|
||||
|
||||
g_return_val_if_fail (GDM_IS_SETTINGS (settings), FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
|
||||
local_error = NULL;
|
||||
- res = gdm_settings_backend_get_value (settings->priv->backend,
|
||||
- key,
|
||||
- value,
|
||||
- &local_error);
|
||||
+
|
||||
+ for (l = settings->priv->backends; l; l = g_list_next (l)) {
|
||||
+ GdmSettingsBackend *backend = l->data;
|
||||
+
|
||||
+ if (local_error) {
|
||||
+ g_error_free (local_error);
|
||||
+ local_error = NULL;
|
||||
+ }
|
||||
+
|
||||
+ res = gdm_settings_backend_get_value (backend,
|
||||
+ key,
|
||||
+ value,
|
||||
+ &local_error);
|
||||
+ if (res)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
if (! res) {
|
||||
g_propagate_error (error, local_error);
|
||||
}
|
||||
@@ -122,6 +137,7 @@ gdm_settings_set_value (GdmSettings *settings,
|
||||
{
|
||||
GError *local_error;
|
||||
gboolean res;
|
||||
+ GList *l;
|
||||
|
||||
g_return_val_if_fail (GDM_IS_SETTINGS (settings), FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
@@ -129,10 +145,23 @@ gdm_settings_set_value (GdmSettings *settings,
|
||||
g_debug ("Setting value %s", key);
|
||||
|
||||
local_error = NULL;
|
||||
- res = gdm_settings_backend_set_value (settings->priv->backend,
|
||||
- key,
|
||||
- value,
|
||||
- &local_error);
|
||||
+
|
||||
+ for (l = settings->priv->backends; l; l = g_list_next (l)) {
|
||||
+ GdmSettingsBackend *backend = l->data;
|
||||
+
|
||||
+ if (local_error) {
|
||||
+ g_error_free (local_error);
|
||||
+ local_error = NULL;
|
||||
+ }
|
||||
+
|
||||
+ res = gdm_settings_backend_set_value (backend,
|
||||
+ key,
|
||||
+ value,
|
||||
+ &local_error);
|
||||
+ if (res)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
if (! res) {
|
||||
g_propagate_error (error, local_error);
|
||||
}
|
||||
@@ -210,13 +239,21 @@ backend_value_changed (GdmSettingsBackend *backend,
|
||||
static void
|
||||
gdm_settings_init (GdmSettings *settings)
|
||||
{
|
||||
+ GList *l;
|
||||
+
|
||||
settings->priv = GDM_SETTINGS_GET_PRIVATE (settings);
|
||||
|
||||
- settings->priv->backend = gdm_settings_desktop_backend_new ();
|
||||
- g_signal_connect (settings->priv->backend,
|
||||
- "value-changed",
|
||||
- G_CALLBACK (backend_value_changed),
|
||||
- settings);
|
||||
+ settings->priv->backends = g_list_prepend (NULL, gdm_settings_desktop_backend_new ());
|
||||
+ settings->priv->backends = g_list_prepend (settings->priv->backends, gdm_settings_system_backend_new ());
|
||||
+
|
||||
+ for (l = settings->priv->backends; l; l = g_list_next (l)) {
|
||||
+ GdmSettingsBackend *backend = l->data;
|
||||
+
|
||||
+ g_signal_connect (backend,
|
||||
+ "value-changed",
|
||||
+ G_CALLBACK (backend_value_changed),
|
||||
+ settings);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -231,9 +268,9 @@ gdm_settings_finalize (GObject *object)
|
||||
|
||||
g_return_if_fail (settings->priv != NULL);
|
||||
|
||||
- if (settings->priv->backend != NULL) {
|
||||
- g_object_unref (settings->priv->backend);
|
||||
- }
|
||||
+ g_list_foreach (settings->priv->backends, (GFunc) g_object_unref, NULL);
|
||||
+ g_list_free (settings->priv->backends);
|
||||
+ settings->priv->backends = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gdm_settings_parent_class)->finalize (object);
|
||||
}
|
@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Nov 7 14:02:20 CET 2008 - vuntz@novell.com
|
||||
|
||||
- Merge hpj's submission: Add gdm-sysconfig-settings.patch, which
|
||||
fixes bnc#432360.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 6 20:34:54 CET 2008 - vuntz@novell.com
|
||||
|
||||
|
9
gdm.spec
9
gdm.spec
@ -57,7 +57,7 @@ PreReq: %insserv_prereq
|
||||
License: GPL v2 or later
|
||||
Group: System/GUI/GNOME
|
||||
Version: 2.24.0
|
||||
Release: 6
|
||||
Release: 7
|
||||
Summary: The GNOME 2.x Display Manager
|
||||
Source: %{name}-%{version}.tar.bz2
|
||||
Source1: gdm.pamd
|
||||
@ -83,6 +83,8 @@ Patch10: gdm-2.23.92-filter-dupes-from-lang-list.patch
|
||||
Patch11: gdm-2.23.92-fix-crash.patch
|
||||
# PATCH-FIX-UPSTREAM gdm-fix-icon-scale.patch vuntz@novell.com -- From upstream/Fedora: don't have a huge size for icons in the greeter
|
||||
Patch12: gdm-fix-icon-scale.patch
|
||||
# PATCH-FIX-OPENSUSE gdm-sysconfig-settings.patch bnc432360 hpj@novell.com -- Read autologin options from /etc/sysconfig/displaymanager
|
||||
Patch13: gdm-sysconfig-settings.patch
|
||||
Patch28: gdm-X_SERVER.patch
|
||||
# PATCH-SUSE: enable SELinux
|
||||
Patch60: gdm-selinux.patch
|
||||
@ -157,10 +159,12 @@ Authors:
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch28
|
||||
%patch60
|
||||
|
||||
%build
|
||||
libtoolize -f -i
|
||||
autoreconf -f -i
|
||||
export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
|
||||
%configure\
|
||||
@ -264,6 +268,9 @@ fi
|
||||
%files lang -f %{name}.lang
|
||||
|
||||
%changelog
|
||||
* Fri Nov 07 2008 vuntz@novell.com
|
||||
- Merge hpj's submission: Add gdm-sysconfig-settings.patch, which
|
||||
fixes bnc#432360.
|
||||
* Thu Nov 06 2008 vuntz@novell.com
|
||||
- Add gdm-fix-icon-scale.patch: make icons in the greeter use a
|
||||
reasonable size. Part of bnc#436431.
|
||||
|
Loading…
x
Reference in New Issue
Block a user