5
* Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License version 2 as
9
* published by the Free Software Foundation.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30
#define CONNMAN_API_SUBJECT_TO_CHANGE
31
#include <connman/plugin.h>
32
#include <connman/notifier.h>
33
#include <connman/dbus.h>
34
#include <connman/log.h>
36
#define PACRUNNER_SERVICE "org.pacrunner"
37
#define PACRUNNER_INTERFACE "org.pacrunner.Manager"
38
#define PACRUNNER_PATH "/org/pacrunner/manager"
40
#define DBUS_TIMEOUT 5000
42
static DBusConnection *connection;
43
static dbus_bool_t daemon_running = FALSE;
45
static struct connman_service *default_service = NULL;
46
static char *current_config = NULL;
48
static void create_config_reply(DBusPendingCall *call, void *user_data)
50
DBusMessage *reply = dbus_pending_call_steal_reply(call);
55
if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
56
connman_error("Failed to create proxy configuration");
60
if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
61
DBUS_TYPE_INVALID) == FALSE)
64
g_free(current_config);
65
current_config = g_strdup(path);
68
dbus_message_unref(reply);
71
static void append_string(DBusMessageIter *iter, void *user_data)
73
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, user_data);
76
static void append_string_list(DBusMessageIter *iter, void *user_data)
78
char **list = user_data;
81
for (i = 0; list[i] != NULL; i++)
82
dbus_message_iter_append_basic(iter,
83
DBUS_TYPE_STRING, &list[i]);
86
static void create_proxy_configuration(void)
89
DBusMessageIter iter, dict;
90
DBusPendingCall *call;
97
if (default_service == NULL)
102
msg = dbus_message_new_method_call(PACRUNNER_SERVICE, PACRUNNER_PATH,
103
PACRUNNER_INTERFACE, "CreateProxyConfiguration");
107
dbus_message_set_auto_start(msg, FALSE);
109
dbus_message_iter_init_append(msg, &iter);
110
connman_dbus_dict_open(&iter, &dict);
112
switch(connman_service_get_proxy_method(default_service)) {
113
case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
115
case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
118
case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
121
str_list = connman_service_get_proxy_servers(default_service);
122
if (str_list == NULL)
125
connman_dbus_dict_append_array(&dict, "Servers",
126
DBUS_TYPE_STRING, append_string_list,
128
g_strfreev(str_list);
130
str_list = connman_service_get_proxy_excludes(default_service);
131
if (str_list == NULL)
134
connman_dbus_dict_append_array(&dict, "Excludes",
135
DBUS_TYPE_STRING, append_string_list,
137
g_strfreev(str_list);
140
case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
143
str = connman_service_get_proxy_url(default_service);
145
str = connman_service_get_proxy_autoconfig(
151
connman_dbus_dict_append_basic(&dict, "URL",
152
DBUS_TYPE_STRING, &str);
156
connman_dbus_dict_append_basic(&dict, "Method",
157
DBUS_TYPE_STRING, &method);
159
interface = connman_service_get_interface(default_service);
160
if (interface != NULL) {
161
connman_dbus_dict_append_basic(&dict, "Interface",
162
DBUS_TYPE_STRING, &interface);
166
str = connman_service_get_domainname(default_service);
168
connman_dbus_dict_append_array(&dict, "Domains",
169
DBUS_TYPE_STRING, append_string, &str);
171
str = connman_service_get_nameserver(default_service);
173
connman_dbus_dict_append_array(&dict, "Nameservers",
174
DBUS_TYPE_STRING, append_string, &str);
176
connman_dbus_dict_close(&iter, &dict);
178
result = dbus_connection_send_with_reply(connection, msg,
179
&call, DBUS_TIMEOUT);
181
if (result == FALSE || call == NULL)
184
dbus_pending_call_set_notify(call, create_config_reply, NULL, NULL);
186
dbus_pending_call_unref(call);
189
dbus_message_unref(msg);
192
static void destroy_config_reply(DBusPendingCall *call, void *user_data)
194
DBusMessage *reply = dbus_pending_call_steal_reply(call);
198
if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
199
connman_error("Failed to destoy proxy configuration");
201
dbus_message_unref(reply);
204
static void destroy_proxy_configuration(void)
207
DBusPendingCall *call;
210
if (current_config == NULL)
215
msg = dbus_message_new_method_call(PACRUNNER_SERVICE, PACRUNNER_PATH,
216
PACRUNNER_INTERFACE, "DestroyProxyConfiguration");
220
dbus_message_set_auto_start(msg, FALSE);
222
dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, ¤t_config,
225
result = dbus_connection_send_with_reply(connection, msg,
226
&call, DBUS_TIMEOUT);
228
dbus_message_unref(msg);
230
if (result == FALSE || call == NULL)
233
dbus_pending_call_set_notify(call, destroy_config_reply, NULL, NULL);
235
dbus_pending_call_unref(call);
237
g_free(current_config);
238
current_config = NULL;
241
static void default_service_changed(struct connman_service *service)
243
DBG("service %p", service);
245
if (service == default_service)
248
default_service = service;
250
if (daemon_running == FALSE)
253
destroy_proxy_configuration();
255
create_proxy_configuration();
258
static struct connman_notifier pacrunner_notifier = {
260
.default_changed = default_service_changed,
263
static void pacrunner_connect(DBusConnection *conn, void *user_data)
267
daemon_running = TRUE;
269
create_proxy_configuration();
272
static void pacrunner_disconnect(DBusConnection *conn, void *user_data)
276
daemon_running = FALSE;
278
g_free(current_config);
279
current_config = NULL;
282
static guint pacrunner_watch;
284
static int pacrunner_init(void)
286
connection = connman_dbus_get_connection();
287
if (connection == NULL)
290
pacrunner_watch = g_dbus_add_service_watch(connection,
291
PACRUNNER_SERVICE, pacrunner_connect,
292
pacrunner_disconnect, NULL, NULL);
293
if (pacrunner_watch == 0) {
294
dbus_connection_unref(connection);
298
connman_notifier_register(&pacrunner_notifier);
303
static void pacrunner_exit(void)
305
connman_notifier_unregister(&pacrunner_notifier);
307
g_dbus_remove_watch(connection, pacrunner_watch);
309
destroy_proxy_configuration();
311
dbus_connection_unref(connection);
314
CONNMAN_PLUGIN_DEFINE(pacrunner, "PAC runner proxy plugin", VERSION,
315
CONNMAN_PLUGIN_PRIORITY_DEFAULT, pacrunner_init, pacrunner_exit)