From e61dc951c432d489b17e3bdaf1e566ac15958c6b Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero 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 + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 + +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 + * + * 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 +#include + +#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 + * + * 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 +#include +#include + +#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 +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 @@ + + + + true + <_summary>Activation of this plugin + <_description>Whether this plugin would be activated by gnome-settings-daemon or not + + + 7 + <_summary>Priority to use for this plugin + <_description>Priority to use for this plugin in gnome-settings-daemon startup queue + + + 'only_if_mode_not_set' + Use the system's proxy settings + 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. + + +