File gnome-settings-daemon-system-proxy-configuration.diff of Package gnome-settings-daemon

From e61dc951c432d489b17e3bdaf1e566ac15958c6b Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@novell.com>
Date: Thu, 14 Aug 2008 18:55:55 -0500
Subject: [PATCH 1/8] Add a new plugin for proxy settings.

We read the system's configuration from /etc/sysconfig/proxy and propagate it to
GNOME's GConf keys.
---
 plugins/proxy/Makefile.am                    |   57 +++
 plugins/proxy/gsd-proxy-manager.c            |  571 ++++++++++++++++++++++++++
 plugins/proxy/gsd-proxy-manager.h            |   57 +++
 plugins/proxy/gsd-proxy-plugin.c             |  103 +++++
 plugins/proxy/gsd-proxy-plugin.h             |   59 +++
 plugins/proxy/novell-sysconfig-proxy-helper  |   19 +
 plugins/proxy/proxy.gnome-settings-plugin.in |    8 +
 7 files changed, 874 insertions(+), 0 deletions(-)
 create mode 100644 plugins/proxy/Makefile.am
 create mode 100644 plugins/proxy/gsd-proxy-manager.c
 create mode 100644 plugins/proxy/gsd-proxy-manager.h
 create mode 100644 plugins/proxy/gsd-proxy-plugin.c
 create mode 100644 plugins/proxy/gsd-proxy-plugin.h
 create mode 100644 plugins/proxy/novell-sysconfig-proxy-helper
 create mode 100644 plugins/proxy/proxy.gnome-settings-plugin.in

