2007-09-12 Tambet Ingo <tambet@gmail.com>
authorTambet Ingo <tambet@gmail.com>
Wed, 12 Sep 2007 16:23:53 +0000 (16:23 +0000)
committerTambet Ingo <tambet@gmail.com>
Wed, 12 Sep 2007 16:23:53 +0000 (16:23 +0000)
        * src/vpn-manager/nm-vpn-connection.[ch]:
        * src/vpn-manager/nm-vpn-manager.[ch]:
        * src/vpn-manager/nm-vpn-service.[ch]: Rewrite the vpn handling
        * code. Using
        dbus-glib, GObjects, signals etc.

        * libnm-glib/nm-vpn-manager.[ch]:
        * libnm-glib/nm-vpn-connection.[ch]: Now that the NM
        * implementation changed
        so much, rewrite these too.

        * libnm-glib/Makefile.am: Add new files to build, build new
        * binding files for
        the new introspection files.

        * libnm-glib/nm-client.[ch]: Remove all VPN related stuff from
        * here.

        * libnm-glib/nm-dbus-utils.[ch]: Renamed from nm-utils.[ch] that
        * was shadowing
        the header with the same name from libnm-utils.

        * libnm-glib/nm-vpn-plugin.[ch]: Implement.

        * libnm-util/Makefile.am: Add nm-utils.[ch] to build.

        * introspection/nm-vpn-plugin.xml: Implement.

        * introspection/nm-vpn-connection.xml: Implement.

        * introspection/nm-vpn-manager.xml: Implement.

        * src/NetworkManagerSystem.c
        * (nm_system_vpn_device_set_from_ip4_config): Remove
        the named manager argument, it can just as easily get it as the
caller.
        (nm_system_vpn_device_unset_from_ip4_config): Ditto.

        * src/vpn-manager/nm-dbus-vpn.[ch]: Remove.

        * src/nm-dbus-manager.h: Fix up the name_owner signal signature.

        * src/dhcp-manager/nm-dhcp-manager.c (garray_to_string): Remove,
        * use one from
        libnm-utils.

        * libnm-util/nm-connection.c: Ditto.

        * src/NetworkManagerMain.h: Remove, it's finally empty.

        * configure.in: Remove utils/ from build.

        * include/NetworkManagerVPN.h: Add some more defines to reduce
        * the amount
        of hard-coded strings.

        * utils/: Move it over to libnm-util.

        * test/Makefile.am: Link against libnm-util now that util/ is
        * gone.

        * dispatcher-daemon/Makefile.am: Ditto.

        * src/Makefile.am: Ditto.

git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2798 4912f4e0-d625-0410-9fb7-b9a5a253dbdc

48 files changed:
ChangeLog
Makefile.am
configure.in
dispatcher-daemon/Makefile.am
include/NetworkManagerVPN.h
introspection/nm-vpn-connection.xml [new file with mode: 0644]
introspection/nm-vpn-manager.xml [new file with mode: 0644]
introspection/nm-vpn-plugin.xml [new file with mode: 0644]
libnm-glib/Makefile.am
libnm-glib/nm-client.c
libnm-glib/nm-client.h
libnm-glib/nm-dbus-utils.c [moved from libnm-glib/nm-utils.c with 99% similarity]
libnm-glib/nm-dbus-utils.h [moved from libnm-glib/nm-utils.h with 100% similarity]
libnm-glib/nm-settings.h
libnm-glib/nm-vpn-connection.c
libnm-glib/nm-vpn-connection.h
libnm-glib/nm-vpn-manager.c [new file with mode: 0644]
libnm-glib/nm-vpn-manager.h [new file with mode: 0644]
libnm-glib/nm-vpn-plugin.c [new file with mode: 0644]
libnm-glib/nm-vpn-plugin.h [new file with mode: 0644]
libnm-util/Makefile.am
libnm-util/nm-connection.c
libnm-util/nm-utils.c [new file with mode: 0644]
libnm-util/nm-utils.h [new file with mode: 0644]
src/Makefile.am
src/NetworkManager.c
src/NetworkManagerMain.h [deleted file]
src/NetworkManagerSystem.c
src/NetworkManagerSystem.h
src/NetworkManagerUtils.h
src/autoip.c
src/backends/NetworkManagerSuSE.c
src/dhcp-manager/nm-dhcp-manager.c
src/nm-dbus-manager.h
src/nm-device-802-11-wireless.h
src/nm-device-802-3-ethernet.h
src/nm-hal-manager.h
src/nm-logging.c
src/vpn-manager/Makefile.am
src/vpn-manager/nm-dbus-vpn.c [deleted file]
src/vpn-manager/nm-dbus-vpn.h [deleted file]
src/vpn-manager/nm-vpn-connection.c
src/vpn-manager/nm-vpn-connection.h
src/vpn-manager/nm-vpn-manager.c
src/vpn-manager/nm-vpn-manager.h
src/vpn-manager/nm-vpn-service.c
src/vpn-manager/nm-vpn-service.h
test/Makefile.am

index 1261ed5..3edee0d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+2007-09-12  Tambet Ingo  <tambet@gmail.com>
+
+       * src/vpn-manager/nm-vpn-connection.[ch]: 
+       * src/vpn-manager/nm-vpn-manager.[ch]:
+       * src/vpn-manager/nm-vpn-service.[ch]: Rewrite the vpn handling code. Using 
+       dbus-glib, GObjects, signals etc.
+
+       * libnm-glib/nm-vpn-manager.[ch]: 
+       * libnm-glib/nm-vpn-connection.[ch]: Now that the NM implementation changed
+       so much, rewrite these too.
+
+       * libnm-glib/Makefile.am: Add new files to build, build new binding files for
+       the new introspection files.
+
+       * libnm-glib/nm-client.[ch]: Remove all VPN related stuff from here.
+
+       * libnm-glib/nm-dbus-utils.[ch]: Renamed from nm-utils.[ch] that was shadowing
+       the header with the same name from libnm-utils.
+
+       * libnm-glib/nm-vpn-plugin.[ch]: Implement.
+
+       * libnm-util/Makefile.am: Add nm-utils.[ch] to build.
+
+       * introspection/nm-vpn-plugin.xml: Implement.
+
+       * introspection/nm-vpn-connection.xml: Implement.
+
+       * introspection/nm-vpn-manager.xml: Implement.
+
+       * src/NetworkManagerSystem.c (nm_system_vpn_device_set_from_ip4_config): Remove
+       the named manager argument, it can just as easily get it as the caller.
+       (nm_system_vpn_device_unset_from_ip4_config): Ditto.
+
+       * src/vpn-manager/nm-dbus-vpn.[ch]: Remove.
+
+       * src/nm-dbus-manager.h: Fix up the name_owner signal signature.
+
+       * src/dhcp-manager/nm-dhcp-manager.c (garray_to_string): Remove, use one from
+       libnm-utils.
+
+       * libnm-util/nm-connection.c: Ditto.
+
+       * src/NetworkManagerMain.h: Remove, it's finally empty.
+
+       * configure.in: Remove utils/ from build.
+
+       * include/NetworkManagerVPN.h: Add some more defines to reduce the amount
+       of hard-coded strings.
+
+       * utils/: Move it over to libnm-util.
+
+       * test/Makefile.am: Link against libnm-util now that util/ is gone.
+
+       * dispatcher-daemon/Makefile.am: Ditto.
+
+       * src/Makefile.am: Ditto.
+
 2007-09-12  Dan Williams  <dcbw@redhat.com>
 
        Wireless connections can be made with config data from the applet now.
index 1d9d725..d36d88d 100644 (file)
@@ -1,5 +1,4 @@
 SUBDIRS =                              \
-          utils                                \
           libnm-util                   \
           libnm-glib                   \
           src                          \
index eb89cd8..72b6ac8 100644 (file)
@@ -258,7 +258,6 @@ fi
 AC_OUTPUT([
 Makefile
 include/Makefile
-utils/Makefile
 src/Makefile
 src/named-manager/Makefile
 src/vpn-manager/Makefile
index 868bbd1..3d7adbc 100644 (file)
@@ -8,7 +8,6 @@ NetworkManagerDispatcher_SOURCES =              \
 
 NetworkManagerDispatcher_CPPFLAGS =            \
        -I$(top_srcdir)                         \
-       -I$(top_srcdir)/utils                   \
        -I$(top_srcdir)/include                 \
        -I$(top_srcdir)/libnm-util              \
        -I$(top_srcdir)/libnm-glib              \
@@ -26,7 +25,6 @@ NetworkManagerDispatcher_CFLAGS =             \
        $(NULL)
 
 NetworkManagerDispatcher_LDADD =               \
-       $(top_builddir)/utils/libnmutils.la     \
        $(top_builddir)/libnm-util/libnm-util.la\
        $(top_builddir)/libnm-glib/libnm_glib.la\
        $(DBUS_LIBS)                            \
index 7ff6c27..e637a23 100644 (file)
 /*
  * dbus services details
  */
-#define        NM_DBUS_PATH_VPN                        "/org/freedesktop/NetworkManager/VPNConnections"
-#define        NM_DBUS_INTERFACE_VPN           "org.freedesktop.NetworkManager.VPNConnections"
+#define        NM_DBUS_PATH_VPN                  "/org/freedesktop/NetworkManager/VPN/Manager"
+#define        NM_DBUS_INTERFACE_VPN             "org.freedesktop.NetworkManager.VPN.Manager"
 
+#define        NM_DBUS_PATH_VPN_CONNECTION       "/org/freedesktop/NetworkManager/VPN/Connection"
+#define        NM_DBUS_INTERFACE_VPN_CONNECTION  "org.freedesktop.NetworkManager.VPN.Connection"
+
+#define NM_VPN_DBUS_PLUGIN_PATH           "/org/freedesktop/NetworkManager/VPN/Plugin"
+#define NM_VPN_DBUS_PLUGIN_INTERFACE      "org.freedesktop.NetworkManager.VPN.Plugin"
 
 /*
  * VPN Errors
@@ -77,14 +82,25 @@ typedef enum NMVPNServiceState
 typedef enum NMVPNConnectionState
 {
        NM_VPN_CONNECTION_STATE_UNKNOWN = 0,
-       NM_VPN_CONNECTION_STATE_DISCONNECTED,
        NM_VPN_CONNECTION_STATE_PREPARE,
        NM_VPN_CONNECTION_STATE_CONNECT,
        NM_VPN_CONNECTION_STATE_IP_CONFIG_GET,
        NM_VPN_CONNECTION_STATE_ACTIVATED,
        NM_VPN_CONNECTION_STATE_FAILED,
-       NM_VPN_CONNECTION_STATE_CANCELED
+       NM_VPN_CONNECTION_STATE_DISCONNECTED,
 } NMVPNConnectionState;
 
 
+#define NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY "gateway"
+#define NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS "address"
+#define NM_VPN_PLUGIN_IP4_CONFIG_PTP     "ptp"
+#define NM_VPN_PLUGIN_IP4_CONFIG_NETMASK "netmask"
+#define NM_VPN_PLUGIN_IP4_CONFIG_DNS     "dns"
+#define NM_VPN_PLUGIN_IP4_CONFIG_NBNS    "nbns"
+#define NM_VPN_PLUGIN_IP4_CONFIG_MSS     "mss"
+#define NM_VPN_PLUGIN_IP4_CONFIG_MTU     "mtu"
+#define NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV  "tundev"
+#define NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN  "domain"
+#define NM_VPN_PLUGIN_IP4_CONFIG_BANNER  "banner"
+
 #endif /* NETWORK_MANAGER_VPN_H */
diff --git a/introspection/nm-vpn-connection.xml b/introspection/nm-vpn-connection.xml
new file mode 100644 (file)
index 0000000..a8974d2
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+  <interface name="org.freedesktop.NetworkManager.VPN.Connection">
+    <method name="Disconnect">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_connection_disconnect"/>
+    </method>
+
+    <property name="Name" type="s" access="read"/>
+    <property name="State" type="u" access="read"/>
+
+    <signal name="StateChanged">
+      <arg name="state" type="u"/>
+    </signal>
+  </interface>
+</node>
+
diff --git a/introspection/nm-vpn-manager.xml b/introspection/nm-vpn-manager.xml
new file mode 100644 (file)
index 0000000..4cabf9e
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+  <interface name="org.freedesktop.NetworkManager.VPN.Manager">
+    <method name="Connect">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_manager_connect"/>
+      <arg name="type" type="s" direction="in"/>
+      <arg name="name" type="s" direction="in"/>
+      <arg name="properties" type="a{sv}" direction="in"/>
+      <arg name="device" type="o" direction="in"/>
+      <arg name="routes" type="as" direction="in"/>
+      <arg name="connection" type="o" direction="out"/>
+    </method>
+
+    <method name="ListConnections">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_manager_get_connections"/>
+      <arg name="connections" type="ao" direction="out"/>
+    </method>
+
+  </interface>
+</node>
+
diff --git a/introspection/nm-vpn-plugin.xml b/introspection/nm-vpn-plugin.xml
new file mode 100644 (file)
index 0000000..a8a3934
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+  <interface name="org.freedesktop.NetworkManager.VPN.Plugin">
+    <method name="Connect">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_plugin_connect"/>
+      <arg name="connection" type="a{sv}" direction="in"/>
+      <arg name="routes" type="as" direction="in"/>
+    </method>
+
+    <method name="Disconnect">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_plugin_disconnect"/>
+    </method>
+
+    <method name="SetIp4Config">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_plugin_set_ip4_config"/>
+      <arg name="config" type="a{sv}" direction="in"/>
+    </method>
+
+    <method name="SetFailure">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_plugin_set_failure"/>
+      <arg name="reason" type="s" direction="in"/>
+    </method>
+
+    <property name="State" type="u" access="read"/>
+
+    <signal name="StateChanged">
+      <arg name="state" type="u"/>
+    </signal>
+
+    <signal name="Ip4Config">
+      <arg name="ip4config" type="a{sv}"/>
+    </signal>
+
+    <signal name="LoginBanner">
+      <arg name="banner" type="s"/>
+    </signal>
+
+    <signal name="Failure">
+      <arg name="reason" type="u"/>
+    </signal>
+
+  </interface>
+</node>
index e7f34aa..c204693 100644 (file)
@@ -1,4 +1,4 @@
-INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/utils -I$(top_srcdir)/libnm-util
+INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/libnm-util
 
 BUILT_SOURCES = \
        nm-access-point-bindings.h \
@@ -9,9 +9,12 @@ BUILT_SOURCES = \
        nm-marshal.h \
        nm-marshal.c \
        nm-settings-connection-glue.h \
-       nm-settings-glue.h
+       nm-settings-glue.h \
+       nm-vpn-manager-bindings.h \
+       nm-vpn-connection-bindings.h \
+       nm-vpn-plugin-glue.h
 
-lib_LTLIBRARIES = libnm_glib.la
+lib_LTLIBRARIES = libnm_glib.la libnm_glib_vpn.la
 
 libnm_glib_la_CFLAGS =                 \
        $(GLIB_CFLAGS)          \
@@ -32,12 +35,16 @@ libnminclude_HEADERS = \
        nm-access-point.h \
        nm-ip4-config.h \
        nm-settings.h \
-       nm-vpn-connection.h
+       nm-vpn-connection.h \
+       nm-vpn-manager.h \
+       nm-vpn-plugin.h
 
 libnm_glib_la_SOURCES = \
        libnm_glib.c            \
        nm-object.c             \
        nm-client.c             \
+       nm-dbus-utils.c         \
+       nm-dbus-utils.h         \
        nm-device.c             \
        nm-device-private.h     \
        nm-device-802-3-ethernet.c \
@@ -46,10 +53,10 @@ libnm_glib_la_SOURCES = \
        nm-ip4-config.c         \
        nm-settings.c           \
        nm-vpn-connection.c     \
+       nm-vpn-manager.c        \
        nm-marshal-main.c
 
 libnm_glib_la_LIBADD = \
-       $(top_builddir)/utils/libnmutils.la             \
        $(top_builddir)/libnm-util/libnm-util.la        \
        $(GLIB_LIBS)                                    \
        $(GTHREAD_LIBS)                                 \
@@ -63,6 +70,11 @@ libnm_glib_test_SOURCES = libnm-glib-test.c
 libnm_glib_test_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS)
 libnm_glib_test_LDADD = libnm_glib.la $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) $(DBUS_LIBS)
 
+libnm_glib_vpn_la_SOURCES = nm-vpn-plugin.c
+libnm_glib_vpn_la_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS)
+libnm_glib_vpn_la_LIBADD = $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) $(DBUS_LIBS)
+
+
 nm-marshal.h: Makefile.am nm-marshal.list
        $(GLIB_GENMARSHAL) --prefix=nm_marshal $(srcdir)/nm-marshal.list --header > \
        xgen-gmh \
@@ -98,6 +110,15 @@ nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml
 nm-settings-connection-glue.h: $(top_srcdir)/introspection/nm-settings-connection.xml
        dbus-binding-tool --prefix=nm_connection_settings --mode=glib-server --output=nm-settings-connection-glue.h $(top_srcdir)/introspection/nm-settings-connection.xml
 
+nm-vpn-manager-bindings.h: $(top_srcdir)/introspection/nm-vpn-manager.xml
+       dbus-binding-tool --prefix=nm_vpn_manager --mode=glib-client --output=nm-vpn-manager-bindings.h $(top_srcdir)/introspection/nm-vpn-manager.xml
+
+nm-vpn-connection-bindings.h: $(top_srcdir)/introspection/nm-vpn-connection.xml
+       dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-client --output=nm-vpn-connection-bindings.h $(top_srcdir)/introspection/nm-vpn-connection.xml
+
+nm-vpn-plugin-glue.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml
+       dbus-binding-tool --prefix=nm_vpn_plugin --mode=glib-server --output=nm-vpn-plugin-glue.h $(top_srcdir)/introspection/nm-vpn-plugin.xml
+
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libnm_glib.pc
 
index f5cd8dd..04d1fd7 100644 (file)
@@ -19,11 +19,6 @@ typedef struct {
        NMState state;
        gboolean have_device_list;
        GHashTable *devices;
-
-       DBusGProxy *vpn_proxy;
-       NMVPNConnectionState vpn_state;
-       gboolean have_vpn_connections;
-       GHashTable *vpn_connections;
 } NMClientPrivate;
 
 enum {
@@ -32,10 +27,6 @@ enum {
        DEVICE_REMOVED,
        STATE_CHANGE,
 
-       VPN_CONNECTION_ADDED,
-       VPN_CONNECTION_REMOVED,
-       VPN_STATE_CHANGE,
-
        LAST_SIGNAL
 };
 
@@ -51,9 +42,6 @@ static void client_state_change_proxy (DBusGProxy *proxy, guint state, gpointer
 static void client_device_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data);
 static void client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data);
 
-static void setup_vpn_proxy (NMClient *client, DBusGConnection *connection);
-static void clear_vpn_connections (NMClient * client);
-
 static void
 nm_client_init (NMClient *client)
 {
@@ -63,12 +51,6 @@ nm_client_init (NMClient *client)
        priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                                                   (GDestroyNotify) g_free,
                                                                                   (GDestroyNotify) g_object_unref);
-
-       priv->vpn_connections = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                      (GDestroyNotify) g_free,
-                                                      NULL);
-
-       priv->vpn_state = NM_VPN_CONNECTION_STATE_UNKNOWN;
 }
 
 static GObject*
@@ -116,8 +98,6 @@ constructor (GType type,
                                                                 object,
                                                                 NULL);
 
-       setup_vpn_proxy (NM_CLIENT (object), connection);
-
        priv->bus_proxy = dbus_g_proxy_new_for_name (connection,
                                                                                                 "org.freedesktop.DBus",
                                                                                                 "/org/freedesktop/DBus",
@@ -149,11 +129,9 @@ finalize (GObject *object)
 {
        NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object);
 
-       g_object_unref (priv->vpn_proxy);
        g_object_unref (priv->client_proxy);
        g_object_unref (priv->bus_proxy);
        g_hash_table_destroy (priv->devices);
-       g_hash_table_destroy (priv->vpn_connections);
 }
 
 static void
@@ -165,9 +143,6 @@ manager_running (NMClient *client, gboolean running)
                priv->state = NM_STATE_UNKNOWN;
                g_hash_table_remove_all (priv->devices);
                priv->have_device_list = FALSE;
-
-               clear_vpn_connections (client);
-               priv->have_vpn_connections = FALSE;
        }
 }
 
@@ -223,36 +198,6 @@ nm_client_class_init (NMClientClass *client_class)
                                          g_cclosure_marshal_VOID__UINT,
                                          G_TYPE_NONE, 1,
                                          G_TYPE_UINT);
-
-       signals[VPN_CONNECTION_ADDED] =
-               g_signal_new ("vpn-connection-added",
-                                         G_OBJECT_CLASS_TYPE (object_class),
-                                         G_SIGNAL_RUN_FIRST,
-                                         G_STRUCT_OFFSET (NMClientClass, vpn_connection_added),
-                                         NULL, NULL,
-                                         g_cclosure_marshal_VOID__OBJECT,
-                                         G_TYPE_NONE, 1,
-                                         G_TYPE_OBJECT);
-
-       signals[VPN_CONNECTION_REMOVED] =
-               g_signal_new ("vpn-connection-removed",
-                                         G_OBJECT_CLASS_TYPE (object_class),
-                                         G_SIGNAL_RUN_FIRST,
-                                         G_STRUCT_OFFSET (NMClientClass, vpn_connection_removed),
-                                         NULL, NULL,
-                                         g_cclosure_marshal_VOID__OBJECT,
-                                         G_TYPE_NONE, 1,
-                                         G_TYPE_OBJECT);
-
-       signals[VPN_STATE_CHANGE] =
-               g_signal_new ("vpn-state-change",
-                                         G_OBJECT_CLASS_TYPE (object_class),
-                                         G_SIGNAL_RUN_FIRST,
-                                         G_STRUCT_OFFSET (NMClientClass, state_change),
-                                         NULL, NULL,
-                                         g_cclosure_marshal_VOID__UINT,
-                                         G_TYPE_NONE, 1,
-                                         G_TYPE_UINT);
 }
 
 NMClient *
@@ -498,288 +443,3 @@ nm_client_sleep (NMClient *client, gboolean sleep)
                g_error_free (err);
        }
 }
-
-/* VPN */
-
-/*
- * This "best" state is the summary of all states from all connections and
- * available for convenience.
- * For the exact state, each connection has it's own state which' changes
- * are also signalled.
- */
-static NMVPNConnectionState
-nm_client_get_best_vpn_state (NMClient *client)
-{
-       GSList *iter, *list;
-       NMVPNConnectionState state;
-       NMVPNConnectionState best_state = NM_VPN_CONNECTION_STATE_UNKNOWN;
-
-       list = nm_client_get_vpn_connections (client);
-       for (iter = list; iter; iter = iter->next) {
-               state = nm_vpn_connection_get_state (NM_VPN_CONNECTION (iter->data));
-               if (state > best_state && state < NM_VPN_CONNECTION_STATE_FAILED)
-                       best_state = state;
-       }
-       g_slist_free (list);
-
-       return best_state;
-}
-
-static void
-proxy_vpn_state_change (DBusGProxy *proxy,
-                        char *connection_name,
-                        NMVPNConnectionState state,
-                        gpointer user_data)
-{
-       NMClient *client = NM_CLIENT (user_data);
-       NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
-       NMVPNConnection *connection;
-       NMVPNConnectionState best_state;
-
-       connection = nm_client_get_vpn_connection_by_name (client, connection_name);
-       if (connection)
-               nm_vpn_connection_set_state (connection, state);
-
-       best_state = nm_client_get_best_vpn_state (client);
-       if (best_state != priv->vpn_state) {
-               priv->vpn_state = state;
-               g_signal_emit (client, signals[VPN_STATE_CHANGE], 0, best_state);
-       }
-}
-
-static void
-proxy_vpn_connection_added (DBusGProxy *proxy, char *name, gpointer user_data)
-{
-       NMClient *client = NM_CLIENT (user_data);
-       NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
-       NMVPNConnection *connection;
-
-       if (g_hash_table_lookup (priv->vpn_connections, name))
-               return;
-
-       connection = nm_vpn_connection_new (proxy, name);
-       if (connection == NULL) {
-               g_log (G_LOG_DOMAIN,
-                      G_LOG_LEVEL_WARNING,
-                      "Warning: out of memory creating NMVPNConnection for '%s'\n",
-                      name);
-               return;
-       }
-
-       g_hash_table_insert (priv->vpn_connections, g_strdup (name), connection);
-       g_signal_emit (client, signals[VPN_CONNECTION_ADDED], 0, connection);
-}
-
-static void
-proxy_vpn_connection_removed (DBusGProxy *proxy, char *name, gpointer user_data)
-{
-       NMClient *client = NM_CLIENT (user_data);
-       NMVPNConnection *connection;
-
-       connection = nm_client_get_vpn_connection_by_name (client, name);
-       if (connection)
-               nm_client_remove_vpn_connection (client, connection);
-}
-
-static void
-proxy_vpn_connection_update (DBusGProxy *proxy, char *name, gpointer user_data)
-{
-       NMClient *client = NM_CLIENT (user_data);
-       NMVPNConnection *connection;
-
-       connection = nm_client_get_vpn_connection_by_name (client, name);
-       if (connection)
-               nm_vpn_connection_update (connection);
-}
-
-static void
-setup_vpn_proxy (NMClient *client, DBusGConnection *connection)
-{
-       DBusGProxy *proxy;
-
-       proxy = dbus_g_proxy_new_for_name (connection,
-                                                                          NM_DBUS_SERVICE,
-                                                                          NM_DBUS_PATH_VPN,
-                                                                          NM_DBUS_INTERFACE_VPN);
-
-       dbus_g_object_register_marshaller (nm_marshal_VOID__STRING_INT,
-                                                                          G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID);
-
-       dbus_g_proxy_add_signal (proxy, "VPNConnectionStateChange", G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID);
-       dbus_g_proxy_connect_signal (proxy, "VPNConnectionStateChange",
-                                                                G_CALLBACK (proxy_vpn_state_change),
-                                                                client, NULL);
-
-       dbus_g_proxy_add_signal (proxy, "VPNConnectionAdded", G_TYPE_STRING, G_TYPE_INVALID);
-       dbus_g_proxy_connect_signal (proxy, "VPNConnectionAdded",
-                                                                G_CALLBACK (proxy_vpn_connection_added),
-                                                                client, NULL);
-
-       dbus_g_proxy_add_signal (proxy, "VPNConnectionRemoved", G_TYPE_STRING, G_TYPE_INVALID);
-       dbus_g_proxy_connect_signal (proxy, "VPNConnectionRemoved",
-                                                                G_CALLBACK (proxy_vpn_connection_removed),
-                                                                client, NULL);
-
-       dbus_g_proxy_add_signal (proxy, "VPNConnectionUpdate", G_TYPE_STRING, G_TYPE_INVALID);
-       dbus_g_proxy_connect_signal (proxy, "VPNConnectionUpdate",
-                                                                G_CALLBACK (proxy_vpn_connection_update),
-                                                                client, NULL);
-
-       NM_CLIENT_GET_PRIVATE (client)->vpn_proxy = proxy;
-}
-
-static void
-get_connections (NMClient *client)
-{
-       NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
-       char **name;
-       char **vpn_names = NULL;
-       GError *err = NULL;
-
-       if (!dbus_g_proxy_call (priv->vpn_proxy, "getVPNConnections", &err,
-                                                       G_TYPE_INVALID,
-                                                       G_TYPE_STRV, &vpn_names,
-                                                       G_TYPE_INVALID)) {
-               g_warning ("Error while getting VPN connections: %s", err->message);
-               g_error_free (err);
-               return;
-       }
-
-       for (name = vpn_names; *name; name++)
-               proxy_vpn_connection_added (priv->vpn_proxy, *name, client);
-       g_strfreev (vpn_names);
-}
-
-static void
-signal_one_vpn_connection_removed (gpointer data,
-                                   gpointer user_data)
-{
-       NMClient * client = NM_CLIENT (user_data);
-       NMVPNConnection * connection = NM_VPN_CONNECTION (data);
-
-       g_signal_emit (client, signals[VPN_CONNECTION_REMOVED], 0, connection);
-}
-
-static void
-clear_vpn_connections (NMClient * client)
-{
-       NMClientPrivate * priv;
-       GSList * list;
-       
-       g_return_if_fail (NM_IS_CLIENT (client));
-
-       priv = NM_CLIENT_GET_PRIVATE (client);
-
-       list = nm_client_get_vpn_connections (client);
-       g_hash_table_remove_all (priv->vpn_connections);
-
-       g_slist_foreach (list, signal_one_vpn_connection_removed, client);
-       g_slist_foreach (list, (GFunc) g_object_unref, NULL);
-       g_slist_free (list);
-}
-
-static void
-vpn_connections_to_slist (gpointer key, gpointer value, gpointer user_data)
-{
-       GSList **list = (GSList **) user_data;
-
-       *list = g_slist_prepend (*list, value);
-}
-
-GSList *
-nm_client_get_vpn_connections (NMClient *client)
-{
-       NMClientPrivate *priv;
-       GSList * list = NULL;
-
-       g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
-
-       priv = NM_CLIENT_GET_PRIVATE (client);
-
-       if (!priv->have_vpn_connections) {
-               get_connections (client);
-               priv->have_vpn_connections = TRUE;
-       }
-
-       g_hash_table_foreach (priv->vpn_connections,
-                             vpn_connections_to_slist,
-                             &list);
-       return list;
-}
-
-NMVPNConnection *
-nm_client_get_vpn_connection_by_name (NMClient *client, const char *name)
-{
-       NMClientPrivate *priv;
-       GSList * list;
-       
-       g_return_if_fail (NM_IS_CLIENT (client));
-
-       priv = NM_CLIENT_GET_PRIVATE (client);
-
-       /* Ensure list of VPN connections is current */
-       list = nm_client_get_vpn_connections (client);
-       g_slist_free (list);
-
-       return g_hash_table_lookup (priv->vpn_connections, name);
-}
-
-struct find_info {
-       char * found_key;
-       NMVPNConnection * connection;
-};
-
-static void
-find_connection (gpointer key,
-                 gpointer value,
-                 gpointer user_data)
-{
-       struct find_info * info = (struct find_info *) user_data;
-
-       if (info->connection == value)
-               info->found_key = key;
-}
-
-void
-nm_client_remove_vpn_connection (NMClient *client, NMVPNConnection *connection)
-{
-       NMClientPrivate *priv;
-       struct find_info info = { NULL, NULL };
-       
-       g_return_if_fail (NM_IS_CLIENT (client));
-       g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
-
-       /* Note that the connection isn't removed from NetworkManager, it's
-          because it doesn't have DBUS API for that right now. */
-
-       priv = NM_CLIENT_GET_PRIVATE (client);
-
-       info.connection = connection;
-       g_hash_table_foreach (priv->vpn_connections, find_connection, &info);
-       if (!info.found_key) {
-               g_log (G_LOG_DOMAIN,
-                      G_LOG_LEVEL_WARNING,
-                      "Warning: tried to remove unknown NMVPNConnection object %p\n",
-                      connection);
-               return;
-       }
-
-       g_hash_table_remove (priv->vpn_connections, info.found_key);
-       g_signal_emit (client, signals[VPN_CONNECTION_REMOVED], 0, connection);
-       g_object_unref (connection);
-}
-
-NMVPNConnectionState
-nm_client_get_vpn_state (NMClient *client)
-{
-       NMClientPrivate *priv;
-
-       g_return_val_if_fail (NM_IS_CLIENT (client), NM_VPN_CONNECTION_STATE_UNKNOWN);
-
-       priv = NM_CLIENT_GET_PRIVATE (client);
-
-       if (priv->vpn_state == NM_VPN_CONNECTION_STATE_UNKNOWN)
-               priv->vpn_state = nm_client_get_best_vpn_state (client);
-
-       return priv->vpn_state;
-}
index f6cb337..2df065a 100644 (file)
@@ -6,10 +6,8 @@
 #include <glib-object.h>
 #include <dbus/dbus-glib.h>
 #include <NetworkManager.h>
-#include <NetworkManagerVPN.h>
 #include "nm-object.h"
 #include "nm-device.h"
-#include "nm-vpn-connection.h"
 
 G_BEGIN_DECLS
 
@@ -32,10 +30,6 @@ typedef struct {
        void (*device_added) (NMClient *client, NMDevice *device);
        void (*device_removed) (NMClient *client, NMDevice *device);
        void (*state_change) (NMClient *client, NMState state);
-
-       void (*vpn_connection_added) (NMClient *client, NMVPNConnection *connection);
-       void (*vpn_connection_removed) (NMClient *client, NMVPNConnection *connection);
-       void (*vpn_state_change) (NMClient *client, NMVPNConnectionState state);
 } NMClientClass;
 
 GType nm_client_get_type (void);
@@ -53,17 +47,6 @@ void      nm_client_wireless_set_enabled (NMClient *client, gboolean enabled);
 NMState   nm_client_get_state            (NMClient *client);
 void      nm_client_sleep                (NMClient *client, gboolean sleep);
 
-/* VPN */
-
-GSList   *nm_client_get_vpn_connections  (NMClient *client);
-NMVPNConnection *nm_client_get_vpn_connection_by_name (NMClient *client,
-                                                                                                          const char *name);
-
-void      nm_client_remove_vpn_connection (NMClient *client,
-                                                                                  NMVPNConnection *connection);
-
-NMVPNConnectionState nm_client_get_vpn_state    (NMClient *client);
-
 G_END_DECLS
 
 #endif /* NM_CLIENT_H */
