summaryrefslogtreecommitdiff
path: root/libnm-glib/nm-settings-service.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-glib/nm-settings-service.c')
-rw-r--r--libnm-glib/nm-settings-service.c372
1 files changed, 372 insertions, 0 deletions
diff --git a/libnm-glib/nm-settings-service.c b/libnm-glib/nm-settings-service.c
new file mode 100644
index 000000000..6266d10da
--- /dev/null
+++ b/libnm-glib/nm-settings-service.c
@@ -0,0 +1,372 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Novell, Inc.
+ * (C) Copyright 2008 - 2009 Red Hat, Inc.
+ */
+
+#include <string.h>
+#include <NetworkManager.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "nm-settings-service.h"
+#include "nm-settings-interface.h"
+#include "nm-exported-connection.h"
+
+static gboolean impl_settings_list_connections (NMSettingsService *self,
+ GPtrArray **connections,
+ GError **error);
+
+static void impl_settings_add_connection (NMSettingsService *self,
+ GHashTable *settings,
+ DBusGMethodInvocation *context);
+
+#include "nm-settings-glue.h"
+
+static void settings_interface_init (NMSettingsInterface *class);
+
+G_DEFINE_TYPE_EXTENDED (NMSettingsService, nm_settings_service, G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, settings_interface_init))
+
+#define NM_SETTINGS_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ NM_TYPE_SETTINGS_SERVICE, \
+ NMSettingsServicePrivate))
+
+typedef struct {
+ DBusGConnection *bus;
+ NMConnectionScope scope;
+ gboolean exported;
+
+ gboolean disposed;
+} NMSettingsServicePrivate;
+
+enum {
+ PROP_0,
+ PROP_BUS,
+ PROP_SCOPE,
+
+ LAST_PROP
+};
+
+
+/**************************************************************/
+
+void
+nm_settings_service_export (NMSettingsService *self)
+{
+ NMSettingsServicePrivate *priv;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (NM_IS_SETTINGS_SERVICE (self));
+
+ priv = NM_SETTINGS_SERVICE_GET_PRIVATE (self);
+
+ g_return_if_fail (priv->bus != NULL);
+
+ /* Don't allow exporting twice */
+ g_return_if_fail (priv->exported == FALSE);
+
+ dbus_g_connection_register_g_object (priv->bus,
+ NM_DBUS_PATH_SETTINGS,
+ G_OBJECT (self));
+ priv->exported = TRUE;
+}
+
+/**************************************************************/
+
+static GSList *
+list_connections (NMSettingsInterface *settings)
+{
+ /* Must always be implemented */
+ g_assert (NM_SETTINGS_SERVICE_GET_CLASS (settings)->list_connections);
+ return NM_SETTINGS_SERVICE_GET_CLASS (settings)->list_connections (NM_SETTINGS_SERVICE (settings));
+}
+
+static gboolean
+impl_settings_list_connections (NMSettingsService *self,
+ GPtrArray **connections,
+ GError **error)
+{
+ GSList *list = NULL, *iter;
+
+ list = list_connections (NM_SETTINGS_INTERFACE (self));
+ *connections = g_ptr_array_sized_new (g_slist_length (list) + 1);
+ for (iter = list; iter; iter = g_slist_next (iter)) {
+ g_ptr_array_add (*connections,
+ g_strdup (nm_connection_get_path (NM_CONNECTION (iter->data))));
+ }
+ g_slist_free (list);
+ return TRUE;
+}
+
+static NMSettingsConnectionInterface *
+get_connection_by_path (NMSettingsInterface *settings, const char *path)
+{
+ NMExportedConnection *connection = NULL;
+ GSList *list = NULL, *iter;
+
+ list = list_connections (settings);
+ for (iter = list; iter; iter = g_slist_next (iter)) {
+ if (!strcmp (nm_connection_get_path (NM_CONNECTION (iter->data)), path)) {
+ connection = NM_EXPORTED_CONNECTION (iter->data);
+ break;
+ }
+ }
+ g_slist_free (list);
+
+ return (NMSettingsConnectionInterface *) connection;
+}
+
+NMExportedConnection *
+nm_settings_service_get_connection_by_path (NMSettingsService *self,
+ const char *path)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SETTINGS_SERVICE (self), NULL);
+
+ return (NMExportedConnection *) get_connection_by_path (NM_SETTINGS_INTERFACE (self), path);
+}
+
+static gboolean
+add_connection (NMSettingsInterface *settings,
+ NMConnection *connection,
+ NMSettingsAddConnectionFunc callback,
+ gpointer user_data)
+{
+ NMSettingsService *self = NM_SETTINGS_SERVICE (settings);
+ GError *error = NULL;
+ gboolean success = FALSE;
+
+ if (NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection) {
+ NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection (NM_SETTINGS_SERVICE (self),
+ connection,
+ NULL,
+ callback,
+ user_data);
+ success = TRUE;
+ } else {
+ error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "%s: %s:%d add_connection() not implemented",
+ __func__, __FILE__, __LINE__);
+ callback (settings, error, user_data);
+ g_error_free (error);
+ }
+
+ return success;
+}
+
+static void
+dbus_add_connection_cb (NMSettingsInterface *settings,
+ GError *error,
+ gpointer user_data)
+{
+ DBusGMethodInvocation *context = user_data;
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context);
+}
+
+static void
+impl_settings_add_connection (NMSettingsService *self,
+ GHashTable *settings,
+ DBusGMethodInvocation *context)
+{
+ NMConnection *tmp;
+ GError *error = NULL;
+
+ /* Check if the settings are valid first */
+ tmp = nm_connection_new_from_hash (settings, &error);
+ if (!tmp) {
+ g_assert (error);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ if (NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection) {
+ NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection (NM_SETTINGS_SERVICE (self),
+ tmp,
+ context,
+ dbus_add_connection_cb,
+ context);
+ } else {
+ error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "%s: %s:%d add_connection() not implemented",
+ __func__, __FILE__, __LINE__);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+
+ g_object_unref (tmp);
+}
+
+void
+nm_settings_service_export_connection (NMSettingsService *self,
+ NMSettingsConnectionInterface *connection)
+{
+ NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (self);
+ static guint32 ec_counter = 0;
+ char *path;
+
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection));
+ g_return_if_fail (priv->bus != NULL);
+
+ /* Don't allow exporting twice */
+ g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL);
+
+ path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++);
+ nm_connection_set_path (NM_CONNECTION (connection), path);
+ nm_connection_set_scope (NM_CONNECTION (connection), priv->scope);
+
+ dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection));
+ g_free (path);
+}
+
+/**************************************************************/
+
+static void
+settings_interface_init (NMSettingsInterface *iface)
+{
+ /* interface implementation */
+ iface->list_connections = list_connections;
+ iface->get_connection_by_path = get_connection_by_path;
+ iface->add_connection = add_connection;
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_INTERFACE (iface),
+ &dbus_glib_nm_settings_object_info);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+
+ object = G_OBJECT_CLASS (nm_settings_service_parent_class)->constructor (type, n_construct_params, construct_params);
+ if (object) {
+ g_assert (NM_SETTINGS_SERVICE_GET_PRIVATE (object)->scope != NM_CONNECTION_SCOPE_UNKNOWN);
+ }
+ return object;
+}
+
+static void
+nm_settings_service_init (NMSettingsService *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (object);
+ DBusGConnection *bus;
+
+ switch (prop_id) {
+ case PROP_BUS:
+ /* Construct only */
+ bus = g_value_get_boxed (value);
+ if (bus)
+ priv->bus = dbus_g_connection_ref (bus);
+ break;
+ case PROP_SCOPE:
+ /* Construct only */
+ priv->scope = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_BUS:
+ g_value_set_boxed (value, priv->bus);
+ break;
+ case PROP_SCOPE:
+ g_value_set_uint (value, priv->scope);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ priv->disposed = TRUE;
+ if (priv->bus)
+ dbus_g_connection_unref (priv->bus);
+ }
+
+ G_OBJECT_CLASS (nm_settings_service_parent_class)->dispose (object);
+}
+
+static void
+nm_settings_service_class_init (NMSettingsServiceClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (NMSettingsServicePrivate));
+
+ /* Virtual methods */
+ object_class->dispose = dispose;
+ object_class->constructor = constructor;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+
+ /**
+ * NMSettingsService:bus:
+ *
+ * The %DBusGConnection which this object is exported on
+ **/
+ g_object_class_install_property (object_class, PROP_BUS,
+ g_param_spec_boxed (NM_SETTINGS_SERVICE_BUS,
+ "Bus",
+ "Bus",
+ DBUS_TYPE_G_CONNECTION,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ /**
+ * NMSettingsService:scope:
+ *
+ * The capabilities of the device.
+ **/
+ g_object_class_install_property (object_class, PROP_SCOPE,
+ g_param_spec_uint (NM_SETTINGS_SERVICE_SCOPE,
+ "Scope",
+ "Scope",
+ NM_CONNECTION_SCOPE_SYSTEM,
+ NM_CONNECTION_SCOPE_USER,
+ NM_CONNECTION_SCOPE_USER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}