Index: plugins/proxy/Makefile.am
===================================================================
--- /dev/null
+++ plugins/proxy/Makefile.am
@@ -0,0 +1,57 @@
+NULL =
+
+plugin_LTLIBRARIES = \
+	libproxy.la  \
+	$(NULL)
+
+libproxy_la_SOURCES = 		\
+	gsd-proxy-plugin.h	\
+	gsd-proxy-plugin.c	\
+	gsd-proxy-manager.h	\
+	gsd-proxy-manager.c	\
+	$(NULL)
+
+libproxy_la_CPPFLAGS = \
+	-I$(top_srcdir)/gnome-settings-daemon		\
+	-DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
+	$(AM_CPPFLAGS)
+
+libproxy_la_CFLAGS = 				\
+	$(SETTINGS_PLUGIN_CFLAGS)		\
+	-DLIBEXECDIR="\"$(libexecdir)\""	\
+	$(AM_CFLAGS)
+
+libproxy_la_LDFLAGS = 		\
+	$(GSD_PLUGIN_LDFLAGS)	\
+	$(NULL)
+
+libproxy_la_LIBADD  = 		\
+	$(SETTINGS_PLUGIN_LIBS)	\
+	$(NULL)
+
+plugin_in_files = 		\
+	proxy.gnome-settings-plugin.in	\
+	$(NULL)
+
+plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin)
+
+helperdir = $(libexecdir)
+helperfile = novell-sysconfig-proxy-helper
+
+install-data-hook :
+	$(INSTALL_SCRIPT) $(srcdir)/$(helperfile) $(DESTDIR)$(libexecdir)/$(helperfile)
+
+EXTRA_DIST = 			\
+	$(plugin_in_files)	\
+	$(helperfile)		\
+	$(NULL)
+
+CLEANFILES = 			\
+	$(plugin_DATA)		\
+	$(NULL)
+
+DISTCLEANFILES =		\
+	$(plugin_DATA)		\
+	$(NULL)
+
+@GSD_INTLTOOL_PLUGIN_RULE@
Index: plugins/proxy/gsd-proxy-manager.c
===================================================================
--- /dev/null
+++ plugins/proxy/gsd-proxy-manager.c
@@ -0,0 +1,733 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Rodrigo Moya <rodrigo@gnome-db.org>
+ *
+ * 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 <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include "gnome-settings-profile.h"
+#include "gsd-proxy-manager.h"
+
+#define GSD_PROXY_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_PROXY_MANAGER, GsdProxyManagerPrivate))
+
+/* Novell extension */
+#define GSD_SETTINGS_PROXY_SCHEMA		"org.gnome.settings-daemon.plugins.proxy"
+#define KEY_USE_SYSTEM_SETTINGS			"use-system-settings"				/* string */
+#define VAL_USE_SYSTEM_SETTINGS_ONLY_IF_NOT_SET	"only_if_mode_not_set"
+#define VAL_USE_SYSTEM_SETTINGS_SYSTEM_VALUES	"system_values"
+#define VAL_USE_SYSTEM_SETTINGS_USER_VALUES	"user_values"
+
+#define ETC_SYSCONFIG_PROXY_URI			"file:///etc/sysconfig/proxy"
+
+/* Gnome keys */
+#define GNOME_SETTINGS_PROXY_SCHEMA		"org.gnome.system.proxy"
+#define KEY_PROXY_AUTOCONFIG_URL		"autoconfig-url"				/* string */
+#define KEY_PROXY_HTTP_IGNORE_HOSTS		"ignore-hosts"					/* list-of-string */
+#define KEY_PROXY_MODE				"mode"						/* string */
+#define KEY_HTTP_AUTHENTICATION_USER		"authentication-user"				/* string */
+#define KEY_HTTP_AUTHENTICATION_PASSWORD	"authentication-password"			/* string */
+#define KEY_HTTP_PROXY_ENABLED			"enabled"					/* bool */
+#define KEY_HTTP_USE_AUTHENTICATION		"use-authentication"				/* bool */
+#define KEY_HOST				"host"						/* string */
+#define KEY_PORT				"port"						/* bool */
+
+struct GsdProxyManagerPrivate
+{
+        GSettings *settings;
+        GSettings *settings_sys;
+        GSettings *settings_ftp;
+        GSettings *settings_http;
+        GSettings *settings_https;
+};
+
+typedef struct {
+        char *proxy_enabled;	/* "yes"/"no" */
+        char *http_proxy;	/* "http://host:port" */
+        char *https_proxy;    /* "http://host:port" */
+        char *ftp_proxy;	/* "http://host:port" */
+        /* char *gopher_proxy; Gnome doesn't have a Gopher proxy setting as of 2.10 */
+        char *no_proxy;	/* "www.me.de, do.main, localhost" */
+        /* char *user;
+           * char *password;
+           * Yast2 currently doesn't support a public username/password; they are just
+           * stored in /root/.wgetrc and /root/.curlrc
+           */
+} SystemSettings;
+
+static void     gsd_proxy_manager_class_init  (GsdProxyManagerClass *klass);
+static void     gsd_proxy_manager_init        (GsdProxyManager      *proxy_manager);
+static void     gsd_proxy_manager_finalize    (GObject             *object);
+
+G_DEFINE_TYPE (GsdProxyManager, gsd_proxy_manager, G_TYPE_OBJECT)
+
+static gpointer manager_object = NULL;
+
+/* Returns whether the org.gnome.system.proxy.mode key has ever been set by the user */
+static gboolean
+user_mode_is_set (GsdProxyManager *manager)
+{
+	char *value;
+
+	value = g_settings_get_string (manager->priv->settings_sys, KEY_PROXY_MODE);
+
+	/* FIXME Poke the default value */
+	if (value && strcmp (value, "none") != 0)
+	{
+		g_free (value);
+		return TRUE;
+	}
+
+	g_free (value);
+	return FALSE;
+}
+
+static const char *
+until_newline (const char *str, char **dest)
+{
+	const char *p;
+
+	p = strchr (str, '\n');
+	if (!p)
+		p = str + strlen (str);
+
+	if (dest)
+		*dest = g_strstrip (g_strndup (str, p - str));
+
+	return p;
+}
+
+static const char *
+scan_for_token_and_jump_until_newline (const char *buf, const char *token, char **dest)
+{
+	int len;
+
+	len = strlen (token);
+
+	if (strncmp (buf, token, len) == 0)
+		return until_newline (buf + len, dest);
+	else
+		return buf;
+}
+
+/* Reads the system's proxy settings */
+static void
+read_system_settings (SystemSettings *settings)
+{
+	char *out;
+	const char *p;
+	int total_len;
+	struct tokens {
+		const char *token;
+		char **dest;
+	} tokens[] = {
+		{ "PROXY_ENABLED ", &settings->proxy_enabled },
+		{ "HTTP_PROXY ",    &settings->http_proxy },
+		{ "HTTPS_PROXY ",   &settings->https_proxy },
+		{ "FTP_PROXY ",     &settings->ftp_proxy },
+		{ "NO_PROXY ",      &settings->no_proxy }
+	};
+	int num_tokens = G_N_ELEMENTS (tokens);
+
+	settings->proxy_enabled = NULL;
+	settings->http_proxy = NULL;
+	settings->https_proxy = NULL;
+	settings->ftp_proxy = NULL;
+	settings->no_proxy = NULL;
+
+	if (!g_spawn_command_line_sync (LIBEXECDIR "/novell-sysconfig-proxy-helper",
+					&out,
+					NULL,
+					NULL,
+					NULL))
+
+		return;
+
+	total_len = strlen (out);
+
+	p = out;
+	while (p < out + total_len)
+	{
+		int i;
+
+		for (i = 0; i < num_tokens; i++)
+			p = scan_for_token_and_jump_until_newline (p, tokens[i].token, tokens[i].dest);
+
+		if (i == num_tokens)
+			p = until_newline (p, NULL);
+
+		if (*p == '\n')
+			p++;
+	}
+
+	g_free (out);
+}
+
+static void
+system_settings_free (SystemSettings *settings)
+{
+	g_free (settings->proxy_enabled);
+	g_free (settings->http_proxy);
+	g_free (settings->https_proxy);
+	g_free (settings->ftp_proxy);
+	g_free (settings->no_proxy);
+}
+
+/* Disables the proxy in the user's settings */
+static void
+copy_proxy_disabled (GsdProxyManager *manager)
+{
+	g_settings_set_boolean (manager->priv->settings_http, KEY_HTTP_PROXY_ENABLED, FALSE);
+	g_settings_set_string (manager->priv->settings_sys, KEY_PROXY_MODE, "none");
+}
+
+
+
+/* The following two functions (the main one being gedit_utils_decode_uri) are
+ * stolen from gedit/gedit/gedit-utils.c.  This is because GIO doesn't yet
+ * export a function to parse URIs, sigh.
+ */
+
+static void
+null_ptr (gchar **ptr)
+{
+        if (ptr)
+                *ptr = NULL;
+}
+
+/**
+* gedit_utils_decode_uri:
+* @uri: the uri to decode
+* @scheme: return value pointer for the uri's scheme (e.g. http, sftp, ...)
+* @user: return value pointer for the uri user info
+* @port: return value pointer for the uri port
+* @host: return value pointer for the uri host
+* @path: return value pointer for the uri path
+*
+* Parse and break an uri apart in its individual components like the uri
+* scheme, user info, port, host and path. The return value pointer can be
+* NULL to ignore certain parts of the uri. If the function returns TRUE, then
+* all return value pointers should be freed using g_free
+*
+* Return value: TRUE if the uri could be properly decoded, FALSE otherwise.
+*/
+static gboolean
+gedit_utils_decode_uri (const gchar *uri,
+                        gchar **scheme,
+                        gchar **user,
+                        gchar **host,
+                        gchar **port,
+                        gchar **path)
+{
+	/* Largely copied from glib/gio/gdummyfile.c:_g_decode_uri. This
+         * functionality should be in glib/gio, but for now we implement it
+         * ourselves (see bug #546182) */
+
+        const char *p, *in, *hier_part_start, *hier_part_end;
+        char *out;
+        char c;
+
+	/* From RFC 3986 Decodes:
+         * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+         */
+
+        p = uri;
+
+        null_ptr (scheme);
+        null_ptr (user);
+        null_ptr (port);
+        null_ptr (host);
+        null_ptr (path);
+
+	/* Decode scheme:
+         * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+         */
+
+        if (!g_ascii_isalpha (*p))
+                return FALSE;
+
+        while (1) {
+                c = *p++;
+
+                if (c == ':')
+                        break;
+
+                if (!(g_ascii_isalnum(c) ||
+                      c == '+' ||
+                      c == '-' ||
+                      c == '.'))
+                        return FALSE;
+        }
+
+        if (scheme) {
+                *scheme = g_malloc (p - uri);
+                out = *scheme;
+
+                for (in = uri; in < p - 1; in++)
+                        *out++ = g_ascii_tolower (*in);
+
+                *out = '\0';
+        }
+
+        hier_part_start = p;
+        hier_part_end = p + strlen (p);
+
+        if (hier_part_start[0] == '/' && hier_part_start[1] == '/') {
+                const char *authority_start, *authority_end;
+                const char *userinfo_start, *userinfo_end;
+                const char *host_start, *host_end;
+                const char *port_start;
+
+                authority_start = hier_part_start + 2;
+		/* authority is always followed by / or nothing */
+                authority_end = memchr (authority_start, '/', hier_part_end - authority_start);
+
+                if (authority_end == NULL)
+                        authority_end = hier_part_end;
+
+		/* 3.2:
+                 * authority = [ userinfo "@" ] host [ ":" port ]
+                 */
+
+                userinfo_end = memchr (authority_start, '@', authority_end - authority_start);
+
+                if (userinfo_end) {
+                        userinfo_start = authority_start;
+
+                        if (user)
+                                *user = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL);
+
+                        if (user && *user == NULL) {
+                                if (scheme)
+                                        g_free (*scheme);
+
+                                return FALSE;
+                        }
+
+                        host_start = userinfo_end + 1;
+                } else
+                        host_start = authority_start;
+
+                port_start = memchr (host_start, ':', authority_end - host_start);
+
+                if (port_start) {
+                        host_end = port_start++;
+
+                        if (port)
+                                *port = g_strndup (port_start, authority_end - port_start);
+                } else
+                        host_end = authority_end;
+
+                if (host)
+                        *host = g_strndup (host_start, host_end - host_start);
+
+                hier_part_start = authority_end;
+        }
+
+        if (path)
+                *path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/");
+
+        return TRUE;
+}
+
+
+
+/* parses a URI to get the host and port */
+static gboolean
+parse_uri (const gchar *uri, gchar **host, guint *port)
+{
+        gchar *port_str;
+
+        if (!gedit_utils_decode_uri (uri,
+                                     NULL,     /* scheme */
+                                     NULL,     /* user */
+                                     host,     /* host */
+                                     &port_str, /* port */
+                                     NULL))    /* path */
+                return FALSE;
+
+        if (port_str) {
+                *port = atoi (port_str);
+                g_free (port_str);
+        } else
+                *port = 0;
+
+        g_debug ("Proxy host: %s:%d", *host, *port);
+
+        return TRUE;
+}
+
+/* Copies the (enabled) system proxy settings in the user's settings */
+static void
+copy_proxy_enabled (GsdProxyManager *manager, SystemSettings *settings)
+{
+        GsdProxyManagerPrivate *priv;
+	gchar *host;
+	guint port;
+
+	priv = manager->priv;
+	g_settings_set_string (priv->settings_sys, KEY_PROXY_MODE, "manual");
+
+	/* 1. HTTP proxy */
+
+	/* Yast2 currently doesn't support a public username/password */
+	g_settings_set_boolean (priv->settings_http, KEY_HTTP_USE_AUTHENTICATION, FALSE);
+	g_settings_set_string (priv->settings_http, KEY_HTTP_AUTHENTICATION_USER, "");
+	g_settings_set_string (priv->settings_http, KEY_HTTP_AUTHENTICATION_PASSWORD, "");
+
+	if (parse_uri (settings->http_proxy, &host, &port))
+	{
+		g_settings_set_boolean (priv->settings_http, KEY_HTTP_PROXY_ENABLED, TRUE);
+
+		g_settings_set_string (priv->settings_http, KEY_HOST, host);
+		g_settings_set_int (priv->settings_http, KEY_PORT, (int) port);
+
+		g_free (host);
+	}
+	else
+	{
+		g_settings_set_boolean (priv->settings_http, KEY_HTTP_PROXY_ENABLED, FALSE);
+		g_settings_set_string (priv->settings_http, KEY_HOST, "");
+		g_settings_set_int (priv->settings_http, KEY_PORT, 0);
+		g_settings_set_strv (priv->settings_sys, KEY_PROXY_HTTP_IGNORE_HOSTS, NULL);
+	}
+
+	/* 2. HTTPS proxy */
+
+	if (parse_uri (settings->https_proxy, &host, &port))
+	{
+		g_settings_set_string (priv->settings_https, KEY_HOST, host);
+		g_settings_set_int (priv->settings_https, KEY_PORT, (int) port);
+
+		g_free (host);
+	}
+	else
+	{
+		g_settings_set_string (priv->settings_https, KEY_HOST, "");
+		g_settings_set_int (priv->settings_https, KEY_PORT, 0);
+	}
+
+	/* 3. FTP proxy */
+
+	if (parse_uri (settings->ftp_proxy, &host, &port))
+	{
+		g_settings_set_string (priv->settings_ftp, KEY_HOST, host);
+		g_settings_set_int (priv->settings_ftp, KEY_PORT, (int) port);
+
+		g_free (host);
+	}
+	else
+	{
+		g_settings_set_string (priv->settings_ftp, KEY_HOST, "");
+		g_settings_set_int (priv->settings_ftp, KEY_PORT, 0);
+	}
+
+	/* 4. No-proxy hosts */
+
+	if (settings->no_proxy != NULL)
+	{
+		char **tokens;
+
+		tokens = g_strsplit_set (settings->no_proxy, ", ", 0);
+		g_settings_set_strv (priv->settings_sys, KEY_PROXY_HTTP_IGNORE_HOSTS, (const gchar * const*)tokens);
+		g_strfreev (tokens);
+	}
+	else
+		g_settings_set_strv (priv->settings_sys, KEY_PROXY_HTTP_IGNORE_HOSTS, NULL);
+}
+
+/* Copies the system's proxy settings to the user's settings */
+static void
+copy_system_to_user (GsdProxyManager *manager)
+{
+	SystemSettings settings;
+
+	read_system_settings (&settings);
+
+	if (settings.proxy_enabled == NULL)
+		copy_proxy_disabled (manager);
+	else
+	{
+		if (strcmp (settings.proxy_enabled, "no") == 0)
+			copy_proxy_disabled (manager);
+		else if (strcmp (settings.proxy_enabled, "yes") == 0)
+			copy_proxy_enabled (manager, &settings);
+	}
+
+	system_settings_free (&settings);
+}
+
+static void
+use_system_settings_change (GsdProxyManager *manager, const char *value)
+{
+	if (strcmp (value, VAL_USE_SYSTEM_SETTINGS_SYSTEM_VALUES) == 0)
+	{
+		copy_system_to_user (manager);
+	}
+	else if (strcmp (value, VAL_USE_SYSTEM_SETTINGS_USER_VALUES) == 0)
+	{
+		/* nothing; the user's values are already set */
+	}
+}
+
+static void
+settings_key_changed_cb (GSettings *gsettings, char *key, GsdProxyManager *manager)
+{
+	char *value;
+
+	if (strcmp (key, KEY_USE_SYSTEM_SETTINGS) == 0) {
+		value = g_settings_get_string (gsettings, key);
+		use_system_settings_change (manager, value);
+		g_free (value);
+	}
+}
+
+static void
+copy_system_values_if_needed (GsdProxyManager *manager)
+{
+	char *value;
+
+	value = g_settings_get_string (manager->priv->settings, KEY_USE_SYSTEM_SETTINGS);
+	if (!value)
+		return;
+
+	use_system_settings_change (manager, value);
+	g_free (value);
+}
+
+/* File monitor callback for /etc/sysconfig/proxy */
+static void
+monitor_cb (GFileMonitor *monitor,
+	    GFile *file,
+	    GFile *other_file,
+	    GFileMonitorEvent event_type,
+	    GsdProxyManager *manager)
+{
+	if (event_type != G_FILE_MONITOR_EVENT_CHANGED)
+		return;
+
+	copy_system_values_if_needed (manager);
+}
+
+gboolean
+gsd_proxy_manager_start (GsdProxyManager *manager,
+                         GError **error)
+{
+        GsdProxyManagerPrivate *priv;
+        GFile *sysconfig_proxy;
+        GFileMonitor *monitor;
+	char *use_system_settings;
+
+        priv = manager->priv;
+
+        g_debug ("Starting proxy manager");
+        gnome_settings_profile_start (NULL);
+
+        /* The very first time g-s-d is run, we change the user's keys if the new
+	 * use_system_settings key is not set at all or is set to the default.
+	 * Afterwards, that key will be set to reflect what the user had previously
+	 * configured.
+	 */
+
+	use_system_settings = g_settings_get_string (priv->settings, KEY_USE_SYSTEM_SETTINGS);
+	if (!use_system_settings || strcmp (use_system_settings, VAL_USE_SYSTEM_SETTINGS_ONLY_IF_NOT_SET) == 0)
+	{
+		if (user_mode_is_set (manager))
+                        g_settings_set_string (priv->settings, KEY_USE_SYSTEM_SETTINGS, VAL_USE_SYSTEM_SETTINGS_USER_VALUES);
+		else
+		{
+			copy_system_to_user (manager);
+			g_settings_set_string (priv->settings, KEY_USE_SYSTEM_SETTINGS, VAL_USE_SYSTEM_SETTINGS_SYSTEM_VALUES);
+		}
+	}
+
+	if (use_system_settings)
+		g_free (use_system_settings);
+
+        g_signal_connect (priv->settings, "changed", G_CALLBACK (settings_key_changed_cb), manager);
+
+        sysconfig_proxy = g_file_new_for_uri (ETC_SYSCONFIG_PROXY_URI);
+        monitor = g_file_monitor_file (sysconfig_proxy, 0, NULL, NULL);
+        g_signal_connect (monitor, "changed", G_CALLBACK (monitor_cb), manager);
+
+        copy_system_values_if_needed (manager);
+
+        gnome_settings_profile_end (NULL);
+
+        return TRUE;
+}
+
+void
+gsd_proxy_manager_stop (GsdProxyManager *manager)
+{
+        g_debug ("Stopping proxy manager");
+}
+
+static void
+gsd_proxy_manager_set_property (GObject        *object,
+                               guint           prop_id,
+                               const GValue   *value,
+                               GParamSpec     *pspec)
+{
+        GsdProxyManager *self;
+
+        self = GSD_PROXY_MANAGER (object);
+
+        switch (prop_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gsd_proxy_manager_get_property (GObject        *object,
+                               guint           prop_id,
+                               GValue         *value,
+                               GParamSpec     *pspec)
+{
+        GsdProxyManager *self;
+
+        self = GSD_PROXY_MANAGER (object);
+
+        switch (prop_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static GObject *
+gsd_proxy_manager_constructor (GType                  type,
+                              guint                  n_construct_properties,
+                              GObjectConstructParam *construct_properties)
+{
+        GsdProxyManager      *proxy_manager;
+        GsdProxyManagerClass *klass;
+
+        klass = GSD_PROXY_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_PROXY_MANAGER));
+
+        proxy_manager = GSD_PROXY_MANAGER (G_OBJECT_CLASS (gsd_proxy_manager_parent_class)->constructor (type,
+                                                                                                      n_construct_properties,
+                                                                                                      construct_properties));
+
+        return G_OBJECT (proxy_manager);
+}
+
+static void
+gsd_proxy_manager_dispose (GObject *object)
+{
+        GsdProxyManager *proxy_manager;
+        GsdProxyManagerPrivate *priv;
+
+        proxy_manager = GSD_PROXY_MANAGER (object);
+        priv = proxy_manager->priv;
+
+        if (priv->settings) {
+                g_object_unref (priv->settings);
+                priv->settings = NULL;
+        }
+        if (priv->settings_sys) {
+                g_object_unref (priv->settings_sys);
+                priv->settings_sys = NULL;
+        }
+        if (priv->settings_ftp) {
+                g_object_unref (priv->settings_ftp);
+                priv->settings_ftp = NULL;
+        }
+        if (priv->settings_http) {
+                g_object_unref (priv->settings_http);
+                priv->settings_http = NULL;
+        }
+        if (priv->settings_https) {
+                g_object_unref (priv->settings_https);
+                priv->settings_https = NULL;
+        }
+
+        G_OBJECT_CLASS (gsd_proxy_manager_parent_class)->dispose (object);
+}
+
+static void
+gsd_proxy_manager_class_init (GsdProxyManagerClass *klass)
+{
+        GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->get_property = gsd_proxy_manager_get_property;
+        object_class->set_property = gsd_proxy_manager_set_property;
+        object_class->constructor = gsd_proxy_manager_constructor;
+        object_class->dispose = gsd_proxy_manager_dispose;
+        object_class->finalize = gsd_proxy_manager_finalize;
+
+        g_type_class_add_private (klass, sizeof (GsdProxyManagerPrivate));
+}
+
+static void
+gsd_proxy_manager_init (GsdProxyManager *manager)
+{
+        manager->priv = GSD_PROXY_MANAGER_GET_PRIVATE (manager);
+        manager->priv->settings = g_settings_new (GSD_SETTINGS_PROXY_SCHEMA);
+        manager->priv->settings_sys = g_settings_new (GNOME_SETTINGS_PROXY_SCHEMA);
+        manager->priv->settings_ftp = g_settings_get_child (manager->priv->settings_sys, "ftp");
+        manager->priv->settings_http = g_settings_get_child (manager->priv->settings_sys, "http");
+        manager->priv->settings_https = g_settings_get_child (manager->priv->settings_sys, "https");
+}
+
+static void
+gsd_proxy_manager_finalize (GObject *object)
+{
+        GsdProxyManager *proxy_manager;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GSD_IS_PROXY_MANAGER (object));
+
+        proxy_manager = GSD_PROXY_MANAGER (object);
+
+        g_return_if_fail (proxy_manager->priv != NULL);
+
+        G_OBJECT_CLASS (gsd_proxy_manager_parent_class)->finalize (object);
+}
+
+GsdProxyManager *
+gsd_proxy_manager_new (void)
+{
+        if (manager_object != NULL) {
+                g_object_ref (manager_object);
+        } else {
+                manager_object = g_object_new (GSD_TYPE_PROXY_MANAGER, NULL);
+                g_object_add_weak_pointer (manager_object,
+                                           (gpointer *) &manager_object);
+        }
+
+        return GSD_PROXY_MANAGER (manager_object);
+}
Index: plugins/proxy/gsd-proxy-manager.h
===================================================================
--- /dev/null
+++ plugins/proxy/gsd-proxy-manager.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Rodrigo Moya <rodrigo@gnome-db.org>
+ *
+ * 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 __GSD_PROXY_MANAGER_H
+#define __GSD_PROXY_MANAGER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GSD_TYPE_PROXY_MANAGER         (gsd_proxy_manager_get_type ())
+#define GSD_PROXY_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_PROXY_MANAGER, GsdProxyManager))
+#define GSD_PROXY_MANAGER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_PROXY_MANAGER, GsdProxyManagerClass))
+#define GSD_IS_PROXY_MANAGER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_PROXY_MANAGER))
+#define GSD_IS_PROXY_MANAGER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_PROXY_MANAGER))
+#define GSD_PROXY_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_PROXY_MANAGER, GsdProxyManagerClass))
+
+typedef struct GsdProxyManagerPrivate GsdProxyManagerPrivate;
+
+typedef struct
+{
+        GObject                     parent;
+        GsdProxyManagerPrivate *priv;
+} GsdProxyManager;
+
+typedef struct
+{
+        GObjectClass   parent_class;
+} GsdProxyManagerClass;
+
+GType                   gsd_proxy_manager_get_type            (void);
+
+GsdProxyManager *       gsd_proxy_manager_new                 (void);
+gboolean                gsd_proxy_manager_start               (GsdProxyManager *manager,
+                                                               GError         **error);
+void                    gsd_proxy_manager_stop                (GsdProxyManager *manager);
+
+G_END_DECLS
+
+#endif /* __GSD_PROXY_MANAGER_H */
Index: plugins/proxy/gsd-proxy-plugin.c
===================================================================
--- /dev/null
+++ plugins/proxy/gsd-proxy-plugin.c
@@ -0,0 +1,109 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Rodrigo Moya <rodrigo@gnome-db.org>
+ *
+ * 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, 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 <glib/gi18n-lib.h>
+#include <gmodule.h>
+
+#include "gnome-settings-plugin.h"
+#include "gsd-proxy-plugin.h"
+#include "gsd-proxy-manager.h"
+
+struct GsdProxyPluginPrivate {
+        GsdProxyManager *manager;
+};
+
+#define GSD_PROXY_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_PROXY_PLUGIN, GsdProxyPluginPrivate))
+
+GNOME_SETTINGS_PLUGIN_REGISTER (GsdProxyPlugin, gsd_proxy_plugin)
+
+static void
+gsd_proxy_plugin_init (GsdProxyPlugin *plugin)
+{
+        plugin->priv = GSD_PROXY_PLUGIN_GET_PRIVATE (plugin);
+
+        g_debug ("GsdProxyPlugin initializing");
+
+        plugin->priv->manager = gsd_proxy_manager_new ();
+}
+
+static void
+gsd_proxy_plugin_finalize (GObject *object)
+{
+        GsdProxyPlugin *plugin;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GSD_IS_PROXY_PLUGIN (object));
+
+        g_debug ("GsdProxyPlugin finalizing");
+
+        plugin = GSD_PROXY_PLUGIN (object);
+
+        g_return_if_fail (plugin->priv != NULL);
+
+        if (plugin->priv->manager != NULL) {
+                g_object_unref (plugin->priv->manager);
+        }
+
+        G_OBJECT_CLASS (gsd_proxy_plugin_parent_class)->finalize (object);
+}
+
+static void
+impl_activate (GnomeSettingsPlugin *plugin)
+{
+        gboolean res;
+        GError  *error;
+
+        g_debug ("Activating proxy plugin");
+
+        error = NULL;
+        res = gsd_proxy_manager_start (GSD_PROXY_PLUGIN (plugin)->priv->manager, &error);
+        if (! res) {
+                g_warning ("Unable to start proxy manager: %s", error->message);
+                g_error_free (error);
+        }
+}
+
+static void
+impl_deactivate (GnomeSettingsPlugin *plugin)
+{
+        g_debug ("Deactivating proxy plugin");
+        gsd_proxy_manager_stop (GSD_PROXY_PLUGIN (plugin)->priv->manager);
+}
+
+static void
+gsd_proxy_plugin_class_init (GsdProxyPluginClass *klass)
+{
+        GObjectClass           *object_class = G_OBJECT_CLASS (klass);
+        GnomeSettingsPluginClass *plugin_class = GNOME_SETTINGS_PLUGIN_CLASS (klass);
+
+        object_class->finalize = gsd_proxy_plugin_finalize;
+
+        plugin_class->activate = impl_activate;
+        plugin_class->deactivate = impl_deactivate;
+
+        g_type_class_add_private (klass, sizeof (GsdProxyPluginPrivate));
+}
+
+static void
+gsd_proxy_plugin_class_finalize (GsdProxyPluginClass *klass)
+{
+}
Index: plugins/proxy/gsd-proxy-plugin.h
===================================================================
--- /dev/null
+++ plugins/proxy/gsd-proxy-plugin.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Rodrigo Moya <rodrigo@gnome-db.org>
+ *
+ * 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, 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 __GSD_PROXY_PLUGIN_H__
+#define __GSD_PROXY_PLUGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gmodule.h>
+
+#include "gnome-settings-plugin.h"
+
+G_BEGIN_DECLS
+
+#define GSD_TYPE_PROXY_PLUGIN                (gsd_proxy_plugin_get_type ())
+#define GSD_PROXY_PLUGIN(o)                  (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_PROXY_PLUGIN, GsdProxyPlugin))
+#define GSD_PROXY_PLUGIN_CLASS(k)            (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_PROXY_PLUGIN, GsdProxyPluginClass))
+#define GSD_IS_PROXY_PLUGIN(o)               (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_PROXY_PLUGIN))
+#define GSD_IS_PROXY_PLUGIN_CLASS(k)         (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_PROXY_PLUGIN))
+#define GSD_PROXY_PLUGIN_GET_CLASS(o)        (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_PROXY_PLUGIN, GsdProxyPluginClass))
+
+typedef struct GsdProxyPluginPrivate GsdProxyPluginPrivate;
+
+typedef struct
+{
+        GnomeSettingsPlugin    parent;
+        GsdProxyPluginPrivate *priv;
+} GsdProxyPlugin;
+
+typedef struct
+{
+        GnomeSettingsPluginClass parent_class;
+} GsdProxyPluginClass;
+
+GType   gsd_proxy_plugin_get_type            (void) G_GNUC_CONST;
+
+/* All the plugins must implement this function */
+G_MODULE_EXPORT GType register_gnome_settings_plugin (GTypeModule *module);
+
+G_END_DECLS
+
+#endif /* __GSD_PROXY_PLUGIN_H__ */
Index: plugins/proxy/novell-sysconfig-proxy-helper
===================================================================
--- /dev/null
+++ plugins/proxy/novell-sysconfig-proxy-helper
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+if [ ! -f /etc/sysconfig/proxy ]
+then
+	exit 0
+fi
+
+source /etc/sysconfig/proxy
+
+# This may look convoluted, but it's an easy way to let random shell
+# script code appear in /etc/sysconfig/proxy and still let user code
+# read the variables in it easily.
+
+echo "PROXY_ENABLED $PROXY_ENABLED"
+echo "HTTP_PROXY $HTTP_PROXY"
+echo "HTTPS_PROXY $HTTPS_PROXY"
+echo "FTP_PROXY $FTP_PROXY"
+echo "GOPHER_PROXY $GOPHER_PROXY"
+echo "NO_PROXY $NO_PROXY"
Index: plugins/proxy/proxy.gnome-settings-plugin.in
===================================================================
--- /dev/null
+++ plugins/proxy/proxy.gnome-settings-plugin.in
@@ -0,0 +1,8 @@
+[GNOME Settings Plugin]
+Module=proxy
+IAge=0
+_Name=Network Proxy
+_Description=Network proxy plugin
+Authors=Rodrigo Moya <rodrigo@gnome-db.org>
+Copyright=
+Website=
Index: plugins/Makefile.am
===================================================================
--- plugins/Makefile.am.orig
+++ plugins/Makefile.am
@@ -15,6 +15,7 @@ enabled_plugins =	\
 	keyboard	\
 	media-keys	\
 	mouse		\