similarity index 99%
rename from libnm-glib/nm-utils.c
rename to libnm-glib/nm-dbus-utils.c
index 0802820..1620464 100644 (file)
@@ -1,4 +1,4 @@
-#include "nm-utils.h"
+#include "nm-dbus-utils.h"
 
 char *
 nm_dbus_get_string_property (DBusGProxy *proxy,
index dcaa7f2..c7ccff1 100644 (file)
@@ -3,6 +3,7 @@
 #define NM_SETTINGS_H 1
 
 #include <glib-object.h>
+#include <dbus/dbus-glib.h>
 
 G_BEGIN_DECLS
 
index 1f6c10d..a1a0b95 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
 /* NetworkManager Wireless Applet -- Display wireless access points and allow user control
  *
  * Dan Williams <dcbw@redhat.com>
 
 #include <string.h>
 #include "nm-vpn-connection.h"
+#include "NetworkManager.h"
+#include "nm-utils.h"
+#include "nm-vpn-connection-bindings.h"
 
-G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT)
+G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_OBJECT)
 
 #define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
 
 typedef struct {
        DBusGProxy *proxy;
        char *name;
-       char *user_name;
-       char *service;
        NMVPNConnectionState state;
 } NMVPNConnectionPrivate;
 
 enum {
-       UPDATED,
        STATE_CHANGED,
 
        LAST_SIGNAL
@@ -43,240 +44,142 @@ enum {
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-static void
-nm_vpn_connection_init (NMVPNConnection *connection)
-{
-       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
-
-       priv->state = NM_VPN_CONNECTION_STATE_UNKNOWN;
-}
-
-static void
-finalize (GObject *object)
-{
-       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
-
-       g_free (priv->name);
-       g_free (priv->user_name);
-       g_free (priv->service);
-}
 
-static void
-nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
+NMVPNConnection *
+nm_vpn_connection_new (DBusGConnection *dbus_connection,
+                                  const char *path)
 {
-       GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
+       NMVPNConnection *connection;
 
-       g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
+       g_return_val_if_fail (dbus_connection != NULL, NULL);
+       g_return_val_if_fail (path != NULL, NULL);
 
-       /* virtual methods */
-       object_class->finalize = finalize;
+       connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, 
+                                                                                 NM_OBJECT_CONNECTION, dbus_connection,
+                                                                                 NM_OBJECT_PATH, path,
+                                                                                 NULL);
 
-       /* signals */
-       signals[UPDATED] =
-               g_signal_new ("updated",
-                                         G_OBJECT_CLASS_TYPE (object_class),
-                                         G_SIGNAL_RUN_FIRST,
-                                         G_STRUCT_OFFSET (NMVPNConnectionClass, updated),
-                                         NULL, NULL,
-                                         g_cclosure_marshal_VOID__VOID,
-                                         G_TYPE_NONE, 0);
-       signals[STATE_CHANGED] =
-               g_signal_new ("state-changed",
-                                         G_OBJECT_CLASS_TYPE (object_class),
-                                         G_SIGNAL_RUN_FIRST,
-                                         G_STRUCT_OFFSET (NMVPNConnectionClass, state_changed),
-                                         NULL, NULL,
-                                         g_cclosure_marshal_VOID__UINT,
-                                         G_TYPE_NONE, 1,
-                                         G_TYPE_UINT);
+       nm_vpn_connection_get_name (connection);
 
+       return connection;
 }
 
-static gboolean
-update_properties (NMVPNConnection *connection)
+const char *
+nm_vpn_connection_get_name (NMVPNConnection *vpn)
 {
        NMVPNConnectionPrivate *priv;
-       char *name = NULL;
-       char *user_name = NULL;
-       char *service = NULL;
-       NMVPNConnectionState state;
-       GError *err = NULL;
 
-       priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
-
-       if (!dbus_g_proxy_call (priv->proxy, "getVPNConnectionProperties", &err,
-                                                       G_TYPE_STRING, priv->name,
-                                                       G_TYPE_INVALID,
-                                                       G_TYPE_STRING, &name,
-                                                       G_TYPE_STRING, &user_name,
-                                                       G_TYPE_STRING, &service,
-                                                       G_TYPE_UINT, &state,
-                                                       G_TYPE_INVALID)) {
-               g_warning ("Error while updating VPN connection: %s", err->message);
-               g_error_free (err);
-               return FALSE;
-       }
-
-       g_free (priv->name);
-       g_free (priv->user_name);
-       g_free (priv->service);
-
-       priv->name = name;
-       priv->user_name = user_name;
-       priv->service = service;
-       
-       nm_vpn_connection_set_state (connection, (NMVPNConnectionState) state);
+       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
 
-       return TRUE;
+       priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn);
+       if (!priv->name)
+               priv->name = nm_object_get_string_property (NM_OBJECT (vpn),
+                                                                                   NM_DBUS_INTERFACE_VPN_CONNECTION,
+                                                                                   "Name");
+       return priv->name;
 }
 
-NMVPNConnection *
-nm_vpn_connection_new (DBusGProxy *proxy, const char *name)
+NMVPNConnectionState
+nm_vpn_connection_get_state (NMVPNConnection *vpn)
 {
-       GObject *object;
-       NMVPNConnectionPrivate *priv;
-
-       g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL);
-       g_return_val_if_fail (name != NULL, NULL);
-
-       object = g_object_new (NM_TYPE_VPN_CONNECTION, NULL);
-       if (!object)
-               return NULL;
-
-       priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
-       priv->proxy = proxy;
-       priv->name = g_strdup (name);
-
-       if (!update_properties ((NMVPNConnection *) object)) {
-               g_object_unref (object);
-               return NULL;
-       }
+       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NM_VPN_CONNECTION_STATE_UNKNOWN);
 
-       return (NMVPNConnection *) object;
+       return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->state;
 }
 
-gboolean
-nm_vpn_connection_update (NMVPNConnection *vpn)
+static void
+state_changed_proxy (DBusGProxy *proxy, NMVPNConnectionState state, gpointer user_data)
 {
-       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
+       NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
-       if (update_properties (vpn)) {
-               g_signal_emit (vpn, signals[UPDATED], 0);
-               return TRUE;
+       if (priv->state != state) {
+               priv->state = state;
+               g_signal_emit (connection, signals[STATE_CHANGED], 0, state);
        }
-
-       return FALSE;
 }
 
-const char *
-nm_vpn_connection_get_name (NMVPNConnection *vpn)
+void
+nm_vpn_connection_disconnect (NMVPNConnection *vpn)
 {
-       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
-
-       return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->name;
-}
+       GError *err = NULL;
 
-const char *
-nm_vpn_connection_get_user_name (NMVPNConnection *vpn)
-{
-       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
+       g_return_if_fail (NM_IS_VPN_CONNECTION (vpn));
 
-       return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->user_name;
+       org_freedesktop_NetworkManager_VPN_Connection_disconnect (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy, &err);
+       if (err) {
+               nm_warning ("Error in VPN disconnect: %s", err->message);
+               g_error_free (err);
+       }
 }
 
-const char *
-nm_vpn_connection_get_service (NMVPNConnection *vpn)
-{
-       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
-
-       return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->service;
-}
+/*****************************************************************************/
 
-NMVPNConnectionState
-nm_vpn_connection_get_state (NMVPNConnection *vpn)
+static void
+nm_vpn_connection_init (NMVPNConnection *connection)
 {
-       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NM_VPN_CONNECTION_STATE_UNKNOWN);
+       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
-       return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->state;
+       priv->state = NM_VPN_CONNECTION_STATE_UNKNOWN;
 }
 
-void
-nm_vpn_connection_set_state (NMVPNConnection *vpn, NMVPNConnectionState state)
+static GObject*
+constructor (GType type,
+                  guint n_construct_params,
+                  GObjectConstructParam *construct_params)
 {
+       NMObject *object;
        NMVPNConnectionPrivate *priv;
 
-       g_return_if_fail (NM_IS_VPN_CONNECTION (vpn));
+       object = (NMObject *) G_OBJECT_CLASS (nm_vpn_connection_parent_class)->constructor (type,
+                                                                                                                                           n_construct_params,
+                                                                                                                                           construct_params);
+       if (!object)
+               return NULL;
 
-       priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn);
-       if (priv->state != state) {
-               priv->state = state;
-               g_signal_emit (vpn, signals[STATE_CHANGED], 0, state);
-       }
+       priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
+
+       priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
+                                                                        NM_DBUS_SERVICE,
+                                                                        nm_object_get_path (object),
+                                                                        NM_DBUS_INTERFACE_VPN_CONNECTION);
+
+       dbus_g_proxy_add_signal (priv->proxy, "StateChanged", G_TYPE_UINT, G_TYPE_INVALID);
+       dbus_g_proxy_connect_signal (priv->proxy,
+                                                   "StateChanged",
+                                                   G_CALLBACK (state_changed_proxy),
+                                                   object,
+                                                   NULL);
+       return G_OBJECT (object);
 }
 
-gboolean
-nm_vpn_connection_is_activating (NMVPNConnection *vpn)
+static void
+finalize (GObject *object)
 {
-       NMVPNConnectionState state;
-
-       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
-
-       state = nm_vpn_connection_get_state (vpn);
-       if (state == NM_VPN_CONNECTION_STATE_PREPARE ||
-               state == NM_VPN_CONNECTION_STATE_CONNECT ||
-               state == NM_VPN_CONNECTION_STATE_IP_CONFIG_GET)
-               return TRUE;
+       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
 
-       return FALSE;
+       g_object_unref (priv->proxy);
 }
 
-gboolean
-nm_vpn_connection_activate (NMVPNConnection *vpn, GSList *passwords)
+static void
+nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
 {
-       char **password_strings;
-       GSList *iter;
-       int i;
-
-       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
-       g_return_val_if_fail (passwords != NULL, FALSE);
-
-       if (nm_vpn_connection_get_state (vpn) != NM_VPN_CONNECTION_STATE_DISCONNECTED) {
-               g_warning ("VPN connection is already connected or connecting");
-               return FALSE;
-       }
+       GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
 
-       i = 0;
-       password_strings = g_new (char *, g_slist_length (passwords) + 1);
-       for (iter = passwords; iter; iter = iter->next)
-               password_strings[i++] = iter->data;
-       password_strings[i] = NULL;
-
-       /* FIXME: This has to be ASYNC for now since NM will call back to get routes.
-          We should just pass the routes along with this call */
-       dbus_g_proxy_call_no_reply (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy,
-                                                               "activateVPNConnection",
-                                                               G_TYPE_STRING, nm_vpn_connection_get_name (vpn),
-                                                               G_TYPE_STRV, password_strings,
-                                                               G_TYPE_INVALID,
-                                                               G_TYPE_INVALID);
-       g_free (password_strings);
-
-       return TRUE;
-}
+       g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
 
-gboolean
-nm_vpn_connection_deactivate (NMVPNConnection *vpn)
-{
-       g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
+       /* virtual methods */
+       object_class->constructor = constructor;
+       object_class->finalize = finalize;
 
-       if (nm_vpn_connection_get_state (vpn) != NM_VPN_CONNECTION_STATE_ACTIVATED &&
-               !nm_vpn_connection_is_activating (vpn)) {
-               g_warning ("VPN connection isn't activated");
-               return FALSE;
-       }
-       
-       dbus_g_proxy_call_no_reply (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy,
-                                                               "deactivateVPNConnection",
-                                                               G_TYPE_INVALID, G_TYPE_INVALID);
-       return TRUE;
+       /* signals */
+       signals[STATE_CHANGED] =
+               g_signal_new ("state-changed",
+                                   G_OBJECT_CLASS_TYPE (object_class),
+                                   G_SIGNAL_RUN_FIRST,
+                                   G_STRUCT_OFFSET (NMVPNConnectionClass, state_changed),
+                                   NULL, NULL,
+                                   g_cclosure_marshal_VOID__UINT,
+                                   G_TYPE_NONE, 1,
+                                   G_TYPE_UINT);
 }
index ade2d6d..fa84d7f 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
 /* NetworkManager Wireless Applet -- Display wireless access points and allow user control
  *
  * Dan Williams <dcbw@redhat.com>
@@ -25,6 +26,7 @@
 #include <glib/gtypes.h>
 #include <glib-object.h>
 #include <dbus/dbus-glib.h>
+#include "nm-object.h"
 #include "NetworkManagerVPN.h"
 
 G_BEGIN_DECLS
@@ -37,35 +39,26 @@ G_BEGIN_DECLS
 #define NM_VPN_CONNECTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass))
 
 typedef struct {
-       GObject parent;
+       NMObject parent;
 } NMVPNConnection;
 
 typedef struct {
-       GObjectClass parent;
+       NMObjectClass parent;
 
        /* Signals */
-       void (*updated) (NMVPNConnection *connection);
        void (*state_changed) (NMVPNConnection *connection, NMVPNConnectionState state);
 } NMVPNConnectionClass;
 
 GType nm_vpn_connection_get_type (void);
 
 
-NMVPNConnection *nm_vpn_connection_new (DBusGProxy *proxy, const char *name);
-gboolean       nm_vpn_connection_update (NMVPNConnection *vpn);
+NMVPNConnection      *nm_vpn_connection_new       (DBusGConnection *dbus_connection,
+                                                                                const char *path);
 
-const char *nm_vpn_connection_get_name (NMVPNConnection *vpn);
-const char *nm_vpn_connection_get_user_name (NMVPNConnection *vpn);
-const char *nm_vpn_connection_get_service (NMVPNConnection *vpn);
-NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *vpn);
-gboolean nm_vpn_connection_is_activating (NMVPNConnection *vpn);
+const char           *nm_vpn_connection_get_name  (NMVPNConnection *vpn);
+NMVPNConnectionState  nm_vpn_connection_get_state (NMVPNConnection *vpn);
 
-gboolean nm_vpn_connection_activate   (NMVPNConnection *vpn,
-                                                                          GSList *passwords);
-
-gboolean nm_vpn_connection_deactivate (NMVPNConnection *vpn);
-
-void nm_vpn_connection_set_state (NMVPNConnection *vpn, NMVPNConnectionState state);
+void                  nm_vpn_connection_disconnect (NMVPNConnection *vpn);
 
 G_END_DECLS
 
