summaryrefslogtreecommitdiff
path: root/plugins/pacrunner.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2010-09-20 10:02:47 +0900
committerMarcel Holtmann <marcel@holtmann.org>2010-09-20 10:02:47 +0900
commitc9f804e1cce4290834b39e937e2a228960e88869 (patch)
tree1b92fd732ffe6160ba0aa9dca017d5f39170537f /plugins/pacrunner.c
parentf5b744f0ea6fea2a2738701d38a11737692183f7 (diff)
downloadconnman-c9f804e1cce4290834b39e937e2a228960e88869.tar.gz
connman-c9f804e1cce4290834b39e937e2a228960e88869.tar.bz2
connman-c9f804e1cce4290834b39e937e2a228960e88869.zip
Add support for PAC runner configuration updates
Diffstat (limited to 'plugins/pacrunner.c')
-rw-r--r--plugins/pacrunner.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/plugins/pacrunner.c b/plugins/pacrunner.c
index 06a309db..82fd8fb9 100644
--- a/plugins/pacrunner.c
+++ b/plugins/pacrunner.c
@@ -23,16 +23,227 @@
#include <config.h>
#endif
+#include <errno.h>
+
+#include <gdbus.h>
+
#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
+#include <connman/notifier.h>
+#include <connman/dbus.h>
+#include <connman/log.h>
+
+#define PACRUNNER_SERVICE "org.pacrunner"
+#define PACRUNNER_INTERFACE "org.pacrunner.Manager"
+#define PACRUNNER_PATH "/org/pacrunner/manager"
+
+#define DBUS_TIMEOUT 5000
+
+static DBusConnection *connection;
+
+static struct connman_service *default_service = NULL;
+static char *current_config = NULL;
+
+static void create_config_reply(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ const char *path;
+
+ DBG("");
+
+ if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+ connman_error("Failed to create proxy configuration");
+ goto done;
+ }
+
+ if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID) == FALSE)
+ goto done;
+
+ g_free(current_config);
+ current_config = g_strdup(path);
+
+done:
+ dbus_message_unref(reply);
+}
+
+static void add_dict_with_string_value(DBusMessageIter *iter,
+ const char *key, const char *str)
+{
+ DBusMessageIter dict, entry, value;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+ dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_STRING_AS_STRING, &value);
+ dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &str);
+ dbus_message_iter_close_container(&entry, &value);
+
+ dbus_message_iter_close_container(&dict, &entry);
+ dbus_message_iter_close_container(iter, &dict);
+}
+
+static void create_proxy_configuration(const char *url)
+{
+ DBusMessage *msg;
+ DBusMessageIter iter;
+ DBusPendingCall *call;
+ dbus_bool_t result;
+
+ if (url == NULL)
+ return;
+
+ DBG("url %s", url);
+
+ msg = dbus_message_new_method_call(PACRUNNER_SERVICE, PACRUNNER_PATH,
+ PACRUNNER_INTERFACE, "CreateProxyConfiguration");
+ if (msg == NULL)
+ return;
+
+ dbus_message_set_auto_start(msg, FALSE);
+
+ dbus_message_iter_init_append(msg, &iter);
+ add_dict_with_string_value(&iter, "URL", url);
+
+ result = dbus_connection_send_with_reply(connection, msg,
+ &call, DBUS_TIMEOUT);
+
+ dbus_message_unref(msg);
+
+ if (result == FALSE || call == NULL)
+ return;
+
+ dbus_pending_call_set_notify(call, create_config_reply, NULL, NULL);
+
+ dbus_pending_call_unref(call);
+}
+
+static void destroy_config_reply(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+
+ DBG("");
+
+ if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+ connman_error("Failed to destoy proxy configuration");
+
+ dbus_message_unref(reply);
+}
+
+static void destroy_proxy_configuration(void)
+{
+ DBusMessage *msg;
+ DBusPendingCall *call;
+ dbus_bool_t result;
+
+ if (current_config == NULL)
+ return;
+
+ DBG("");
+
+ msg = dbus_message_new_method_call(PACRUNNER_SERVICE, PACRUNNER_PATH,
+ PACRUNNER_INTERFACE, "DestroyProxyConfiguration");
+ if (msg == NULL)
+ return;
+
+ dbus_message_set_auto_start(msg, FALSE);
+
+ dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &current_config,
+ DBUS_TYPE_INVALID);
+
+ result = dbus_connection_send_with_reply(connection, msg,
+ &call, DBUS_TIMEOUT);
+
+ dbus_message_unref(msg);
+
+ if (result == FALSE || call == NULL)
+ return;
+
+ dbus_pending_call_set_notify(call, destroy_config_reply, NULL, NULL);
+
+ dbus_pending_call_unref(call);
+
+ g_free(current_config);
+ current_config = NULL;
+}
+
+static void default_service_changed(struct connman_service *service)
+{
+ const char *url;
+
+ DBG("service %p", service);
+
+ if (service == default_service)
+ return;
+
+ default_service = service;
+
+ destroy_proxy_configuration();
+
+ url = connman_service_get_proxy_autoconfig(service);
+ create_proxy_configuration(url);
+}
+
+static struct connman_notifier pacrunner_notifier = {
+ .name = "pacrunner",
+ .default_changed = default_service_changed,
+};
+
+static void pacrunner_connect(DBusConnection *conn, void *user_data)
+{
+ const char *url;
+
+ DBG("");
+
+ url = connman_service_get_proxy_autoconfig(default_service);
+ create_proxy_configuration(url);
+}
+
+static void pacrunner_disconnect(DBusConnection *conn, void *user_data)
+{
+ DBG("");
+
+ g_free(current_config);
+ current_config = NULL;
+}
+
+static guint pacrunner_watch;
static int pacrunner_init(void)
{
+ connection = connman_dbus_get_connection();
+ if (connection == NULL)
+ return -EIO;
+
+ pacrunner_watch = g_dbus_add_service_watch(connection,
+ PACRUNNER_SERVICE, pacrunner_connect,
+ pacrunner_disconnect, NULL, NULL);
+ if (pacrunner_watch == 0) {
+ dbus_connection_unref(connection);
+ return -EIO;
+ }
+
+ connman_notifier_register(&pacrunner_notifier);
+
return 0;
}
static void pacrunner_exit(void)
{
+ connman_notifier_unregister(&pacrunner_notifier);
+
+ g_dbus_remove_watch(connection, pacrunner_watch);
+
+ destroy_proxy_configuration();
+
+ dbus_connection_unref(connection);
}
CONNMAN_PLUGIN_DEFINE(pacrunner, "PAC runner proxy plugin", VERSION,