+	proxy		\
 	sound		\
 	wacom		\
 	xrandr		\
Index: configure.ac
===================================================================
--- configure.ac.orig
+++ configure.ac
@@ -575,6 +575,7 @@ plugins/media-keys/cut-n-paste/Makefile
 plugins/mouse/Makefile
 plugins/orientation/Makefile
 plugins/print-notifications/Makefile
+plugins/proxy/Makefile
 plugins/smartcard/Makefile
 plugins/sound/Makefile
 plugins/updates/Makefile
@@ -598,6 +599,7 @@ data/org.gnome.settings-daemon.plugins.u
 data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in
 data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in
 data/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml.in
+data/org.gnome.settings-daemon.plugins.proxy.gschema.xml.in
 po/Makefile.in
 ])
 
Index: data/Makefile.am
===================================================================
--- data/Makefile.am.orig
+++ data/Makefile.am
@@ -16,6 +16,7 @@ gsettings_SCHEMAS =							\
 	org.gnome.settings-daemon.plugins.xsettings.gschema.xml		\
 	org.gnome.settings-daemon.plugins.housekeeping.gschema.xml	\
 	org.gnome.settings-daemon.plugins.print-notifications.gschema.xml	\
+	org.gnome.settings-daemon.plugins.proxy.gschema.xml		\
 	org.gnome.settings-daemon.peripherals.wacom.gschema.xml		\
 	org.gnome.settings-daemon.plugins.xrandr.gschema.xml
 