diff --git a/libnm-glib/nm-vpn-manager.c b/libnm-glib/nm-vpn-manager.c
new file mode 100644 (file)
index 0000000..b59ad68
--- /dev/null
@@ -0,0 +1,139 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#include <dbus/dbus-glib.h>
+#include <string.h>
+#include "nm-vpn-manager.h"
+#include "nm-marshal.h"
+
+#include "nm-vpn-manager-bindings.h"
+
+G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, NM_TYPE_OBJECT)
+
+#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate))
+
+typedef struct {
+       DBusGProxy *manager_proxy;
+} NMVPNManagerPrivate;
+
+NMVPNManager *
+nm_vpn_manager_new (void)
+{
+       DBusGConnection *connection;
+       GError *err = NULL;
+
+       connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+       if (!connection) {
+               g_warning ("Couldn't connect to system bus: %s", err->message);
+               g_error_free (err);
+               return NULL;
+       }
+
+       return (NMVPNManager *) g_object_new (NM_TYPE_VPN_MANAGER,
+                                                                  NM_OBJECT_CONNECTION, connection,
+                                                                  NM_OBJECT_PATH, NM_DBUS_PATH_VPN,
+                                                                  NULL);
+
+}
+
+NMVPNConnection *
+nm_vpn_manager_connect (NMVPNManager *manager,
+                                   const char   *type,
+                                   const char   *name,
+                                   GHashTable   *properties,
+                                   NMDevice     *device,
+                                   char        **routes)
+{
+       char *connection_path = NULL;
+       GError *err = NULL;
+
+       g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
+       g_return_val_if_fail (type != NULL, NULL);
+       g_return_val_if_fail (name != NULL, NULL);
+       g_return_val_if_fail (properties != NULL, NULL);
+       g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+
+       if (!org_freedesktop_NetworkManager_VPN_Manager_connect (NM_VPN_MANAGER_GET_PRIVATE (manager)->manager_proxy,
+                                                                                                 type, name,
+                                                                                                 properties,
+                                                                                                 nm_object_get_path (NM_OBJECT (device)),
+                                                                                                 routes,
+                                                                                                 &connection_path,
+                                                                                                 &err)) {
+               g_warning ("Error in VPN Connect: %s", err->message);
+               g_error_free (err);
+               return NULL;
+       }
+
+       return nm_vpn_connection_new (nm_object_get_connection (NM_OBJECT (manager)), connection_path);
+}
+
+GSList *
+nm_vpn_manager_get_connections (NMVPNManager *manager)
+{
+       GPtrArray *array = NULL;
+       GSList *list = NULL;
+       DBusGConnection *dbus_connection;
+       int i;
+       GError *err = NULL;
+
+       g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
+
+       if (!org_freedesktop_NetworkManager_VPN_Manager_list_connections (NM_VPN_MANAGER_GET_PRIVATE (manager)->manager_proxy,
+                                                                                                                &array, &err)) {
+               g_warning ("Error in getting VPN connections: %s", err->message);
+               g_error_free (err);
+               return NULL;
+       }
+
+       dbus_connection = nm_object_get_connection (NM_OBJECT (manager));
+
+       for (i = 0; i < array->len; i++)
+               list = g_slist_prepend (list, nm_vpn_connection_new (dbus_connection, (char *) g_ptr_array_index (array, i)));
+
+       return list;
+}
+
+/*****************************************************************************/
+
+static void
+nm_vpn_manager_init (NMVPNManager *manager)
+{
+}
+
+static GObject*
+constructor (GType type,
+                  guint n_construct_params,
+                  GObjectConstructParam *construct_params)
+{
+       NMObject *object;
+
+       object = (NMObject *) G_OBJECT_CLASS (nm_vpn_manager_parent_class)->constructor (type,
+                                                                                                                                        n_construct_params,
+                                                                                                                                        construct_params);
+       if (!object)
+               return NULL;
+
+       NM_VPN_MANAGER_GET_PRIVATE (object)->manager_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
+                                                                                                                                       NM_DBUS_SERVICE,
+                                                                                                                                       nm_object_get_path (object),
+                                                                                                                                       NM_DBUS_INTERFACE_VPN);
+       return G_OBJECT (object);
+}
+
+static void
+finalize (GObject *object)
+{
+       g_object_unref (NM_VPN_MANAGER_GET_PRIVATE (object)->manager_proxy);
+}
+
+static void
+nm_vpn_manager_class_init (NMVPNManagerClass *manager_class)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
+
+       g_type_class_add_private (manager_class, sizeof (NMVPNManagerPrivate));
+
+       /* virtual methods */
+       object_class->constructor = constructor;
+       object_class->finalize = finalize;
+}
diff --git a/libnm-glib/nm-vpn-manager.h b/libnm-glib/nm-vpn-manager.h
new file mode 100644 (file)
index 0000000..f92a103
--- /dev/null
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#ifndef NM_VPN_MANAGER_H
+#define NM_VPN_MANAGER_H 1
+
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include <NetworkManager.h>
+#include <NetworkManagerVPN.h>
+#include "nm-object.h"
+#include "nm-device.h"
+#include "nm-vpn-connection.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_VPN_MANAGER            (nm_vpn_manager_get_type ())
+#define NM_VPN_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_MANAGER, NMVPNManager))
+#define NM_VPN_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_MANAGER, NMVPNManagerClass))
+#define NM_IS_VPN_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_MANAGER))
+#define NM_IS_VPN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_MANAGER))
+#define NM_VPN_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_MANAGER, NMVPNManagerClass))
+
+typedef struct {
+       NMObject parent;
+} NMVPNManager;
+
+typedef struct {
+       NMObjectClass parent;
+} NMVPNManagerClass;
+
+GType nm_vpn_manager_get_type (void);
+
+
+NMVPNManager    *nm_vpn_manager_new     (void);
+NMVPNConnection *nm_vpn_manager_connect (NMVPNManager *manager,
+                                                                const char   *type,
+                                                                const char   *name,
+                                                                GHashTable   *properties,
+                                                                NMDevice     *device,
+                                                                char        **routes);
+
+GSList *nm_vpn_manager_get_connections  (NMVPNManager *manager);
+
+G_END_DECLS
+
+#endif /* NM_MANAGER_H */
diff --git a/libnm-glib/nm-vpn-plugin.c b/libnm-glib/nm-vpn-plugin.c
new file mode 100644 (file)
index 0000000..f96d3cc
--- /dev/null
@@ -0,0 +1,676 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#include <signal.h>
+#include "nm-vpn-plugin.h"
+#include "nm-utils.h"
+
+static gboolean impl_vpn_plugin_connect    (NMVPNPlugin *plugin,
+                                                                   GHashTable *connection,
+                                                                   char **routes,
+                                                                   GError **err);
+
+static gboolean impl_vpn_plugin_disconnect (NMVPNPlugin *plugin,
+                                                                   GError **err);
+
+static gboolean impl_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
+                                                                          GHashTable *config,
+                                                                          GError **err);
+
+static gboolean impl_vpn_plugin_set_failure (NMVPNPlugin *plugin,
+                                                                       char *reason,
+                                                                       GError **err);
+
+#include "nm-vpn-plugin-glue.h"
+
+#define NM_VPN_PLUGIN_CONNECT_TIMER 60000
+#define NM_VPN_PLUGIN_QUIT_TIMER    20000
+
+G_DEFINE_ABSTRACT_TYPE (NMVPNPlugin, nm_vpn_plugin, G_TYPE_OBJECT)
+
+typedef struct {
+       NMVPNServiceState state;
+
+       /* DBUS-y stuff */
+       DBusGConnection *connection;
+       char *dbus_service_name;
+
+       /* GObject-y stuff */
+       gboolean disposed;
+
+       /* Temporary stuff */
+       guint connect_timer;
+       guint quit_timer;
+} NMVPNPluginPrivate;
+
+#define NM_VPN_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_PLUGIN, NMVPNPluginPrivate))
+
+enum {
+       STATE_CHANGED,
+       IP4_CONFIG,
+       LOGIN_BANNER,
+       FAILURE,
+       QUIT,
+
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+enum {
+       PROP_0,
+       PROP_DBUS_SERVICE_NAME,
+       PROP_STATE,
+
+       LAST_PROP
+};
+
+static GSList *active_plugins = NULL;
+
+
+GQuark
+nm_vpn_plugin_error_quark (void)
+{
+       static GQuark quark = 0;
+       
+       if (!quark)
+               quark = g_quark_from_static_string ("nm_vpn_plugin_error");
+
+       return quark;
+}
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GType
+nm_vpn_plugin_error_get_type (void)
+{
+       static GType etype = 0;
+
+       if (etype == 0) {
+               static const GEnumValue values[] = {
+                       ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_GENERAL,              "General"),
+                       ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS, "StartingInProgress"),
+                       ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_ALREADY_STARTED,      "AlreadyStarted"),
+                       ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, "StoppingInProgress"),
+                       ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED,      "AlreadyStopped"),
+                       ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_WRONG_STATE,          "WrongState"),
+                       ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,        "BadArguments"),
+                       ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,        "LaunchFailed"),
+                       { 0, 0, 0 }
+               };
+
+               etype = g_enum_register_static ("NMVPNPluginError", values);
+       }
+
+       return etype;
+}
+
+
+static void
+nm_vpn_plugin_set_connection (NMVPNPlugin *plugin,
+                                               DBusGConnection *connection)
+{
+       NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+
+       if (priv->connection)
+               dbus_g_connection_unref (priv->connection);
+
+       priv->connection = connection;
+}
+
+DBusGConnection *
+nm_vpn_plugin_get_connection (NMVPNPlugin *plugin)
+{
+       DBusGConnection *connection;
+
+       g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), NULL);
+
+       connection = NM_VPN_PLUGIN_GET_PRIVATE (plugin)->connection;
+
+       if (connection)
+               dbus_g_connection_ref (connection);
+
+       return connection;
+}
+
+NMVPNServiceState
+nm_vpn_plugin_get_state (NMVPNPlugin *plugin)
+{
+       g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), NM_VPN_SERVICE_STATE_UNKNOWN);
+
+       return NM_VPN_PLUGIN_GET_PRIVATE (plugin)->state;
+}
+
+void
+nm_vpn_plugin_set_state (NMVPNPlugin *plugin,
+                                       NMVPNServiceState state)
+{
+       NMVPNPluginPrivate *priv;
+
+       g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
+
+       priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+       if (priv->state != state) {
+               priv->state = state;
+               g_signal_emit (plugin, signals[STATE_CHANGED], 0, state);
+       }
+}
+
+void
+nm_vpn_plugin_set_login_banner (NMVPNPlugin *plugin,
+                                                 const char *banner)
+{
+       g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
+       g_return_if_fail (banner != NULL);
+
+       g_signal_emit (plugin, signals[LOGIN_BANNER], 0, banner);
+}
+
+void
+nm_vpn_plugin_failure (NMVPNPlugin *plugin,
+                                  NMVPNPluginFailure reason)
+{
+       g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
+
+       g_signal_emit (plugin, signals[FAILURE], 0, reason);
+}
+
+gboolean
+nm_vpn_plugin_disconnect (NMVPNPlugin *plugin, GError **err)
+{
+       gboolean ret = FALSE;
+       NMVPNServiceState state;
+
+       g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);
+
+       state = nm_vpn_plugin_get_state (plugin);
+       switch (state) {
+       case NM_VPN_SERVICE_STATE_STOPPING:
+               g_set_error (err,
+                                  NM_VPN_PLUGIN_ERROR,
+                                  NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS,
+                                  "%s",
+                                  "Could not process the request because the VPN connection is already being stopped.");
+               break;
+       case NM_VPN_SERVICE_STATE_STOPPED:
+               g_set_error (err,
+                                  NM_VPN_PLUGIN_ERROR,
+                                  NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED,
+                                  "%s",
+                                  "Could not process the request because no VPN connection was active.");
+               break;
+       case NM_VPN_SERVICE_STATE_STARTING:
+       case NM_VPN_SERVICE_STATE_STARTED:
+               nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPING);
+               ret = NM_VPN_PLUGIN_GET_CLASS (plugin)->disconnect (plugin, err);
+               nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
+               break;
+
+       default:
+               g_assert_not_reached ();
+               break;
+       }
+
+       return ret;
+}
+
+static void
+nm_vpn_plugin_emit_quit (NMVPNPlugin *plugin)
+{
+       g_signal_emit (plugin, signals[QUIT], 0);
+}
+
+static gboolean
+connect_timer_expired (gpointer data)
+{
+       NMVPNPlugin *plugin = NM_VPN_PLUGIN (data);
+       GError *err = NULL;
+
+       nm_info ("Connect timer expired, disconnecting.");
+       nm_vpn_plugin_disconnect (plugin, &err);
+       if (err) {
+               nm_warning ("Disconnect failed: %s", err->message);
+               g_error_free (err);
+       }
+
+       return FALSE;
+}
+
+static gboolean
+quit_timer_expired (gpointer data)
+{
+       NMVPNPlugin *plugin = NM_VPN_PLUGIN (data);
+
+       nm_vpn_plugin_emit_quit (plugin);
+
+       return FALSE;
+}
+
+static gboolean
+nm_vpn_plugin_connect (NMVPNPlugin *plugin,
+                                  GHashTable *properties,
+                                  char **routes,
+                                  GError **err)
+{
+       gboolean ret = FALSE;
+       NMVPNServiceState state;
+
+       g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);
+
+       state = nm_vpn_plugin_get_state (plugin);
+       switch (state) {
+       case NM_VPN_SERVICE_STATE_STARTING:
+               g_set_error (err,
+                                  NM_VPN_PLUGIN_ERROR,
+                                  NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS,
+                                  "%s",
+                                  "Could not process the request because the VPN connection is already being started.");
+               break;
+       case NM_VPN_SERVICE_STATE_STARTED:
+               g_set_error (err,
+                                  NM_VPN_PLUGIN_ERROR,
+                                  NM_VPN_PLUGIN_ERROR_ALREADY_STARTED,
+                                  "%s",
+                                  "Could not process the request because a VPN connection was already active.");
+               break;
+       case NM_VPN_SERVICE_STATE_STOPPING:
+               g_set_error (err,
+                                  NM_VPN_PLUGIN_ERROR,
+                                  NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS,
+                                  "%s",
+                                  "Could not process the request because the VPN connection is being stopped.");
+               break;
+       case NM_VPN_SERVICE_STATE_STOPPED:
+       case NM_VPN_SERVICE_STATE_INIT:
+               nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING);
+               ret = NM_VPN_PLUGIN_GET_CLASS (plugin)->connect (plugin, properties, routes, err);
+               if (!ret)
+                       nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
+               break;
+
+       default:
+               g_assert_not_reached ();
+               break;
+       }
+
+       return ret;
+}
+
+void
+nm_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
+                                               GHashTable *ip4_config)
+{
+       g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
+       g_return_if_fail (ip4_config != NULL);
+
+       g_signal_emit (plugin, signals[IP4_CONFIG], 0, ip4_config);
+
+       nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED);
+}
+
+
+static gboolean
+impl_vpn_plugin_connect (NMVPNPlugin *plugin,
+                                       GHashTable *properties,
+                                       char **routes,
+                                       GError **err)
+{
+       return nm_vpn_plugin_connect (plugin, properties, routes, err);
+}
+
+static gboolean
+impl_vpn_plugin_disconnect (NMVPNPlugin *plugin,
+                                          GError **err)
+{
+       return nm_vpn_plugin_disconnect (plugin, err);
+}
+
+static gboolean
+impl_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
+                                                 GHashTable *config,
+                                                 GError **err)
+{
+       nm_vpn_plugin_set_ip4_config (plugin, config);
+
+       return TRUE;
+}
+
+static gboolean
+impl_vpn_plugin_set_failure (NMVPNPlugin *plugin,
+                                           char *reason,
+                                           GError **err)
+{
+       nm_vpn_plugin_failure (plugin, NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG);
+
+       return TRUE;
+}
+
+/*********************************************************************/
+
+static void
+sigterm_handler (int signum)
+{
+       g_slist_foreach (active_plugins, (GFunc) nm_vpn_plugin_emit_quit, NULL);
+}
+
+static void
+setup_unix_signal_handler (void)
+{
+       struct sigaction action;
+       sigset_t block_mask;
+
+       action.sa_handler = sigterm_handler;
+       sigemptyset (&block_mask);
+       action.sa_mask = block_mask;
+       action.sa_flags = 0;
+       sigaction (SIGINT, &action, NULL);
+       sigaction (SIGTERM, &action, NULL);
+}
+
+/*********************************************************************/
+
+static void
+one_plugin_destroyed (gpointer data,
+                                 GObject *object)
+{
+       active_plugins = g_slist_remove (active_plugins, object);
+}
+
+static void
+nm_vpn_plugin_init (NMVPNPlugin *plugin)
+{
+       active_plugins = g_slist_append (active_plugins, plugin);
+       g_object_weak_ref (G_OBJECT (plugin),
+                                   one_plugin_destroyed,
+                                   NULL);
+}
+
+static GObject *
+constructor (GType type,
+                  guint n_construct_params,
+                  GObjectConstructParam *construct_params)
+{
+       GObject *object;
+       NMVPNPlugin *plugin;
+       NMVPNPluginPrivate *priv;
+       DBusGConnection *connection;
+       DBusGProxy *proxy;
+       guint request_name_result;
+       GError *err = NULL;
+
+       object = G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->constructor (type,
+                                                                                                                 n_construct_params,
+                                                                                                                 construct_params);
+       if (!object)
+               return NULL;
+
+       priv = NM_VPN_PLUGIN_GET_PRIVATE (object);
+       if (!priv->dbus_service_name)
+               goto err;
+
+       connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+       if (!connection)
+               goto err;
+
+       proxy = dbus_g_proxy_new_for_name (connection,
+                                                               "org.freedesktop.DBus",
+                                                               "/org/freedesktop/DBus",
+                                                               "org.freedesktop.DBus");
+
+       if (!dbus_g_proxy_call (proxy, "RequestName", &err,
+                                           G_TYPE_STRING, priv->dbus_service_name,
+                                           G_TYPE_UINT, 0,
+                                           G_TYPE_INVALID,
+                                           G_TYPE_UINT, &request_name_result,
+                                           G_TYPE_INVALID)) {
+               g_object_unref (proxy);
+               goto err;
+       }
+
+       g_object_unref (proxy);
+
+       dbus_g_connection_register_g_object (connection,
+                                                                 NM_VPN_DBUS_PLUGIN_PATH,
+                                                                 object);
+
+       plugin = NM_VPN_PLUGIN (object);
+
+       nm_vpn_plugin_set_connection (plugin, connection);
+       nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_INIT);
+
+       return object;
+
+ err:
+       if (err) {
+               nm_warning ("%s", err->message);
+               g_error_free (err);
+       }
+
+       if (object)
+               g_object_unref (object);
+
+       return NULL;
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+                   const GValue *value, GParamSpec *pspec)
+{
+       NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (object);
+
+       switch (prop_id) {
+       case PROP_DBUS_SERVICE_NAME:
+               /* Construct-only */
+               priv->dbus_service_name = g_strdup (g_value_get_string (value));
+               break;
+       case PROP_STATE:
+               nm_vpn_plugin_set_state (NM_VPN_PLUGIN (object),
+                                                       (NMVPNServiceState) 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)
+{
+       NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (object);
+
+       switch (prop_id) {
+       case PROP_DBUS_SERVICE_NAME:
+               g_value_set_string (value, priv->dbus_service_name);
+               break;
+       case PROP_STATE:
+               g_value_set_uint (value, nm_vpn_plugin_get_state (NM_VPN_PLUGIN (object)));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+dispose (GObject *object)
+{
+       NMVPNPlugin *plugin = NM_VPN_PLUGIN (object);
+       NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+       NMVPNServiceState state;
+       GError *err = NULL;
+
+       if (priv->disposed)
+               return;
+
+       priv->disposed = TRUE;
+
+       state = nm_vpn_plugin_get_state (plugin);
+
+       if (state == NM_VPN_SERVICE_STATE_STARTED ||
+           state == NM_VPN_SERVICE_STATE_STARTING)
+               nm_vpn_plugin_disconnect (plugin, &err);
+
+       if (err) {
+               nm_warning ("%s", err->message);
+               g_error_free (err);
+       }
+
+       G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+       NMVPNPlugin *plugin = NM_VPN_PLUGIN (object);
+       NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+
+       nm_vpn_plugin_set_connection (plugin, NULL);
+       g_free (priv->dbus_service_name);
+
+       G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->finalize (object);
+}
+
+static void
+connect_timer_removed (gpointer data)
+{
+       NM_VPN_PLUGIN_GET_PRIVATE (data)->connect_timer = 0;
+}
+
+static void
+quit_timer_removed (gpointer data)
+{
+       NM_VPN_PLUGIN_GET_PRIVATE (data)->quit_timer = 0;
+}
+
+static void
+state_changed (NMVPNPlugin *plugin, NMVPNServiceState state)
+{
+       NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+
+       switch (state) {
+       case NM_VPN_SERVICE_STATE_STARTING:
+               /* Remove the quit timer. */
+               if (priv->quit_timer)
+                       g_source_remove (priv->quit_timer);
+
+               /* Add a timer to make sure we do not wait indefinitely for the successful connect. */
+               priv->connect_timer = g_timeout_add_full (G_PRIORITY_DEFAULT,
+                                                                                 NM_VPN_PLUGIN_CONNECT_TIMER,
+                                                                                 connect_timer_expired,
+                                                                                 plugin,
+                                                                                 connect_timer_removed);
+               break;
+       case NM_VPN_SERVICE_STATE_STOPPED:
+               priv->quit_timer = g_timeout_add_full (G_PRIORITY_DEFAULT, 
+                                                                           NM_VPN_PLUGIN_QUIT_TIMER,
+                                                                           quit_timer_expired,
+                                                                           plugin,
+                                                                           quit_timer_removed);
+               break;
+       default:
+               /* Clean up all timers we might have set up. */
+               if (priv->connect_timer)
+                       g_source_remove (priv->connect_timer);
+
+               if (priv->quit_timer)
+                       g_source_remove (priv->quit_timer);
+
+               break;
+       }
+}
+
+static void
+nm_vpn_plugin_class_init (NMVPNPluginClass *plugin_class)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (plugin_class);
+
+       g_type_class_add_private (object_class, sizeof (NMVPNPluginPrivate));
+
+       dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (plugin_class),
+                                                          &dbus_glib_nm_vpn_plugin_object_info);
+
+       /* virtual methods */
+       object_class->constructor  = constructor;
+       object_class->set_property = set_property;
+       object_class->get_property = get_property;
+       object_class->dispose      = dispose;
+       object_class->finalize     = finalize;
+
+       plugin_class->state_changed = state_changed;
+
+       /* properties */
+       g_object_class_install_property
+               (object_class, PROP_DBUS_SERVICE_NAME,
+                g_param_spec_string (NM_VPN_PLUGIN_DBUS_SERVICE_NAME,
+                                                 "DBus service name",
+                                                 "DBus service name",
+                                                 NULL,
+                                                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+       g_object_class_install_property
+               (object_class, PROP_STATE,
+                g_param_spec_uint (NM_VPN_PLUGIN_STATE,
+                                               "State",
+                                               "Current VPN service state",
+                                               NM_VPN_SERVICE_STATE_UNKNOWN,
+                                               NM_VPN_SERVICE_STATE_STOPPED,
+                                               NM_VPN_SERVICE_STATE_INIT,
+                                               G_PARAM_READWRITE));
+
+       /* signals */
+       signals[STATE_CHANGED] =
+               g_signal_new ("state-changed",
+                                   G_OBJECT_CLASS_TYPE (object_class),
+                                   G_SIGNAL_RUN_FIRST,
+                                   G_STRUCT_OFFSET (NMVPNPluginClass, state_changed),
+                                   NULL, NULL,
+                                   g_cclosure_marshal_VOID__UINT,
+                                   G_TYPE_NONE, 1,
+                                   G_TYPE_UINT);
+
+       signals[IP4_CONFIG] =
+               g_signal_new ("ip4-config",
+                                   G_OBJECT_CLASS_TYPE (object_class),
+                                   G_SIGNAL_RUN_FIRST,
+                                   G_STRUCT_OFFSET (NMVPNPluginClass, ip4_config),
+                                   NULL, NULL,
+                                   g_cclosure_marshal_VOID__BOXED,
+                                   G_TYPE_NONE, 1,
+                                   dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE));
+
+       signals[LOGIN_BANNER] =
+               g_signal_new ("login-banner",
+                                   G_OBJECT_CLASS_TYPE (object_class),
+                                   G_SIGNAL_RUN_FIRST,
+                                   G_STRUCT_OFFSET (NMVPNPluginClass, login_banner),
+                                   NULL, NULL,
+                                   g_cclosure_marshal_VOID__STRING,
+                                   G_TYPE_NONE, 1,
+                                   G_TYPE_STRING);
+
+       signals[FAILURE] =
+               g_signal_new ("failure",
+                                   G_OBJECT_CLASS_TYPE (object_class),
+                                   G_SIGNAL_RUN_FIRST,
+                                   G_STRUCT_OFFSET (NMVPNPluginClass, failure),
+                                   NULL, NULL,
+                                   g_cclosure_marshal_VOID__UINT,
+                                   G_TYPE_NONE, 1,
+                                   G_TYPE_UINT);
+
+       signals[QUIT] =
+               g_signal_new ("quit",
+                                   G_OBJECT_CLASS_TYPE (object_class),
+                                   G_SIGNAL_RUN_FIRST,
+                                   G_STRUCT_OFFSET (NMVPNPluginClass, quit),
+                                   NULL, NULL,
+                                   g_cclosure_marshal_VOID__VOID,
+                                   G_TYPE_NONE, 0,
+                                   G_TYPE_NONE);
+
+       dbus_g_error_domain_register (NM_VPN_PLUGIN_ERROR,
+                                                       NULL,
+                                                       NM_TYPE_VPN_PLUGIN_ERROR);
+
+       setup_unix_signal_handler ();
+}
diff --git a/libnm-glib/nm-vpn-plugin.h b/libnm-glib/nm-vpn-plugin.h
new file mode 100644 (file)
index 0000000..59672b0
--- /dev/null
@@ -0,0 +1,98 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#ifndef NM_VPN_PLUGIN_H
+#define NM_VPN_PLUGIN_H
+
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include <NetworkManagerVPN.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_VPN_PLUGIN            (nm_vpn_plugin_get_type ())
+#define NM_VPN_PLUGIN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_PLUGIN, NMVPNPlugin))
+#define NM_VPN_PLUGIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_PLUGIN, NMVPNPluginClass))
+#define NM_IS_VPN_PLUGIN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_PLUGIN))
+#define NM_IS_VPN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_PLUGIN))
+#define NM_VPN_PLUGIN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_PLUGIN, NMVPNPluginClass))
+
+#define NM_VPN_PLUGIN_DBUS_SERVICE_NAME "service-name"
+#define NM_VPN_PLUGIN_STATE             "state"
+
+typedef enum {
+       NM_VPN_PLUGIN_ERROR_GENERAL,
+       NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS,
+       NM_VPN_PLUGIN_ERROR_ALREADY_STARTED,
+       NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS,
+       NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED,
+       NM_VPN_PLUGIN_ERROR_WRONG_STATE,
+       NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+       NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+} NMVPNPluginError;
+
+#define NM_VPN_PLUGIN_ERROR      (nm_vpn_plugin_error_quark ())
+#define NM_TYPE_VPN_PLUGIN_ERROR (nm_vpn_plugin_error_get_type ()) 
+
+typedef enum {
+       NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED,
+       NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED,
+       NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG
+} NMVPNPluginFailure;
+
+typedef struct {
+       GObject parent;
+} NMVPNPlugin;
+
+typedef struct {
+       GObjectClass parent;
+
+       /* virtual methods */
+       gboolean (*connect)    (NMVPNPlugin   *plugin,
+                                           GHashTable    *properties,
+                                           char         **routes,
+                                           GError       **err);
+
+       gboolean (*disconnect) (NMVPNPlugin   *plugin,
+                                           GError       **err);
+
+       /* Signals */
+       void (*state_changed)  (NMVPNPlugin *plugin,
+                                           NMVPNServiceState state);
+
+       void (*ip4_config)     (NMVPNPlugin *plugin,
+                                           GHashTable  *ip4_config);
+
+       void (*login_banner)   (NMVPNPlugin *plugin,
+                                           const char *banner);
+
+       void (*failure)        (NMVPNPlugin *plugin,
+                                           NMVPNPluginFailure reason);
+
+       void (*quit)           (NMVPNPlugin *plugin);
+} NMVPNPluginClass;
+
+GType  nm_vpn_plugin_get_type       (void);
+GQuark nm_vpn_plugin_error_quark    (void);
+GType  nm_vpn_plugin_error_get_type (void);
+
+DBusGConnection   *nm_vpn_plugin_get_connection (NMVPNPlugin *plugin);
+NMVPNServiceState  nm_vpn_plugin_get_state      (NMVPNPlugin *plugin);
+void               nm_vpn_plugin_set_state      (NMVPNPlugin *plugin,
+                                                                           NMVPNServiceState state);
+
+void               nm_vpn_plugin_set_login_banner (NMVPNPlugin *plugin,
+                                                                                const char *banner);
+
+void               nm_vpn_plugin_failure        (NMVPNPlugin *plugin,
+                                                                           NMVPNPluginFailure reason);
+
+void               nm_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
+                                                                           GHashTable *ip4_config);
+
+gboolean           nm_vpn_plugin_disconnect     (NMVPNPlugin *plugin,
+                                                                           GError **err);
+
+G_END_DECLS
+
+#endif /* NM_VPN_PLUGIN_H */
index 6c5ecb6..05154ce 100644 (file)
@@ -40,7 +40,9 @@ libnm_util_la_SOURCES=                        \
        nm-connection.c                 \
        nm-connection.h                 \
        nm-setting.c                    \
-       nm-setting.h
+       nm-setting.h                    \
+       nm-utils.c                      \
+       nm-utils.h
 
 if !WITH_GCRYPT
 libnm_util_la_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h
@@ -67,7 +69,8 @@ libnm_util_include_HEADERS =          \
        dbus-method-dispatcher.h        \
        dbus-dict-helpers.h             \
        nm-connection.h                 \
-       nm-setting.h
+       nm-setting.h                    \
+       nm-utils.h
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libnm-util.pc
index 7931220..1c006d8 100644 (file)
@@ -225,29 +225,6 @@ nm_connection_to_hash (NMConnection *connection)
        return connection_hash;
 }
 
-static char *
-garray_to_string (GArray *array)
-{
-       GString *str;
-       int i;
-       char c;
-
-       g_return_val_if_fail (array != NULL, NULL);
-
-       str = g_string_sized_new (array->len);
-       for (i = 0; i < array->len; i++) {
-               c = array->data[i];
-
-               /* Convert NULLs to spaces to increase the readability. */
-               if (c == '\0')
-                       c = ' ';
-               str = g_string_append_c (str, c);
-       }
-       str = g_string_append_c (str, '\0');
-
-       return g_string_free (str, FALSE);
-}
-
 static char *
 gvalue_to_string (GValue *val)
 {
@@ -277,7 +254,7 @@ gvalue_to_string (GValue *val)
        default:
                /* These return dynamic values and thus can't be 'case's */
                if (type == DBUS_TYPE_G_UCHAR_ARRAY)
-                       ret = garray_to_string ((GArray *) g_value_get_boxed (val));
+                       ret = nm_utils_garray_to_string ((GArray *) g_value_get_boxed (val));
                else if (type == dbus_g_type_get_collection ("GSList", G_TYPE_STRING)) {
                        GSList *iter;
 
@@ -302,7 +279,7 @@ gvalue_to_string (GValue *val)
 
                        ptr_array = (GPtrArray *) g_value_get_boxed (val);
                        for (i = 0; i < ptr_array->len; i++) {
-                               ret = garray_to_string ((GArray *) g_ptr_array_index (ptr_array, i));
+                               ret = nm_utils_garray_to_string ((GArray *) g_ptr_array_index (ptr_array, i));
 
                                if (need_comma)
                                        g_string_append (str, ", ");
diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c
new file mode 100644 (file)
index 0000000..5bab0db
--- /dev/null
@@ -0,0 +1,541 @@
+/* NetworkManager -- Network link manager
+ *
+ * Ray Strode <rstrode@redhat.com>
+ *
+ * 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.
+ *
+ * (C) Copyright 2005 Red Hat, Inc.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <iwlib.h>
+#include <wireless.h>
+
+#include <glib.h>
+#include <glib-object.h>
+#include <dbus/dbus.h>
+#include "nm-utils.h"
+
+gchar *nm_dbus_escape_object_path (const gchar *utf8_string)
+{
+       const gchar *p;
+       gchar *object_path;
+       GString *string;
+
+       g_return_val_if_fail (utf8_string != NULL, NULL);       
+       g_return_val_if_fail (g_utf8_validate (utf8_string, -1, NULL), NULL);
+
+       string = g_string_sized_new ((strlen (utf8_string) + 1) * 6);
+
+       for (p = utf8_string; *p != '\0'; p = g_utf8_next_char (p))
+       {
+               gunichar character;
+
+               character = g_utf8_get_char (p);
+
+               if (((character >= ((gunichar) 'a')) && 
+                    (character <= ((gunichar) 'z'))) ||
+                   ((character >= ((gunichar) 'A')) && 
+                    (character <= ((gunichar) 'Z'))) ||
+                   ((character >= ((gunichar) '0')) && 
+                    (character <= ((gunichar) '9'))) ||
+                    (character == ((gunichar) '/')))
+               {
+                       g_string_append_c (string, (gchar) character);
+                       continue;
+               }
+
+               g_string_append_printf (string, "_%x_", character);
+       }
+
+       object_path = string->str;
+
+       g_string_free (string, FALSE);
+
+       return object_path;
+}
+
+gchar *nm_dbus_unescape_object_path (const gchar *object_path)
+{
+       const gchar *p;
+       gchar *utf8_string;
+       GString *string;
+
+       g_return_val_if_fail (object_path != NULL, NULL);       
+
+       string = g_string_sized_new (strlen (object_path) + 1);
+
+       for (p = object_path; *p != '\0'; p++)
+       {
+               const gchar *q;
+               gchar *hex_digits, *end, utf8_character[6] = { '\0' };
+               gint utf8_character_size;
+               gunichar character;
+               gulong hex_value;
+
+               if (*p != '_')
+               {
+                   g_string_append_c (string, *p);
+                   continue;
+               }
+
+               q = strchr (p + 1, '_'); 
+
+               if ((q == NULL) || (q == p + 1))
+               {
+                   g_string_free (string, TRUE);
+                   return NULL;
+               }
+
+               hex_digits = g_strndup (p + 1, (q - 1) - p);
+
+               hex_value = strtoul (hex_digits, &end, 16);
+
+               character = (gunichar) hex_value;
+
+               if (((hex_value == G_MAXLONG) && (errno == ERANGE)) ||
+                   (hex_value > G_MAXUINT32) ||
+                   (*end != '\0') ||
+                   (!g_unichar_validate (character)))
+               {
+                   g_free (hex_digits);
+                   g_string_free (string, TRUE);
+                   return NULL;
+               }
+
+               utf8_character_size = 
+                       g_unichar_to_utf8 (character, utf8_character);
+
+               g_assert (utf8_character_size > 0);
+
+               g_string_append_len (string, utf8_character,
+                                    utf8_character_size);
+
+               p = q;
+       }
+
+       utf8_string = string->str;
+
+       g_string_free (string, FALSE);
+
+       return utf8_string;
+}
+
+struct EncodingTriplet
+{
+       const char *encoding1;
+       const char *encoding2;
+       const char *encoding3;
+};
+
+struct IsoLangToEncodings
+{
+       const char *    lang;
+       struct EncodingTriplet encodings;
+};
+
+/* 5-letter language codes */
+static const struct IsoLangToEncodings isoLangEntries5[] =
+{
+       /* Simplified Chinese */
+       { "zh_cn",      {"euc-cn",      "gb2312",                       "gb18030"} },   /* PRC */
+       { "zh_sg",      {"euc-cn",      "gb2312",                       "gb18030"} },   /* Singapore */
+
+       /* Traditional Chinese */
+       { "zh_tw",      {"big5",                "euc-tw",                       NULL} },                /* Taiwan */
+       { "zh_hk",      {"big5",                "euc-tw",                       "big5-hkcs"} },/* Hong Kong */
+       { "zh_mo",      {"big5",                "euc-tw",                       NULL} },                /* Macau */
+
+       /* Table end */
+       { NULL, {NULL, NULL, NULL} }
+};
+
+/* 2-letter language codes; we don't care about the other 3 in this table */
+static const struct IsoLangToEncodings isoLangEntries2[] =
+{
+       /* Japanese */
+       { "ja",         {"euc-jp",      "shift_jis",            "iso-2022-jp"} },
+
+       /* Korean */
+       { "ko",         {"euc-kr",      "iso-2022-kr",          "johab"} },
+
+       /* Thai */
+       { "th",         {"iso-8859-11","windows-874",           NULL} },
+
+       /* Central European */
+       { "hu",         {"iso-8859-2",  "windows-1250", NULL} },        /* Hungarian */
+       { "cs",         {"iso-8859-2",  "windows-1250", NULL} },        /* Czech */
+       { "hr",         {"iso-8859-2",  "windows-1250", NULL} },        /* Croatian */
+       { "pl",         {"iso-8859-2",  "windows-1250", NULL} },        /* Polish */
+       { "ro",         {"iso-8859-2",  "windows-1250", NULL} },        /* Romanian */
+       { "sk",         {"iso-8859-2",  "windows-1250", NULL} },        /* Slovakian */
+       { "sl",         {"iso-8859-2",  "windows-1250", NULL} },        /* Slovenian */
+       { "sh",         {"iso-8859-2",  "windows-1250", NULL} },        /* Serbo-Croatian */
+
+       /* Cyrillic */
+       { "ru",         {"koi8-r",      "windows-1251", "iso-8859-5"} },        /* Russian */
+       { "be",         {"koi8-r",      "windows-1251", "iso-8859-5"} },        /* Belorussian */
+       { "bg",         {"windows-1251","koi8-r",               "iso-8859-5"} },        /* Bulgarian */
+       { "mk",         {"koi8-r",      "windows-1251", "iso-8859-5"} },        /* Macedonian */
+       { "sr",         {"koi8-r",      "windows-1251", "iso-8859-5"} },        /* Serbian */
+       { "uk",         {"koi8-u",      "koi8-r",                       "windows-1251"} },      /* Ukranian */
+
+       /* Arabic */
+       { "ar",         {"iso-8859-6",  "windows-1256", NULL} },
+
+       /* Balitc */
+       { "et",         {"iso-8859-4",  "windows-1257", NULL} },        /* Estonian */
+       { "lt",         {"iso-8859-4",  "windows-1257", NULL} },        /* Lithuanian */
+       { "lv",         {"iso-8859-4",  "windows-1257", NULL} },        /* Latvian */
+
+       /* Greek */
+       { "el",         {"iso-8859-7",  "windows-1253", NULL} },
+
+       /* Hebrew */
+       { "he",         {"iso-8859-8",  "windows-1255", NULL} },
+       { "iw",         {"iso-8859-8",  "windows-1255", NULL} },
+
+       /* Turkish */
+       { "tr",         {"iso-8859-9",  "windows-1254", NULL} },
+
+       /* Table end */
+       { NULL, {NULL, NULL, NULL} }
+};
+
+
+static GHashTable * langToEncodings5 = NULL;
+static GHashTable * langToEncodings2 = NULL;
+
+static void
+init_lang_to_encodings_hash (void)
+{
+       static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+       g_static_mutex_lock (&mutex);
+       if (G_UNLIKELY (!langToEncodings5 || !langToEncodings2))
+       {
+               const struct IsoLangToEncodings *       enc = &isoLangEntries5[0];
+
+               /* Five-letter codes */
+               langToEncodings5 = g_hash_table_new (g_str_hash, g_str_equal);
+               while (enc->lang)
+               {
+                       g_hash_table_insert (langToEncodings5, (gpointer) enc->lang,
+                                       (gpointer) &enc->encodings);
+                       enc++;
+               }
+
+               /* Two-letter codes */
+               enc = &isoLangEntries2[0];
+               langToEncodings2 = g_hash_table_new (g_str_hash, g_str_equal);
+               while (enc->lang)
+               {
+                       g_hash_table_insert (langToEncodings2, (gpointer) enc->lang,
+                                       (gpointer) &enc->encodings);
+                       enc++;
+               }
+       }
+       g_static_mutex_unlock (&mutex);
+}
+
+
+static gboolean
+get_encodings_for_lang (const char *lang,
+                        char **encoding1,
+                        char **encoding2,
+                        char **encoding3)
+{
+       struct EncodingTriplet *        encodings;
+       gboolean                                success = FALSE;
+       char *                          tmp_lang;
+
+       g_return_val_if_fail (lang != NULL, FALSE);
+       g_return_val_if_fail (encoding1 != NULL, FALSE);
+       g_return_val_if_fail (encoding2 != NULL, FALSE);
+       g_return_val_if_fail (encoding3 != NULL, FALSE);
+
+       *encoding1 = "iso-8859-1";
+       *encoding2 = "windows-1251";
+       *encoding3 = NULL;
+
+       init_lang_to_encodings_hash ();
+
+       tmp_lang = g_strdup (lang);
+       if ((encodings = g_hash_table_lookup (langToEncodings5, tmp_lang)))
+       {
+               *encoding1 = (char *) encodings->encoding1;
+               *encoding2 = (char *) encodings->encoding2;
+               *encoding3 = (char *) encodings->encoding3;
+               success = TRUE;
+       }
+
+       /* Truncate tmp_lang to length of 2 */
+       if (strlen (tmp_lang) > 2)
+               tmp_lang[2] = '\0';
+       if (!success && (encodings = g_hash_table_lookup (langToEncodings2, tmp_lang)))
+       {
+               *encoding1 = (char *) encodings->encoding1;
+               *encoding2 = (char *) encodings->encoding2;
+               *encoding3 = (char *) encodings->encoding3;
+               success = TRUE;
+       }
+
+       g_free (tmp_lang);
+       return success;
+}
+
+
+
+char *
+nm_utils_ssid_to_utf8 (const char *ssid, guint32 len)
+{
+       char * new_ssid = NULL;
+       char buf[IW_ESSID_MAX_SIZE + 1];
+       guint32 buf_len = MIN (sizeof (buf) - 1, len);
+       char * lang;
+       char *e1 = NULL, *e2 = NULL, *e3 = NULL;
+
+       g_return_val_if_fail (ssid != NULL, NULL);
+
+       memset (buf, 0, sizeof (buf));
+       memcpy (buf, ssid, buf_len);
+
+       if (g_utf8_validate (buf, buf_len, NULL)) {
+               new_ssid = g_strdup (buf);
+               goto out;
+       }
+
+       /* Even if the local encoding is UTF-8, LANG may give
+        * us a clue as to what encoding SSIDs are more likely to be in.
+        */
+       g_get_charset ((const char **)(&e1));
+       if ((lang = getenv ("LANG"))) {
+               char * dot;
+
+               lang = g_ascii_strdown (lang, -1);
+               if ((dot = strchr (lang, '.')))
+                       *dot = '\0';
+
+               get_encodings_for_lang (lang, &e1, &e2, &e3);
+               g_free (lang);
+       }
+
+       new_ssid = g_convert (buf, buf_len, "UTF-8", e1, NULL, NULL, NULL);
+       if (!new_ssid && e2) {
+               new_ssid = g_convert (buf, buf_len, "UTF-8", e2, NULL, NULL, NULL);
+       }
+       if (!new_ssid && e3) {
+               new_ssid = g_convert (buf, buf_len, "UTF-8", e3, NULL, NULL, NULL);
+       }
+       if (!new_ssid) {
+               new_ssid = g_convert_with_fallback (buf, buf_len, "UTF-8", e1,
+                       "?", NULL, NULL, NULL);
+       }
+
+out:
+       return new_ssid;
+}
+
+
+/*
+ * Pending Call Debug stuff
+ *
+ */
+typedef struct PCallInfo
+{
+       DBusPendingCall *       pcall;
+       char *                  caller;
+       guint32                 id;
+       GTimeVal                        start;
+} PCallInfo;
+
+static GStaticMutex pcall_mutex = G_STATIC_MUTEX_INIT;
+static GHashTable *    pcall_table = NULL;
+static guint32         pcall_gid = 0;
+static guint32         pcall_pending = 0;
+
+
+DBusPendingCall *
+nm_dbus_send_with_callback (DBusConnection *connection,
+                            DBusMessage *msg, 
+                            DBusPendingCallNotifyFunction func,
+                            gpointer data,
+                            DBusFreeFunction free_func,
+                            const char *caller)
+{
+       PCallInfo * info = NULL;
+       DBusPendingCall * pcall = NULL;
+
+       g_return_val_if_fail (connection != NULL, NULL);
+       g_return_val_if_fail (msg != NULL, NULL);
+       g_return_val_if_fail (func != NULL, NULL);
+       g_return_val_if_fail (caller != NULL, NULL);
+
+       if (!(info = g_malloc0 (sizeof (PCallInfo))))
+       {
+               g_warning ("Error: '%s' couldn't allocate memory for tracking PCall.", caller);
+               if (free_func)
+                       (*free_func)(data);
+               return NULL;
+       }
+
+       dbus_connection_send_with_reply (connection, msg, &pcall, -1);
+       if (!pcall)
+       {
+               g_warning ("Error: '%s' couldn't send dbus message.", caller);
+               if (free_func)
+                       (*free_func)(data);
+               g_free (info);
+               return NULL;
+       }
+       dbus_pending_call_set_notify (pcall, func, data, free_func);
+
+       info->caller = g_strdup (caller);
+       info->pcall = pcall;
+       g_get_current_time (&info->start);
+       dbus_pending_call_ref (pcall);
+
+       g_static_mutex_lock (&pcall_mutex);
+       info->id = pcall_gid++;
+       pcall_pending++;
+
+       if (!pcall_table)
+               pcall_table = g_hash_table_new (g_direct_hash, g_direct_equal);
+       g_hash_table_insert (pcall_table, pcall, info);
+
+#ifdef DBUS_PENDING_CALL_DEBUG
+       nm_info ("PCall Debug: new id %d (%p), from '%s' (%s), "
+               "%d pending.", info->id, pcall, info->caller,
+               dbus_message_get_member (msg), pcall_pending);
+#endif
+
+       g_static_mutex_unlock (&pcall_mutex);
+
+       return pcall;
+}
+
+void
+nm_dbus_send_with_callback_replied (DBusPendingCall *pcall,
+                                    const char *caller)
+{
+       PCallInfo *     info;
+#ifdef DBUS_PENDING_CALL_DEBUG
+       GTimeVal                now;
+       long                    elapsed_ms = 0;
+#endif
+
+       g_return_if_fail (pcall != NULL);
+       g_return_if_fail (caller != NULL);
+
+       g_static_mutex_lock (&pcall_mutex);
+       if (!(info = g_hash_table_lookup (pcall_table, pcall)))
+       {
+               nm_warning ("Error: couldn't find pending call %p in tracking"
+                       " table.", pcall);
+               goto out;
+       }
+
+       pcall_pending--;
+#ifdef DBUS_PENDING_CALL_DEBUG
+       g_get_current_time (&now);
+       if (info->start.tv_usec > now.tv_usec)
+       {
+               now.tv_sec--;
+               now.tv_usec = G_USEC_PER_SEC - (info->start.tv_usec - now.tv_usec);
+       }
+       else
+               now.tv_usec -= info->start.tv_usec;
+       now.tv_sec -= info->start.tv_sec;
+       elapsed_ms = now.tv_sec * G_USEC_PER_SEC + now.tv_usec;
+       elapsed_ms /= 1000;
+
+       nm_info ("PCall Debug: unregistered ID %d (%p), %s -> %s,"
+               " %lums elapsed.  Total pending: %d", info->id, info->pcall, info->caller,
+               caller, elapsed_ms, pcall_pending);
+#endif
+
+       g_hash_table_remove (pcall_table, pcall);
+       g_free (info->caller);
+       dbus_pending_call_unref (info->pcall);
+       g_free (info);
+
+out:
+       g_static_mutex_unlock (&pcall_mutex);
+}
+
+static void
+value_destroy (gpointer data)
+{
+       GValue *value = (GValue *) data;
+
+       g_value_unset (value);
+       g_slice_free (GValue, value);
+}
+
+static void
+value_dup (gpointer key, gpointer val, gpointer user_data)
+{
+       GHashTable *dup = (GHashTable *) user_data;
+       GValue *value = (GValue *) val;
+       GValue *dup_value;
+
+       dup_value = g_slice_new0 (GValue);
+       g_value_init (dup_value, G_VALUE_TYPE (val));
+       g_value_copy (value, dup_value);
+
+       g_hash_table_insert (dup, g_strdup ((char *) key), dup_value);
+}
+
+GHashTable *
+nm_utils_gvalue_hash_dup (GHashTable *hash)
+{
+       GHashTable *dup;
+
+       g_return_val_if_fail (hash != NULL, NULL);
+
+       dup = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                   (GDestroyNotify) g_free,
+                                                   value_destroy);
+
+       g_hash_table_foreach (hash, value_dup, dup);
+
+       return dup;
+}
+
+char *
+nm_utils_garray_to_string (GArray *array)
+{
+       GString *str;
+       int i;
+       char c;
+
+       g_return_val_if_fail (array != NULL, NULL);
+
+       str = g_string_sized_new (array->len);
+       for (i = 0; i < array->len; i++) {
+               c = array->data[i];
+
+               /* Convert NULLs to spaces to increase the readability. */
+               if (c == '\0')
+                       c = ' ';
+               str = g_string_append_c (str, c);
+       }
+       str = g_string_append_c (str, '\0');
+
+       return g_string_free (str, FALSE);
+}
diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h
new file mode 100644 (file)
index 0000000..feee5be
--- /dev/null
@@ -0,0 +1,148 @@
+/* NetworkManager -- Network link manager
+ *
+ * Ray Strode <rstrode@redhat.com>
+ *
+ * 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.
+ *
+ * (C) Copyright 2005 Red Hat, Inc.
+ */
+
+#ifndef NM_UTILS_H
+#define NM_UTILS_H
+
+#include <glib.h>
+#include <execinfo.h>
+#include <dbus/dbus.h>
+
+#define nm_print_backtrace()                                           \
+G_STMT_START                                                           \
+{                                                                      \
+       void *_call_stack[512];                                         \
+       int  _call_stack_size;                                          \
+       char **_symbols;                                                \
+       _call_stack_size = backtrace (_call_stack,                      \
+                                     G_N_ELEMENTS (_call_stack));      \
+       _symbols = backtrace_symbols (_call_stack, _call_stack_size);   \
+       if (_symbols != NULL)                                           \
+       {                                                               \
+               int _i;                                                 \
+               _i = 0;                                                 \
+               g_critical ("traceback:\n");                            \
+               while (_i < _call_stack_size)                           \
+               {                                                       \
+                       g_critical ("\t%s\n", _symbols[_i]);            \
+                       _i++;                                           \
+               }                                                       \
+               free (_symbols);                                        \
+       }                                                               \
+}                                                                      \
+G_STMT_END
+
+#define nm_get_timestamp(timestamp)                                    \
+G_STMT_START                                                           \
+{                                                                      \
+       GTimeVal _tv;                                                   \
+       g_get_current_time (&_tv);                                      \
+       *timestamp = (_tv.tv_sec * (1.0 * G_USEC_PER_SEC) +             \
+                     _tv.tv_usec) / G_USEC_PER_SEC;                    \
+}                                                                      \
+G_STMT_END
+
+#define nm_info(fmt, args...)                                          \
+G_STMT_START                                                           \
+{                                                                      \
+       g_message ("<info>  " fmt "\n", ##args);                        \
+} G_STMT_END
+
+#define nm_info_str(fmt_str, args...)                                          \
+G_STMT_START                                                           \
+{                                                                      \
+       g_message ("<info>  %s\n", fmt_str, ##args);                    \
+} G_STMT_END
+
+#define nm_debug(fmt, args...)                                         \
+G_STMT_START                                                           \
+{                                                                      \
+       gdouble _timestamp;                                             \
+       nm_get_timestamp (&_timestamp);                                 \
+       g_debug ("<debug> [%f] %s(): " fmt "\n", _timestamp,    \
+                G_STRFUNC, ##args);                            \
+} G_STMT_END
+
+#define nm_debug_str(fmt_str, args...)                                         \
+G_STMT_START                                                           \
+{                                                                      \
+       gdouble _timestamp;                                             \
+       nm_get_timestamp (&_timestamp);                                 \
+       g_debug ("<debug> [%f] %s(): %s\n", _timestamp, \
+                G_STRFUNC, fmt_str, ##args);                           \
+} G_STMT_END
+
+#define nm_warning(fmt, args...)                                       \
+G_STMT_START                                                           \
+{                                                                      \
+       g_warning ("<WARN>  %s(): " fmt "\n",                   \
+                  G_STRFUNC, ##args);                  \
+} G_STMT_END
+
+#define nm_warning_str(fmt_str, args...)                                       \
+G_STMT_START                                                           \
+{                                                                      \
+       g_warning ("<WARN>  %s(): %s\n",                        \
+                  G_STRFUNC, fmt_str, ##args);                 \
+} G_STMT_END
+
+#define nm_error(fmt, args...)                                         \
+G_STMT_START                                                           \
+{                                                                      \
+       gdouble _timestamp;                                             \
+       nm_get_timestamp (&_timestamp);                                 \
+       g_critical ("<ERROR>\t[%f] %s (): " fmt "\n", _timestamp,       \
+                   G_STRFUNC, ##args);                 \
+       nm_print_backtrace ();                                          \
+       G_BREAKPOINT ();                                                \
+} G_STMT_END
+
+#define nm_error_str(fmt_str, args...)                                         \
+G_STMT_START                                                           \
+{                                                                      \
+       gdouble _timestamp;                                             \
+       nm_get_timestamp (&_timestamp);                                 \
+       g_critical ("<ERROR>\t[%f] %s (): %s\n", _timestamp,    \
+                   G_STRFUNC, fmt_str, ##args);                        \
+       nm_print_backtrace ();                                          \
+       G_BREAKPOINT ();                                                \
+} G_STMT_END
+
+gchar *nm_dbus_escape_object_path (const gchar *utf8_string);
+gchar *nm_dbus_unescape_object_path (const gchar *object_path);
+
+char *nm_utils_ssid_to_utf8 (const char *ssid, guint32 len);
+
+/* #define DBUS_PENDING_CALL_DEBUG */
+
+DBusPendingCall * nm_dbus_send_with_callback (DBusConnection *connection,
+                                              DBusMessage *msg, 
+                                              DBusPendingCallNotifyFunction func,
+                                              gpointer data,
+                                              DBusFreeFunction free_func,
+                                              const char *caller);
+void nm_dbus_send_with_callback_replied (DBusPendingCall *pcall,
+                                         const char *caller);
+
+GHashTable *nm_utils_gvalue_hash_dup  (GHashTable *hash);
+char       *nm_utils_garray_to_string (GArray *array);
+
+#endif /* NM_UTILS_H */
index cbc730e..bd8cf51 100644 (file)
@@ -6,7 +6,6 @@ INCLUDES = -I${top_srcdir}                   \
            -I${top_srcdir}/src/vpn-manager   \
            -I${top_srcdir}/src/dhcp-manager  \
            -I${top_srcdir}/src/supplicant-manager  \
-           -I${top_srcdir}/utils                       \
            -I${top_srcdir}/libnm-util
 
 sbin_PROGRAMS = NetworkManager
@@ -35,7 +34,6 @@ NetworkManager_SOURCES =                              \
                nm-ip4-config.c                 \
                nm-ip4-config.h                 \
                NetworkManager.c                        \
-               NetworkManagerMain.h            \
                NetworkManagerPolicy.c          \
                NetworkManagerPolicy.h          \
                NetworkManagerUtils.c           \
@@ -129,7 +127,6 @@ NetworkManager_LDADD =                                                      \
                        $(HAL_LIBS)                                             \
                        $(IWLIB)                                                        \
                        $(LIBNL_LIBS)                                           \
-                       $(top_builddir)/utils/libnmutils.la     \
                        ./named-manager/libnamed-manager.la     \
                        ./vpn-manager/libvpn-manager.la         \
                        ./dhcp-manager/libdhcp-manager.la               \
index d258c60..1eee23d 100644 (file)
 #include "NetworkManagerPolicy.h"
 #include "NetworkManagerSystem.h"
 #include "nm-named-manager.h"
-#include "nm-dbus-vpn.h"
 #include "nm-dbus-manager.h"
 #include "nm-supplicant-manager.h"
 #include "nm-netlink-monitor.h"
+#include "nm-vpn-manager.h"
 #include "nm-logging.h"
 
 #define NM_DEFAULT_PID_FILE    LOCALSTATEDIR"/run/NetworkManager.pid"
@@ -375,7 +375,7 @@ done:
        nm_print_open_socks ();
 
        if (vpn_manager)
-               nm_vpn_manager_dispose (vpn_manager);
+               g_object_unref (vpn_manager);
 
        nm_hal_manager_destroy (hal_manager);
        if (policy)
diff --git a/src/NetworkManagerMain.h b/src/NetworkManagerMain.h
deleted file mode 100644 (file)
index c27d84a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* NetworkManager -- Network link manager
- *
- * Dan Williams <dcbw@redhat.com>
- *
- * 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.
- *
- * (C) Copyright 2004 Red Hat, Inc.
- */
-
-#ifndef NETWORK_MANAGER_MAIN_H
-#define NETWORK_MANAGER_MAIN_H
-
-typedef struct NMVPNActRequest NMVPNActRequest;
-typedef struct NMVPNManager NMVPNManager;
-
-#endif
index 29c10b7..7102518 100644 (file)
@@ -43,6 +43,7 @@
 #include <pthread.h>
 #include "NetworkManagerSystem.h"
 #include "nm-device.h"
+#include "nm-named-manager.h"
 #include "NetworkManagerUtils.h"
 #include "nm-utils.h"
 #include "nm-netlink.h"
@@ -310,17 +311,17 @@ out:
  *
  */
 gboolean
-nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
-                                          NMDevice *active_device,
+nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
                                           const char *iface,
                                           NMIP4Config *config,
-                                          char **routes,
-                                          int num_routes)
+                                          char **routes)
 {
        NMIP4Config *           ad_config = NULL;
        struct nl_handle *      nlh = NULL;
        struct rtnl_addr *      addr = NULL;
        struct rtnl_link *      request = NULL;
+       int num_routes;
+       NMNamedManager *named_mgr;
 
        g_return_val_if_fail (config != NULL, FALSE);
 
@@ -370,7 +371,10 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
 
                sleep (1);
 
+               num_routes = g_strv_length (routes);
                nm_system_device_flush_routes_with_iface (iface);
+
+
                if (num_routes <= 0)
                {
                        nm_system_delete_default_route ();
@@ -400,7 +404,9 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
                }
        }
 
-       nm_named_manager_add_ip4_config (named, config);
+       named_mgr = nm_named_manager_get ();
+       nm_named_manager_add_ip4_config (named_mgr, config);
+       g_object_unref (named_mgr);
 
        return TRUE;
 }
@@ -412,13 +418,16 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
  * Unset an IPv4 configuration of a VPN device from an NMIP4Config object.
  *
  */
-gboolean nm_system_vpn_device_unset_from_ip4_config (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config)
+gboolean nm_system_vpn_device_unset_from_ip4_config (NMDevice *active_device, const char *iface, NMIP4Config *config)
 {
-       g_return_val_if_fail (named != NULL, FALSE);
+       NMNamedManager *named_mgr;
+
        g_return_val_if_fail (active_device != NULL, FALSE);
        g_return_val_if_fail (config != NULL, FALSE);
 
-       nm_named_manager_remove_ip4_config (named, config);
+       named_mgr = nm_named_manager_get ();
+       nm_named_manager_remove_ip4_config (named_mgr, config);
+       g_object_unref (named_mgr);
 
        return TRUE;
 }
index 4752585..c129cb8 100644 (file)
@@ -25,7 +25,6 @@
 #include <glib.h>
 #include "nm-device.h"
 #include "nm-ip4-config.h"
-#include "nm-named-manager.h"
 
 /* Prototypes for system/distribution dependent functions,
  * implemented in the backend files in backends/ directory
@@ -63,8 +62,14 @@ gboolean             nm_system_device_get_use_dhcp                           (NMDevice *dev);
 gboolean               nm_system_device_get_disabled                           (NMDevice *dev);
 
 gboolean               nm_system_device_set_from_ip4_config            (NMDevice *dev);
-gboolean               nm_system_vpn_device_set_from_ip4_config        (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config, char **routes, int num_routes);
-gboolean               nm_system_vpn_device_unset_from_ip4_config      (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config);
+gboolean               nm_system_vpn_device_set_from_ip4_config        (NMDevice *active_device,
+                                                                        const char *iface,
+                                                                        NMIP4Config *config,
+                                                                        char **routes);
+
+gboolean               nm_system_vpn_device_unset_from_ip4_config      (NMDevice *active_device, 
+                                                                        const char *iface,
+                                                                        NMIP4Config *config);
 
 gboolean               nm_system_device_set_up_down                            (NMDevice *dev, gboolean up);
 gboolean               nm_system_device_set_up_down_with_iface         (const char *iface, gboolean up);
index d15068e..27c4b45 100644 (file)
@@ -31,7 +31,6 @@
 #include <stdarg.h>
 
 #include "NetworkManager.h"
-#include "NetworkManagerMain.h"
 #include "nm-device.h"
 
 typedef enum SockType
index 5ea6cfc..2809a4e 100644 (file)
@@ -33,7 +33,6 @@
 #include "nm-device.h"
 #include "nm-device-802-3-ethernet.h"
 #include "nm-device-802-11-wireless.h"
-#include "NetworkManagerMain.h"
 #include "NetworkManagerUtils.h"
 #include "nm-utils.h"
 #include "autoip.h"
index 6e00794..7be7995 100644 (file)
@@ -36,7 +36,6 @@
 #include "NetworkManagerGeneric.h"
 #include "NetworkManagerSystem.h"
 #include "NetworkManagerUtils.h"
-#include "NetworkManagerMain.h"
 #include "nm-device.h"
 #include "NetworkManagerPolicy.h"
 #include "nm-device-802-3-ethernet.h"
index 3df1f5e..93b3799 100644 (file)
@@ -288,30 +288,6 @@ string_to_state (const char *state)
                return 255;
 }
 
-static char *
-garray_to_string (GArray *array)
-{
-       GString *str;
-       int i;
-       char c;
-
-       str = g_string_sized_new (array->len + 1);
-       if (str == NULL)
-               return NULL;
-
-       for (i = 0; i < array->len; i++) {
-               c = array->data[i];
-
-               /* Convert NULLs to spaces to increase the readability. */
-               if (c == '\0')
-                       c = ' ';
-               str = g_string_append_c (str, c);
-       }
-       str = g_string_append_c (str, '\0');
-
-       return g_string_free (str, FALSE);
-}
-
 static char *
 get_option (GHashTable * hash,
             gpointer key)
@@ -329,7 +305,7 @@ get_option (GHashTable * hash,
                return NULL;
        }
 
-       return garray_to_string ((GArray *) g_value_get_boxed (value));
+       return nm_utils_garray_to_string ((GArray *) g_value_get_boxed (value));
 }
 
 static void
@@ -352,7 +328,7 @@ copy_option (gpointer key,
                goto error;
        }
 
-       dup_value = garray_to_string ((GArray *) g_value_get_boxed (value));
+       dup_value = nm_utils_garray_to_string ((GArray *) g_value_get_boxed (value));
        if (!dup_value)
                goto error;
 
index 1ed0418..415275c 100644 (file)
@@ -52,7 +52,6 @@ typedef struct {
                                         DBusConnection *connection);
 
        void (*name_owner_changed)      (NMDBusManager *mgr,
-                                        DBusConnection *connection,
                                         const char *name,
                                         const char *old_owner,
                                         const char *new_owner);
index a13bbdd..071e691 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "nm-device.h"
 #include "NetworkManagerAP.h"
-#include "NetworkManagerMain.h"
 
 struct NMAccessPointList;
 
index 352cef2..96c53b2 100644 (file)
@@ -26,7 +26,6 @@
 #include <net/ethernet.h>
 
 #include "nm-device.h"
-#include "NetworkManagerMain.h"
 
 G_BEGIN_DECLS
 
index 975e680..7b8a0e6 100644 (file)
@@ -2,7 +2,6 @@
 #define NM_HAL_MANAGER_H
 
 #include "nm-manager.h"
-#include "NetworkManagerMain.h"
 
 typedef struct _NMHalManager NMHalManager;
 
index 48782f3..5b0fee4 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "nm-logging.h"
 #include "nm-utils.h"
-#include "NetworkManagerMain.h"
 
 static void
 fallback_get_backtrace (void)
index 394f0b7..1a854e7 100644 (file)
@@ -3,33 +3,44 @@ INCLUDES = -I${top_srcdir}                       \
            -I${top_srcdir}/libnm-util            \
            -I${top_srcdir}/utils                 \
            -I${top_srcdir}/src                   \
-           -I${top_srcdir}/src/named-manager
+           -I${top_srcdir}/src/named-manager     \
+           -DVPN_NAME_FILES_DIR=\""$(sysconfdir)/NetworkManager/VPN"\"
+
 
 noinst_LTLIBRARIES = libvpn-manager.la
 
-libvpn_manager_la_SOURCES =    nm-dbus-vpn.c                   \
-                                               nm-dbus-vpn.h                   \
-                                               nm-vpn-connection.c             \
-                                               nm-vpn-connection.h             \
-                                               nm-vpn-manager.c                \
-                                               nm-vpn-manager.h                \
-                                               nm-vpn-service.c                \
-                                               nm-vpn-service.h                \
-                                               nm-vpn-act-request.c    \
-                                               nm-vpn-act-request.h
-
-libvpn_manager_la_CPPFLAGS =   $(DBUS_CFLAGS)                                  \
-                                               $(GTHREAD_CFLAGS)                               \
-                                               $(HAL_CFLAGS)                                   \
-                                               -g                                                      \
-                                               -Wall                                           \
-                                               -DDBUS_API_SUBJECT_TO_CHANGE            \
-                                               -DG_DISABLE_DEPRECATED                  \
-                                               -DBINDIR=\"$(bindir)\"                  \
-                                               -DDATADIR=\"$(datadir)\"                        \
-                                               -DSYSCONFDIR=\"$(sysconfdir)\"
-
-
-libvpn_manager_la_LIBADD = $(DBUS_LIBS)           \
-                           $(GTHREAD_LIBS)        \
-                           $(top_builddir)/libnm-util/libnm-util.la 
+libvpn_manager_la_SOURCES =    \
+       nm-vpn-manager.c        \
+       nm-vpn-manager.h        \
+       nm-vpn-service.c        \
+       nm-vpn-service.h        \
+       nm-vpn-connection.c     \
+       nm-vpn-connection.h
+
+libvpn_manager_la_CPPFLAGS =   \
+       $(DBUS_CFLAGS)          \
+       -DG_DISABLE_DEPRECATED
+
+libvpn_manager_la_LIBADD =     \
+       $(DBUS_LIBS)            \
+       $(GTHREAD_LIBS)         \
+       $(top_builddir)/libnm-util/libnm-util.la
+
+nm-vpn-manager-glue.h: $(top_srcdir)/introspection/nm-vpn-manager.xml
+       dbus-binding-tool --prefix=nm_vpn_manager --mode=glib-server --output=nm-vpn-manager-glue.h $(top_srcdir)/introspection/nm-vpn-manager.xml
+
+nm-vpn-connection-glue.h: $(top_srcdir)/introspection/nm-vpn-connection.xml
+       dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-server --output=nm-vpn-connection-glue.h $(top_srcdir)/introspection/nm-vpn-connection.xml
+
+nm-vpn-plugin-bindings.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml
+       dbus-binding-tool --prefix=nm_vpn_plugin --mode=glib-client --output=nm-vpn-plugin-bindings.h $(top_srcdir)/introspection/nm-vpn-plugin.xml
+
+
+built_sources = \
+       nm-vpn-manager-glue.h \
+       nm-vpn-connection-glue.h \
+       nm-vpn-plugin-bindings.h
+
+$(libvpn_manager_la_OBJECTS): $(built_sources)
+
+CLEANFILES = $(built_sources)
\ No newline at end of file
diff --git a/src/vpn-manager/nm-dbus-vpn.c b/src/vpn-manager/nm-dbus-vpn.c
deleted file mode 100644 (file)
index 6b9ca2a..0000000
+++ /dev/null
@@ -1,1119 +0,0 @@
-/* NetworkManager -- Network link manager
- *
- * Dan Williams <dcbw@redhat.com>
- *
- * 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.
- *
- * (C) Copyright 2005 Red Hat, Inc.
- */
-
-#include <glib.h>
-#include <dbus/dbus.h>
-#include "NetworkManagerMain.h"
-#include "nm-device.h"
-#include "NetworkManagerUtils.h"
-#include "NetworkManagerVPN.h"
-#include "nm-dbus-vpn.h"
-#include "nm-vpn-manager.h"
-#include "nm-vpn-connection.h"
-#include "nm-vpn-service.h"
-#include "nm-vpn-act-request.h"
-#include "nm-utils.h"
-#include "nm-dbus-manager.h"
-
-/*
- * nm_dbus_create_error_message
- *
- * Make a DBus error message
- *
- */
-static DBusMessage *
-nm_dbus_create_error_message (DBusMessage *message,
-                              const char *exception_namespace,
-                              const char *exception,
-                              const char *format,
-                              ...)
-{
-       char *exception_text;
-       DBusMessage     *reply_message;
-       va_list          args;
-       char                     error_text[512];
-
-       va_start (args, format);
-       vsnprintf (error_text, 512, format, args);
-       va_end (args);
-
-       exception_text = g_strdup_printf ("%s.%s", exception_namespace, exception);
-       reply_message = dbus_message_new_error (message, exception_text, error_text);
-       g_free (exception_text);
-
-       return (reply_message);
-}
-
-
-static DBusMessage *
-nm_dbus_new_invalid_args_error (DBusMessage *replyto,
-                                const char *namespace)
-{
-       return nm_dbus_create_error_message (replyto,
-                                                namespace,
-                                                "InvalidArguments",
-                                                "Invalid method arguments.");
-}
-
-/*
- * Pending Call Debug stuff
- *
- */
-typedef struct PCallInfo
-{
-       DBusPendingCall *       pcall;
-       char *                  caller;
-       guint32                 id;
-       GTimeVal                        start;
-} PCallInfo;
-
-static GStaticMutex pcall_mutex = G_STATIC_MUTEX_INIT;
-static GHashTable *    pcall_table = NULL;
-static guint32         pcall_gid = 0;
-static guint32         pcall_pending = 0;
-
-
-static DBusPendingCall *
-nm_dbus_send_with_callback (DBusConnection *connection,
-                            DBusMessage *msg, 
-                            DBusPendingCallNotifyFunction func,
-                            gpointer data,
-                            DBusFreeFunction free_func,
-                            const char *caller)
-{
-       PCallInfo * info = NULL;
-       DBusPendingCall * pcall = NULL;
-
-       g_return_val_if_fail (connection != NULL, NULL);
-       g_return_val_if_fail (msg != NULL, NULL);
-       g_return_val_if_fail (func != NULL, NULL);
-       g_return_val_if_fail (caller != NULL, NULL);
-
-       if (!(info = g_malloc0 (sizeof (PCallInfo))))
-       {
-               g_warning ("Error: '%s' couldn't allocate memory for tracking PCall.", caller);
-               if (free_func)
-                       (*free_func)(data);
-               return NULL;
-       }
-
-       dbus_connection_send_with_reply (connection, msg, &pcall, -1);
-       if (!pcall)
-       {
-               g_warning ("Error: '%s' couldn't send dbus message.", caller);
-               if (free_func)
-                       (*free_func)(data);
-               g_free (info);
-               return NULL;
-       }
-       dbus_pending_call_set_notify (pcall, func, data, free_func);
-
-       info->caller = g_strdup (caller);
-       info->pcall = pcall;
-       g_get_current_time (&info->start);
-       dbus_pending_call_ref (pcall);
-
-       g_static_mutex_lock (&pcall_mutex);
-       info->id = pcall_gid++;
-       pcall_pending++;
-
-       if (!pcall_table)
-               pcall_table = g_hash_table_new (g_direct_hash, g_direct_equal);
-       g_hash_table_insert (pcall_table, pcall, info);
-
-#ifdef DBUS_PENDING_CALL_DEBUG
-       nm_info ("PCall Debug: new id %d (%p), from '%s' (%s), "
-               "%d pending.", info->id, pcall, info->caller,
-               dbus_message_get_member (msg), pcall_pending);
-#endif
-
-       g_static_mutex_unlock (&pcall_mutex);
-
-       return pcall;
-}
-
-static void
-nm_dbus_send_with_callback_replied (DBusPendingCall *pcall,
-                                    const char *caller)
-{
-       PCallInfo *     info;
-#ifdef DBUS_PENDING_CALL_DEBUG
-       GTimeVal                now;
-       long                    elapsed_ms = 0;
-#endif
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (caller != NULL);
-
-       g_static_mutex_lock (&pcall_mutex);
-       if (!(info = g_hash_table_lookup (pcall_table, pcall)))
-       {
-               nm_warning ("Error: couldn't find pending call %p in tracking"
-                       " table.", pcall);
-               goto out;
-       }
-
-       pcall_pending--;
-#ifdef DBUS_PENDING_CALL_DEBUG
-       g_get_current_time (&now);
-       if (info->start.tv_usec > now.tv_usec)
-       {
-               now.tv_sec--;
-               now.tv_usec = G_USEC_PER_SEC - (info->start.tv_usec - now.tv_usec);
-       }
-       else
-               now.tv_usec -= info->start.tv_usec;
-       now.tv_sec -= info->start.tv_sec;
-       elapsed_ms = now.tv_sec * G_USEC_PER_SEC + now.tv_usec;
-       elapsed_ms /= 1000;
-
-       nm_info ("PCall Debug: unregistered ID %d (%p), %s -> %s,"
-               " %lums elapsed.  Total pending: %d", info->id, info->pcall, info->caller,
-               caller, elapsed_ms, pcall_pending);
-#endif
-
-       g_hash_table_remove (pcall_table, pcall);
-       g_free (info->caller);
-       dbus_pending_call_unref (info->pcall);
-       g_free (info);
-
-out:
-       g_static_mutex_unlock (&pcall_mutex);
-}
-
-
-
-static DBusMessage *
-new_invalid_vpn_connection_error (DBusMessage *replyto)
-{
-       return nm_dbus_create_error_message (replyto, NM_DBUS_INTERFACE_VPN,
-                                                "InvalidVPNConnection",
-                                                "No VPN connection with that name"
-                                                " was found.");
-}
-
-/*
- * nm_dbus_vpn_signal_vpn_connection_update
- *
- * Notifies the bus that a VPN connection's properties have changed.
- *
- */
-void
-nm_dbus_vpn_signal_vpn_connection_update (DBusConnection *connection,
-                                          NMVPNConnection *vpn,
-                                          const char *signal)
-{
-       DBusMessage     *message;
-       const char      *vpn_name;
-
-       g_return_if_fail (connection != NULL);
-       g_return_if_fail (vpn != NULL);
-
-       message = dbus_message_new_signal (NM_DBUS_PATH_VPN,
-                                          NM_DBUS_INTERFACE_VPN,
-                                          signal);
-       if (!message) {
-               nm_warning ("could not allocate the dbus message.");
-               return;
-       }
-
-       vpn_name = nm_vpn_connection_get_name (vpn);
-       dbus_message_append_args (message,
-                                 DBUS_TYPE_STRING, &vpn_name,
-                                 DBUS_TYPE_INVALID);
-       dbus_connection_send (connection, message, NULL);
-       dbus_message_unref (message);
-}
-
-/*
- * nm_dbus_vpn_signal_vpn_connection_state_change
- *
- * Notifies the bus that a VPN connection's state has changed.
- */
-void
-nm_dbus_vpn_signal_vpn_connection_state_change (DBusConnection *connection,
-                                                NMVPNConnection *vpn,
-                                                NMVPNConnectionState new_state)
-{
-       DBusMessage *   message;
-       const char *    vpn_name;
-       dbus_uint32_t   int_state = (dbus_uint32_t) new_state;
-
-       g_return_if_fail (connection != NULL);
-       g_return_if_fail (vpn != NULL);
-
-       message = dbus_message_new_signal (NM_DBUS_PATH_VPN,
-                                          NM_DBUS_INTERFACE_VPN,
-                                          "VPNConnectionStateChange");
-       if (!message) {
-               nm_warning ("could not allocate dbus connection.");
-               return;
-       }
-
-       vpn_name = nm_vpn_connection_get_name (vpn);
-       dbus_message_append_args (message,
-                                 DBUS_TYPE_STRING, &vpn_name,
-                                 DBUS_TYPE_UINT32, &int_state,
-                                 DBUS_TYPE_INVALID);
-       dbus_connection_send (connection, message, NULL);
-       dbus_message_unref (message);
-}
-
-
-/*
- * nnm_dbus_vpn_signal_vpn_failure
- *
- * Proxy a VPN Failure message from the vpn daemon to the bus.
- *
- */
-void
-nm_dbus_vpn_signal_vpn_failed (DBusConnection *connection,
-                               const char *signal,
-                               NMVPNConnection *vpn,
-                               const char *error_msg)
-{
-       DBusMessage     *message;
-       const char      *vpn_name;
-
-       g_return_if_fail (connection != NULL);
-       g_return_if_fail (signal != NULL);
-       g_return_if_fail (vpn != NULL);
-       g_return_if_fail (error_msg != NULL);
-
-       message = dbus_message_new_signal (NM_DBUS_PATH_VPN,
-                                          NM_DBUS_INTERFACE_VPN,
-                                          signal);
-       if (!message) {
-               nm_warning ("could not allocate the dbus message.");
-               return;
-       }
-
-       vpn_name = nm_vpn_connection_get_name (vpn);
-       dbus_message_append_args (message,
-                                 DBUS_TYPE_STRING, &vpn_name,
-                                 DBUS_TYPE_STRING, &error_msg,
-                                 DBUS_TYPE_INVALID);
-       dbus_connection_send (connection, message, NULL);
-       dbus_message_unref (message);
-}
-
-
-/*
- * nnm_dbus_vpn_signal_vpn_login_banner
- *
- * Pass the VPN's login banner message to the bus if anyone wants to use it.
- *
- */
-void
-nm_dbus_vpn_signal_vpn_login_banner (DBusConnection *connection,
-                                     NMVPNConnection *vpn,
-                                     const char *banner)
-{
-       DBusMessage     *message;
-       const char      *vpn_name;
-
-       g_return_if_fail (connection != NULL);
-       g_return_if_fail (vpn != NULL);
-       g_return_if_fail (banner != NULL);
-
-       message = dbus_message_new_signal (NM_DBUS_PATH_VPN,
-                                          NM_DBUS_INTERFACE_VPN,
-                                          NM_DBUS_VPN_SIGNAL_LOGIN_BANNER);
-       if (!message) {
-               nm_warning ("could not allocate the dbus message.");
-               return;
-       }
-
-       vpn_name = nm_vpn_connection_get_name (vpn);
-       dbus_message_append_args (message,
-                                 DBUS_TYPE_STRING, &vpn_name,
-                                 DBUS_TYPE_STRING, &banner,
-                                 DBUS_TYPE_INVALID);
-       dbus_connection_send (connection, message, NULL);
-       dbus_message_unref (message);
-}
-
-
-/*
- * nm_dbus_vpn_get_vpn_data
- *
- * Get VPN specific data from NMI for a vpn connection
- *
- * NOTE: caller MUST free returned value using g_strfreev()
- *
- */
-static char **
-nm_dbus_vpn_get_vpn_data (DBusConnection *connection,
-                          NMVPNConnection *vpn,
-                          int *num_items)
-{
-       DBusMessage             *message;
-       DBusError                        error;
-       DBusMessage             *reply = NULL;
-       char                        **data_items = NULL;
-       const char              *vpn_name;
-       DBusMessageIter iter, array_iter;
-       GArray *                buffer;
-
-       g_return_val_if_fail (connection != NULL, NULL);
-       g_return_val_if_fail (vpn != NULL, NULL);
-       g_return_val_if_fail (num_items != NULL, NULL);
-
-       *num_items = -1;
-
-       message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
-                                               NMI_DBUS_PATH,
-                                               NMI_DBUS_INTERFACE,
-                                               "getVPNConnectionVPNData");
-       if (!message) {
-               nm_warning ("couldn't allocate the dbus message.");
-               return NULL;
-       }
-
-       vpn_name = nm_vpn_connection_get_name (vpn);
-       dbus_message_append_args (message,
-                                 DBUS_TYPE_STRING, &vpn_name,
-                                 DBUS_TYPE_INVALID);
-
-       dbus_error_init (&error);
-       reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
-       dbus_message_unref (message);
-       if (dbus_error_is_set (&error)) {
-               nm_warning ("%s raised %s", error.name, error.message);
-               dbus_error_free (&error);
-               goto out;
-       }
-
-       if (!reply) {
-               nm_warning ("did not receive a reply.");
-               goto out;
-       }
-
-       dbus_message_iter_init (reply, &iter);
-       dbus_message_iter_recurse (&iter, &array_iter);
-
-       buffer = g_array_new (TRUE, TRUE, sizeof (gchar *));
-       if (buffer == NULL) {
-               nm_warning ("could not allocate buffer for VPN connection data.");
-               goto out;
-       }
-
-       while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) {
-               const char *value;
-               char *str;
-       
-               dbus_message_iter_get_basic (&array_iter, &value);
-               str = g_strdup (value);
-               if (!str) {
-                       nm_warning ("could not allocate string.");
-                       g_array_free (buffer, TRUE);
-                       goto out;
-               }
-               g_array_append_val (buffer, str);
-               dbus_message_iter_next (&array_iter);
-       }
-       data_items = (gchar **)(buffer->data);
-       *num_items = buffer->len;
-       g_array_free (buffer, FALSE);
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-
-       return data_items;
-}
-
-
-/*
- * nm_dbus_vpn_get_routes
- *
- * Get VPN routes from NMI for a vpn connection
- *
- * NOTE: caller MUST free returned value using g_strfreev()
- *
- */
-char **
-nm_dbus_vpn_get_routes (DBusConnection *connection,
-                        NMVPNConnection *vpn,
-                        int *num_items)
-{
-       DBusMessage             *message;
-       DBusError                        error;
-       DBusMessage             *reply;
-       char                        **routes = NULL;
-       const char              *vpn_name;
-       DBusMessageIter iter, array_iter;
-       GArray *                buffer;
-
-       g_return_val_if_fail (connection != NULL, NULL);
-       g_return_val_if_fail (vpn != NULL, NULL);
-       g_return_val_if_fail (num_items != NULL, NULL);
-
-       *num_items = -1;
-
-       message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
-                                               NMI_DBUS_PATH,
-                                               NMI_DBUS_INTERFACE,
-                                               "getVPNConnectionRoutes");
-       if (!message) {
-               nm_warning ("couldn't allocate the dbus message.");
-               return NULL;
-       }
-
-       vpn_name = nm_vpn_connection_get_name (vpn);
-       dbus_message_append_args (message,
-                                 DBUS_TYPE_STRING, &vpn_name,
-                                 DBUS_TYPE_INVALID);
-
-       dbus_error_init (&error);
-       reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
-       dbus_message_unref (message);
-       if (dbus_error_is_set (&error)) {
-               nm_warning ("%s raised %s", error.name, error.message);
-               dbus_error_free (&error);
-               goto out;
-       }
-
-       if (!reply) {
-               nm_warning ("did not receive a reply.");
-               goto out;
-       }
-
-       dbus_message_iter_init (reply, &iter);
-       dbus_message_iter_recurse (&iter, &array_iter);
-
-       buffer = g_array_new (TRUE, TRUE, sizeof (gchar *));
-       if (!buffer) {
-               nm_warning ("could not allocate buffer for VPN routes.");
-               goto out;
-       }
-
-       while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) {
-               const char *value;
-               char *str;
-       
-               dbus_message_iter_get_basic (&array_iter, &value);
-               str = g_strdup (value);
-               if (!str) {
-                       nm_warning ("could not allocate string.");
-                       g_array_free (buffer, TRUE);
-                       goto out;
-               }
-               g_array_append_val (buffer, str);
-               dbus_message_iter_next (&array_iter);
-       }
-       routes = (gchar **)(buffer->data);
-       *num_items = buffer->len;
-       g_array_free (buffer, FALSE);
-
-out:   
-       if (reply)
-               dbus_message_unref (reply);
-
-       return routes;
-}
-
-
-typedef struct UpdateOneVPNCBData {
-       NMVPNManager *manager;
-       char *  vpn;
-} UpdateOneVPNCBData;
-
-
-static void
-free_update_one_vpn_cb_data (UpdateOneVPNCBData *data)
-{
-       if (data)
-               g_free (data->vpn);
-       g_slice_free (UpdateOneVPNCBData, data);
-}
-
-/*
- * nm_dbus_vpn_update_one_connection_cb
- *
- * Retrieve and add to our VPN Manager one VPN connection from NMI.
- *
- */
-static void
-nm_dbus_vpn_update_one_connection_cb (DBusPendingCall *pcall,
-                                      void *user_data)
-{
-       UpdateOneVPNCBData *    cb_data = (UpdateOneVPNCBData *) user_data;
-       NMDBusManager *                 dbus_mgr = NULL;
-       DBusConnection *                dbus_connection;
-       DBusMessage *                   reply = NULL;
-       const char *                    con_name = NULL;
-       const char *                    service_name = NULL;
-       const char *                    user_name = NULL;
-       const char *                    vpn_service_name;
-       NMVPNConnection *               vpn;
-       gboolean                                new = TRUE;
-       
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (cb_data != NULL);
-       g_return_if_fail (cb_data->manager != NULL);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
-
-       dbus_pending_call_ref (pcall);
-
-       if (!dbus_pending_call_get_completed (pcall))
-               goto out;
-
-       dbus_mgr = nm_dbus_manager_get ();
-       dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("couldn't get the dbus connection.");
-               goto out;
-       }
-
-       if (!(reply = dbus_pending_call_steal_reply (pcall)))
-               goto out;
-
-       if (dbus_message_is_error (reply, "BadVPNConnectionData")) {
-               /* Bad VPN, remove it from our VPN connection list */
-               if ((vpn = nm_vpn_manager_find_connection_by_name (cb_data->manager,
-                                                                  cb_data->vpn))) {
-                       nm_vpn_connection_ref (vpn);
-                       nm_vpn_manager_remove_connection (cb_data->manager, vpn);
-                       nm_dbus_vpn_signal_vpn_connection_update (dbus_connection,
-                                                                 vpn,
-                                                                 "VPNConnectionRemoved");
-                       nm_vpn_connection_unref (vpn);
-               }
-               goto unref_reply;
-       }
-
-       if (!dbus_message_get_args (reply,
-                                   NULL,
-                                   DBUS_TYPE_STRING, &con_name,
-                                   DBUS_TYPE_STRING, &service_name,
-                                   DBUS_TYPE_STRING, &user_name,
-                                   DBUS_TYPE_INVALID)) {
-               goto unref_reply;
-       }
-
-       vpn = nm_vpn_manager_find_connection_by_name (cb_data->manager,
-                                                     con_name);
-       if (vpn) {
-               /* If all attributes of the existing connection are the same as
-                * the one we get from NMI, don't do anything.
-                */
-               vpn_service_name = nm_vpn_connection_get_service_name (vpn);
-               if (    (strcmp (vpn_service_name, service_name) != 0)
-                    || (strcmp (nm_vpn_connection_get_user_name (vpn), user_name) != 0)) {
-                       nm_vpn_manager_remove_connection (cb_data->manager, vpn);
-               } else {
-                       new = FALSE;
-               }
-       }
-
-       if (new) {
-               vpn = nm_vpn_manager_add_connection (cb_data->manager,
-                                                    con_name,
-                                                    service_name,
-                                                    user_name);
-       }
-
-       if (vpn) {
-               const char * signal = new ? "VPNConnectionAdded" : "VPNConnectionUpdate";
-               nm_dbus_vpn_signal_vpn_connection_update (dbus_connection, vpn, signal);
-       }
-
-unref_reply:
-       dbus_message_unref (reply);
-
-out:
-       if (dbus_mgr)
-               g_object_unref (dbus_mgr);
-       dbus_pending_call_unref (pcall);
-}
-
-
-/*
- * nm_dbus_vpn_connections_update_cb
- *
- * Async callback from nnm_dbus_vpn_connections_update
- *
- */
-static void
-nm_dbus_vpn_connections_update_cb (DBusPendingCall *pcall,
-                                   void *user_data)
-{
-       NMVPNManager *manager = (NMVPNManager *) user_data;
-       DBusMessage *           reply;
-       DBusMessageIter iter, array_iter;
-       GSList *                        remove_list = NULL;
-       GSList *                        elt;
-       NMDBusManager *         dbus_mgr = NULL;
-       DBusConnection *        dbus_connection;
-
-       g_return_if_fail (pcall);
-       g_return_if_fail (manager != NULL);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
-
-       dbus_pending_call_ref (pcall);
-
-       if (!dbus_pending_call_get_completed (pcall))
-               goto out;
-
-       dbus_mgr = nm_dbus_manager_get ();
-       dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("couldn't get the dbus connection.");
-               goto out;
-       }
-
-       if (!(reply = dbus_pending_call_steal_reply (pcall)))
-               goto out;
-
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
-               goto unref_reply;
-
-       nm_info ("Updating VPN Connections...");
-
-       remove_list = nm_vpn_manager_vpn_connection_list_copy (manager);
-
-       dbus_message_iter_init (reply, &iter);
-       dbus_message_iter_recurse (&iter, &array_iter);
-       while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) {
-               DBusMessage *           message;
-               const char *            con_name;
-               NMVPNConnection *       vpn;
-
-               dbus_message_iter_get_basic (&array_iter, &con_name);
-
-               /* If the connection already exists, remove it from the remove list */
-               if ((vpn = nm_vpn_manager_find_connection_by_name (manager, con_name)))
-                       remove_list = g_slist_remove (remove_list, vpn);
-
-               message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
-                                                       NMI_DBUS_PATH,
-                                                       NMI_DBUS_INTERFACE,
-                                                       "getVPNConnectionProperties");
-               if (message) {
-                       UpdateOneVPNCBData * vpn_cb_data = g_slice_new0 (UpdateOneVPNCBData);
-
-                       dbus_message_append_args (message,
-                                                 DBUS_TYPE_STRING, &con_name,
-                                                 DBUS_TYPE_INVALID);
-
-                       vpn_cb_data->manager = manager;
-                       vpn_cb_data->vpn = g_strdup (con_name);
-                       nm_dbus_send_with_callback (dbus_connection,
-                                                   message,
-                                                   (DBusPendingCallNotifyFunction) nm_dbus_vpn_update_one_connection_cb,
-                                                   vpn_cb_data,
-                                                   (DBusFreeFunction) free_update_one_vpn_cb_data,
-                                                   __func__);
-                       dbus_message_unref (message);
-               }
-               dbus_message_iter_next (&array_iter);
-       }
-
-       /* VPN connections left in the remove list aren't known by NMI, therefore we delete them */
-       for (elt = remove_list; elt; elt = g_slist_next (elt)) {
-               nm_vpn_manager_remove_connection (manager, elt->data);
-               nm_vpn_connection_unref (elt->data);
-       }
-
-       g_slist_free (remove_list);
-
-unref_reply:
-       dbus_message_unref (reply);
-
-out:
-       if (dbus_mgr)
-               g_object_unref (dbus_mgr);
-       dbus_pending_call_unref (pcall);
-}
-
-
-/*
- * nm_dbus_vpn_update_one_vpn_connection
- *
- * Update one VPN connection
- *
- */
-void
-nm_dbus_vpn_update_one_vpn_connection (DBusConnection *connection,
-                                                                          NMVPNManager *manager,
-                                       const char *vpn)
-{
-       DBusMessage *           message;
-       UpdateOneVPNCBData *cb_data;
-
-       g_return_if_fail (connection != NULL);
-       g_return_if_fail (manager != NULL);
-       g_return_if_fail (vpn != NULL);
-
-       message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
-                                               NMI_DBUS_PATH,
-                                               NMI_DBUS_INTERFACE,
-                                               "getVPNConnectionProperties");
-       if (!message) {
-               nm_warning ("Couldn't allocate the dbus message.");
-               return;
-       }
-
-       dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn, DBUS_TYPE_INVALID);
-
-       cb_data = g_slice_new0 (UpdateOneVPNCBData);
-       cb_data->manager = manager;
-       cb_data->vpn = g_strdup (vpn);
-       nm_dbus_send_with_callback (connection,
-                                   message,
-                                   (DBusPendingCallNotifyFunction) nm_dbus_vpn_update_one_connection_cb,
-                                   cb_data,
-                                   (DBusFreeFunction) free_update_one_vpn_cb_data,
-                                   __func__);
-       dbus_message_unref (message);
-}
-
-
-/*
- * nm_dbus_vpn_connections_update_from_nmi
- *
- * Update VPN connections from NetworkManagerInfo.
- *
- */
-static gboolean
-nm_dbus_vpn_connections_update_from_nmi (NMVPNManager *manager)
-{
-       DBusMessage *           message;
-       NMDBusManager *         dbus_mgr;
-       DBusConnection *        dbus_connection;
-
-       g_return_val_if_fail (manager != NULL, FALSE);
-
-       dbus_mgr = nm_dbus_manager_get ();
-       dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("couldn't get the dbus connection.");
-               goto out;
-       }
-
-       message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
-                                               NMI_DBUS_PATH,
-                                               NMI_DBUS_INTERFACE,
-                                               "getVPNConnections");
-       if (!message) {
-               nm_warning ("Couldn't allocate the dbus message.");
-               goto out;
-       }
-
-       nm_dbus_send_with_callback (dbus_connection,
-                                   message,
-                                   (DBusPendingCallNotifyFunction) nm_dbus_vpn_connections_update_cb,
-                                   manager,
-                                   NULL,
-                                   __func__);
-       dbus_message_unref (message);
-
-out:
-       g_object_unref (dbus_mgr);
-       return FALSE;
-}
-
-
-/*
- * nm_dbus_vpn_schedule_vpn_connections_update
- *
- * Schedule an update of VPN connections in the main thread
- *
- */
-void nm_dbus_vpn_schedule_vpn_connections_update (NMVPNManager *manager)
-{
-       g_return_if_fail (manager != NULL);
-
-       g_idle_add_full (G_PRIORITY_HIGH_IDLE,
-                                        (GSourceFunc) nm_dbus_vpn_connections_update_from_nmi,
-                                        manager,
-                                        NULL);
-}
-
-
-/*
- * nm_dbus_vpn_get_vpn_connections
- *
- * Returns a string array of VPN connection names.
- *
- */
-static DBusMessage *
-nm_dbus_vpn_get_vpn_connections (DBusConnection *connection,
-                                 DBusMessage *message,
-                                 gpointer user_data)
-{
-       NMVPNManager *  vpn_mgr = (NMVPNManager *) user_data;
-       DBusMessage *   reply = NULL;
-       char **                 vpn_names = NULL;
-       int                             num_names;
-
-       g_return_val_if_fail (vpn_mgr != NULL, NULL);
-       g_return_val_if_fail (connection != NULL, NULL);
-       g_return_val_if_fail (message != NULL, NULL);
-
-       vpn_names = nm_vpn_manager_get_connection_names (vpn_mgr);
-       num_names = vpn_names ? g_strv_length (vpn_names) : 0;
-       if (num_names == 0) {
-               reply = nm_dbus_create_error_message (message,
-                                                     NM_DBUS_INTERFACE_VPN,
-                                                     "NoVPNConnections",
-                                                     "There are no available VPN "
-                                                     "connections.");
-               goto out;
-       }
-
-       if (!(reply = dbus_message_new_method_return (message)))
-               goto out;
-
-       dbus_message_append_args (reply,
-                                 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &vpn_names, num_names,
-                                 DBUS_TYPE_INVALID);
-
-out:
-       if (vpn_names)
-               g_strfreev (vpn_names); 
-
-       return (reply);
-}
-
-
-/*
- * nm_dbus_vpn_get_vpn_connection_properties
- *
- * Grab properties of a VPN connection
- *
- */
-static DBusMessage *
-nm_dbus_vpn_get_vpn_connection_properties (DBusConnection *connection,
-                                           DBusMessage *message,
-                                           gpointer user_data)
-{
-       DBusMessage *           reply = NULL;
-       DBusError                       error;
-       const char *            name;
-       gboolean                        success = FALSE;
-       NMVPNManager *          vpn_mgr = (NMVPNManager *) user_data;
-       NMVPNConnection *       vpn;
-       const char *            user_name;
-       const char *            service_name;
-       NMVPNService *          service;
-       NMVPNActRequest *       req;
-       dbus_uint32_t           state;
-
-       g_return_val_if_fail (vpn_mgr != NULL, NULL);
-       g_return_val_if_fail (connection != NULL, NULL);
-       g_return_val_if_fail (message != NULL, NULL);
-
-       if (!(reply = dbus_message_new_method_return (message)))
-               return NULL;
-
-       dbus_error_init (&error);
-       if (!dbus_message_get_args (message, &error,
-                                   DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) {
-               if (dbus_error_is_set (&error))
-                       dbus_error_free (&error);
-               reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE_VPN);
-               goto out;
-       }
-
-       if (!(vpn = nm_vpn_manager_find_connection_by_name (vpn_mgr, name)))
-               goto out;
-
-       user_name = nm_vpn_connection_get_user_name (vpn);
-       service_name = nm_vpn_connection_get_service_name (vpn);
-       if (!(service = nm_vpn_manager_find_service_by_name (vpn_mgr, service_name)))
-               goto out;
-
-       req = nm_vpn_manager_get_vpn_act_request (vpn_mgr);
-       state = (dbus_uint32_t) NM_VPN_CONNECTION_STATE_DISCONNECTED;
-       if (req && (nm_vpn_act_request_get_connection (req) == vpn))
-               state = nm_vpn_act_request_get_state (req);
-
-       dbus_message_append_args (reply, DBUS_TYPE_STRING, &name,
-                                        DBUS_TYPE_STRING, &user_name,
-                                        DBUS_TYPE_STRING, &service_name,
-                                        DBUS_TYPE_UINT32, &state,
-                                        DBUS_TYPE_INVALID);
-       success = TRUE;
-
-out:
-       if (!success)
-               reply = new_invalid_vpn_connection_error (message);
-
-       return reply;
-}
-
-
-/*
- * nm_dbus_vpn_activate_connection
- *
- * Activate a specific VPN connection.
- *
- */
-static DBusMessage *
-nm_dbus_vpn_activate_connection (DBusConnection *connection,
-                                 DBusMessage *message,
-                                 gpointer user_data)
-{
-       NMVPNManager *          vpn_mgr = (NMVPNManager *) user_data;
-       DBusMessage *           reply = NULL;
-       DBusError                       error;
-       const char *            name;
-       char **                 passwords;
-       int                             num_passwords;
-       NMVPNConnection *       vpn;
-       int     item_count = -1;
-       char **items;
-       int routes_count = -1;
-       char **routes;
-
-       g_return_val_if_fail (vpn_mgr != NULL, NULL);
-       g_return_val_if_fail (connection != NULL, NULL);
-       g_return_val_if_fail (message != NULL, NULL);
-
-       dbus_error_init (&error);
-       if (!dbus_message_get_args (message, &error,
-                                  DBUS_TYPE_STRING, &name,
-                                  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &passwords, &num_passwords,
-                                  DBUS_TYPE_INVALID)) {
-               reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE_VPN);
-               goto out;
-       }
-
-       if (!(vpn = nm_vpn_manager_find_connection_by_name (vpn_mgr, name))) {
-               reply = new_invalid_vpn_connection_error (message);
-               goto out;
-       }
-
-       routes = nm_dbus_vpn_get_routes (connection, vpn, &routes_count);
-       if ((items = nm_dbus_vpn_get_vpn_data (connection, vpn, &item_count)))
-       {
-               char *  joined_string = g_strjoinv (" / ", items);
-               char *  routes_string = g_strjoinv (" / ", routes);
-               nm_info ("Will activate VPN connection '%s', service '%s', user_name "
-                        "'%s', vpn_data '%s', route '%s'.",
-                        name,
-                        nm_vpn_connection_get_service_name (vpn),
-                        nm_vpn_connection_get_user_name (vpn),
-                        joined_string,
-                        routes_string);
-               nm_vpn_manager_activate_vpn_connection (vpn_mgr, vpn, passwords,
-                                                       num_passwords, items, item_count, 
-                                                       routes, routes_count);
-
-               g_free (joined_string);
-               g_free (routes_string);
-               g_strfreev (items);
-       }
-
-out:
-       return reply;
-}
-
-
-/*
- * nm_dbus_vpn_deactivate_connection
- *
- * Deactivate the active VPN connection, if any.
- *
- */
-static DBusMessage *
-nm_dbus_vpn_deactivate_connection (DBusConnection *connection,
-                                   DBusMessage *message,
-                                   gpointer user_data)
-{
-       NMVPNManager *          vpn_mgr = (NMVPNManager *) user_data;
-       NMVPNActRequest *       req;
-       NMVPNConnection *       vpn;
-
-       g_return_val_if_fail (vpn_mgr != NULL, NULL);
-       g_return_val_if_fail (connection != NULL, NULL);
-       g_return_val_if_fail (message != NULL, NULL);
-
-       if (!(req = nm_vpn_manager_get_vpn_act_request (vpn_mgr)))
-               return NULL;
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
-
-       nm_info ("Will deactivate the VPN connection '%s', service '%s'.",
-                nm_vpn_connection_get_name (vpn),
-                nm_vpn_connection_get_service_name (vpn));
-       nm_vpn_manager_deactivate_vpn_connection (vpn_mgr,
-                                                 nm_vpn_act_request_get_parent_dev (req));
-
-       return NULL;
-}
-
-
-static DBusHandlerResult
-dbus_message_handler (DBusConnection *con, DBusMessage *message, void *user_data)
-{
-       DBusMessage *reply = NULL;
-       DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED;
-
-       if (dbus_message_has_member (message, "getVPNConnections"))
-               reply = nm_dbus_vpn_get_vpn_connections (con, message, user_data);
-       else if (dbus_message_has_member (message, "getVPNConnectionProperties"))
-               reply = nm_dbus_vpn_get_vpn_connection_properties (con, message, user_data);
-       else if (dbus_message_has_member (message, "activateVPNConnection"))
-               reply = nm_dbus_vpn_activate_connection (con, message, user_data);
-       else if (dbus_message_has_member (message, "deactivateVPNConnection"))
-               reply = nm_dbus_vpn_deactivate_connection (con, message, user_data);
-       else
-               result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-       if (reply) {
-               dbus_connection_send (con, reply, NULL);
-               dbus_message_unref (reply);
-       }
-
-       return result;
-}
-
-
-/*
- * nm_dbus_vpn_methods_setup
- *
- * Register handlers for dbus methods on the
- * org.freedesktop.NetworkManager.VPNConnections object.
- *
- */
-gboolean
-nm_dbus_vpn_methods_setup (NMVPNManager *mgr)
-{
-       NMDBusManager *dbus_mgr;
-       gboolean success;
-       DBusObjectPathVTable vtable = { NULL, &dbus_message_handler, NULL, NULL, NULL, NULL };
-
-       dbus_mgr = nm_dbus_manager_get ();
-       success = dbus_connection_register_object_path (nm_dbus_manager_get_dbus_connection (dbus_mgr),
-                                                                                                       NM_DBUS_PATH_VPN, &vtable, mgr);
-       if (!success)
-               nm_warning ("Could not register a dbus handler for VPN. Not enough memory?");
-
-       g_object_unref (dbus_mgr);
-
-       return success;
-}
diff --git a/src/vpn-manager/nm-dbus-vpn.h b/src/vpn-manager/nm-dbus-vpn.h
deleted file mode 100644 (file)
index cb15a7f..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* NetworkManager -- Network link manager
- *
- * Dan Williams <dcbw@redhat.com>
- *
- * 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.
- *
- * (C) Copyright 2005 Red Hat, Inc.
- */
-
-#ifndef NM_DBUS_VPN_H
-#define NM_DBUS_VPN_H
-
-#include "NetworkManagerDbusUtils.h"
-#include "nm-vpn-manager.h"
-#include "nm-vpn-connection.h"
-
-#define        NMI_DBUS_SERVICE                        "org.freedesktop.NetworkManagerInfo"
-#define        NMI_DBUS_PATH                           "/org/freedesktop/NetworkManagerInfo"
-#define        NMI_DBUS_INTERFACE                      "org.freedesktop.NetworkManagerInfo"
-
-void   nm_dbus_vpn_schedule_vpn_connections_update (NMVPNManager *manager);
-
-void   nm_dbus_vpn_update_one_vpn_connection       (DBusConnection *connection,
-                                                     NMVPNManager *manager,
-                                                     const char *vpn);
-
-void   nm_dbus_vpn_signal_vpn_connection_update    (DBusConnection *con,
-                                                     NMVPNConnection *vpn,
-                                                     const char *signal);
-
-void   nm_dbus_vpn_signal_vpn_failed               (DBusConnection *con,
-                                                     const char *signal,
-                                                     NMVPNConnection *vpn,
-                                                     const char *error_msg);
-
-void   nm_dbus_vpn_signal_vpn_login_banner         (DBusConnection *con,
-                                                     NMVPNConnection *vpn,
-                                                     const char *banner);
-
-void   nm_dbus_vpn_signal_vpn_connection_state_change (DBusConnection *con,
-                                                        NMVPNConnection *vpn,
-                                                        NMVPNConnectionState new_state);
-
-char **        nm_dbus_vpn_get_routes                      (DBusConnection *connection,
-                                                     NMVPNConnection *vpn,
-                                                     int *num_items);
-
-gboolean nm_dbus_vpn_methods_setup                  (NMVPNManager *mgr);
-
-#endif
index e3aa35a..ba83550 100644 (file)
@@ -1,11 +1,13 @@
-/* nm-vpn-connection.c - handle a single VPN connections within NetworkManager's framework 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+/* NetworkManager -- Network link manager
  *
- * Copyright (C) 2005 Dan Williams
+ * Dan Williams <dcbw@redhat.com>
  *
  * 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.
+ * 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
  *
  * 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.  
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * (C) Copyright 2005 Red Hat, Inc.
  */
 
-#include "config.h"
+
 #include <glib.h>
 #include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
 #include "nm-vpn-connection.h"
-#include "nm-dbus-vpn.h"
 #include "nm-dbus-manager.h"
-#include "nm-utils.h"
 #include "NetworkManagerSystem.h"
+#include "nm-utils.h"
+#include "nm-vpn-plugin-bindings.h"
 
+static gboolean impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err);
 
-struct NMVPNConnection
-{
-       int                     refcount;
+#include "nm-vpn-connection-glue.h"
+
+G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT)
 
-       /* Won't change over life of object */
-       char *          name;
-       char *          user_name;
-       char *          service_name;
+typedef struct {
+       char *name;
+       char *dbus_service;
+       GHashTable *properties;
+       char **routes;
+       NMDevice *parent_dev;
+       char *object_path;
+       
+       NMVPNConnectionState state;
+       gulong device_monitor;
+       DBusGProxy *proxy;
+       guint ipconfig_timeout;
+       NMIP4Config *ip4_config;
+       char *tundev;
+} NMVPNConnectionPrivate;
 
-       NMNamedManager *named_manager;
+#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
 
-       /* Change when connection is activated/deactivated */
-       NMDevice *      parent_dev;
-       NMIP4Config *   ip4_config;
-       char *          vpn_iface;
+enum {
+       STATE_CHANGED,
+
+       LAST_SIGNAL
 };
 