Index: data/gnome-settings-daemon.convert
===================================================================
--- data/gnome-settings-daemon.convert.orig
+++ data/gnome-settings-daemon.convert
@@ -79,6 +79,11 @@ left-handed = /desktop/gnome/peripherals
 motion-acceleration = /desktop/gnome/peripherals/mouse/motion_acceleration
 motion-threshold = /desktop/gnome/peripherals/mouse/motion_threshold
 
+[org.gnome.settings-daemon.plugins.proxy]
+active = /apps/gnome_settings_daemon/plugins/proxy/active
+priority = /apps/gnome_settings_daemon/plugins/proxy/priority
+use-system-settings = /system/proxy/use_system_settings
+
 [org.gnome.settings-daemon.plugins.smartcard]
 active = /apps/gnome_settings_daemon/plugins/smartcard/active
 priority = /apps/gnome_settings_daemon/plugins/smartcard/priority
Index: data/org.gnome.settings-daemon.plugins.proxy.gschema.xml.in.in
===================================================================
--- /dev/null
+++ data/org.gnome.settings-daemon.plugins.proxy.gschema.xml.in.in
@@ -0,0 +1,19 @@
+<schemalist>
+  <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.proxy" path="/org/gnome/settings-daemon/plugins/proxy/">
+    <key name="active" type="b">
+      <default>true</default>
+      <_summary>Activation of this plugin</_summary>
+      <_description>Whether this plugin would be activated by gnome-settings-daemon or not</_description>
+    </key>
+    <key name="priority" type="i">
+      <default>7</default>
+      <_summary>Priority to use for this plugin</_summary>
+      <_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
+    </key>
+    <key name="use-system-settings" type="s">
+      <default>'only_if_mode_not_set'</default>
+      <summary>Use the system's proxy settings</summary>
+      <description>Whether to use the system's proxy settings. Possible values are "only_if_mode_not_set", "system_values", and "user_values".  The first one is the default value; in it, the system's proxy settings will be used if and only if the user has never set his org.gnome.system.proxy.mode key.  Once the user sets that key, use-system-settings will switch to "system_values", which indicates that the system's proxy settings should be used, or "user_values", which indicates that the user's settings should be used.  The key will alternate between these last two values in the future and will not go back to the default value.</description>
+    </key>
+  </schema>
+</schemalist>
openSUSE Build Service is sponsored by