+static guint signals[LAST_SIGNAL] = { 0 };
 
-static void    nm_vpn_connection_set_vpn_iface (NMVPNConnection *con, const char *vpn_iface);
-static void    nm_vpn_connection_set_ip4_config        (NMVPNConnection *con, NMIP4Config *ip4_config);
-static void    nm_vpn_connection_set_parent_device(NMVPNConnection *con, NMDevice *parent_dev);
+enum {
+       PROP_0,
+       PROP_NAME,
+       PROP_STATE,
 
+       LAST_PROP
+};
 
-NMVPNConnection *
-nm_vpn_connection_new (const char *name,
-                       const char *user_name,
-                       const char *service_name,
-                       NMNamedManager *named_manager)
+static void
+nm_vpn_connection_set_state (NMVPNConnection *connection,
+                                           NMVPNConnectionState state)
 {
-       NMVPNConnection *connection;
+       NMVPNConnectionPrivate *priv;
 
-       g_return_val_if_fail (name != NULL, NULL);
-       g_return_val_if_fail (user_name != NULL, NULL);
-       g_return_val_if_fail (service_name != NULL, NULL);
-       g_return_val_if_fail (named_manager != NULL, NULL);
-
-       connection = g_malloc0 (sizeof (NMVPNConnection));
-       connection->refcount = 1;
+       g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
 
-       connection->name = g_strdup (name);
-       connection->user_name = g_strdup (user_name);
-       connection->service_name = g_strdup (service_name);
+       priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
-       g_object_ref (named_manager);
-       connection->named_manager = named_manager;
+       if (state != priv->state) {
+               priv->state = state;
 
-       return connection;
+               g_object_ref (connection);
+               g_signal_emit (connection, signals[STATE_CHANGED], 0, state);
+               g_object_unref (connection);
+       }
 }
 
+static void
+device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
+{
+       NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+
+       if (state == NM_DEVICE_STATE_DISCONNECTED)
+               nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_DISCONNECTED);
+}
 
-void nm_vpn_connection_ref (NMVPNConnection *connection)
+NMVPNConnection *
+nm_vpn_connection_new (const char *name,
+                                  const char *dbus_service,
+                                  NMDevice *parent_device,
+                                  GHashTable *properties,
+                                  char **routes)
 {
-       g_return_if_fail (connection != NULL);
+       NMVPNConnection *connection;
+
+       g_return_val_if_fail (name != NULL, NULL);
+       g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
+       g_return_val_if_fail (properties != NULL, NULL);
+
+       connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL);
+       if (connection) {
+               NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+               priv->name = g_strdup (name);
+               priv->dbus_service = g_strdup (dbus_service);
+               priv->parent_dev = g_object_ref (parent_device);
+               priv->properties = properties;
+               priv->routes = routes;
+
+               priv->device_monitor = g_signal_connect (parent_device, "state-changed",
+                                                                                G_CALLBACK (device_state_changed),
+                                                                                connection);
+       }
 
-       connection->refcount++;
+       return connection;
 }
 
-void nm_vpn_connection_unref (NMVPNConnection *connection)
+static void
+plugin_state_changed (DBusGProxy *proxy,
+                                 NMVPNServiceState state,
+                                 gpointer user_data)
 {
-       g_return_if_fail (connection != NULL);
+       NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+
+       nm_debug ("plugin state changed: %d", state);
+
+       if (state == NM_VPN_SERVICE_STATE_STOPPED) {
+               switch (nm_vpn_connection_get_state (connection)) {
+               case NM_VPN_CONNECTION_STATE_CONNECT:
+               case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
+                       nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
+                       break;
+               case NM_VPN_CONNECTION_STATE_ACTIVATED:
+                       nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_DISCONNECTED);
+                       break;
+               default:
+                       break;
+               }
+       }
+}
 
-       connection->refcount--;
-       if (connection->refcount <= 0)
-       {
-               g_free (connection->name);
-               g_free (connection->user_name);
-               g_free (connection->service_name);
+static void
+print_vpn_config (NMIP4Config *config,
+                          const char *tundev,
+                          const char *login_banner)
+{
+        struct in_addr  temp_addr;
+        char *          dns_domain = NULL;
+        guint32         num;
+        guint32                 i;
+
+        g_return_if_fail (config != NULL);
+
+        temp_addr.s_addr = nm_ip4_config_get_gateway (config);
+        nm_info ("VPN Gateway: %s", inet_ntoa (temp_addr));
+        nm_info ("Tunnel Device: %s", tundev);
+        temp_addr.s_addr = nm_ip4_config_get_address (config);
+        nm_info ("Internal IP4 Address: %s", inet_ntoa (temp_addr));
+        temp_addr.s_addr = nm_ip4_config_get_netmask (config);
+        nm_info ("Internal IP4 Netmask: %s", inet_ntoa (temp_addr));
+        temp_addr.s_addr = nm_ip4_config_get_ptp_address (config);
+        nm_info ("Internal IP4 Point-to-Point Address: %s", inet_ntoa (temp_addr));
+        nm_info ("Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (config));
+
+        num = nm_ip4_config_get_num_nameservers (config);
+        for (i = 1; i <= num; i++)
+        {
+                temp_addr.s_addr = nm_ip4_config_get_nameserver (config, i);
+                nm_info ("Internal IP4 DNS: %s", inet_ntoa (temp_addr));
+        }
+
+        if (nm_ip4_config_get_num_domains (config) > 0)
+                dns_domain = (char *) nm_ip4_config_get_domain (config, 1);
+        nm_info ("DNS Domain: '%s'", dns_domain ? dns_domain : "(none)");
+        nm_info ("Login Banner:");
+        nm_info ("-----------------------------------------");
+        nm_info ("%s", login_banner);
+        nm_info ("-----------------------------------------");
+}
 
-               if (connection->parent_dev)
-                       g_object_unref (G_OBJECT (connection->parent_dev));
-               if (connection->ip4_config)
-                       g_object_unref (connection->ip4_config);
-               g_free (connection->vpn_iface);
+static void
+nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
+                                                   GHashTable *config_hash,
+                                                   gpointer user_data)
+{
+       NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+       NMIP4Config *config;
+       GValue *val;
+       const char *banner = NULL;
+       int i;
+
+       nm_info ("VPN connection '%s' (IP Config Get) reply received.",
+                   nm_vpn_connection_get_name (connection));
+
+       g_source_remove (priv->ipconfig_timeout);
+       priv->ipconfig_timeout = 0;
+
+       config = nm_ip4_config_new ();
+       nm_ip4_config_set_secondary (config, TRUE);
+
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY);
+       if (val)
+               nm_ip4_config_set_gateway (config, g_value_get_uint (val));
+
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS);
+       if (val)
+               nm_ip4_config_set_address (config, g_value_get_uint (val));
+
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_PTP);
+       if (val)
+               nm_ip4_config_set_ptp_address (config, g_value_get_uint (val));
+
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NETMASK);
+       if (val)
+               nm_ip4_config_set_netmask (config, g_value_get_uint (val));
+       else
+               /* If no netmask, default to Class C address */
+               nm_ip4_config_set_netmask (config, 0x00FF);
+
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_DNS);
+       if (val) {
+               GArray *dns = (GArray *) g_value_get_boxed (val);
+
+               for (i = 0; i < dns->len; i++)
+                       nm_ip4_config_add_nameserver (config, g_array_index (dns, guint, i));
+       }
 
-               g_object_unref (connection->named_manager);
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NBNS);
+       if (val) {
+               GArray *nbns = (GArray *) g_value_get_boxed (val);
 
-               memset (connection, 0, sizeof (NMVPNConnection));
-               g_free (connection);
+               for (i = 0; i < nbns->len; i++)
+                       nm_ip4_config_add_nameserver (config, g_array_index (nbns, guint, i));
        }
-}
 
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_MSS);
+       if (val)
+               nm_ip4_config_set_mss (config, g_value_get_uint (val));
+
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_MTU);
+       if (val)
+               nm_ip4_config_set_mtu (config, g_value_get_uint (val));
+
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV);
+       if (val)
+               priv->tundev = g_strdup (g_value_get_string (val));
+
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN);
+       if (val)
+               nm_ip4_config_add_domain (config, g_value_get_string (val));
+
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_BANNER);
+       if (val)
+               banner = g_value_get_string (val);
+
+       print_vpn_config (config, priv->tundev, banner);
+
+       priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+       priv->ip4_config = config;
+
+       if (nm_system_vpn_device_set_from_ip4_config (priv->parent_dev,
+                                                                                priv->tundev,
+                                                                                priv->ip4_config,
+                                                                                priv->routes)) {
+               nm_info ("VPN connection '%s' (IP Config Get) complete.",
+                           nm_vpn_connection_get_name (connection));
+               nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_ACTIVATED);
+       } else {
+               nm_warning ("VPN connection '%s' did not receive valid IP config information.",
+                                 nm_vpn_connection_get_name (connection));
+               nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
+       }
+}
 
-void nm_vpn_connection_activate (NMVPNConnection *connection)
+static gboolean
+nm_vpn_connection_ip_config_timeout (gpointer user_data)
 {
-       g_return_if_fail (connection != NULL);
+       NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+       priv->ipconfig_timeout = 0;
+
+       /* If the activation request's state is still IP_CONFIG_GET and we're
+        * in this timeout, cancel activation because it's taken too long.
+        */
+       if (nm_vpn_connection_get_state (connection) == NM_VPN_CONNECTION_STATE_IP_CONFIG_GET) {
+               nm_info ("VPN connection '%s' (IP Config Get) timeout exceeded.",
+                        nm_vpn_connection_get_name (connection));
+               nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
+       }
 
-       /* Nothing done here yet */
+       return FALSE;
 }
 
+static void
+nm_vpn_connection_connect_cb (DBusGProxy *proxy, GError *err, gpointer user_data)
+{
+       NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+       nm_info ("VPN connection '%s' (Connect) reply received.",
+                   nm_vpn_connection_get_name (connection));
+
+       if (err) {
+               nm_warning ("(VPN connection '%s' could not start.  dbus says: '%s'.", 
+                                 nm_vpn_connection_get_name (connection), err->message);
+               g_error_free (err);
+               nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
+       } else {
+               nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_IP_CONFIG_GET);
+               
+               /* 40 second timeout waiting for IP config signal from VPN service */
+               priv->ipconfig_timeout = g_timeout_add (40000, nm_vpn_connection_ip_config_timeout, connection);
+       }
+}
 
-gboolean
-nm_vpn_connection_set_config (NMVPNConnection *connection,
-                              const char *vpn_iface,
-                              NMDevice *dev,
-                              NMIP4Config *ip4_config)
+void
+nm_vpn_connection_activate (NMVPNConnection *connection)
 {
-       gboolean        success = FALSE;
-       int             num_routes = -1;
-       char ** routes;
-       DBusConnection *dbus_connection;
-       NMDBusManager * dbus_mgr = NULL;
+       NMVPNConnectionPrivate *priv;
+       NMDBusManager *dbus_mgr;
 
-       g_return_val_if_fail (connection != NULL, FALSE);
-       g_return_val_if_fail (dev != NULL, FALSE);
-       g_return_val_if_fail (ip4_config != NULL, FALSE);
+       g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
+       g_return_if_fail (nm_vpn_connection_get_state (connection) == NM_VPN_CONNECTION_STATE_PREPARE);
 
+       priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
        dbus_mgr = nm_dbus_manager_get ();
-       dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("couldn't get dbus connection.");
-               goto out;
-       }
 
-       /* IPsec VPNs will not have tunnel device */
-       if (vpn_iface != NULL && strlen (vpn_iface))
-               nm_vpn_connection_set_vpn_iface (connection, vpn_iface);
-       nm_vpn_connection_set_parent_device (connection, dev);
-       nm_vpn_connection_set_ip4_config (connection, ip4_config);
-
-       routes = nm_dbus_vpn_get_routes (dbus_connection, connection, &num_routes);
-       nm_system_vpn_device_set_from_ip4_config (connection->named_manager,
-                                                 connection->parent_dev,
-                                                 connection->vpn_iface,
-                                                 connection->ip4_config,
-                                                 routes,
-                                                 num_routes);
-       g_strfreev(routes);
-       success = TRUE;
-
-out:
-       return success;
+       priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (dbus_mgr),
+                                                                        priv->dbus_service,
+                                                                        NM_VPN_DBUS_PLUGIN_PATH,
+                                                                        NM_VPN_DBUS_PLUGIN_INTERFACE);
+       g_object_unref (dbus_mgr);
+
+       /* StateChanges signal */
+       dbus_g_proxy_add_signal (priv->proxy, "StateChanged", G_TYPE_UINT, G_TYPE_INVALID);
+       dbus_g_proxy_connect_signal (priv->proxy, "StateChanged",
+                                                   G_CALLBACK (plugin_state_changed),
+                                                   connection, NULL);
+
+       /* Ip4Config signal */
+       dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED,
+                                                               G_TYPE_NONE, G_TYPE_VALUE, G_TYPE_INVALID);
+       dbus_g_proxy_add_signal (priv->proxy, "Ip4Config",
+                                               dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+                                               G_TYPE_INVALID);
+       dbus_g_proxy_connect_signal (priv->proxy, "Ip4Config",
+                                                   G_CALLBACK (nm_vpn_connection_ip4_config_get),
+                                                   connection, NULL);
+
+       org_freedesktop_NetworkManager_VPN_Plugin_connect_async (priv->proxy,
+                                                                                                 priv->properties,
+                                                                                                 priv->routes,
+                                                                                                 nm_vpn_connection_connect_cb,
+                                                                                                 connection);
+
+       nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_CONNECT);
 }
 
-
-void nm_vpn_connection_deactivate (NMVPNConnection *connection)
+const char *
+nm_vpn_connection_get_object_path (NMVPNConnection *connection)
 {
-       g_return_if_fail (connection != NULL);
+       g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
 
-       if (connection->vpn_iface)
-       {
-               nm_system_device_set_up_down_with_iface (connection->vpn_iface, FALSE);
-               nm_system_device_flush_routes_with_iface (connection->vpn_iface);
-               nm_system_device_flush_addresses_with_iface (connection->vpn_iface);
-       }
-
-       if (connection->ip4_config)
-       {
-               /* Remove attributes of the VPN's IP4 Config */
-               nm_system_vpn_device_unset_from_ip4_config (connection->named_manager, connection->parent_dev,
-                               connection->vpn_iface, connection->ip4_config);
+       return NM_VPN_CONNECTION_GET_PRIVATE (connection)->object_path;
+}
 
-               /* Reset routes, nameservers, and domains of the currently active device */
-               nm_system_device_set_from_ip4_config (connection->parent_dev);
-       }
+const char *
+nm_vpn_connection_get_name (NMVPNConnection *connection)
+{
+       g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
 
-       nm_vpn_connection_set_ip4_config (connection, NULL);
-       nm_vpn_connection_set_vpn_iface (connection, NULL);
-       nm_vpn_connection_set_parent_device (connection, NULL);
+       return NM_VPN_CONNECTION_GET_PRIVATE (connection)->name;
 }
 
+NMVPNConnectionState
+nm_vpn_connection_get_state (NMVPNConnection *connection)
+{
+       g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NM_VPN_CONNECTION_STATE_UNKNOWN);
+
+       return NM_VPN_CONNECTION_GET_PRIVATE (connection)->state;
+}
 
-const char *nm_vpn_connection_get_name (NMVPNConnection *connection)
+void
+nm_vpn_connection_fail (NMVPNConnection *connection)
 {
-       g_return_val_if_fail (connection != NULL, NULL);
+       g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
 
-       return connection->name;
+       nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
 }
 
-const char *nm_vpn_connection_get_user_name (NMVPNConnection *connection)
+void
+nm_vpn_connection_disconnect (NMVPNConnection *connection)
 {
-       g_return_val_if_fail (connection != NULL, NULL);
+       g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
 
-       return connection->user_name;
+       nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_DISCONNECTED);
 }
 
-const char  *nm_vpn_connection_get_service_name (NMVPNConnection *connection)
+static gboolean
+impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err)
 {
-       g_return_val_if_fail (connection != NULL, NULL);
+       nm_vpn_connection_disconnect (connection);
 
-       return connection->service_name;
+       return TRUE;
 }
 
+/******************************************************************************/
 
-static void nm_vpn_connection_set_vpn_iface (NMVPNConnection *con, const char *vpn_iface)
+static void
+connection_state_changed (NMVPNConnection *connection, NMVPNConnectionState state)
 {
-       g_return_if_fail (con != NULL);
-
-       if (con->vpn_iface)
-       {
-               g_free (con->vpn_iface);
-               con->vpn_iface = NULL;
+       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+       switch (state) {
+       case NM_VPN_CONNECTION_STATE_DISCONNECTED:
+       case NM_VPN_CONNECTION_STATE_FAILED:
+               if (priv->proxy) {
+                       GError *err = NULL;
+
+                       org_freedesktop_NetworkManager_VPN_Plugin_disconnect (priv->proxy, &err);
+                       if (err) {
+                               nm_warning ("%s", err->message);
+                               g_error_free (err);
+                       }
+
+                       g_object_unref (priv->proxy);
+                       priv->proxy = NULL;
+               }
+
+               if (priv->tundev) {
+                       nm_system_device_set_up_down_with_iface (priv->tundev, FALSE);
+                       nm_system_device_flush_routes_with_iface (priv->tundev);
+                       nm_system_device_flush_addresses_with_iface (priv->tundev);
+               }
+
+               if (priv->ip4_config) {
+                       /* Remove attributes of the VPN's IP4 Config */
+                       nm_system_vpn_device_unset_from_ip4_config (priv->parent_dev, priv->tundev, priv->ip4_config);
+
+                       /* Reset routes, nameservers, and domains of the currently active device */
+                       nm_system_device_set_from_ip4_config (priv->parent_dev);
+               }
+
+               break;
+       default:
+               break;
        }
-
-       if (vpn_iface)
-               con->vpn_iface = g_strdup (vpn_iface);
 }
 
-static void nm_vpn_connection_set_ip4_config (NMVPNConnection *con, NMIP4Config *ip4_config)
+static void
+nm_vpn_connection_init (NMVPNConnection *connection)
 {
-       g_return_if_fail (con != NULL);
+       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+       NMDBusManager *dbus_mgr;
+       static guint32 counter = 0;
 
-       if (con->ip4_config)
-       {
-               g_object_unref (con->ip4_config);
-               con->ip4_config = NULL;
-       }
+       priv->state = NM_VPN_CONNECTION_STATE_PREPARE;
+       priv->object_path = g_strdup_printf (NM_DBUS_PATH_VPN_CONNECTION "/%d", counter++);
 
-       if (ip4_config)
-               con->ip4_config = g_object_ref (ip4_config);
+       dbus_mgr = nm_dbus_manager_get ();
+       dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
+                                                                 priv->object_path,
+                                                                 G_OBJECT (connection));
+       g_object_unref (dbus_mgr);
 }
 
-static void nm_vpn_connection_set_parent_device (NMVPNConnection *con, NMDevice *parent_dev)
+static void
+finalize (GObject *object)
 {
-       g_return_if_fail (con != NULL);
+       NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
 
-       if (con->parent_dev)
-       {
-               g_object_unref (G_OBJECT (con->parent_dev));
-               con->parent_dev = NULL;
+       if (priv->parent_dev) {
+               if (priv->device_monitor)
+                       g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor);
+
+               g_object_unref (priv->parent_dev);
        }
 
-       if (parent_dev)
-       {
-               g_object_ref (G_OBJECT (parent_dev));
-               con->parent_dev = parent_dev;
+       g_free (priv->tundev);
+
+       if (priv->ip4_config)
+               g_object_unref (priv->ip4_config);
+
+       if (priv->ipconfig_timeout)
+               g_source_remove (priv->ipconfig_timeout);
+
+       if (priv->proxy)
+               g_object_unref (priv->proxy);
+
+       g_free (priv->name);
+       g_free (priv->dbus_service);
+       g_hash_table_unref (priv->properties);
+       g_strfreev (priv->routes);
+       g_free (priv->object_path);
+
+       G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+                   GValue *value, GParamSpec *pspec)
+{
+       switch (prop_id) {
+       case PROP_NAME:
+               g_value_set_string (value, nm_vpn_connection_get_name (NM_VPN_CONNECTION (object)));
+               break;
+       case PROP_STATE:
+               g_value_set_uint (value, nm_vpn_connection_get_state (NM_VPN_CONNECTION (object)));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
        }
 }
+
+static void
+nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
+
+       g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
+
+       /* virtual methods */
+       connection_class->state_changed = connection_state_changed;
+       object_class->get_property = get_property;
+       object_class->finalize = finalize;
+
+       /* properties */
+       g_object_class_install_property
+               (object_class, PROP_NAME,
+                g_param_spec_string (NM_VPN_CONNECTION_NAME,
+                                                 "Name",
+                                                 "Connection name",
+                                                 NULL,
+                                                 G_PARAM_READABLE));
+
+       g_object_class_install_property
+               (object_class, PROP_STATE,
+                g_param_spec_uint (NM_VPN_CONNECTION_STATE,
+                                               "State",
+                                               "Current state",
+                                               NM_VPN_CONNECTION_STATE_UNKNOWN,
+                                               NM_VPN_CONNECTION_STATE_DISCONNECTED,
+                                               NM_VPN_CONNECTION_STATE_UNKNOWN,
+                                               G_PARAM_READABLE));
+
+       /* signals */
+       signals[STATE_CHANGED] =
+               g_signal_new ("state-changed",
+                                   G_OBJECT_CLASS_TYPE (object_class),
+                                   G_SIGNAL_RUN_FIRST,
+                                   G_STRUCT_OFFSET (NMVPNConnectionClass, state_changed),
+                                   NULL, NULL,
+                                   g_cclosure_marshal_VOID__UINT,
+                                   G_TYPE_NONE, 1,
+                                   G_TYPE_UINT);
+
+       dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (connection_class),
+                                                          &dbus_glib_nm_vpn_connection_object_info);
+}
index 3713cb4..380038b 100644 (file)
@@ -1,11 +1,12 @@
-/* nm-vpn-connection.h - handle a single VPN connection within NetworkManager's framework 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* NetworkManager -- Network link manager
  *
- * Copyright (C) 2005 Dan Williams
+ * Dan Williams <dcbw@redhat.com>
  *
  * 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.
+ * 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
  *
  * 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.  
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * (C) Copyright 2005 Red Hat, Inc.
  */
+
 #ifndef NM_VPN_CONNECTION_H
 #define NM_VPN_CONNECTION_H
 
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include "NetworkManagerVPN.h"
 #include "nm-device.h"
-#include "nm-named-manager.h"
 
-typedef struct NMVPNConnection NMVPNConnection;
+#define NM_TYPE_VPN_CONNECTION            (nm_vpn_connection_get_type ())
+#define NM_VPN_CONNECTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection))
+#define NM_VPN_CONNECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass))
+#define NM_IS_VPN_CONNECTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_CONNECTION))
+#define NM_IS_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_CONNECTION))
+#define NM_VPN_CONNECTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass))
+
+#define NM_VPN_CONNECTION_NAME "name"
+#define NM_VPN_CONNECTION_STATE "state"
+
+typedef struct {
+       GObject parent;
+} NMVPNConnection;
+
+typedef struct {
+       GObjectClass parent;
 
+       /* Signals */
+       void (*state_changed) (NMVPNConnection *connection, NMVPNConnectionState state);
+} NMVPNConnectionClass;
 
-NMVPNConnection *      nm_vpn_connection_new                   (const char *name, const char *user_name, const char *service_name,
-                                                                                               NMNamedManager *named_manager);
-void                           nm_vpn_connection_ref                   (NMVPNConnection *con);
-void                           nm_vpn_connection_unref                 (NMVPNConnection *con);
+GType nm_vpn_connection_get_type (void);
 
-const char *           nm_vpn_connection_get_name              (NMVPNConnection *con);
-const char *           nm_vpn_connection_get_user_name (NMVPNConnection *con);
-const char *           nm_vpn_connection_get_service_name      (NMVPNConnection *con);
+NMVPNConnection     *nm_vpn_connection_new             (const char *name,
+                                                                                        const char *dbus_service,
+                                                                                        NMDevice *parent_device,
+                                                                                        GHashTable *properties,
+                                                                                        char **routes);
 
-void                           nm_vpn_connection_activate              (NMVPNConnection *con);
-void                           nm_vpn_connection_deactivate            (NMVPNConnection *con);
+void                 nm_vpn_connection_activate        (NMVPNConnection *connection);
+const char          *nm_vpn_connection_get_object_path (NMVPNConnection *connection);
+const char          *nm_vpn_connection_get_name        (NMVPNConnection *connection);
+NMVPNConnectionState nm_vpn_connection_get_state       (NMVPNConnection *connection);
+void                 nm_vpn_connection_fail            (NMVPNConnection *connection);
+void                 nm_vpn_connection_disconnect      (NMVPNConnection *connection);
 
-gboolean                       nm_vpn_connection_set_config            (NMVPNConnection *con, const char *vpn_iface, NMDevice *dev, NMIP4Config *ip4_config);
 
-#endif  /* NM_VPN_MANAGER_H */
+#endif /* NM_VPN_CONNECTION_H */
index b4cd215..05452e5 100644 (file)
-/* nm-vpn-manager.c - handle VPN connections within NetworkManager's framework 
- *
- * Copyright (C) 2005 Dan Williams
- *
- * 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 <glib.h>
-#include <stdio.h>
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
 #include <string.h>
-#include <dbus/dbus.h>
+
 #include "nm-vpn-manager.h"
-#include "nm-named-manager.h"
-#include "NetworkManager.h"
-#include "NetworkManagerMain.h"
-#include "NetworkManagerSystem.h"
-#include "nm-vpn-act-request.h"
-#include "nm-vpn-connection.h"
 #include "nm-vpn-service.h"
-#include "nm-dbus-vpn.h"
-#include "nm-utils.h"
+#include "nm-vpn-connection.h"
 #include "nm-dbus-manager.h"
+#include "NetworkManagerVPN.h"
+#include "nm-utils.h"
 
-#define VPN_SERVICE_FILE_PATH          SYSCONFDIR"/NetworkManager/VPN"
-
-struct NMVPNManager
-{
-       NMManager *         nm_manager;
-       GHashTable *            service_table;
-       GSList *                        connections;
-
-       NMVPNActRequest *       act_req;
-       gulong                          device_signal_id;
-};
-
-static void load_services (NMVPNManager *manager, GHashTable *table);
-
-static void
-nm_name_owner_changed_handler (NMDBusManager *mgr,
-                               const char *name,
-                               const char *old,
-                               const char *new,
-                               gpointer user_data)
-{
-       NMVPNManager *vpn_manager = (NMVPNManager *) user_data;
-       gboolean old_owner_good = (old && (strlen (old) > 0));
-       gboolean new_owner_good = (new && (strlen (new) > 0));
-
-       if (strcmp (name, NMI_DBUS_SERVICE) == 0 && (!old_owner_good && new_owner_good))
-               /* NMI appeared, update stuff */
-               nm_dbus_vpn_schedule_vpn_connections_update (vpn_manager);
-}
-
-static gboolean
-nm_dbus_nmi_vpn_signal_handler (DBusConnection *connection,
-                                                               DBusMessage *message,
-                                                               gpointer user_data)
-{
-       NMVPNManager *manager = (NMVPNManager *) user_data;
-       const char * object_path;
-       gboolean        handled = FALSE;
-
-       if (!(object_path = dbus_message_get_path (message)))
-               return FALSE;
-
-       if (strcmp (object_path, NMI_DBUS_PATH) != 0)
-               return FALSE;
-
-       if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "VPNConnectionUpdate")) {
-               char *name = NULL;
-
-               if (dbus_message_get_args (message,
-                                          NULL,
-                                          DBUS_TYPE_STRING, &name,
-                                          DBUS_TYPE_INVALID)) {
-                       nm_debug ("NetworkManagerInfo triggered update of VPN connection '%s'", name);
-                       nm_dbus_vpn_update_one_vpn_connection (connection, manager, name);
-                       handled = TRUE;
-               }
-       }
-
-       return handled;
-}
-
-/*
- * nm_vpn_manager_new
- *
- * Create a new VPN manager instance.
- *
- */
-NMVPNManager *nm_vpn_manager_new (NMManager *nm_manager)
-{
-       NMVPNManager *  manager;
-       NMDBusManager * dbus_mgr;
-
-       g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
-
-       manager = g_slice_new0 (NMVPNManager);
-       manager->nm_manager = g_object_ref (nm_manager);
-
-       manager->service_table = g_hash_table_new_full (g_str_hash,
-                                                       g_str_equal,
-                                                       NULL,
-                                                       (GDestroyNotify) nm_vpn_service_unref);
-       load_services (manager, manager->service_table);
-
-       if (!nm_dbus_vpn_methods_setup (manager)) {
-               nm_vpn_manager_dispose (manager);
-               return NULL;
-       }
+static gboolean impl_vpn_manager_connect (NMVPNManager *manager,
+                                                                 const char *type,
+                                                                 const char *name,
+                                                                 GHashTable *properties,
+                                                                 const char *device_path,
+                                                                 char **routes,
+                                                                 char **connection,
+                                                                 GError **err);
 
-       dbus_mgr = nm_dbus_manager_get ();
+static gboolean impl_vpn_manager_get_connections (NMVPNManager *manager,
+                                                                               GPtrArray **connections,
+                                                                               GError **err);
 
-       g_signal_connect (dbus_mgr,
-                                         "name-owner-changed",
-                         G_CALLBACK (nm_name_owner_changed_handler),
-                                         manager);
+#include "nm-vpn-manager-glue.h"
 
-       nm_dbus_manager_register_signal_handler (dbus_mgr,
-                                                                                        NMI_DBUS_INTERFACE,
-                                                                                        NULL,
-                                                                                        nm_dbus_nmi_vpn_signal_handler,
-                                                                                        manager);
+G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT)
 
-       if (nm_dbus_manager_name_has_owner (dbus_mgr, NMI_DBUS_SERVICE))
-               nm_dbus_vpn_schedule_vpn_connections_update (manager);
+typedef struct {
+       NMManager *nm_mgr;
+       NMDBusManager *dbus_mgr;
+       GSList *services;
+} NMVPNManagerPrivate;
 
-       g_object_unref (dbus_mgr);
+#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate))
 
-       return manager;
-}
-
-
-/*
- * nm_vpn_manager_dispose
- *
- * Release the VPN manager and all its data.
- *
- */
-void nm_vpn_manager_dispose (NMVPNManager *manager)
+static NMVPNService *
+nm_vpn_manager_get_service (NMVPNManager *manager, const char *service_name)
 {
-       g_return_if_fail (manager != NULL);
-
-       if (manager->act_req)
-               nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (manager->act_req));
-
-       g_slist_foreach (manager->connections, (GFunc) nm_vpn_connection_unref, NULL);
-       g_slist_free (manager->connections);
+       GSList *iter;
 
-       g_hash_table_destroy (manager->service_table);
-
-       g_object_unref (manager->nm_manager);
-
-       memset (manager, 0, sizeof (NMVPNManager));
-       g_slice_free (NMVPNManager, manager);
-}
+       for (iter = NM_VPN_MANAGER_GET_PRIVATE (manager)->services; iter; iter = iter->next) {
+               NMVPNService *service = NM_VPN_SERVICE (iter->data);
 
-
-/*
- * nm_vpn_manager_find_connection_by_name
- *
- * Return the NMVPNConnection object associated with a particular name.
- *
- */
-NMVPNConnection *nm_vpn_manager_find_connection_by_name (NMVPNManager *manager, const char *con_name)
-{
-       NMVPNConnection *con = NULL;
-       GSList                  *elt;
-
-       g_return_val_if_fail (manager != NULL, NULL);
-       g_return_val_if_fail (con_name != NULL, NULL);
-
-       for (elt = manager->connections; elt; elt = g_slist_next (elt))
-       {
-               if ((con = (NMVPNConnection *)(elt->data)))
-               {
-                       const char *search_name = nm_vpn_connection_get_name (con);
-                       if (search_name && (strcmp (con_name, search_name) == 0))
-                               break;
-               }
-               con = NULL;
+               if (!strcmp (service_name, nm_vpn_service_get_name (service)))
+                       return service;
        }
 
-       return con;
+       return NULL;
 }
 
-
-NMVPNService *nm_vpn_manager_find_service_by_name (NMVPNManager *manager, const char *service_name)
+static void
+remove_service (gpointer data, GObject *service)
 {
-       g_return_val_if_fail (manager != NULL, NULL);
-       g_return_val_if_fail (service_name != NULL, NULL);
+       NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (data);
 
-       return (NMVPNService *) g_hash_table_lookup (manager->service_table, service_name);
+       priv->services = g_slist_remove (priv->services, service);
 }
 
-
-/*
- * nm_vpn_manager_vpn_connection_list_copy
- *
- * Make a shallow copy of the VPN connection list, should
- * only be used by nm-dbus-vpn.c
- *
- */
-GSList *nm_vpn_manager_vpn_connection_list_copy (NMVPNManager *manager)
+static void
+nm_vpn_manager_add_service (NMVPNManager *manager, NMVPNService *service)
 {
-       GSList *        list;
-       GSList *        elt;
-
-       g_return_val_if_fail (manager != NULL, NULL);
+       NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
 
-       list = g_slist_copy (manager->connections);
-       for (elt = list; elt; elt = g_slist_next (elt))
-               nm_vpn_connection_ref (elt->data);
-
-       return list;
+       priv->services = g_slist_prepend (priv->services, service);
+       g_object_weak_ref (G_OBJECT (service), remove_service, manager);
 }
 
-
-/*
- * nm_vpn_manager_add_connection
- *
- * Add a new VPN connection if none already exits, otherwise update the existing one.
- *
- */
 NMVPNConnection *
-nm_vpn_manager_add_connection (NMVPNManager *manager,
-                               const char *name,
-                               const char *service_name,
-                               const char *user_name)
+nm_vpn_manager_connect (NMVPNManager *manager,
+                                   const char *type,
+                                   const char *name,
+                                   NMDevice *device,
+                                   GHashTable *properties,
+                                   char **routes)
 {
-       NMVPNConnection *       connection = NULL;
-       NMVPNService *          service;
-       DBusConnection *        dbus_connection;
-       NMDBusManager *         dbus_mgr = NULL;
-       NMNamedManager *        named_mgr = NULL;
-       GSList  *                       elt;
-
-       g_return_val_if_fail (manager != NULL, NULL);
+       NMVPNService *service;
+
+       g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
+       g_return_val_if_fail (type != NULL, NULL);
        g_return_val_if_fail (name != NULL, NULL);
-       g_return_val_if_fail (service_name != NULL, NULL);
-       g_return_val_if_fail (user_name != NULL, NULL);
+       g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+       g_return_val_if_fail (properties != NULL, NULL);
 
-       /* Verify that the service name we are adding is in our allowed list */
-       if (!(service = nm_vpn_manager_find_service_by_name (manager, service_name)))
+       if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED)
                return NULL;
 
-       dbus_mgr = nm_dbus_manager_get ();
-       dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("couldn't get dbus connection.");
-               goto out;
+       service = nm_vpn_manager_get_service (manager, type);
+       if (!service) {
+               service = nm_vpn_service_new (type);
+               if (service)
+                       nm_vpn_manager_add_service (manager, service);
        }
 
-       named_mgr = nm_named_manager_get ();
-       connection = nm_vpn_connection_new (name,
-                                           user_name,
-                                           service_name,
-                                           named_mgr);
-       g_object_unref (named_mgr);
-       if (!connection) {
-               nm_warning ("couldn't create VPN connecton for '%s (%s).",
-                           name,
-                           service_name);
-               goto out;
-       }
-
-       /* Remove the existing connection if found */
-       for (elt = manager->connections; elt; elt = g_slist_next (elt)) {
-               NMVPNConnection *con = (NMVPNConnection *)(elt->data);
-
-               
-               if (!con || !nm_vpn_connection_get_name (con))
-                       continue;
-               if (strcmp (nm_vpn_connection_get_name (con), name) != 0)
-                       continue;
+       if (service)
+               return nm_vpn_service_activate (service, name, device, properties, routes);
 
-               manager->connections = g_slist_remove_link (manager->connections, elt);
-               nm_vpn_connection_unref (con);
-               g_slist_free (elt);
-       }
-
-       /* Add in the updated connection */
-       manager->connections = g_slist_append (manager->connections, connection);
-
-out:
-       g_object_unref (dbus_mgr);
-       return connection;
+       return NULL;
 }
 
-
-/*
- * nm_vpn_manager_remove_connection
- *
- * Remove a VPN connection.
- *
- */
-void nm_vpn_manager_remove_connection (NMVPNManager *manager, NMVPNConnection *vpn)
+static NMDevice *
+find_device (NMVPNManager *manager, const char *device_path)
 {
-       g_return_if_fail (manager != NULL);
-       g_return_if_fail (vpn != NULL);
+       GSList *devices;
+       GSList *iter;
 
-       /* If this VPN is currently active, kill it */
-       if (manager->act_req && (nm_vpn_act_request_get_connection (manager->act_req) == vpn))
-       {
-               NMVPNService *          service = nm_vpn_act_request_get_service (manager->act_req);
-               NMVPNConnection *       v = nm_vpn_act_request_get_connection (manager->act_req);
+       devices = nm_manager_get_devices (NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_mgr);
+       for (iter = devices; iter; iter = iter->next) {
+               NMDevice *device = NM_DEVICE (iter->data);
 
-               nm_vpn_connection_deactivate (v);
-               nm_vpn_service_stop_connection (service, manager->act_req);
-
-               nm_vpn_act_request_unref (manager->act_req);
-               manager->act_req = NULL;
+               if (!strcmp (device_path, nm_device_get_dbus_path       (device)))
+                       return device;
        }
 
-       manager->connections = g_slist_remove (manager->connections, vpn);
-       nm_vpn_connection_unref (vpn);
+       return NULL;
 }
 
+static gboolean
+impl_vpn_manager_connect (NMVPNManager *manager,
+                                        const char *type,
+                                        const char *name,
+                                        GHashTable *properties,
+                                        const char *device_path,
+                                        char **routes,
+                                        char **connection_path,
+                                        GError **err)
+{
+       NMDevice *device;
+       NMVPNConnection *connection;
+       GHashTable *properties_dup;
+       char **routes_dup;
+
+       device = find_device (manager, device_path);
+       if (!device)
+               return FALSE;
 
-/*
- * nm_vpn_manager_get_connection_names
- *
- * Return an array of strings of all the VPN Connection names
- * we know about.
- *
- */
-char **nm_vpn_manager_get_connection_names (NMVPNManager *manager)
-{
-       char            **names = NULL;
-       GSList   *elt;
-       int               i;
-
-       g_return_val_if_fail (manager != NULL, NULL);
-
-       names = g_malloc0 ((g_slist_length (manager->connections) + 1) * sizeof (char *));
-       for (elt = manager->connections, i = 0; elt; elt = g_slist_next (elt), i++)
-       {
-               NMVPNConnection *vpn_con = (NMVPNConnection *)(elt->data);
-               if (vpn_con)
-                       names[i] = g_strdup (nm_vpn_connection_get_name (vpn_con));
+       properties_dup = nm_utils_gvalue_hash_dup (properties);
+       routes_dup = g_strdupv (routes);
+
+       connection = nm_vpn_manager_connect (manager,
+                                                                 type, name,
+                                                                 device,
+                                                                 properties_dup,
+                                                                 routes_dup);
+       if (connection)
+               *connection_path = g_strdup (nm_vpn_connection_get_object_path (connection));
+       else {
+               g_hash_table_destroy (properties_dup);
+               g_strfreev (routes_dup);
        }
 
-       return names;
+       return *connection_path != NULL;
 }
 
-
-/*
- * nm_vpn_manager_get_vpn_act_request
- *
- * Return the VPN activation request, if any.
- *
- */
-NMVPNActRequest *nm_vpn_manager_get_vpn_act_request (NMVPNManager *manager)
-{
-       g_return_val_if_fail (manager != NULL, NULL);
-
-       return manager->act_req;
-}
-
-
 static void
-device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
+get_connections (gpointer data, gpointer user_data)
 {
-       NMVPNManager *manager = (NMVPNManager *) user_data;
+       NMVPNService *service = NM_VPN_SERVICE (data);
+       GSList **list = (GSList **) user_data;
 
-       if (state == NM_DEVICE_STATE_DISCONNECTED)
-               nm_vpn_manager_deactivate_vpn_connection (manager, device);
+       *list = g_slist_concat (*list, nm_vpn_service_get_connections (service));
 }
 
-
-/*
- * nm_vpn_manager_activate_vpn_connection
- *
- * Signal the VPN service daemon to activate a particular VPN connection,
- * launching that daemon if necessary.
- *
- */
-void nm_vpn_manager_activate_vpn_connection (NMVPNManager *manager, NMVPNConnection *vpn,
-                               char **password_items, int password_count, char **data_items, int data_count, char **user_routes, int user_routes_count)
+GSList *
+nm_vpn_manager_get_connections (NMVPNManager *manager)
 {
-       NMDevice *              parent_dev;
-       NMVPNActRequest *       req;
-       NMVPNService *          service;
-       const char *            service_name;
-
-       g_return_if_fail (manager != NULL);
-       g_return_if_fail (vpn != NULL);
-       g_return_if_fail (password_items != NULL);
-       g_return_if_fail (data_items != NULL);
-
-       if (nm_vpn_manager_get_vpn_act_request (manager))
-               nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (manager->act_req));
-
-       service_name = nm_vpn_connection_get_service_name (vpn);
-       if (!(service = nm_vpn_manager_find_service_by_name (manager, service_name)))
-               return;
-
-       if (!(parent_dev = nm_manager_get_active_device (manager->nm_manager)))
-       {
-               nm_warning ("nm_vpn_manager_activate_vpn_connection(): no currently active network device, won't activate VPN.");
-               return;
-       }
-
-       req = nm_vpn_act_request_new (manager, service, vpn, parent_dev, password_items, password_count, data_items, data_count,
-                                        user_routes, user_routes_count);
-       manager->act_req = req;
-
-       manager->device_signal_id = g_signal_connect (parent_dev, "state-changed",
-                                                                                                 G_CALLBACK (device_state_changed),
-                                                                                                 manager);
-
-       nm_vpn_service_start_connection (service, req);
-}
-
-
-/*
- * nm_vpn_manager_deactivate_vpn_connection
- *
- * Signal the VPN service daemon to deactivate a particular VPN connection.
- *
- */
-void nm_vpn_manager_deactivate_vpn_connection (NMVPNManager *manager, NMDevice *dev)
-{
-       NMVPNService *          service;
-       NMVPNConnection *       vpn;
-
-       g_return_if_fail (manager != NULL);
+       GSList *list = NULL;
 
-       if (!manager->act_req || (dev != nm_vpn_act_request_get_parent_dev (manager->act_req)))
-               return;
+       g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
 
-       if (manager->device_signal_id) {
-               g_signal_handler_disconnect (dev, manager->device_signal_id);
-               manager->device_signal_id = 0;
-       }
+       g_slist_foreach (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, get_connections, &list);
 
-       if (nm_vpn_act_request_is_activating (manager->act_req)
-               || nm_vpn_act_request_is_activated (manager->act_req)
-               || nm_vpn_act_request_is_failed (manager->act_req))
-       {
-               if (nm_vpn_act_request_is_activated (manager->act_req))
-               {
-                       vpn = nm_vpn_act_request_get_connection (manager->act_req);
-                       g_assert (vpn);
-                       nm_vpn_connection_deactivate (vpn);
-               }
-
-               service = nm_vpn_act_request_get_service (manager->act_req);
-               g_assert (service);
-               nm_vpn_service_stop_connection (service, manager->act_req);
-       }
-
-       nm_vpn_act_request_unref (manager->act_req);
-       manager->act_req = NULL;
+       return list;
 }
 
-
-static gboolean nm_vpn_manager_vpn_activation_failed (gpointer user_data)
+static gboolean
+impl_vpn_manager_get_connections (NMVPNManager *manager, GPtrArray **connections, GError **err)
 {
-       NMVPNActRequest *       req = (NMVPNActRequest *) user_data;
-       NMVPNManager *          manager;
-
-       g_assert (req);
+       GSList *list;
+       GSList *iter;
 
-       manager = nm_vpn_act_request_get_manager (req);
-       g_assert (manager);
+       list = nm_vpn_manager_get_connections (manager);
+       *connections = g_ptr_array_sized_new (g_slist_length (list));
 
-       if (manager->act_req == req)
-               nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (req));
-
-       return FALSE;
-}
+       for (iter = list; iter; iter = iter->next)
+               g_ptr_array_add (*connections,
+                                         g_strdup (nm_vpn_connection_get_object_path (NM_VPN_CONNECTION (iter->data))));
 
+       g_slist_free (list);
 
-void nm_vpn_manager_schedule_vpn_activation_failed (NMVPNManager *manager, NMVPNActRequest *req)
-{
-       g_return_if_fail (manager != NULL);
-       g_return_if_fail (req != NULL);
-
-       g_idle_add (nm_vpn_manager_vpn_activation_failed, req);
+       return TRUE;
 }
 
-
-static gboolean nm_vpn_manager_vpn_connection_died (gpointer user_data)
+NMVPNManager *
+nm_vpn_manager_new (NMManager *nm_manager)
 {
-       NMVPNActRequest *       req = (NMVPNActRequest *) user_data;
-       NMVPNManager *          manager;
-
-       g_assert (req);
+       NMVPNManager *manager;
 
-       manager = nm_vpn_act_request_get_manager (req);
-       g_assert (manager);
+       g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
 
-       if (manager->act_req == req)
-               nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (req));
+       manager = (NMVPNManager *) g_object_new (NM_TYPE_VPN_MANAGER, NULL);
+       if (manager)
+               NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_mgr = g_object_ref (nm_manager);
 
-       return FALSE;
+       return manager;
 }
 
+/******************************************************************************/
 
-void nm_vpn_manager_schedule_vpn_connection_died (NMVPNManager *manager, NMVPNActRequest *req)
+static void
+nm_vpn_manager_init (NMVPNManager *manager)
 {
-       g_return_if_fail (manager != NULL);
-       g_return_if_fail (req != NULL);
+       NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
 
-       g_idle_add (nm_vpn_manager_vpn_connection_died, req);
+       priv->dbus_mgr = nm_dbus_manager_get ();
+       dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr),
+                                                                 NM_DBUS_PATH_VPN,
+                                                                 G_OBJECT (manager));
 }
 
-
-/*********************************************************************/
-
-#define NAME_TAG "name="
-#define SERVICE_TAG "service="
-#define PROGRAM_TAG "program="
-
-static gboolean
-set_service_from_contents (char ** lines, NMVPNService * service, char **err)
+static void
+finalize (GObject *object)
 {
-       int                     i;
-       guint32         len = g_strv_length (lines);
-       gboolean        have_name = FALSE;
-       gboolean        have_service = FALSE;
-       gboolean        have_program = FALSE;
-
-       g_return_val_if_fail (err != NULL, FALSE);
-       g_return_val_if_fail (*err == NULL, FALSE);
-
-       for (i = 0; i < len; i++) {
-               char * line = lines[i];
-
-               /* Blank lines, or comment lines */
-               if (!line || !strlen (line) || (line[0] == '#'))
-                       continue;
-
-               if ((strncmp (line, NAME_TAG, strlen (NAME_TAG)) == 0)) {
-                       const char * name = line+strlen (NAME_TAG);
-
-                       if (have_name) {
-                               *err = "already parsed 'name' tag";
-                               return FALSE;
-                       }
-
-                       nm_vpn_service_set_name (service, name);
-                       have_name = TRUE;
-                       continue;
-               }
-
-               if ((strncmp (line, SERVICE_TAG, strlen (SERVICE_TAG)) == 0)) {
-                       const char * serv_name = line+strlen (SERVICE_TAG);
-
-                       /* Minimal service name sanity checking */
-                       if (have_service) {
-                               *err = "already parsed 'service' tag";
-                               return FALSE;
-                       }
-
-                       if (   !strcmp (serv_name, NM_DBUS_SERVICE)
-                           || !strcmp (serv_name, NMI_DBUS_SERVICE)) {
-                               *err = "service name is invalid";
-                               return FALSE;
-                       }
-
-                       nm_vpn_service_set_service_name (service, serv_name);
-                       have_service = TRUE;
-                       continue;
-               }
-
-               if ((strncmp (line, PROGRAM_TAG, strlen (PROGRAM_TAG)) == 0)) {
-                       const char * program = line+strlen (PROGRAM_TAG);
-
-                       if (have_program) {
-                               *err = "already parsed 'program' tag";
-                               return FALSE;
-                       }
-                       
-                       if (!g_path_is_absolute (program)) {
-                               *err = "path to program was not absolute";
-                               return FALSE;
-                       }
-
-                       if (!g_file_test (program,   G_FILE_TEST_EXISTS
-                                                  | G_FILE_TEST_IS_EXECUTABLE
-                                                  | G_FILE_TEST_IS_REGULAR )) {
-                               *err = "program does not exist, or is not executable";
-                               return FALSE;
-                       }
-
-                       nm_vpn_service_set_program (service, (const char *)(line+strlen (PROGRAM_TAG)));
-                       have_program = TRUE;
-                       continue;
-               }
-       }
+       NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object);
 
-       if (!have_name || !have_service || !have_program) {
-               *err = "didn't contain all required tags";
-               return FALSE;
-       }
+       g_slist_foreach (priv->services, (GFunc) g_object_unref, NULL);
+       g_object_unref (priv->dbus_mgr);
+       g_object_unref (priv->nm_mgr);
 
-       return TRUE;
+       G_OBJECT_CLASS (nm_vpn_manager_parent_class)->finalize (object);
 }
 
-
-struct dup_search_data {
-       const char * name;
-       const char * serv_name;
-       gboolean found;
-};
-
 static void
-find_dup_name (gpointer key, gpointer value, gpointer user_data)
+nm_vpn_manager_class_init (NMVPNManagerClass *manager_class)
 {
-       struct dup_search_data * data = (struct dup_search_data *) user_data;
-       NMVPNService * service = (NMVPNService *) value;
-       const char * serv_name = nm_vpn_service_get_service_name (service);
-       const char * name = nm_vpn_service_get_name (service);
-
-       /* already found a dupe, do nothing */
-       if (data->found)
-               return;
-
-       if (strcmp (serv_name, data->serv_name) == 0)
-               data->found = TRUE;
-       else if (strcmp (name, data->name) == 0)
-               data->found = TRUE;
-}
+       GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
 
+       g_type_class_add_private (manager_class, sizeof (NMVPNManagerPrivate));
 
-static void
-load_services (NMVPNManager *manager, GHashTable *table)
-{
-       GDir *          vpn_dir;
-       const char *file_name;
-
-       g_return_if_fail (manager != NULL);
-       g_return_if_fail (table != NULL);
-
-       /* Load allowed service names */
-       if (!(vpn_dir = g_dir_open (VPN_SERVICE_FILE_PATH, 0, NULL)))
-               return;
-
-       while ((file_name = g_dir_read_name (vpn_dir))) {
-               char *                  file_path;
-               char *                  contents;
-               char **                 lines;
-               NMVPNService *  service;
-               char *                  err = NULL;
-               gboolean                success;
-
-               file_path = g_strdup_printf (VPN_SERVICE_FILE_PATH"/%s", file_name);
-
-               /* Check for the .name extension */
-               if (strcmp (file_name + strlen (file_name) - 5, ".name") != 0) {
-                       nm_warning ("Error loading VPN service file '%s': doesn't "
-                                   "end with .name", file_path);
-                       goto free_file_path;
-               }
-
-               if (!g_file_get_contents (file_path, &contents, NULL, NULL))
-                       goto free_file_path;
-
-               lines = g_strsplit (contents, "\n", 0);
-               g_free (contents);
-               if (!lines)
-                       goto free_file_path;
-               service = nm_vpn_service_new (manager);
-               success = set_service_from_contents (lines, service, &err);
-               g_strfreev (lines);
-
-               if (!success) {
-                       nm_warning ("Error loading VPN service file '%s': %s.",
-                                   file_path, err);
-                       nm_vpn_service_unref (service);
-               } else {
-                       const char * serv_name = nm_vpn_service_get_service_name (service);
-                       const char * name = nm_vpn_service_get_name (service);
-                       struct dup_search_data dup_data = { name, serv_name, FALSE };
-
-                       /* Check for duplicates */
-                       g_hash_table_foreach (table, find_dup_name, &dup_data);
-                       if (dup_data.found) {
-                               nm_warning ("Ignoring duplicate VPN service '%s' (%s) from %s.",
-                                           name, serv_name, file_path);
-                       } else {
-                               /* All good, add it */
-                               nm_info ("New VPN service '%s' (%s).", name, serv_name);
-                               g_hash_table_insert (table, (char *) serv_name, service);
-                       }
-               }
-
-       free_file_path:
-               g_free (file_path);
-       }
+       /* virtual methods */
+       object_class->finalize = finalize;
 
-       g_dir_close (vpn_dir);
+       dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class),
+                                                          &dbus_glib_nm_vpn_manager_object_info);
 }
-
index 035c871..6337f2e 100644 (file)
@@ -1,51 +1,40 @@
-/* nm-vpn-manager.h - handle VPN connections within NetworkManager's framework 
- *
- * Copyright (C) 2005 Dan Williams
- *
- * 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.  
- */
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
 #ifndef NM_VPN_MANAGER_H
 #define NM_VPN_MANAGER_H
 
-#include <dbus/dbus.h>
-#include "nm-manager.h"
-#include "NetworkManagerMain.h"
+#include <glib/gtypes.h>
+#include <glib-object.h>
 #include "nm-vpn-connection.h"
-#include "nm-vpn-service.h"
+#include "nm-manager.h"
+
+#define NM_TYPE_VPN_MANAGER            (nm_vpn_manager_get_type ())
+#define NM_VPN_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_MANAGER, NMVPNManager))
+#define NM_VPN_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_MANAGER, NMVPNManagerClass))
+#define NM_IS_VPN_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_MANAGER))
+#define NM_IS_VPN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_MANAGER))
+#define NM_VPN_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_MANAGER, NMVPNManagerClass))
 
+typedef struct {
+       GObject parent;
+} NMVPNManager;
 
-NMVPNManager *         nm_vpn_manager_new                                              (NMManager *nm_manager);
-NMVPNConnection *      nm_vpn_manager_add_connection                           (NMVPNManager *manager, const char *name, const char *service_name, const char *user_name);
-void                           nm_vpn_manager_remove_connection                        (NMVPNManager *manager, NMVPNConnection *vpn);
-char   **                      nm_vpn_manager_get_connection_names             (NMVPNManager *manager);
-void                           nm_vpn_manager_dispose                                  (NMVPNManager *manager);
+typedef struct {
+       GObjectClass parent;
+} NMVPNManagerClass;
 
-NMVPNActRequest *      nm_vpn_manager_get_vpn_act_request                      (NMVPNManager *manager);
+GType nm_vpn_manager_get_type (void);
 
-GSList *                       nm_vpn_manager_vpn_connection_list_copy         (NMVPNManager *manager);
+NMVPNManager *nm_vpn_manager_new (NMManager *nm_manager);
 
-void                           nm_vpn_manager_activate_vpn_connection          (NMVPNManager *manager, NMVPNConnection *vpn, char **password_items,
-                                                                               int password_count, char **data_items, int data_count,
-                                                                               char **user_routes, int user_routes_count );
-void                           nm_vpn_manager_deactivate_vpn_connection        (NMVPNManager *manager, NMDevice *dev);
+NMVPNConnection *nm_vpn_manager_connect (NMVPNManager *manager,
+                                                                const char *type,
+                                                                const char *name,
+                                                                NMDevice *device,
+                                                                GHashTable *properties,
+                                                                char **routes);
 
-NMVPNConnection *      nm_vpn_manager_find_connection_by_name          (NMVPNManager *manager, const char *con_name);
-NMVPNService *         nm_vpn_manager_find_service_by_name             (NMVPNManager *manager, const char *service_name);
+GSList *nm_vpn_manager_get_connections (NMVPNManager *manager);
 
-void                           nm_vpn_manager_schedule_vpn_activation_failed(NMVPNManager *manager, NMVPNActRequest *req);
-void                           nm_vpn_manager_schedule_vpn_connection_died     (NMVPNManager *manager, NMVPNActRequest *req);
 
-#endif  /* NM_VPN_MANAGER_H */
+#endif /* NM_VPN_VPN_MANAGER_H */
index 606c750..177631e 100644 (file)
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
 /* NetworkManager -- Network link manager
  *
  * Dan Williams <dcbw@redhat.com>
 
 #include <glib.h>
 #include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
 #include <dbus/dbus.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <signal.h>
 #include <unistd.h>
 
-#include "nm-dbus-vpn.h"
 #include "nm-vpn-service.h"
-#include "nm-vpn-act-request.h"
-#include "nm-utils.h"
-#include "dbus-dict-helpers.h"
 #include "nm-dbus-manager.h"
+#include "nm-utils.h"
 
-/* define this for getting VPN debug messages */
-#undef NM_DEBUG_VPN_CONFIG
-
-struct NMVPNService
-{
-       int                             refcount;
-       NMVPNManager *  manager;
-       GPid                    pid;
-       guint32         sig_handler_id;
-       gulong                  watch_id;
-       gulong                  dbus_con_watch_id;
-       NMDBusManager * dbus_mgr;
-
-       char *                  name;
-       char *                  service;
-       char *                  program;
-       NMVPNServiceState       state;
-};
-
-
-static void nm_vpn_service_add_watch (NMVPNService *service);
-static void nm_vpn_service_remove_watch (NMVPNService *service);
-static void nm_vpn_service_stop_connection_internal (NMVPNService *service);
-
-static void nm_vpn_service_schedule_stage1_daemon_exec (NMVPNService *service, NMVPNActRequest *req);
-static void nm_vpn_service_schedule_stage3_connect (NMVPNService *service, NMVPNActRequest *req);
-static void nm_vpn_service_schedule_stage2_daemon_wait (NMVPNService *service, NMVPNActRequest *req);
-static void nm_vpn_service_schedule_stage4_ip_config_get_timeout (NMVPNService *service, NMVPNActRequest *req);
-static void nm_vpn_service_cancel_callback (NMVPNService *service, NMVPNActRequest *req);
-
-static gboolean nm_vpn_service_process_signal (DBusConnection *connection,
-                                               DBusMessage *message,
-                                               gpointer user_data);
-
-static void nm_vpn_service_name_owner_changed (NMDBusManager *mgr,
-                                               const char *name,
-                                               const char *old,
-                                               const char *new,
-                                               gpointer user_data);
-
-static void nm_vpn_service_dbus_connection_changed (NMDBusManager *mgr,
-                                                    DBusConnection *connection,
-                                                    gpointer user_data);
-
-#ifdef NM_DEBUG_VPN_CONFIG
-static void print_vpn_config (NMIP4Config *config,
-                                               const char *tundev,
-                                               const char *login_banner);
-#endif
-
-
-/*
- * nm_vpn_service_new
- *
- * Create a new VPNService object
- *
- */
-NMVPNService *nm_vpn_service_new (NMVPNManager *manager)
-{
-       NMVPNService *service = g_malloc0 (sizeof (NMVPNService));
-
-       service->refcount = 1;
-       service->state = NM_VPN_SERVICE_STATE_SHUTDOWN;
-       service->manager = manager;
-       service->dbus_mgr = nm_dbus_manager_get ();
-
-       return service;
-}
-
-void nm_vpn_service_ref (NMVPNService *service)
-{
-       g_return_if_fail (service != NULL);
-
-       service->refcount++;
-}
-
-
-void nm_vpn_service_unref (NMVPNService *service)
-{
-       g_return_if_fail (service != NULL);
-
-       service->refcount--;
-       if (service->refcount <= 0)
-       {
-               nm_vpn_service_remove_watch (service);
-               g_free (service->name);
-               g_free (service->service);
-               g_free (service->program);
-               g_object_unref (service->dbus_mgr);
-               memset (service, 0, sizeof (NMVPNService));
-               g_free (service);
-       }
-}
-
-
-const char *nm_vpn_service_get_name (NMVPNService *service)
-{
-       g_return_val_if_fail (service != NULL, NULL);
-
-       return service->name;
-}
-
-
-void nm_vpn_service_set_name (NMVPNService *service, const char *name)
-{
-       g_return_if_fail (service != NULL);
-
-       if (service->name)
-               g_free (service->name);
-       service->name = g_strdup (name);
-}
+G_DEFINE_TYPE (NMVPNService, nm_vpn_service, G_TYPE_OBJECT)
 
+typedef struct {
+       NMDBusManager *dbus_mgr;
+       char *name;
+       char *dbus_service;
+       char *program;
 
-const char *nm_vpn_service_get_service_name (NMVPNService *service)
-{
-       g_return_val_if_fail (service != NULL, NULL);
+       GPid pid;
+       GSList *connections;
+       guint service_start_timeout;
+       gulong name_owner_id;
+} NMVPNServicePrivate;
 
-       return service->service;
-}
+#define NM_VPN_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_SERVICE, NMVPNServicePrivate))
 
+#define VPN_CONNECTION_GROUP "VPN Connection"
 
-void nm_vpn_service_set_service_name (NMVPNService *service, const char *name)
+static GKeyFile *
+find_service_file (const char *name)
 {
-       g_return_if_fail (service != NULL);
+       GDir *dir;
+       const char *fn;
+       GKeyFile *key_file = NULL;
 
-       if (service->service)
-               g_free (service->service);
-       service->service = g_strdup (name);
-
-       /* If the VPN daemon is currently running, tell it to stop */
-       if (nm_dbus_manager_name_has_owner (service->dbus_mgr, service->service))
-               nm_vpn_service_stop_connection_internal (service);
-}
-
-
-const char *nm_vpn_service_get_program (NMVPNService *service)
-{
-       g_return_val_if_fail (service != NULL, NULL);
+       dir = g_dir_open (VPN_NAME_FILES_DIR, 0, NULL);
+       if (!dir)
+               return NULL;
 
-       return service->program;
-}
+       while ((fn = g_dir_read_name (dir))) {
+               char *path;
+               gboolean found = FALSE;
 
+               key_file = g_key_file_new ();
+               path = g_build_filename (VPN_NAME_FILES_DIR, fn, NULL);
 
-void nm_vpn_service_set_program (NMVPNService *service, const char *program)
-{
-       g_return_if_fail (service != NULL);
+               if (g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, NULL)) {
+                       gchar *val;
 
-       if (service->program)
-               g_free (service->program);
-       service->program = g_strdup (program);
-}
+                       val = g_key_file_get_string (key_file, VPN_CONNECTION_GROUP, "service", NULL);
+                       if (val) {
+                               if (!strcmp (val, name))
+                                       found = TRUE;
+                               g_free (val);
+                       }
+               }
 
+               g_free (path);
 
-NMVPNServiceState
-nm_vpn_service_get_state (NMVPNService *service)
-{
-       g_return_val_if_fail (service != NULL, NM_VPN_SERVICE_STATE_UNKNOWN);
+               if (found)
+                       break;
 
-       return service->state;
-}
+               g_key_file_free (key_file);
+               key_file = NULL;
+       }
 
+       g_dir_close (dir);
 
-static void
-nm_vpn_service_set_state (NMVPNService *service,
-                          const NMVPNServiceState state)
-{
-       g_return_if_fail (service != NULL);
-
-       service->state = state;
+       return key_file;
 }
 
-
-/*
- * construct_op_from_service_name
- *
- * Construct an object path from a dbus service name by replacing
- * all "." in the service with "/" and prepending a "/" to the
- * object path.
- *
- */
-static char *construct_op_from_service_name (const char *service_name)
+NMVPNService *
+nm_vpn_service_new (const char *name)
 {
-       char **split = NULL;
-       char *temp1;
-       char *temp2;
+       GKeyFile *key_file;
+       NMVPNService *service;
+       NMVPNServicePrivate *priv;
+       char *dbus_service = NULL;
+       char *program = NULL;
+       gboolean success = FALSE;
 
-       g_return_val_if_fail (service_name != NULL, NULL);
+       g_return_val_if_fail (name != NULL, NULL);
 
-       if (!(split = g_strsplit (service_name, ".", 0)))
+       key_file = find_service_file (name);
+       if (!key_file)
                return NULL;
 
-       temp1 = g_strjoinv ("/", split);
-       g_strfreev (split);
-       temp2 = g_strdup_printf ("/%s", temp1);
-       g_free (temp1);
-
-       return temp2;
-}
+       dbus_service = g_key_file_get_string (key_file, VPN_CONNECTION_GROUP, "service", NULL);
+       if (!dbus_service)
+               goto out;
 
+       program = g_key_file_get_string (key_file, VPN_CONNECTION_GROUP, "program", NULL);
+       if (!program)
+               goto out;
 
-/*
- * nm_vpn_service_act_request_failed
- *
- * Clean up after an activation request and tell the VPN manager that it
- * has failed.
- *
- */
-static void
-nm_vpn_service_act_request_failed (NMVPNService *service,
-                                   NMVPNActRequest *req)
-{
-       NMVPNConnection *vpn;
+       service = (NMVPNService *) g_object_new (NM_TYPE_VPN_SERVICE, NULL);
+       if (!service)
+               goto out;
 
-       g_return_if_fail (service != NULL);
-       g_return_if_fail (req != NULL);
+       priv = NM_VPN_SERVICE_GET_PRIVATE (service);
 
-       /* Sanity checks */
-       if (nm_vpn_act_request_get_service (req) != service)
-               return;
+       priv->name = g_strdup (name);
+       priv->dbus_service = dbus_service;
+       priv->program = program;
 
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
+       success = TRUE;
 
-       nm_vpn_service_cancel_callback (service, req);
+ out:
+       g_key_file_free (key_file);
 
-       nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_FAILED);
-       nm_info ("VPN Activation (%s) failed.", nm_vpn_connection_get_name (vpn));
+       if (!success) {
+               g_free (dbus_service);
+               g_free (program);
+       }
 
-       nm_vpn_act_request_unref (req);
-       nm_vpn_manager_schedule_vpn_activation_failed (service->manager, req);  
+       return service;
 }
 
-
-static void
-nm_vpn_service_activation_success (NMVPNService *service,
-                                   NMVPNActRequest *req)
+const char *
+nm_vpn_service_get_name (NMVPNService *service)
 {
-       NMVPNConnection *       vpn = NULL;
-
-       g_assert (service != NULL);
-       g_assert (req != NULL);
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
+       g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
 
-       nm_vpn_service_cancel_callback (service, req);
-
-       nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_ACTIVATED);
-       nm_info ("VPN Activation (%s) successful.", nm_vpn_connection_get_name (vpn));
+       return NM_VPN_SERVICE_GET_PRIVATE (service)->name;
 }
 
-
-/*
- * nm_vpn_service_start_connection
- *
- * Kick off the VPN connection process.
- *
- */
-void
-nm_vpn_service_start_connection (NMVPNService *service,
-                                 NMVPNActRequest *req)
+static void
+nm_vpn_service_connections_stop (NMVPNService *service, gboolean fail)
 {
-       g_return_if_fail (service != NULL);
-       g_return_if_fail (req != NULL);
-
-       nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_PREPARE);
-       nm_vpn_service_add_watch (service);
+       NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+       GSList *iter;
 
-       /* Start the daemon if it's not already running */
-       nm_vpn_act_request_ref (req);
-       if (!nm_dbus_manager_name_has_owner (service->dbus_mgr, service->service))
-               nm_vpn_service_schedule_stage1_daemon_exec (service, req);
-       else
-               nm_vpn_service_schedule_stage2_daemon_wait (service, req);
+       for (iter = priv->connections; iter; iter = iter->next)
+               fail ? nm_vpn_connection_fail (NM_VPN_CONNECTION (iter->data)) 
+                       : nm_vpn_connection_disconnect (NM_VPN_CONNECTION (iter->data));
 }
 
-
 /*
  * nm_vpn_service_child_setup
  *
@@ -327,1073 +174,254 @@ nm_vpn_service_child_setup (gpointer user_data G_GNUC_UNUSED)
        setpgid (pid, pid);
 }
 
-
-/*
- * nm_vpn_service_stage_1_daemon_exec
- *
- * Execute the VPN service daemon.
- *
- */
-static gboolean nm_vpn_service_stage1_daemon_exec (gpointer user_data)
-{
-       NMVPNActRequest *       req = (NMVPNActRequest *) user_data;
-       NMVPNService *          service;
-       NMVPNConnection *       vpn = NULL;
-       GPtrArray *             vpn_argv;
-       GError *                        error = NULL;
-       gboolean                launched = FALSE;
-
-       g_assert (req != NULL);
-
-       service = nm_vpn_act_request_get_service (req);
-       g_assert (service != NULL);
-       g_assert (service->program != NULL);
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
-
-       nm_vpn_act_request_set_callback_id (req, 0);
-
-       vpn_argv = g_ptr_array_new ();
-       g_ptr_array_add (vpn_argv, service->program);
-       g_ptr_array_add (vpn_argv, NULL);
-
-       launched = g_spawn_async (NULL,
-                                 (char **) vpn_argv->pdata,
-                                 NULL,
-                                 0,
-                                 &nm_vpn_service_child_setup,
-                                 NULL,
-                                 &service->pid,
-                                 &error);
-       if (!launched) {
-               g_ptr_array_free (vpn_argv, TRUE);
-               nm_warning ("(VPN Service %s): could not launch the VPN service.  "
-                           "error: '%s'.",
-                           service->service,
-                           error->message);
-               g_error_free (error);
-               nm_vpn_service_act_request_failed (service, req);
-               goto out;
-       }
-       g_ptr_array_free (vpn_argv, TRUE);
-       nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) ran VPN "
-                "service daemon %s (PID %d)",
-                nm_vpn_connection_get_name (vpn),
-                service->service,
-                service->pid);
-       nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) complete.",
-                nm_vpn_connection_get_name (vpn));
-
-       nm_vpn_service_schedule_stage2_daemon_wait (service, req);
-
-out:
-       return FALSE;
-}
-
-
 static void
-nm_vpn_service_schedule_stage1_daemon_exec (NMVPNService *service,
-                                            NMVPNActRequest *req)
-{
-       NMVPNConnection * vpn = NULL;
-       guint             id;
-
-       g_assert (service != NULL);
-       g_assert (req != NULL);
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
+vpn_service_watch_cb (GPid pid, gint status, gpointer user_data)
+{
+       NMVPNService *service = NM_VPN_SERVICE (user_data);
+       NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+
+       if (WIFEXITED (status)) {
+               guint err = WEXITSTATUS (status);
+
+               if (err != 0)
+                       nm_warning ("VPN service '%s' exited with error: %d",
+                                         nm_vpn_service_get_name (service), WSTOPSIG (status));
+       } else if (WIFSTOPPED (status))
+               nm_warning ("VPN service '%s' stopped unexpectedly with signal %d",
+                                 nm_vpn_service_get_name (service), WSTOPSIG (status));
+       else if (WIFSIGNALED (status))
+               nm_warning ("VPN service '%s' died with signal %d",
+                                 nm_vpn_service_get_name (service), WTERMSIG (status));
+       else
+               nm_warning ("VPN service '%s' died from an unknown cause", 
+                                 nm_vpn_service_get_name (service));
 
-       nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_PREPARE);
-       nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_SHUTDOWN);
+       /* Reap child if needed. */
+       waitpid (pid, NULL, WNOHANG);
+       priv->pid = 0;
 
-       id = g_idle_add (nm_vpn_service_stage1_daemon_exec, req);
-       nm_vpn_act_request_set_callback_id (req, id);
-       nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) scheduled...",
-                nm_vpn_connection_get_name (vpn));
+       nm_vpn_service_connections_stop (service, TRUE);
 }
 
-
-/*
- * nm_vpn_service_stage2_daemon_wait
- *
- * Wait until the VPN daemon has become active.
- *
- */
 static gboolean
-nm_vpn_service_stage2_daemon_wait (gpointer user_data)
+nm_vpn_service_timeout (gpointer data)
 {
-       NMVPNActRequest *       req = (NMVPNActRequest *) user_data;
-       NMVPNService *          service;
-       NMVPNConnection *       vpn = NULL;
-       gboolean                        service_exists = FALSE;
-
-       g_assert (req != NULL);
-
-       service = nm_vpn_act_request_get_service (req);
-       g_assert (service != NULL);
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
-
-       nm_vpn_act_request_set_callback_id (req, 0);
-
-       nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) "
-                               "waiting...", nm_vpn_connection_get_name (vpn));
-
-       service_exists = nm_dbus_manager_name_has_owner (service->dbus_mgr,
-                                                        service->service);
-       if (service_exists && (service->state == NM_VPN_SERVICE_STATE_STOPPED)) {
-               nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) "
-                               "complete.", nm_vpn_connection_get_name (vpn));
-               nm_vpn_service_schedule_stage3_connect (service, req);
-       } else if (nm_vpn_act_request_get_daemon_wait_count (req) > 10) {
-               /* We only wait 2s (10 * 200 milliseconds) for the service to
-                * become available.
-                */
-               nm_vpn_service_act_request_failed (service, req);
-       } else {
-               nm_vpn_service_schedule_stage2_daemon_wait (service, req);
-       }
-
-       return FALSE;
-}
-
-
-static void
-nm_vpn_service_schedule_stage2_daemon_wait (NMVPNService *service,
-                                            NMVPNActRequest *req)
-{
-       NMVPNConnection * vpn = NULL;
-       guint             id;
-
-       g_assert (service != NULL);
-       g_assert (req != NULL);
+       NMVPNService *service = NM_VPN_SERVICE (data);
 
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
+       nm_info ("VPN service '%s' did not start in time, cancelling connections",
+                   nm_vpn_service_get_name (service));
 
-       nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_PREPARE);
+       NM_VPN_SERVICE_GET_PRIVATE (service)->service_start_timeout = 0;
+       nm_vpn_service_connections_stop (service, TRUE);
 
-       nm_vpn_act_request_set_daemon_wait_count (req, nm_vpn_act_request_get_daemon_wait_count (req) + 1);
-
-       id = g_timeout_add (200, nm_vpn_service_stage2_daemon_wait, req);
-       nm_vpn_act_request_set_callback_id (req, id);
-       nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) "
-                "scheduled...",
-                nm_vpn_connection_get_name (vpn));
+       return FALSE;
 }
 
-
-static void
-nm_vpn_service_stage3_connect_cb (DBusPendingCall *pcall,
-                                  void *user_data)
+static gboolean
+nm_vpn_service_daemon_exec (gpointer user_data)
 {
-       DBusMessage *           reply;
-       NMVPNActRequest *       req = (NMVPNActRequest *) user_data;
-       NMVPNService *          service;
-       NMVPNConnection *       vpn;
+       NMVPNService *service = NM_VPN_SERVICE (user_data);
+       NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+       GPtrArray *vpn_argv;
+       gboolean launched;
+       GError *err = NULL;
 
-       g_assert (pcall != NULL);
-       g_assert (req != NULL);
-
-       service = nm_vpn_act_request_get_service (req);
-       g_assert (service != NULL);
+       vpn_argv = g_ptr_array_new ();
+       g_ptr_array_add (vpn_argv, priv->program);
+       g_ptr_array_add (vpn_argv, NULL);
 
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
+       launched = g_spawn_async (NULL,
+                                 (char **) vpn_argv->pdata,
+                                 NULL,
+                                 0,
+                                 nm_vpn_service_child_setup,
+                                 NULL,
+                                 &priv->pid,
+                                 &err);
 
-       nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) reply received.",
-                       nm_vpn_connection_get_name (vpn));
+       g_ptr_array_free (vpn_argv, TRUE);
 
-       if (!(reply = dbus_pending_call_steal_reply (pcall))) {
-               nm_warning ("(VPN Service %s): could not obtain VPN service's reply.",
-                               service->service);
-               nm_vpn_service_act_request_failed (service, req);
-               goto out;
-       }
+       if (launched) {
+               GSource *vpn_watch;
 
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               const char *member = dbus_message_get_member (reply);
-               char *message;
+               vpn_watch = g_child_watch_source_new (priv->pid);
+               g_source_set_callback (vpn_watch, (GSourceFunc) vpn_service_watch_cb, service, NULL);
+               g_source_attach (vpn_watch, NULL);
+               g_source_unref (vpn_watch);
 
-               if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &message, NULL))
-                       message = (char *) "";
+               nm_info ("VPN service '%s' executed (%s), PID %d", 
+                           nm_vpn_service_get_name (service),
+                           priv->dbus_service,
+                           priv->pid);
 
-               nm_warning ("(VPN Service %s): could not start the VPN '%s'.  dbus says: '%s'  '%s'.", 
-                                       service->service, nm_vpn_connection_get_name (vpn), member, message);
-               nm_vpn_service_act_request_failed (service, req);
+               priv->service_start_timeout = g_timeout_add (2000, nm_vpn_service_timeout, service);
        } else {
-               nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_IP_CONFIG_GET);
-               nm_vpn_service_schedule_stage4_ip_config_get_timeout (service, req);
-               nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) complete, "
-                               "waiting for IP configuration...", nm_vpn_connection_get_name (vpn));
-       }
-
-       dbus_message_unref (reply);
-
-out:
-       dbus_pending_call_unref (pcall);
-}
-
-
-static char **
-sanitize_dbus_string_array (char **in_array, dbus_uint32_t *in_num)
-{
-       char ** out_array;
-
-       g_return_val_if_fail (in_num != NULL, NULL);
-
-       if (in_array)
-               return in_array;
-
-       out_array = g_malloc0 (sizeof (char *));
-       out_array[0] = g_strdup ("");
-       *in_num = 1;
-       return out_array;
-}
-
-
-static gboolean nm_vpn_service_stage3_connect (gpointer user_data)
-{
-       NMVPNActRequest *       req = (NMVPNActRequest *) user_data;
-       NMVPNService *          service;
-       NMVPNConnection *       vpn;
-       char *                  op;
-       const char *            name;
-       const char *            user_name;
-       char **                 password_items;
-       dbus_uint32_t           password_count;
-       char **                 data_items;
-       dbus_uint32_t           data_count;
-       char **                 user_routes;
-       dbus_uint32_t           user_routes_count = 0;
-       DBusMessage *           message;
-       DBusPendingCall *       pcall = NULL;
-       DBusConnection *        dbus_connection;
-       gboolean                        success = FALSE;
-
-       g_assert (req != NULL);
-
-       service = nm_vpn_act_request_get_service (req);
-       g_assert (service != NULL);
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn != NULL);
-
-       dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("VPN Activation (%s) Stage 3 of 4 (Connect) could not get "
-                           "the DBus connection.",
-                           nm_vpn_connection_get_name (vpn));
-               goto out;
-       }
-
-       nm_vpn_act_request_set_callback_id (req, 0);
-
-       /* Send the start vpn request to the daemon */
-       op = construct_op_from_service_name (service->service);
-       message = dbus_message_new_method_call (service->service,
-                                               op,
-                                               service->service,
-                                               "startConnection");
-       g_free (op);
-       if (!message) {
-               nm_warning ("VPN Activation (%s) Stage 3 of 4 (Connect): couldn't "
-                           " allocate dbus message.",
-                           service->service);
-               goto out;
-       }
+               nm_warning ("VPN service '%s': could not launch the VPN service. error: '%s'.",
+                           nm_vpn_service_get_name (service), err->message);
+               g_error_free (err);
 
-       name = nm_vpn_connection_get_name (vpn);
-       user_name = nm_vpn_connection_get_user_name (vpn);
-       password_items = (char **) nm_vpn_act_request_get_password_items (req, &password_count);
-       data_items = (char **) nm_vpn_act_request_get_data_items (req, &data_count);
-       user_routes = (char **) nm_vpn_act_request_get_user_routes(req, &user_routes_count);
-
-       /* Ensure that data_items and user_routes are safe to put through dbus */
-       data_items = sanitize_dbus_string_array (data_items, &data_count);
-       user_routes = sanitize_dbus_string_array (user_routes, &user_routes_count);
-
-       nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) sending connect request.",
-                       nm_vpn_connection_get_name (vpn));
-       dbus_message_append_args (message, DBUS_TYPE_STRING, &name,
-                                 DBUS_TYPE_STRING, &user_name,
-                                 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &password_items, password_count,
-                                 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &data_items, data_count,
-                                 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &user_routes, user_routes_count,
-                                 DBUS_TYPE_INVALID);
-
-       dbus_connection_send_with_reply (dbus_connection, message, &pcall, -1);
-       if (pcall) {
-               dbus_pending_call_set_notify (pcall,
-                                             nm_vpn_service_stage3_connect_cb,
-                                             req,
-                                             NULL);
-               nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) request sent,"
-                        " waiting for reply...",
-                        nm_vpn_connection_get_name (vpn));
-               success = TRUE;
+               nm_vpn_service_connections_stop (service, TRUE);
        }
-       dbus_message_unref (message);
-
-out:
-       if (!success)
-               nm_vpn_service_act_request_failed (service, req);
 
        return FALSE;
 }
 
-
-static void
-nm_vpn_service_schedule_stage3_connect (NMVPNService *service,
-                                        NMVPNActRequest *req)
-{
-       NMVPNConnection * vpn = NULL;
-       guint             id;
-
-       g_assert (service != NULL);
-       g_assert (req != NULL);
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
-
-       nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_CONNECT);
-
-       id = g_idle_add (nm_vpn_service_stage3_connect, req);
-       nm_vpn_act_request_set_callback_id (req, id);
-       nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) scheduled...",
-                nm_vpn_connection_get_name (vpn));
-}
-
-
 static gboolean
-nm_vpn_service_stage4_ip_config_get_timeout (gpointer user_data)
+destroy_service (gpointer data)
 {
-       NMVPNActRequest *       req = (NMVPNActRequest *) user_data;
-       NMVPNService *          service;
-       NMVPNConnection *       vpn;
-
-       g_assert (req != NULL);
-
-       service = nm_vpn_act_request_get_service (req);
-       g_assert (service != NULL);
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn != NULL);
-
-       nm_vpn_act_request_set_callback_id (req, 0);
-
-       /* If the activation request's state is still IP_CONFIG_GET and we're
-        * in this timeout, cancel activation because it's taken too long.
-        */
-       if (nm_vpn_act_request_get_state (req) == NM_VPN_CONNECTION_STATE_IP_CONFIG_GET) {
-               nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) timeout "
-                        "exceeded.",
-                        nm_vpn_connection_get_name (vpn));
-               nm_vpn_service_act_request_failed (service, req);
-       }
+       g_object_unref (data);
 
        return FALSE;
 }
 
-
 static void
-nm_vpn_service_schedule_stage4_ip_config_get_timeout (NMVPNService *service,
-                                                      NMVPNActRequest *req)
+connection_state_changed (NMVPNConnection *connection, NMVPNConnectionState state, gpointer user_data)
 {
-       NMVPNConnection * vpn = NULL;
-       guint             id;
-
-       g_assert (service != NULL);
-       g_assert (req != NULL);
+       NMVPNServicePrivate *priv;
 
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
+       switch (state) {
+       case NM_VPN_CONNECTION_STATE_FAILED:
+       case NM_VPN_CONNECTION_STATE_DISCONNECTED:
+               /* Remove the connection from our list */
+               priv = NM_VPN_SERVICE_GET_PRIVATE (user_data);
+               priv->connections = g_slist_remove (priv->connections, connection);
+               g_object_unref (connection);
 
-       nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_IP_CONFIG_GET);
-
-       /* 20 second timeout waiting for IP config signal from VPN service */
-       id = g_timeout_add (20000, nm_vpn_service_stage4_ip_config_get_timeout, req);
-       nm_vpn_act_request_set_callback_id (req, id);
-       nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) timeout "
-                " scheduled...",
-                nm_vpn_connection_get_name (vpn));
+               if (priv->connections == NULL) {
+                       /* schedule a timeout (10 seconds) to destroy the service */
+                       g_timeout_add (10000, destroy_service, user_data);
+               }
+               break;
+       default:
+               break;
+       }
 }
 
-
-static void nm_vpn_service_cancel_callback (NMVPNService *service, NMVPNActRequest *req)
+NMVPNConnection *
+nm_vpn_service_activate (NMVPNService *service,
+                                       const char *name,
+                                       NMDevice *device,
+                                       GHashTable *properties,
+                                       char **routes)
 {
-       guint     id;
+       NMVPNConnection *connection;
+       NMVPNServicePrivate *priv;
 
-       g_return_if_fail (service != NULL);
-       g_return_if_fail (req != NULL);
+       g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
+       g_return_val_if_fail (name != NULL, NULL);
+       g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+       g_return_val_if_fail (properties != NULL, NULL);
 
-       if ((id = nm_vpn_act_request_get_callback_id (req)) == 0)
-               return;
+       priv = NM_VPN_SERVICE_GET_PRIVATE (service);
 
-       g_source_destroy (g_main_context_find_source_by_id (NULL, id));
-       nm_vpn_act_request_set_callback_id (req, 0);
-}
+       connection = nm_vpn_connection_new (name, priv->dbus_service, device, properties, routes);
+       g_signal_connect (connection, "state-changed",
+                                  G_CALLBACK (connection_state_changed),
+                                  service);
 
+       priv->connections = g_slist_prepend (priv->connections, connection);
 
-static gboolean
-get_dbus_guint32_helper (DBusMessageIter *iter,
-                         guint32 *num,
-                                       char *desc)
-{
-       if (!dbus_message_iter_next (iter)
-           || (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_UINT32))
-       {
-               nm_warning ("Error: couldn't get %s from VPN IP Config message.", desc);
-               return FALSE;
+       if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, priv->dbus_service))
+               nm_vpn_connection_activate (connection);
+       else if (priv->service_start_timeout == 0) {
+               nm_info ("VPN service '%s' exec scheduled...", nm_vpn_service_get_name (service));
+               g_idle_add (nm_vpn_service_daemon_exec, service);
        }
-       dbus_message_iter_get_basic (iter, num);
-       return TRUE;
-}
 
-static gboolean
-get_dbus_string_helper (DBusMessageIter *iter,
-                        char **str,
-                        char *desc)
-{
-       if (!dbus_message_iter_next (iter)
-           || (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRING))
-       {
-               nm_warning ("Error: couldn't get %s from VPN IP Config message.", desc);
-               return FALSE;
-       }
-       dbus_message_iter_get_basic (iter, str);
-       return TRUE;
+       return connection;
 }
 
-
-/*
- * nm_vpn_service_stage4_ip4_config_get_old
- *
- * Configure a device with IPv4 config info in response the the VPN daemon.
- *
- */
-static void
-nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
-                                          NMVPNActRequest *req,
-                                          DBusConnection *dbus_connection,
-                                          DBusMessage *message)
+GSList *
+nm_vpn_service_get_connections (NMVPNService *service)
 {
-       NMVPNConnection *       vpn;
-       guint32                 num;
-       char *                  str;
-       char *                  tundev;
-       char *                  login_banner;
-       gboolean                        success = FALSE;
-       DBusMessageIter iter;
-       DBusMessageIter subiter;
-       NMIP4Config *           config = NULL;
-       NMDevice *              parent_dev;
-
-       g_return_if_fail (service != NULL);
-       g_return_if_fail (message != NULL);
-       g_return_if_fail (req != NULL);
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
-
-       nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) reply received.",
-               nm_vpn_connection_get_name (vpn));
-
-       config = nm_ip4_config_new ();
-       nm_ip4_config_set_secondary (config, TRUE);
-
-       dbus_message_iter_init (message, &iter);
-
-       /* First arg: IP4 VPN Gateway address (UINT32) */
-       if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32) {
-               nm_warning ("Error: couldn't get IP4 VPN Gateway Address"
-                         " from VPN IP Config message.");
-               goto out;
-       }
-       dbus_message_iter_get_basic (&iter, &num);
-       nm_ip4_config_set_gateway (config, num);
-
-       /* Second arg: Tunnel device, if any (STRING) */
-       if (!get_dbus_string_helper (&iter, &tundev, "Tunnel Device"))
-               goto out;
-
-       /* Third arg: IP4 VPN Local Address (UINT32) */
-       if (!get_dbus_guint32_helper (&iter, &num, "IP4 VPN Local Address"))
-               goto out;
-       nm_ip4_config_set_address (config, num);
-
-       /* Fourth arg: IP4 VPN Point-to-Point Address (UINT32) */
-       if (!get_dbus_guint32_helper (&iter, &num, "IP4 VPN PtP Address"))
-               goto out;
-       nm_ip4_config_set_ptp_address (config, num);
-
-       /* Fifth arg: IP4 VPN Local Netmask (UINT32) */
-       if (!get_dbus_guint32_helper (&iter, &num, "IP4 VPN Local Netmask"))
-               goto out;
-       /* If no netmask, default to Class C address */
-       nm_ip4_config_set_netmask (config, num ? num : 0x00FF);
-
-       /* Sixth arg: IP4 DNS Server Addresses (ARRAY, UINT32) */
-       if (   !dbus_message_iter_next (&iter)
-           || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)) {
-               nm_warning ("Error: couldn't get IP4 DNS Server Addresses"
-                         " from VPN IP Config message.");
-               goto out;
-       }
-       dbus_message_iter_recurse (&iter, &subiter);
-       while (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_UINT32) {
-               dbus_message_iter_get_basic (&subiter, &num);
-               if (num)
-                       nm_ip4_config_add_nameserver (config, num);
-               dbus_message_iter_next (&subiter);
-       }
-
-       /* Seventh arg: IP4 NBNS Server Addresses (ARRAY, UINT32) */
-       if (   !dbus_message_iter_next (&iter)
-           || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)) {
-               nm_warning ("Error: couldn't get IP4 NBNS Server Addresses"
-                         " from VPN IP Config message.");
-               goto out;
-       }
-       dbus_message_iter_recurse (&iter, &subiter);
-       while (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_UINT32) {
-               dbus_message_iter_get_basic (&subiter, &num);
-               /* We don't do anything with these yet */
-               dbus_message_iter_next (&subiter);
-       }
-
-       /* Eighth arg: MSS (UINT32) */
-       if (!get_dbus_guint32_helper (&iter, &num, "MSS"))
-               goto out;
-       nm_ip4_config_set_mss (config, num);
-       
-       /* Ninth arg: DNS Domain (STRING) */
-       if (!get_dbus_string_helper (&iter, &str, "DNS Domain"))
-               goto out;
-       if (strlen (str))
-               nm_ip4_config_add_domain (config, str);
+       g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
 
-       /* Tenth arg: VPN Login Banner (STRING) */
-       if (!get_dbus_string_helper (&iter, &login_banner, "Login Banner"))
-               goto out;
-
-#ifdef NM_DEBUG_VPN_CONFIG
-       print_vpn_config (config, tundev, login_banner);
-#endif
-
-       if (!(parent_dev = nm_vpn_act_request_get_parent_dev (req)))
-               goto out;
-
-       if (nm_vpn_connection_set_config (vpn, tundev, parent_dev, config)) {
-               nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) complete.",
-                               nm_vpn_connection_get_name (vpn));
-               if (login_banner && strlen (login_banner)) {
-                       nm_dbus_vpn_signal_vpn_login_banner (dbus_connection,
-                                                            vpn,
-                                                            login_banner);
-               }
-               success = TRUE;
-               nm_vpn_service_activation_success (service, req);
-       }
-
-out:
-       if (!success) {
-               g_object_unref (config);
-               nm_warning ("(VPN Service %s): did not receive valid IP config "
-                           "information.",
-                           service->service);
-               nm_vpn_service_act_request_failed (service, req);
-       }
+       return g_slist_copy (NM_VPN_SERVICE_GET_PRIVATE (service)->connections);
 }
 
-
-#define HANDLE_DICT_ITEM(in_key, in_type, in_ary_type, op) \
-       if (!strcmp (entry.key, in_key)) { \
-               if (entry.type != in_type) { \
-                       nm_warning (in_key "had invalid type in VPN IP Config message."); \
-               } else { \
-                       if (in_type == DBUS_TYPE_ARRAY && entry.array_type != in_ary_type) { \
-                               nm_warning (in_key "had invalid type in VPN IP Config message."); \
-                       } else { \
-                               op \
-                       } \
-               } \
-               goto next; \
-       }
-
-
-/*
- * nm_vpn_service_stage4_ip4_config_get
- *
- * Configure a device with IPv4 config info in response the the VPN daemon.
- *
- */
 static void
-nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
-                                     NMVPNActRequest *req,
-                                     DBusMessage *message)
+nm_vpn_service_name_owner_changed (NMDBusManager *mgr,
+                                                       const char *name,
+                                                       const char *old,
+                                                       const char *new,
+                                                       gpointer user_data)
 {
-       NMVPNConnection *       vpn;
-       char *                  tundev = NULL;
-       char *                  login_banner = NULL;
-       gboolean                        success = FALSE;
-       DBusMessageIter iter;
-       DBusMessageIter iter_dict;
-       NMIP4Config *           config = NULL;
-       NMDevice *              parent_dev;
-       NMUDictEntry            entry = { .type = DBUS_TYPE_STRING };
-       DBusConnection *dbus_connection;
-
-       g_return_if_fail (service != NULL);
-       g_return_if_fail (message != NULL);
-       g_return_if_fail (req != NULL);
-
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
-
-       nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) reply received.",
-               nm_vpn_connection_get_name (vpn));
-
-       dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
-       if (!dbus_connection) {
-               nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) could not "
-                        "get the DBus connection.",
-                        nm_vpn_connection_get_name (vpn));
-               goto out;
-       }
-
-       dbus_message_iter_init (message, &iter);
+       NMVPNService *service = NM_VPN_SERVICE (user_data);
+       NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+       gboolean old_owner_good;
+       gboolean new_owner_good;
 
-       /* If first arg is (UINT32) then this is an old type message */
-       if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_UINT32) {
-               nm_warning ("Warning: VPN plugin is using the old IP4Config message type");
-               nm_vpn_service_stage4_ip4_config_get_old (service,
-                                                         req,
-                                                         dbus_connection,
-                                                         message);
+       if (strcmp (name, priv->dbus_service))
                return;
-       }
 
-       if (!nmu_dbus_dict_open_read (&iter, &iter_dict)) {
-               nm_warning ("Warning: couldn't get config dictionary"
-                           " from VPN IP Config message.");
-               goto out;
+       /* Service changed, no need to wait for the timeout any longer */
+       if (priv->service_start_timeout) {
+               g_source_remove (priv->service_start_timeout);
+               priv->service_start_timeout = 0;
        }
 
-       config = nm_ip4_config_new ();
-       nm_ip4_config_set_secondary (config, TRUE);
+       old_owner_good = (old && (strlen (old) > 0));
+       new_owner_good = (new && (strlen (new) > 0));
 
-       /* First arg: Dict Type */
-       if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) {
-               nm_warning ("Error: couldn't get configuration dict"
-                         " from VPN IP Config message.");
-               goto out;
-       }
-
-       while (nmu_dbus_dict_has_dict_entry (&iter_dict)) {
-               int i;
-
-               if (!nmu_dbus_dict_get_entry (&iter_dict, &entry)) {
-                       nm_warning ("Error: couldn't read dict entry"
-                                   " from VPN IP Config message.");
-                       goto out;
-               }
-
-               /* IP specific options */
-               HANDLE_DICT_ITEM("gateway", DBUS_TYPE_UINT32, 0,
-                       { nm_ip4_config_set_gateway (config, entry.uint32_value); });
-               HANDLE_DICT_ITEM("local_addr", DBUS_TYPE_UINT32, 0,
-                       { nm_ip4_config_set_address (config, entry.uint32_value); });
-               HANDLE_DICT_ITEM("ptp_addr", DBUS_TYPE_UINT32, 0,
-                       { nm_ip4_config_set_ptp_address (config, entry.uint32_value); });
-               /* If no netmask, default to Class C address */
-               HANDLE_DICT_ITEM("local_netmask", DBUS_TYPE_UINT32, 0,
-                       { nm_ip4_config_set_netmask (config,  entry.uint32_value ? entry.uint32_value : 0x00FF); });
-               /* Multiple DNS servers are allowed */
-               HANDLE_DICT_ITEM("dns_server", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
-                       {
-                               for (i = 0; i < entry.array_len; i++)
-                                       nm_ip4_config_add_nameserver (config, entry.uint32array_value[i]);
-                       });
-               /* Multiple NBNS servers are allowed */
-               HANDLE_DICT_ITEM("nbns_server", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
-                       {
-                               for (i = 0; i < entry.array_len; i++) {
-                                       /* We don't do anything with these yet */
-                               }
-                       });
-               /* Generic options */
-               HANDLE_DICT_ITEM("mss", DBUS_TYPE_UINT32, 0,
-                       { nm_ip4_config_set_mss (config, entry.uint32_value); });
-               HANDLE_DICT_ITEM("mtu", DBUS_TYPE_UINT32, 0,
-                       { nm_ip4_config_set_mtu (config, entry.uint32_value); });
-               HANDLE_DICT_ITEM("tundev", DBUS_TYPE_STRING, 0,
-                       { if (strlen (entry.str_value)) tundev = g_strdup (entry.str_value); });
-               HANDLE_DICT_ITEM("dns_domain", DBUS_TYPE_STRING, 0,
-                       { if (strlen (entry.str_value)) nm_ip4_config_add_domain (config, entry.str_value); });
-               HANDLE_DICT_ITEM("login_banner", DBUS_TYPE_STRING, 0,
-                       { if (strlen (entry.str_value)) login_banner = g_strdup (entry.str_value); });
-
-       next:
-               nmu_dbus_dict_entry_clear (&entry);
-       };
-
-#ifdef NM_DEBUG_VPN_CONFIG
-       print_vpn_config (config, tundev, login_banner);
-#endif
-
-       if (!(parent_dev = nm_vpn_act_request_get_parent_dev (req)))
-               goto out;
-
-       if (nm_vpn_connection_set_config (vpn, tundev, parent_dev, config)) {
-               nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) complete.",
-                               nm_vpn_connection_get_name (vpn));
-               if (login_banner && strlen (login_banner)) {
-                       nm_dbus_vpn_signal_vpn_login_banner (dbus_connection,
-                                                            vpn,
-                                                            login_banner);
-               }
-               success = TRUE;
-               nm_vpn_service_activation_success (service, req);
-       }
-
-out:
-       if (tundev) g_free (tundev);
-       if (login_banner) g_free (login_banner);
-       if (!success) {
-               if (config)
-                       g_object_unref (config);
-               nm_warning ("(VPN Service %s): did not receive valid IP config "
-                           "information.",
-                           service->service);
-               nm_vpn_service_act_request_failed (service, req);
-       }
-}
-
-
-static void
-nm_vpn_service_stop_connection_internal (NMVPNService *service)
-{
-       DBusConnection *        dbus_connection;
-
-       g_return_if_fail (service != NULL);
-
-       dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
-       if (dbus_connection) {
-               DBusMessage *   message;
-               char *                  op;
-
-               /* Construct a new method call with the correct service and object path */
-               op = construct_op_from_service_name (service->service);
-               message = dbus_message_new_method_call (service->service,
-                                                       op,
-                                                       service->service,
-                                                       "stopConnection");
-               g_free (op);
-               if (!message) {
-                       nm_warning ("(VPN Service %s): couldn't allocate dbus message.",
-                                   service->service);
-               } else {
-                       dbus_connection_send (dbus_connection, message, NULL);
-                       dbus_message_unref (message);
-               }
-       } else {
-               /* If we have the PID of the VPN service daemon, send it a TERM */
-               if (service->pid) {
-                       kill (service->pid, SIGTERM);
-                       service->pid = 0;
-               } else {
-                       nm_warning ("(VPN Service %s): stop called, but did not have PID "
-                                   "for VPN service daemon.",
-                                   service->service);
-               }
-       }
-}
-
-
-void
-nm_vpn_service_stop_connection (NMVPNService *service,
-                                NMVPNActRequest *req)
-{
-       NMVPNConnection *vpn;
-
-       g_return_if_fail (service != NULL);
-       g_return_if_fail (req != NULL);
+       if (!old_owner_good && new_owner_good) {
+               /* service just appeared */
+               GSList *iter;
 
-       vpn = nm_vpn_act_request_get_connection (req);
-       g_assert (vpn);
+               nm_info ("VPN service '%s' just appeared, activating connections",
+                           nm_vpn_service_get_name (service));
 
-       nm_vpn_service_cancel_callback (service, req);
-       nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_DISCONNECTED);
+               for (iter = priv->connections; iter; iter = iter->next)
+                       nm_vpn_connection_activate (NM_VPN_CONNECTION (iter->data));
 
-       /* Ensure we can stop the connection in this state */
-       if (   (service->state != NM_VPN_SERVICE_STATE_STARTED)
-           && (service->state != NM_VPN_SERVICE_STATE_STARTING)) {
-               nm_warning ("(VPN Service %s): could not stop connection '%s' because "
-                           " service was %d.", 
-                           service->service,
-                                       nm_vpn_connection_get_name (vpn),
-                                       service->state);
-               return;
+       } else if (old_owner_good && !new_owner_good) {
+               /* service went away */
+               nm_info ("VPN service '%s' disappeared, cancelling connections",
+                           nm_vpn_service_get_name (service));
+               nm_vpn_service_connections_stop (service, TRUE);
        }
-
-       nm_vpn_service_stop_connection_internal (service);
-       nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_STOPPED);
-}
-
-
-static void
-nm_vpn_service_add_watch (NMVPNService *service)
-{
-       guint32 id;
-
-       g_return_if_fail (service != NULL);
-
-       if (service->watch_id)
-               return;
-
-       /* Add a dbus filter for this connection's service name so its signals
-        * get delivered to us.
-        */
-       id = nm_dbus_manager_register_signal_handler (service->dbus_mgr,
-                                                     service->service,
-                                                     NULL,
-                                                     nm_vpn_service_process_signal,
-                                                     service);
-       service->sig_handler_id = id;
-       service->watch_id = g_signal_connect (service->dbus_mgr,
-                                             "name-owner-changed",
-                                             G_CALLBACK (nm_vpn_service_name_owner_changed),
-                                             service);
-       service->dbus_con_watch_id = g_signal_connect (service->dbus_mgr,
-                                                      "dbus-connection-changed",
-                                                      G_CALLBACK (nm_vpn_service_dbus_connection_changed),
-                                                      service);
 }
 
+/******************************************************************************/
 
 static void
-nm_vpn_service_remove_watch (NMVPNService *service)
+nm_vpn_service_init (NMVPNService *service)
 {
-       g_return_if_fail (service != NULL);
+       NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
 
-       if (!service->watch_id)
-               return;
-
-       nm_dbus_manager_remove_signal_handler (service->dbus_mgr, service->sig_handler_id);
-       g_signal_handler_disconnect (service->dbus_mgr, service->watch_id);
-       service->watch_id = 0;
-       g_signal_handler_disconnect (service->dbus_mgr, service->dbus_con_watch_id);
-       service->dbus_con_watch_id = 0;
-}
-
-
-static inline gboolean same_service_name (NMVPNService *service, NMVPNConnection *vpn)
-{
-       g_return_val_if_fail (service != NULL, FALSE);
-       g_return_val_if_fail (vpn != NULL, FALSE);
-
-       return (!strcmp (nm_vpn_service_get_service_name (service), nm_vpn_connection_get_service_name (vpn)));
+       priv->dbus_mgr = nm_dbus_manager_get ();
+       
+       priv->name_owner_id = g_signal_connect (priv->dbus_mgr, "name-owner-changed",
+                                                                       G_CALLBACK (nm_vpn_service_name_owner_changed),
+                                                                       service);
 }
 
 static void
-nm_vpn_service_dbus_connection_changed (NMDBusManager *mgr,
-                                        DBusConnection *dbus_connection,
-                                        gpointer user_data)
+finalize (GObject *object)
 {
-       NMVPNService *  service = (NMVPNService *) user_data;
+       NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (object);
 
-       g_return_if_fail (service != NULL);
+       if (priv->service_start_timeout)
+               g_source_remove (priv->service_start_timeout);
 
-       if (!dbus_connection) {
-               NMVPNActRequest *       req;
-               NMVPNConnection *       vpn;
-               gboolean                        valid_vpn = FALSE;
+       nm_vpn_service_connections_stop (NM_VPN_SERVICE (object), FALSE);
 
-               /* Kill the VPN service since we can't talk to it anymore anyway */
-               nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_SHUTDOWN);
-               nm_vpn_service_remove_watch (service);
+       g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id);
+       g_object_unref (priv->dbus_mgr);
 
-               req = nm_vpn_manager_get_vpn_act_request (service->manager);
-               if (req && (vpn = nm_vpn_act_request_get_connection (req)))
-                       valid_vpn = same_service_name (service, vpn);
+       g_free (priv->name);
+       g_free (priv->dbus_service);
+       g_free (priv->program);
 
-               if (valid_vpn) {
-                       nm_vpn_act_request_unref (req);
-                       nm_vpn_manager_schedule_vpn_connection_died (service->manager, req);
-               }
-       }
+       G_OBJECT_CLASS (nm_vpn_service_parent_class)->finalize (object);
 }
 
 static void
-nm_vpn_service_name_owner_changed (NMDBusManager *mgr,
-                                   const char *name,
-                                   const char *old,
-                                   const char *new,
-                                   gpointer user_data)
+nm_vpn_service_class_init (NMVPNServiceClass *service_class)
 {
-       NMVPNService *          service = (NMVPNService *) user_data;
-       NMVPNActRequest *       req;
-       NMVPNConnection *       vpn;
-       gboolean                        valid_vpn = FALSE;
-       gboolean                        old_owner_good = (old && strlen (old));
-       gboolean                        new_owner_good = (new && strlen (new));
-
-       g_return_if_fail (service != NULL);
-
-       if (strcmp (name, service->service) != 0)
-               return;
+       GObjectClass *object_class = G_OBJECT_CLASS (service_class);
 
-       req = nm_vpn_manager_get_vpn_act_request (service->manager);
-       if (req && (vpn = nm_vpn_act_request_get_connection (req)))
-               valid_vpn = same_service_name (service, vpn);
+       g_type_class_add_private (service_class, sizeof (NMVPNServicePrivate));
 
-       if (!old_owner_good && new_owner_good) {
-               /* VPN service started. */
-               nm_vpn_service_add_watch (service);
-               nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_INIT);
-       } else if (old_owner_good && !new_owner_good) {
-               /* VPN service went away. */
-               nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_SHUTDOWN);
-               nm_vpn_service_remove_watch (service);
-
-               if (valid_vpn) {
-                       nm_vpn_act_request_unref (req);
-                       nm_vpn_manager_schedule_vpn_connection_died (service->manager, req);
-               }
-       }
-}
-
-
-static gboolean
-nm_vpn_service_process_signal (DBusConnection *connection,
-                               DBusMessage *message,
-                               gpointer user_data)
-{
-       NMVPNService *          service = (NMVPNService *) user_data;
-       NMVPNConnection *       vpn = NULL;
-       NMVPNActRequest *       req;
-       gboolean                        valid_vpn = FALSE;
-
-       g_return_val_if_fail (connection != NULL, FALSE);
-       g_return_val_if_fail (message != NULL, FALSE);
-       g_return_val_if_fail (service != NULL, FALSE);
-
-       req = nm_vpn_manager_get_vpn_act_request (service->manager);
-       if (req && (vpn = nm_vpn_act_request_get_connection (req)))
-               valid_vpn = same_service_name (service, vpn);
-
-       if (   dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED)
-           || dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED)
-           || dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED)
-           || dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD)
-           || dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
-       {
-               const char *    member = dbus_message_get_member (message);
-               char *          error_msg;
-
-               if (valid_vpn) {
-                       if (!dbus_message_get_args (message,
-                                                   NULL,
-                                                   DBUS_TYPE_STRING, &error_msg,
-                                                   DBUS_TYPE_INVALID)) {
-                               error_msg = (char *) "";
-                       }
-                       nm_warning ("VPN failed for service '%s', signal '%s', with "
-                                   " message '%s'.",
-                                   service->service,
-                                   member,
-                                   error_msg);
-                       nm_dbus_vpn_signal_vpn_failed (connection, member, vpn, error_msg);
-
-                       /* Don't deal with VPN Connection stopping here, we'll do that
-                        * when we get the STOPPED or STOPPING signal below.
-                        */
-               }
-       } else if (dbus_message_is_signal (message, service->service,
-                                          NM_DBUS_VPN_SIGNAL_STATE_CHANGE)) {
-               dbus_uint32_t old_state_int;
-               dbus_uint32_t new_state_int;
-
-               if (dbus_message_get_args (message,
-                                          NULL,
-                                          DBUS_TYPE_UINT32, &old_state_int,
-                                          DBUS_TYPE_UINT32, &new_state_int,
-                                          DBUS_TYPE_INVALID)) {
-                       NMVPNServiceState old_state = (NMVPNServiceState) old_state_int;
-                       NMVPNServiceState new_state = (NMVPNServiceState) new_state_int;
-
-                       nm_info ("VPN service '%s' signaled state change %d -> %d.",
-                                service->service,
-                                old_state,
-                                new_state);
-                       nm_vpn_service_set_state (service, new_state);
-
-                       /* If the VPN daemon state is now stopped and it was starting, 
-                        * clear the active connection.
-                        */
-                       if (   (   (new_state == NM_VPN_SERVICE_STATE_STOPPED)
-                               || (new_state == NM_VPN_SERVICE_STATE_SHUTDOWN)
-                               || (new_state == NM_VPN_SERVICE_STATE_STOPPING))
-                           && (   (old_state == NM_VPN_SERVICE_STATE_STARTED)
-                               || (old_state == NM_VPN_SERVICE_STATE_STARTING))
-                               && valid_vpn) {
-                               nm_vpn_act_request_unref (req);
-                               nm_vpn_manager_schedule_vpn_connection_died (service->manager, req);
-                       }
-               }
-       } else if (   valid_vpn
-                  && dbus_message_is_signal (message, service->service,
-                                             NM_DBUS_VPN_SIGNAL_IP4_CONFIG)) {
-               nm_vpn_service_stage4_ip4_config_get (service, req, message);
-       }
-
-       return TRUE;
-}
-
-#ifdef NM_DEBUG_VPN_CONFIG
-/*
- *  Prints config returned from the service daemo
- */
-static void print_vpn_config (NMIP4Config *config,
-                              const char *tundev,
-                                               const char *login_banner)
-{
-       struct in_addr  temp_addr;
-       char *          dns_domain = NULL;
-       guint32         num;
-       guint32                 i;
-
-       g_return_if_fail (config != NULL);
-
-       temp_addr.s_addr = nm_ip4_config_get_gateway (config);
-       nm_info ("VPN Gateway: %s", inet_ntoa (temp_addr));
-       nm_info ("Tunnel Device: %s", tundev);
-       temp_addr.s_addr = nm_ip4_config_get_address (config);
-       nm_info ("Internal IP4 Address: %s", inet_ntoa (temp_addr));
-       temp_addr.s_addr = nm_ip4_config_get_netmask (config);
-       nm_info ("Internal IP4 Netmask: %s", inet_ntoa (temp_addr));
-       temp_addr.s_addr = nm_ip4_config_get_ptp_address (config);
-       nm_info ("Internal IP4 Point-to-Point Address: %s", inet_ntoa (temp_addr));
-       nm_info ("Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (config));
-
-       num = nm_ip4_config_get_num_nameservers (config);
-       for (i = 1; i <= num; i++)
-       {
-               temp_addr.s_addr = nm_ip4_config_get_nameserver (config, i);
-               nm_info ("Internal IP4 DNS: %s", inet_ntoa (temp_addr));
-       }
-
-       if (nm_ip4_config_get_num_domains (config) > 0)
-               dns_domain = (char *) nm_ip4_config_get_domain (config, 1);
-       nm_info ("DNS Domain: '%s'", dns_domain ? dns_domain : "(none)");
-       nm_info ("Login Banner:");
-       nm_info ("-----------------------------------------");
-       nm_info ("%s", login_banner);
-       nm_info ("-----------------------------------------");
+       /* virtual methods */
+       object_class->finalize = finalize;
 }
-
-#endif
index f45afc5..8ca2070 100644 (file)
@@ -1,54 +1,39 @@
-/* NetworkManager -- Network link manager
- *
- * Dan Williams <dcbw@redhat.com>
- *
- * 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.
- *
- * (C) Copyright 2005 Red Hat, Inc.
- */
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
 
 #ifndef NM_VPN_SERVICE_H
 #define NM_VPN_SERVICE_H
 
-
-#include <dbus/dbus.h>
-#include "NetworkManager.h"
-#include "NetworkManagerVPN.h"
-#include "NetworkManagerMain.h"
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include "nm-device.h"
 #include "nm-vpn-connection.h"
 
-typedef struct NMVPNService NMVPNService;
-
-
-NMVPNService * nm_vpn_service_new                              (NMVPNManager *manager);
+#define NM_TYPE_VPN_SERVICE            (nm_vpn_service_get_type ())
+#define NM_VPN_SERVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_SERVICE, NMVPNService))
+#define NM_VPN_SERVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_SERVICE, NMVPNServiceClass))
+#define NM_IS_VPN_SERVICE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_SERVICE))
+#define NM_IS_VPN_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_SERVICE))
+#define NM_VPN_SERVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_SERVICE, NMVPNServiceClass))
 
-void                   nm_vpn_service_ref                              (NMVPNService *service);
-void                   nm_vpn_service_unref                    (NMVPNService *service);
+typedef struct {
+       GObject parent;
+} NMVPNService;
 
-const char *   nm_vpn_service_get_name                 (NMVPNService *service);
-void                   nm_vpn_service_set_name                 (NMVPNService *service, const char *name);
+typedef struct {
+       GObjectClass parent;
+} NMVPNServiceClass;
 
-const char *   nm_vpn_service_get_service_name (NMVPNService *service);
-void                   nm_vpn_service_set_service_name (NMVPNService *service, const char *name);
+GType nm_vpn_service_get_type (void);
 
-const char *   nm_vpn_service_get_program              (NMVPNService *service);
-void                   nm_vpn_service_set_program              (NMVPNService *service, const char *program);
+NMVPNService    *nm_vpn_service_new      (const char *service_name);
+const char      *nm_vpn_service_get_name (NMVPNService *service);
 
-NMVPNServiceState      nm_vpn_service_get_state        (NMVPNService *service);
+NMVPNConnection *nm_vpn_service_activate (NMVPNService *service,
+                                                                 const char *name,
+                                                                 NMDevice *device,
+                                                                 GHashTable *properties,
+                                                                 char **routes);
 
-void                   nm_vpn_service_start_connection (NMVPNService *service, NMVPNActRequest *req);
-void                   nm_vpn_service_stop_connection  (NMVPNService *service, NMVPNActRequest *req);
+GSList   *nm_vpn_service_get_connections (NMVPNService *service);
 
-#endif
+#endif  /* NM_VPN_VPN_SERVICE_H */
index aede93f..2f13ca1 100644 (file)
@@ -4,7 +4,6 @@ INCLUDES = -I${top_srcdir}                    \
            -I${top_srcdir}/libnm-util         \
            -I${top_srcdir}/libnm-glib         \
            -I${top_srcdir}/gnome/libnm_glib   \
-           -I${top_srcdir}/utils              \
            -I${top_srcdir}/include
 
 AM_CPPFLAGS =                                          \
@@ -28,16 +27,15 @@ nm_tool_LDADD =     $(DBUS_LIBS) $(GTHREAD_LIBS) $(HAL_LIBS)        \
 
 nm_online_SOURCES = nm-online.c
 nm_online_LDADD =      $(DBUS_LIBS) $(GTHREAD_LIBS) $(HAL_LIBS)        \
-               $(top_builddir)/utils/libnmutils.la
+               $(top_builddir)/libnm-util/libnm-util.la
 
 nmtestdevices_SOURCES = nmtestdevices.c
 nmtestdevices_LDADD =  $(DBUS_LIBS) $(GTHREAD_LIBS)    \
-                       $(top_builddir)/utils/libnmutils.la
+                       $(top_builddir)/libnm-util/libnm-util.la
 
 libnm_glib_test_SOURCES = libnm_glib_test.c
 libnm_glib_test_LDADD =        $(DBUS_LIBS) $(GTHREAD_LIBS) \
                        $(top_builddir)/libnm-glib/libnm_glib.la \
-                       $(top_builddir)/utils/libnmutils.la \
                        $(top_builddir)/libnm-util/libnm-util.la
 
 nm_supplicant_test_SOURCES = nm-supplicant-test.c