From 33491bc4279481db8ae47213e34a6d695a0e8830 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Sun, 6 Jul 2014 02:16:10 +0200 Subject: Imported Upstream version 0.9.10.0 --- libnm-glib/Makefile.am | 33 +- libnm-glib/Makefile.in | 143 +++- libnm-glib/libnm-glib-test.c | 10 +- libnm-glib/libnm-glib-vpn.ver | 1 + libnm-glib/libnm-glib.pc.in | 2 +- libnm-glib/libnm-glib.ver | 47 ++ libnm-glib/libnm_glib.c | 6 +- libnm-glib/nm-access-point.c | 29 +- libnm-glib/nm-access-point.h | 1 + libnm-glib/nm-active-connection.c | 351 ++++++++- libnm-glib/nm-active-connection.h | 31 +- libnm-glib/nm-client.c | 467 ++++++----- libnm-glib/nm-client.h | 26 +- libnm-glib/nm-dbus-helpers-private.h | 38 + libnm-glib/nm-dbus-helpers.c | 107 +++ libnm-glib/nm-device-adsl.c | 20 +- libnm-glib/nm-device-bond.c | 36 +- libnm-glib/nm-device-bridge.c | 36 +- libnm-glib/nm-device-bt.c | 28 +- libnm-glib/nm-device-ethernet.c | 35 +- libnm-glib/nm-device-ethernet.h | 4 +- libnm-glib/nm-device-generic.c | 289 +++++++ libnm-glib/nm-device-generic.h | 81 ++ libnm-glib/nm-device-infiniband.c | 35 +- libnm-glib/nm-device-modem.c | 59 +- libnm-glib/nm-device-olpc-mesh.c | 32 +- libnm-glib/nm-device-team.c | 356 +++++++++ libnm-glib/nm-device-team.h | 85 ++ libnm-glib/nm-device-vlan.c | 49 +- libnm-glib/nm-device-vlan.h | 2 + libnm-glib/nm-device-wifi.c | 123 +-- libnm-glib/nm-device-wifi.h | 1 + libnm-glib/nm-device-wimax.c | 112 +-- libnm-glib/nm-device-wimax.h | 1 + libnm-glib/nm-device.c | 786 +++++++++++++++++-- libnm-glib/nm-device.h | 48 +- libnm-glib/nm-dhcp4-config.c | 31 +- libnm-glib/nm-dhcp6-config.c | 31 +- libnm-glib/nm-glib-enum-types.c | 122 +++ libnm-glib/nm-glib-enum-types.h | 12 + libnm-glib/nm-glib-marshal.c | 204 ----- libnm-glib/nm-glib-marshal.h | 44 -- libnm-glib/nm-ip4-config.c | 213 +++-- libnm-glib/nm-ip4-config.h | 10 +- libnm-glib/nm-ip6-config.c | 248 ++++-- libnm-glib/nm-ip6-config.h | 22 +- libnm-glib/nm-object-private.h | 17 +- libnm-glib/nm-object.c | 526 ++++++------- libnm-glib/nm-object.h | 2 + libnm-glib/nm-remote-connection.c | 509 +++++++++--- libnm-glib/nm-remote-connection.h | 63 +- libnm-glib/nm-remote-settings.c | 550 ++++++++++--- libnm-glib/nm-remote-settings.h | 27 + libnm-glib/nm-secret-agent.c | 167 ++-- libnm-glib/nm-secret-agent.h | 23 +- libnm-glib/nm-types.c | 3 +- libnm-glib/nm-vpn-connection.c | 19 +- libnm-glib/nm-vpn-enum-types.c | 1 + libnm-glib/nm-vpn-plugin-ui-interface.h | 8 +- libnm-glib/nm-vpn-plugin.c | 311 +++++--- libnm-glib/nm-vpn-plugin.h | 41 +- libnm-glib/nm-wimax-nsp.c | 14 +- libnm-glib/tests/Makefile.am | 36 +- libnm-glib/tests/Makefile.in | 105 ++- libnm-glib/tests/test-fake-nm.py | 776 ++++++++++++++++++ libnm-glib/tests/test-nm-client.c | 953 +++++++++++++++++++++++ libnm-glib/tests/test-remote-settings-client.c | 24 +- libnm-glib/tests/test-remote-settings-service.py | 37 +- 68 files changed, 6807 insertions(+), 1852 deletions(-) create mode 100644 libnm-glib/nm-dbus-helpers-private.h create mode 100644 libnm-glib/nm-dbus-helpers.c create mode 100644 libnm-glib/nm-device-generic.c create mode 100644 libnm-glib/nm-device-generic.h create mode 100644 libnm-glib/nm-device-team.c create mode 100644 libnm-glib/nm-device-team.h delete mode 100644 libnm-glib/nm-glib-marshal.c delete mode 100644 libnm-glib/nm-glib-marshal.h create mode 100755 libnm-glib/tests/test-fake-nm.py create mode 100644 libnm-glib/tests/test-nm-client.c (limited to 'libnm-glib') diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 410848af..623bf45d 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -6,7 +6,11 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util + -I$(top_builddir)/libnm-util \ + -DG_LOG_DOMAIN=\""libnm-glib"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) BUILT_SOURCES = \ nm-vpn-plugin-glue.h \ @@ -26,8 +30,6 @@ libdeprecated_nm_glib_la_SOURCES = \ libnm_glib.c libdeprecated_nm_glib_la_CPPFLAGS = \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ $(AM_CPPFLAGS) \ -Wno-deprecated-declarations \ -Wno-deprecated @@ -48,7 +50,8 @@ lib_LTLIBRARIES = libnm-glib.la libnm-glib-vpn.la libnm_glib_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(GUDEV_CFLAGS) + $(GUDEV_CFLAGS) \ + -DNMRUNDIR=\"$(nmrundir)\" libnmincludedir = $(includedir)/libnm-glib libnmvpndir = $(includedir)/libnm-glib @@ -64,8 +67,10 @@ libnminclude_HEADERS = \ nm-device-bt.h \ nm-device-olpc-mesh.h \ nm-device-bond.h \ + nm-device-team.h \ nm-device-bridge.h \ nm-device-vlan.h \ + nm-device-generic.h \ nm-access-point.h \ nm-ip4-config.h \ nm-device-modem.h \ @@ -90,6 +95,7 @@ libnmvpn_HEADERS = \ libnm_glib_la_csources = \ nm-object.c \ + nm-dbus-helpers.c \ nm-client.c \ nm-device.c \ nm-device-ethernet.c \ @@ -99,8 +105,10 @@ libnm_glib_la_csources = \ nm-device-bt.c \ nm-device-olpc-mesh.c \ nm-device-bond.c \ + nm-device-team.c \ nm-device-bridge.c \ nm-device-vlan.c \ + nm-device-generic.c \ nm-access-point.c \ nm-ip4-config.c \ nm-device-modem.c \ @@ -116,8 +124,7 @@ libnm_glib_la_csources = \ nm-secret-agent.c \ nm-device-wimax.c \ nm-wimax-nsp.c \ - nm-glib-enum-types.c \ - nm-glib-marshal.c + nm-glib-enum-types.c libnm_glib_la_private_headers = \ nm-object-private.h \ @@ -125,7 +132,7 @@ libnm_glib_la_private_headers = \ nm-types-private.h \ nm-object-cache.h \ nm-remote-connection-private.h \ - nm-glib-marshal.h + nm-dbus-helpers-private.h libnm_glib_la_SOURCES = \ $(libnm_glib_la_csources) \ @@ -136,9 +143,6 @@ nm_glib_enum_types_sources = $(libnminclude_HEADERS) GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -GLIB_GENERATED += nm-glib-marshal.h nm-glib-marshal.c -nm_glib_marshal_sources = $(libnm_glib_la_SOURCES) - libnm_glib_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(builddir)/libdeprecated-nm-glib.la \ @@ -149,7 +153,7 @@ libnm_glib_la_LIBADD = \ SYMBOL_VIS_FILE=$(srcdir)/libnm-glib.ver libnm_glib_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "10:0:6" + -version-info "12:0:8" noinst_PROGRAMS = libnm-glib-test @@ -168,7 +172,7 @@ nm_vpn_enum_types_sources = $(libnmvpn_HEADERS) 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) libnm_glib_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib-vpn.ver \ - -version-info "2:0:1" + -version-info "3:0:2" BUILT_SOURCES += $(GLIB_GENERATED) @@ -180,10 +184,11 @@ libnm_glib_test_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ $(GUDEV_CFLAGS) \ - -DLIBNM_GLIB_TEST + -DLIBNM_GLIB_TEST \ + -DNMRUNDIR=\"$(nmrundir)\" libnm_glib_test_la_SOURCES = \ - $(li0bnminclude_HEADERS) \ + $(libnminclude_HEADERS) \ $(libnm_glib_la_SOURCES) libnm_glib_test_la_LIBADD = \ diff --git a/libnm-glib/Makefile.in b/libnm-glib/Makefile.in index e726df56..4b169f40 100644 --- a/libnm-glib/Makefile.in +++ b/libnm-glib/Makefile.in @@ -90,7 +90,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp $(libdeprecated_HEADERS) \ $(libnminclude_HEADERS) $(libnmvpn_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -154,7 +155,9 @@ am__v_lt_1 = libnm_glib_test_la_DEPENDENCIES = \ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__objects_1 = libnm_glib_test_la-nm-object.lo \ +am__objects_1 = +am__objects_2 = libnm_glib_test_la-nm-object.lo \ + libnm_glib_test_la-nm-dbus-helpers.lo \ libnm_glib_test_la-nm-client.lo \ libnm_glib_test_la-nm-device.lo \ libnm_glib_test_la-nm-device-ethernet.lo \ @@ -164,8 +167,10 @@ am__objects_1 = libnm_glib_test_la-nm-object.lo \ libnm_glib_test_la-nm-device-bt.lo \ libnm_glib_test_la-nm-device-olpc-mesh.lo \ libnm_glib_test_la-nm-device-bond.lo \ + libnm_glib_test_la-nm-device-team.lo \ libnm_glib_test_la-nm-device-bridge.lo \ libnm_glib_test_la-nm-device-vlan.lo \ + libnm_glib_test_la-nm-device-generic.lo \ libnm_glib_test_la-nm-access-point.lo \ libnm_glib_test_la-nm-ip4-config.lo \ libnm_glib_test_la-nm-device-modem.lo \ @@ -181,11 +186,9 @@ am__objects_1 = libnm_glib_test_la-nm-object.lo \ libnm_glib_test_la-nm-secret-agent.lo \ libnm_glib_test_la-nm-device-wimax.lo \ libnm_glib_test_la-nm-wimax-nsp.lo \ - libnm_glib_test_la-nm-glib-enum-types.lo \ - libnm_glib_test_la-nm-glib-marshal.lo -am__objects_2 = -am__objects_3 = $(am__objects_1) $(am__objects_2) -am_libnm_glib_test_la_OBJECTS = $(am__objects_3) + libnm_glib_test_la-nm-glib-enum-types.lo +am__objects_3 = $(am__objects_2) $(am__objects_1) +am_libnm_glib_test_la_OBJECTS = $(am__objects_1) $(am__objects_3) libnm_glib_test_la_OBJECTS = $(am_libnm_glib_test_la_OBJECTS) libnm_glib_test_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -206,15 +209,18 @@ libnm_glib_vpn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ libnm_glib_la_DEPENDENCIES = $(top_builddir)/libnm-util/libnm-util.la \ $(builddir)/libdeprecated-nm-glib.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__objects_4 = libnm_glib_la-nm-object.lo libnm_glib_la-nm-client.lo \ +am__objects_4 = libnm_glib_la-nm-object.lo \ + libnm_glib_la-nm-dbus-helpers.lo libnm_glib_la-nm-client.lo \ libnm_glib_la-nm-device.lo libnm_glib_la-nm-device-ethernet.lo \ libnm_glib_la-nm-device-infiniband.lo \ libnm_glib_la-nm-device-adsl.lo \ libnm_glib_la-nm-device-wifi.lo libnm_glib_la-nm-device-bt.lo \ libnm_glib_la-nm-device-olpc-mesh.lo \ libnm_glib_la-nm-device-bond.lo \ + libnm_glib_la-nm-device-team.lo \ libnm_glib_la-nm-device-bridge.lo \ libnm_glib_la-nm-device-vlan.lo \ + libnm_glib_la-nm-device-generic.lo \ libnm_glib_la-nm-access-point.lo \ libnm_glib_la-nm-ip4-config.lo \ libnm_glib_la-nm-device-modem.lo \ @@ -228,9 +234,8 @@ am__objects_4 = libnm_glib_la-nm-object.lo libnm_glib_la-nm-client.lo \ libnm_glib_la-nm-remote-settings.lo \ libnm_glib_la-nm-secret-agent.lo \ libnm_glib_la-nm-device-wimax.lo libnm_glib_la-nm-wimax-nsp.lo \ - libnm_glib_la-nm-glib-enum-types.lo \ - libnm_glib_la-nm-glib-marshal.lo -am_libnm_glib_la_OBJECTS = $(am__objects_4) $(am__objects_2) + libnm_glib_la-nm-glib-enum-types.lo +am_libnm_glib_la_OBJECTS = $(am__objects_4) $(am__objects_1) libnm_glib_la_OBJECTS = $(am_libnm_glib_la_OBJECTS) libnm_glib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libnm_glib_la_CFLAGS) \ @@ -381,12 +386,15 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ DSYMUTIL = @DSYMUTIL@ @@ -411,7 +419,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ @@ -456,12 +463,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -478,6 +489,8 @@ MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ @@ -505,11 +518,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -524,6 +542,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ VAPIGEN = @VAPIGEN@ VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ @@ -586,6 +605,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ target_alias = @target_alias@ @@ -596,12 +616,17 @@ with_dhclient = @with_dhclient@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util + -I$(top_builddir)/libnm-util \ + -DG_LOG_DOMAIN=\""libnm-glib"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) BUILT_SOURCES = nm-vpn-plugin-glue.h nm-secret-agent-glue.h \ $(GLIB_GENERATED) @@ -618,8 +643,6 @@ libdeprecated_nm_glib_la_SOURCES = \ libnm_glib.c libdeprecated_nm_glib_la_CPPFLAGS = \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ $(AM_CPPFLAGS) \ -Wno-deprecated-declarations \ -Wno-deprecated @@ -638,7 +661,8 @@ lib_LTLIBRARIES = libnm-glib.la libnm-glib-vpn.la libnm_glib_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(GUDEV_CFLAGS) + $(GUDEV_CFLAGS) \ + -DNMRUNDIR=\"$(nmrundir)\" libnmincludedir = $(includedir)/libnm-glib libnmvpndir = $(includedir)/libnm-glib @@ -653,8 +677,10 @@ libnminclude_HEADERS = \ nm-device-bt.h \ nm-device-olpc-mesh.h \ nm-device-bond.h \ + nm-device-team.h \ nm-device-bridge.h \ nm-device-vlan.h \ + nm-device-generic.h \ nm-access-point.h \ nm-ip4-config.h \ nm-device-modem.h \ @@ -679,6 +705,7 @@ libnmvpn_HEADERS = \ libnm_glib_la_csources = \ nm-object.c \ + nm-dbus-helpers.c \ nm-client.c \ nm-device.c \ nm-device-ethernet.c \ @@ -688,8 +715,10 @@ libnm_glib_la_csources = \ nm-device-bt.c \ nm-device-olpc-mesh.c \ nm-device-bond.c \ + nm-device-team.c \ nm-device-bridge.c \ nm-device-vlan.c \ + nm-device-generic.c \ nm-access-point.c \ nm-ip4-config.c \ nm-device-modem.c \ @@ -705,8 +734,7 @@ libnm_glib_la_csources = \ nm-secret-agent.c \ nm-device-wimax.c \ nm-wimax-nsp.c \ - nm-glib-enum-types.c \ - nm-glib-marshal.c + nm-glib-enum-types.c libnm_glib_la_private_headers = \ nm-object-private.h \ @@ -714,19 +742,17 @@ libnm_glib_la_private_headers = \ nm-types-private.h \ nm-object-cache.h \ nm-remote-connection-private.h \ - nm-glib-marshal.h + nm-dbus-helpers-private.h libnm_glib_la_SOURCES = \ $(libnm_glib_la_csources) \ $(libnm_glib_la_private_headers) GLIB_GENERATED = nm-glib-enum-types.h nm-glib-enum-types.c \ - nm-glib-marshal.h nm-glib-marshal.c nm-vpn-enum-types.h \ - nm-vpn-enum-types.c + nm-vpn-enum-types.h nm-vpn-enum-types.c nm_glib_enum_types_sources = $(libnminclude_HEADERS) GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -nm_glib_marshal_sources = $(libnm_glib_la_SOURCES) libnm_glib_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(builddir)/libdeprecated-nm-glib.la \ @@ -736,7 +762,7 @@ libnm_glib_la_LIBADD = \ SYMBOL_VIS_FILE = $(srcdir)/libnm-glib.ver libnm_glib_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "10:0:6" + -version-info "12:0:8" libnm_glib_test_SOURCES = libnm-glib-test.c libnm_glib_test_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS) @@ -751,7 +777,7 @@ nm_vpn_enum_types_sources = $(libnmvpn_HEADERS) 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) libnm_glib_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib-vpn.ver \ - -version-info "2:0:1" + -version-info "3:0:2" ##################################################### @@ -761,10 +787,11 @@ libnm_glib_test_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ $(GUDEV_CFLAGS) \ - -DLIBNM_GLIB_TEST + -DLIBNM_GLIB_TEST \ + -DNMRUNDIR=\"$(nmrundir)\" libnm_glib_test_la_SOURCES = \ - $(li0bnminclude_HEADERS) \ + $(libnminclude_HEADERS) \ $(libnm_glib_la_SOURCES) libnm_glib_test_la_LIBADD = \ @@ -913,14 +940,17 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-access-point.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-active-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-client.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-dbus-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-adsl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-bond.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-bridge.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-bt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-ethernet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-generic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-infiniband.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-modem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-olpc-mesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-team.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-vlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-wifi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-device-wimax.Plo@am__quote@ @@ -928,7 +958,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-dhcp4-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-dhcp6-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-glib-enum-types.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-glib-marshal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-ip4-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-ip6-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-object-cache.Plo@am__quote@ @@ -943,14 +972,17 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-access-point.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-active-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-client.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-dbus-helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-adsl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-bond.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-bridge.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-bt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-ethernet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-generic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-infiniband.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-modem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-olpc-mesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-team.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-vlan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-wifi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-wimax.Plo@am__quote@ @@ -958,7 +990,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-dhcp4-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-dhcp6-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-glib-enum-types.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-glib-marshal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-ip4-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-ip6-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-object-cache.Plo@am__quote@ @@ -1009,6 +1040,13 @@ libnm_glib_test_la-nm-object.lo: nm-object.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-object.lo `test -f 'nm-object.c' || echo '$(srcdir)/'`nm-object.c +libnm_glib_test_la-nm-dbus-helpers.lo: nm-dbus-helpers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-dbus-helpers.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-dbus-helpers.Tpo -c -o libnm_glib_test_la-nm-dbus-helpers.lo `test -f 'nm-dbus-helpers.c' || echo '$(srcdir)/'`nm-dbus-helpers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-dbus-helpers.Tpo $(DEPDIR)/libnm_glib_test_la-nm-dbus-helpers.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dbus-helpers.c' object='libnm_glib_test_la-nm-dbus-helpers.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-dbus-helpers.lo `test -f 'nm-dbus-helpers.c' || echo '$(srcdir)/'`nm-dbus-helpers.c + libnm_glib_test_la-nm-client.lo: nm-client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-client.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-client.Tpo -c -o libnm_glib_test_la-nm-client.lo `test -f 'nm-client.c' || echo '$(srcdir)/'`nm-client.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-client.Tpo $(DEPDIR)/libnm_glib_test_la-nm-client.Plo @@ -1072,6 +1110,13 @@ libnm_glib_test_la-nm-device-bond.lo: nm-device-bond.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-bond.lo `test -f 'nm-device-bond.c' || echo '$(srcdir)/'`nm-device-bond.c +libnm_glib_test_la-nm-device-team.lo: nm-device-team.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-team.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-team.Tpo -c -o libnm_glib_test_la-nm-device-team.lo `test -f 'nm-device-team.c' || echo '$(srcdir)/'`nm-device-team.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-team.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-team.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-team.c' object='libnm_glib_test_la-nm-device-team.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-team.lo `test -f 'nm-device-team.c' || echo '$(srcdir)/'`nm-device-team.c + libnm_glib_test_la-nm-device-bridge.lo: nm-device-bridge.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-bridge.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-bridge.Tpo -c -o libnm_glib_test_la-nm-device-bridge.lo `test -f 'nm-device-bridge.c' || echo '$(srcdir)/'`nm-device-bridge.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-bridge.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-bridge.Plo @@ -1086,6 +1131,13 @@ libnm_glib_test_la-nm-device-vlan.lo: nm-device-vlan.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-vlan.lo `test -f 'nm-device-vlan.c' || echo '$(srcdir)/'`nm-device-vlan.c +libnm_glib_test_la-nm-device-generic.lo: nm-device-generic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-generic.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-generic.Tpo -c -o libnm_glib_test_la-nm-device-generic.lo `test -f 'nm-device-generic.c' || echo '$(srcdir)/'`nm-device-generic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-generic.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-generic.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-generic.c' object='libnm_glib_test_la-nm-device-generic.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-generic.lo `test -f 'nm-device-generic.c' || echo '$(srcdir)/'`nm-device-generic.c + libnm_glib_test_la-nm-access-point.lo: nm-access-point.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-access-point.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-access-point.Tpo -c -o libnm_glib_test_la-nm-access-point.lo `test -f 'nm-access-point.c' || echo '$(srcdir)/'`nm-access-point.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-access-point.Tpo $(DEPDIR)/libnm_glib_test_la-nm-access-point.Plo @@ -1198,13 +1250,6 @@ libnm_glib_test_la-nm-glib-enum-types.lo: nm-glib-enum-types.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-glib-enum-types.lo `test -f 'nm-glib-enum-types.c' || echo '$(srcdir)/'`nm-glib-enum-types.c -libnm_glib_test_la-nm-glib-marshal.lo: nm-glib-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-glib-marshal.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-glib-marshal.Tpo -c -o libnm_glib_test_la-nm-glib-marshal.lo `test -f 'nm-glib-marshal.c' || echo '$(srcdir)/'`nm-glib-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-glib-marshal.Tpo $(DEPDIR)/libnm_glib_test_la-nm-glib-marshal.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-glib-marshal.c' object='libnm_glib_test_la-nm-glib-marshal.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-glib-marshal.lo `test -f 'nm-glib-marshal.c' || echo '$(srcdir)/'`nm-glib-marshal.c - libnm_glib_vpn_la-nm-vpn-plugin.lo: nm-vpn-plugin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_vpn_la_CFLAGS) $(CFLAGS) -MT libnm_glib_vpn_la-nm-vpn-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_glib_vpn_la-nm-vpn-plugin.Tpo -c -o libnm_glib_vpn_la-nm-vpn-plugin.lo `test -f 'nm-vpn-plugin.c' || echo '$(srcdir)/'`nm-vpn-plugin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_vpn_la-nm-vpn-plugin.Tpo $(DEPDIR)/libnm_glib_vpn_la-nm-vpn-plugin.Plo @@ -1240,6 +1285,13 @@ libnm_glib_la-nm-object.lo: nm-object.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_la-nm-object.lo `test -f 'nm-object.c' || echo '$(srcdir)/'`nm-object.c +libnm_glib_la-nm-dbus-helpers.lo: nm-dbus-helpers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -MT libnm_glib_la-nm-dbus-helpers.lo -MD -MP -MF $(DEPDIR)/libnm_glib_la-nm-dbus-helpers.Tpo -c -o libnm_glib_la-nm-dbus-helpers.lo `test -f 'nm-dbus-helpers.c' || echo '$(srcdir)/'`nm-dbus-helpers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_la-nm-dbus-helpers.Tpo $(DEPDIR)/libnm_glib_la-nm-dbus-helpers.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dbus-helpers.c' object='libnm_glib_la-nm-dbus-helpers.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_la-nm-dbus-helpers.lo `test -f 'nm-dbus-helpers.c' || echo '$(srcdir)/'`nm-dbus-helpers.c + libnm_glib_la-nm-client.lo: nm-client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -MT libnm_glib_la-nm-client.lo -MD -MP -MF $(DEPDIR)/libnm_glib_la-nm-client.Tpo -c -o libnm_glib_la-nm-client.lo `test -f 'nm-client.c' || echo '$(srcdir)/'`nm-client.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_la-nm-client.Tpo $(DEPDIR)/libnm_glib_la-nm-client.Plo @@ -1303,6 +1355,13 @@ libnm_glib_la-nm-device-bond.lo: nm-device-bond.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_la-nm-device-bond.lo `test -f 'nm-device-bond.c' || echo '$(srcdir)/'`nm-device-bond.c +libnm_glib_la-nm-device-team.lo: nm-device-team.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -MT libnm_glib_la-nm-device-team.lo -MD -MP -MF $(DEPDIR)/libnm_glib_la-nm-device-team.Tpo -c -o libnm_glib_la-nm-device-team.lo `test -f 'nm-device-team.c' || echo '$(srcdir)/'`nm-device-team.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_la-nm-device-team.Tpo $(DEPDIR)/libnm_glib_la-nm-device-team.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-team.c' object='libnm_glib_la-nm-device-team.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_la-nm-device-team.lo `test -f 'nm-device-team.c' || echo '$(srcdir)/'`nm-device-team.c + libnm_glib_la-nm-device-bridge.lo: nm-device-bridge.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -MT libnm_glib_la-nm-device-bridge.lo -MD -MP -MF $(DEPDIR)/libnm_glib_la-nm-device-bridge.Tpo -c -o libnm_glib_la-nm-device-bridge.lo `test -f 'nm-device-bridge.c' || echo '$(srcdir)/'`nm-device-bridge.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_la-nm-device-bridge.Tpo $(DEPDIR)/libnm_glib_la-nm-device-bridge.Plo @@ -1317,6 +1376,13 @@ libnm_glib_la-nm-device-vlan.lo: nm-device-vlan.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_la-nm-device-vlan.lo `test -f 'nm-device-vlan.c' || echo '$(srcdir)/'`nm-device-vlan.c +libnm_glib_la-nm-device-generic.lo: nm-device-generic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -MT libnm_glib_la-nm-device-generic.lo -MD -MP -MF $(DEPDIR)/libnm_glib_la-nm-device-generic.Tpo -c -o libnm_glib_la-nm-device-generic.lo `test -f 'nm-device-generic.c' || echo '$(srcdir)/'`nm-device-generic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_la-nm-device-generic.Tpo $(DEPDIR)/libnm_glib_la-nm-device-generic.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-generic.c' object='libnm_glib_la-nm-device-generic.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_la-nm-device-generic.lo `test -f 'nm-device-generic.c' || echo '$(srcdir)/'`nm-device-generic.c + libnm_glib_la-nm-access-point.lo: nm-access-point.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -MT libnm_glib_la-nm-access-point.lo -MD -MP -MF $(DEPDIR)/libnm_glib_la-nm-access-point.Tpo -c -o libnm_glib_la-nm-access-point.lo `test -f 'nm-access-point.c' || echo '$(srcdir)/'`nm-access-point.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_la-nm-access-point.Tpo $(DEPDIR)/libnm_glib_la-nm-access-point.Plo @@ -1429,13 +1495,6 @@ libnm_glib_la-nm-glib-enum-types.lo: nm-glib-enum-types.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_la-nm-glib-enum-types.lo `test -f 'nm-glib-enum-types.c' || echo '$(srcdir)/'`nm-glib-enum-types.c -libnm_glib_la-nm-glib-marshal.lo: nm-glib-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -MT libnm_glib_la-nm-glib-marshal.lo -MD -MP -MF $(DEPDIR)/libnm_glib_la-nm-glib-marshal.Tpo -c -o libnm_glib_la-nm-glib-marshal.lo `test -f 'nm-glib-marshal.c' || echo '$(srcdir)/'`nm-glib-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_la-nm-glib-marshal.Tpo $(DEPDIR)/libnm_glib_la-nm-glib-marshal.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-glib-marshal.c' object='libnm_glib_la-nm-glib-marshal.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_la-nm-glib-marshal.lo `test -f 'nm-glib-marshal.c' || echo '$(srcdir)/'`nm-glib-marshal.c - libnm_glib_test-libnm-glib-test.o: libnm-glib-test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_CFLAGS) $(CFLAGS) -MT libnm_glib_test-libnm-glib-test.o -MD -MP -MF $(DEPDIR)/libnm_glib_test-libnm-glib-test.Tpo -c -o libnm_glib_test-libnm-glib-test.o `test -f 'libnm-glib-test.c' || echo '$(srcdir)/'`libnm-glib-test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test-libnm-glib-test.Tpo $(DEPDIR)/libnm_glib_test-libnm-glib-test.Po diff --git a/libnm-glib/libnm-glib-test.c b/libnm-glib/libnm-glib-test.c index 4e80806f..e38457f0 100644 --- a/libnm-glib/libnm-glib-test.c +++ b/libnm-glib/libnm-glib-test.c @@ -70,16 +70,16 @@ static gchar * ip4_address_as_string (guint32 ip) { char buf[INET_ADDRSTRLEN+1]; - struct in_addr tmp_addr; + guint32 tmp_addr; memset (&buf, '\0', sizeof (buf)); - tmp_addr.s_addr = ip; + tmp_addr = ip; if (inet_ntop (AF_INET, &tmp_addr, buf, INET_ADDRSTRLEN)) { return g_strdup (buf); } else { g_warning ("%s: error converting IP4 address 0x%X", - __func__, ntohl (tmp_addr.s_addr)); + __func__, ntohl (tmp_addr)); return NULL; } } @@ -173,7 +173,7 @@ dump_access_point (NMAccessPoint *ap) g_print ("\tSsid: %s\n", ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)"); - str = nm_access_point_get_hw_address (ap); + str = nm_access_point_get_bssid (ap); g_print ("\tMAC Address: %s\n", str); g_print ("\tFlags: 0x%X\n", nm_access_point_get_flags (ap)); @@ -390,7 +390,9 @@ main (int argc, char *argv[]) { NMClient *client; +#if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); +#endif client = nm_client_new (); if (!client) { diff --git a/libnm-glib/libnm-glib-vpn.ver b/libnm-glib/libnm-glib-vpn.ver index 9d2bad5e..b2e763b2 100644 --- a/libnm-glib/libnm-glib-vpn.ver +++ b/libnm-glib/libnm-glib-vpn.ver @@ -7,6 +7,7 @@ global: nm_vpn_plugin_get_connection; nm_vpn_plugin_get_state; nm_vpn_plugin_get_type; + nm_vpn_plugin_secrets_required; nm_vpn_plugin_set_ip4_config; nm_vpn_plugin_set_login_banner; nm_vpn_plugin_set_state; diff --git a/libnm-glib/libnm-glib.pc.in b/libnm-glib/libnm-glib.pc.in index 754c43da..2b4e6996 100644 --- a/libnm-glib/libnm-glib.pc.in +++ b/libnm-glib/libnm-glib.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: libnm-glib Description: Convenience library for clients of NetworkManager Version: @VERSION@ -Requires: NetworkManager >= @VERSION@ gobject-2.0 dbus-glib-1 +Requires: libnm-util >= @VERSION@ NetworkManager >= @VERSION@ gobject-2.0 dbus-glib-1 Cflags: -I${includedir}/libnm-glib Libs: -L${libdir} -lnm-glib diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index b7d33211..982288e5 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -20,14 +20,21 @@ global: nm_access_point_get_wpa_flags; nm_access_point_new; nm_active_connection_get_connection; + nm_active_connection_get_connection_type; nm_active_connection_get_default6; nm_active_connection_get_default; nm_active_connection_get_devices; + nm_active_connection_get_dhcp4_config; + nm_active_connection_get_dhcp6_config; + nm_active_connection_get_id; + nm_active_connection_get_ip4_config; + nm_active_connection_get_ip6_config; nm_active_connection_get_master; nm_active_connection_get_specific_object; nm_active_connection_get_state; nm_active_connection_get_type; nm_active_connection_get_uuid; + nm_active_connection_get_vpn; nm_active_connection_new; nm_client_activate_connection; nm_client_add_and_activate_connection; @@ -35,6 +42,8 @@ global: nm_client_check_connectivity_async; nm_client_check_connectivity_finish; nm_client_deactivate_connection; + nm_client_error_get_type; + nm_client_error_quark; nm_client_get_activating_connection; nm_client_get_active_connections; nm_client_get_connectivity; @@ -45,6 +54,7 @@ global: nm_client_get_manager_running; nm_client_get_permission_result; nm_client_get_primary_connection; + nm_client_get_startup; nm_client_get_state; nm_client_get_type; nm_client_get_version; @@ -94,7 +104,10 @@ global: nm_device_bt_new; nm_device_connection_compatible; nm_device_connection_valid; + nm_device_disambiguate_names; nm_device_disconnect; + nm_device_error_get_type; + nm_device_error_quark; nm_device_ethernet_error_get_type; nm_device_ethernet_error_quark; nm_device_ethernet_get_carrier; @@ -104,10 +117,16 @@ global: nm_device_ethernet_get_type; nm_device_ethernet_new; nm_device_filter_connections; + nm_device_generic_error_get_type; + nm_device_generic_error_quark; + nm_device_generic_get_hw_address; + nm_device_generic_get_type; + nm_device_generic_new; nm_device_get_active_connection; nm_device_get_autoconnect; nm_device_get_available_connections; nm_device_get_capabilities; + nm_device_get_description; nm_device_get_device_type; nm_device_get_dhcp4_config; nm_device_get_dhcp6_config; @@ -115,15 +134,20 @@ global: nm_device_get_driver_version; nm_device_get_firmware_missing; nm_device_get_firmware_version; + nm_device_get_hw_address; nm_device_get_iface; nm_device_get_ip4_config; nm_device_get_ip6_config; nm_device_get_ip_iface; nm_device_get_managed; + nm_device_get_mtu; + nm_device_get_physical_port_id; nm_device_get_product; + nm_device_get_setting_type; nm_device_get_state; nm_device_get_state_reason; nm_device_get_type; + nm_device_get_type_description; nm_device_get_udi; nm_device_get_vendor; nm_device_infiniband_error_get_type; @@ -146,6 +170,13 @@ global: nm_device_olpc_mesh_get_type; nm_device_olpc_mesh_new; nm_device_set_autoconnect; + nm_device_team_error_get_type; + nm_device_team_error_quark; + nm_device_team_get_carrier; + nm_device_team_get_hw_address; + nm_device_team_get_slaves; + nm_device_team_get_type; + nm_device_team_new; nm_device_vlan_error_get_type; nm_device_vlan_error_quark; nm_device_vlan_get_carrier; @@ -189,8 +220,10 @@ global: nm_dhcp6_config_new; nm_ip4_config_get_addresses; nm_ip4_config_get_domains; + nm_ip4_config_get_gateway; nm_ip4_config_get_nameservers; nm_ip4_config_get_routes; + nm_ip4_config_get_searches; nm_ip4_config_get_type; nm_ip4_config_get_wins_servers; nm_ip4_config_new; @@ -198,8 +231,12 @@ global: nm_ip6_address_object_array_get_type; nm_ip6_config_get_addresses; nm_ip6_config_get_domains; + nm_ip6_config_get_gateway; + nm_ip6_config_get_nameserver; nm_ip6_config_get_nameservers; + nm_ip6_config_get_num_nameservers; nm_ip6_config_get_routes; + nm_ip6_config_get_searches; nm_ip6_config_get_type; nm_ip6_config_new; nm_ip6_route_object_array_get_type; @@ -210,21 +247,31 @@ global: nm_object_get_path; nm_object_get_type; nm_remote_connection_commit_changes; + nm_remote_connection_commit_changes_unsaved; nm_remote_connection_delete; + nm_remote_connection_error_get_type; + nm_remote_connection_error_quark; nm_remote_connection_get_secrets; nm_remote_connection_get_type; + nm_remote_connection_get_unsaved; nm_remote_connection_new; + nm_remote_connection_save; nm_remote_settings_add_connection; + nm_remote_settings_add_connection_unsaved; nm_remote_settings_error_get_type; nm_remote_settings_error_quark; + nm_remote_settings_get_connection_by_id; nm_remote_settings_get_connection_by_path; nm_remote_settings_get_connection_by_uuid; nm_remote_settings_get_type; nm_remote_settings_list_connections; + nm_remote_settings_load_connections; nm_remote_settings_new; nm_remote_settings_new_async; nm_remote_settings_new_finish; + nm_remote_settings_reload_connections; nm_remote_settings_save_hostname; + nm_secret_agent_capabilities_get_type; nm_secret_agent_delete_secrets; nm_secret_agent_error_get_type; nm_secret_agent_error_quark; diff --git a/libnm-glib/libnm_glib.c b/libnm-glib/libnm_glib.c index 1d755786..a2a6d26e 100644 --- a/libnm-glib/libnm_glib.c +++ b/libnm-glib/libnm_glib.c @@ -456,8 +456,7 @@ _libnm_glib_ctx_free (libnm_glib_ctx *ctx) if (ctx->callbacks_lock) g_mutex_free (ctx->callbacks_lock); - g_slist_foreach (ctx->callbacks, (GFunc)g_free, NULL); - g_slist_free (ctx->callbacks); + g_slist_free_full (ctx->callbacks, g_free); if (ctx->thread) g_thread_join (ctx->thread); @@ -494,7 +493,10 @@ libnm_glib_init (void) { libnm_glib_ctx *ctx = NULL; +#if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); +#endif + if (!g_thread_supported ()) g_thread_init (NULL); dbus_g_thread_init (); diff --git a/libnm-glib/nm-access-point.c b/libnm-glib/nm-access-point.c index d13a7d3c..ca3f1bf2 100644 --- a/libnm-glib/nm-access-point.c +++ b/libnm-glib/nm-access-point.c @@ -72,16 +72,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_FLAGS "Flags" -#define DBUS_PROP_WPA_FLAGS "WpaFlags" -#define DBUS_PROP_RSN_FLAGS "RsnFlags" -#define DBUS_PROP_SSID "Ssid" -#define DBUS_PROP_FREQUENCY "Frequency" -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_MODE "Mode" -#define DBUS_PROP_MAX_BITRATE "MaxBitrate" -#define DBUS_PROP_STRENGTH "Strength" - /** * nm_access_point_new: * @connection: the #DBusGConnection @@ -194,7 +184,7 @@ nm_access_point_get_frequency (NMAccessPoint *ap) * nm_access_point_get_bssid: * @ap: a #NMAccessPoint * - * Gets the Basic Service Set ID (BSSID) of the WiFi access point. + * Gets the Basic Service Set ID (BSSID) of the Wi-Fi access point. * * Returns: the BSSID of the access point. This is an internal string and must * not be modified or freed. @@ -246,9 +236,9 @@ nm_access_point_get_mode (NMAccessPoint *ap) * nm_access_point_get_max_bitrate: * @ap: a #NMAccessPoint * - * Gets the maximum bit rate of the access point. + * Gets the maximum bit rate of the access point in kbit/s. * - * Returns: the maximum bit rate + * Returns: the maximum bit rate (kbit/s) **/ guint32 nm_access_point_get_max_bitrate (NMAccessPoint *ap) @@ -281,12 +271,12 @@ nm_access_point_get_strength (NMAccessPoint *ap) * @ap: an #NMAccessPoint to validate @connection against * @connection: an #NMConnection to validate against @ap * - * Validates a given connection against a given WiFi access point to ensure that + * Validates a given connection against a given Wi-Fi access point to ensure that * the connection may be activated with that AP. The connection must match the * @ap's SSID, (if given) BSSID, and other attributes like security settings, * channel, band, etc. * - * Returns: %TRUE if the connection may be activated with this WiFi AP, + * Returns: %TRUE if the connection may be activated with this Wi-Fi AP, * %FALSE if it cannot be. **/ gboolean @@ -539,12 +529,7 @@ constructed (GObject *object) G_OBJECT_CLASS (nm_access_point_parent_class)->constructed (object); priv = NM_ACCESS_POINT_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_ACCESS_POINT); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_ACCESS_POINT); register_properties (NM_ACCESS_POINT (object)); } @@ -675,7 +660,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) /** * NMAccessPoint:max-bitrate: * - * The maximum bit rate of the access point. + * The maximum bit rate of the access point in kbit/s. **/ g_object_class_install_property (object_class, PROP_MAX_BITRATE, diff --git a/libnm-glib/nm-access-point.h b/libnm-glib/nm-access-point.h index 76275f00..4862e6b7 100644 --- a/libnm-glib/nm-access-point.h +++ b/libnm-glib/nm-access-point.h @@ -90,6 +90,7 @@ gboolean nm_access_point_connection_valid (NMAccessPoint *ap, NMConnection *connection); /* DEPRECATED */ +NM_DEPRECATED_IN_0_9_10 const char * nm_access_point_get_hw_address (NMAccessPoint *ap); G_END_DECLS diff --git a/libnm-glib/nm-active-connection.c b/libnm-glib/nm-active-connection.c index f170121b..bca21b4d 100644 --- a/libnm-glib/nm-active-connection.c +++ b/libnm-glib/nm-active-connection.c @@ -17,7 +17,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2014 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. */ @@ -32,6 +32,7 @@ #include "nm-connection.h" #include "nm-vpn-connection.h" #include "nm-glib-compat.h" +#include "nm-dbus-helpers-private.h" static GType _nm_active_connection_type_for_path (DBusGConnection *connection, const char *path); @@ -52,38 +53,43 @@ typedef struct { DBusGProxy *proxy; char *connection; + char *id; char *uuid; + char *type; char *specific_object; GPtrArray *devices; NMActiveConnectionState state; gboolean is_default; + NMIP4Config *ip4_config; + NMDHCP4Config *dhcp4_config; gboolean is_default6; + NMIP6Config *ip6_config; + NMDHCP6Config *dhcp6_config; + gboolean is_vpn; char *master; } NMActiveConnectionPrivate; enum { PROP_0, PROP_CONNECTION, + PROP_ID, PROP_UUID, + PROP_TYPE, PROP_SPECIFIC_OBJECT, PROP_DEVICES, PROP_STATE, PROP_DEFAULT, + PROP_IP4_CONFIG, + PROP_DHCP4_CONFIG, PROP_DEFAULT6, + PROP_IP6_CONFIG, + PROP_DHCP6_CONFIG, + PROP_VPN, PROP_MASTER, LAST_PROP }; -#define DBUS_PROP_CONNECTION "Connection" -#define DBUS_PROP_UUID "Uuid" -#define DBUS_PROP_SPECIFIC_OBJECT "SpecificObject" -#define DBUS_PROP_DEVICES "Devices" -#define DBUS_PROP_STATE "State" -#define DBUS_PROP_DEFAULT "Default" -#define DBUS_PROP_DEFAULT6 "Default6" -#define DBUS_PROP_MASTER "Master" - /** * nm_active_connection_new: * @connection: the #DBusGConnection @@ -111,13 +117,10 @@ _nm_active_connection_type_for_path (DBusGConnection *connection, { DBusGProxy *proxy; GError *error = NULL; - GValue value = {0,}; + GValue value = G_VALUE_INIT; GType type; - proxy = dbus_g_proxy_new_for_name (connection, - NM_DBUS_SERVICE, - path, - "org.freedesktop.DBus.Properties"); + proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties"); if (!proxy) { g_warning ("%s: couldn't create D-Bus object proxy.", __func__); return G_TYPE_INVALID; @@ -194,8 +197,7 @@ _nm_active_connection_type_for_path_async (DBusGConnection *connection, async_data->callback = callback; async_data->user_data = user_data; - proxy = dbus_g_proxy_new_for_name (connection, NM_DBUS_SERVICE, path, - "org.freedesktop.DBus.Properties"); + proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties"); dbus_g_proxy_begin_call (proxy, "Get", async_got_type, async_data, NULL, G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION, @@ -207,10 +209,13 @@ _nm_active_connection_type_for_path_async (DBusGConnection *connection, * nm_active_connection_get_connection: * @connection: a #NMActiveConnection * - * Gets the #NMConnection's DBus object path. + * Gets the #NMConnection's DBus object path. This is often used with + * nm_remote_settings_get_connection_by_path() to retrieve the + * #NMRemoteConnection object that describes the connection. * - * Returns: the object path of the #NMConnection inside of #NMActiveConnection. - * This is the internal string used by the connection, and must not be modified. + * Returns: the object path of the #NMConnection which this #NMActiveConnection + * is an active instance of. This is the internal string used by the + * connection, and must not be modified. **/ const char * nm_active_connection_get_connection (NMActiveConnection *connection) @@ -221,11 +226,31 @@ nm_active_connection_get_connection (NMActiveConnection *connection) return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->connection; } +/** + * nm_active_connection_get_id: + * @connection: a #NMActiveConnection + * + * Gets the #NMConnection's ID. + * + * Returns: the ID of the #NMConnection that backs the #NMActiveConnection. + * This is the internal string used by the connection, and must not be modified. + * + * Since: 0.9.10 + **/ +const char * +nm_active_connection_get_id (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + _nm_object_ensure_inited (NM_OBJECT (connection)); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->id; +} + /** * nm_active_connection_get_uuid: * @connection: a #NMActiveConnection * - * Gets the #NMConnection's UUID. + * Gets the #NMConnection's UUID. * * Returns: the UUID of the #NMConnection that backs the #NMActiveConnection. * This is the internal string used by the connection, and must not be modified. @@ -239,6 +264,26 @@ nm_active_connection_get_uuid (NMActiveConnection *connection) return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->uuid; } +/** + * nm_active_connection_get_connection_type: + * @connection: a #NMActiveConnection + * + * Gets the #NMConnection's type. + * + * Returns: the type of the #NMConnection that backs the #NMActiveConnection. + * This is the internal string used by the connection, and must not be modified. + * + * Since: 0.9.10 + **/ +const char * +nm_active_connection_get_connection_type (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + _nm_object_ensure_inited (NM_OBJECT (connection)); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->type; +} + /** * nm_active_connection_get_specific_object: * @connection: a #NMActiveConnection @@ -261,9 +306,9 @@ nm_active_connection_get_specific_object (NMActiveConnection *connection) * nm_active_connection_get_devices: * @connection: a #NMActiveConnection * - * Gets the #NMDevices used for the active connections. + * Gets the #NMDevices used for the active connections. * - * Returns: (element-type NMClient.Device): the #GPtrArray containing #NMDevices. + * Returns: (element-type NMClient.Device): the #GPtrArray containing #NMDevices. * This is the internal copy used by the connection, and must not be modified. **/ const GPtrArray * @@ -310,6 +355,49 @@ nm_active_connection_get_default (NMActiveConnection *connection) return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->is_default; } +/** + * nm_active_connection_get_ip4_config: + * @connection: an #NMActiveConnection + * + * Gets the current #NMIP4Config associated with the #NMActiveConnection. + * + * Returns: (transfer none): the #NMIP4Config, or %NULL if the + * connection is not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED + * state. + * + * Since: 0.9.10 + **/ +NMIP4Config * +nm_active_connection_get_ip4_config (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + _nm_object_ensure_inited (NM_OBJECT (connection)); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->ip4_config; +} + +/** + * nm_active_connection_get_dhcp4_config: + * @connection: an #NMActiveConnection + * + * Gets the current #NMDHCP4Config (if any) associated with the + * #NMActiveConnection. + * + * Returns: (transfer none): the #NMDHCP4Config, or %NULL if the + * connection does not use DHCP, or is not in the + * %NM_ACTIVE_CONNECTION_STATE_ACTIVATED state. + * + * Since: 0.9.10 + **/ +NMDHCP4Config * +nm_active_connection_get_dhcp4_config (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + _nm_object_ensure_inited (NM_OBJECT (connection)); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->dhcp4_config; +} + /** * nm_active_connection_get_default6: * @connection: a #NMActiveConnection @@ -328,6 +416,68 @@ nm_active_connection_get_default6 (NMActiveConnection *connection) return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->is_default6; } +/** + * nm_active_connection_get_ip6_config: + * @connection: an #NMActiveConnection + * + * Gets the current #NMIP6Config associated with the #NMActiveConnection. + * + * Returns: (transfer none): the #NMIP6Config, or %NULL if the + * connection is not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED + * state. + * + * Since: 0.9.10 + **/ +NMIP6Config * +nm_active_connection_get_ip6_config (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + _nm_object_ensure_inited (NM_OBJECT (connection)); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->ip6_config; +} + +/** + * nm_active_connection_get_dhcp6_config: + * @connection: an #NMActiveConnection + * + * Gets the current #NMDHCP6Config (if any) associated with the + * #NMActiveConnection. + * + * Returns: (transfer none): the #NMDHCP6Config, or %NULL if the + * connection does not use DHCPv6, or is not in the + * %NM_ACTIVE_CONNECTION_STATE_ACTIVATED state. + * + * Since: 0.9.10 + **/ +NMDHCP6Config * +nm_active_connection_get_dhcp6_config (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + _nm_object_ensure_inited (NM_OBJECT (connection)); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->dhcp6_config; +} + +/** + * nm_active_connection_get_vpn: + * @connection: a #NMActiveConnection + * + * Whether the active connection is a VPN connection. + * + * Returns: %TRUE if the active connection is a VPN connection + * + * Since: 0.9.10 + **/ +gboolean +nm_active_connection_get_vpn (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), FALSE); + + _nm_object_ensure_inited (NM_OBJECT (connection)); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->is_vpn; +} + /** * nm_active_connection_get_master: * @connection: a #NMActiveConnection @@ -357,11 +507,16 @@ dispose (GObject *object) NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); if (priv->devices) { - g_ptr_array_foreach (priv->devices, (GFunc) g_object_unref, NULL); + g_ptr_array_set_free_func (priv->devices, g_object_unref); g_ptr_array_free (priv->devices, TRUE); priv->devices = NULL; } + g_clear_object (&priv->ip4_config); + g_clear_object (&priv->dhcp4_config); + g_clear_object (&priv->ip6_config); + g_clear_object (&priv->dhcp6_config); + g_clear_object (&priv->proxy); G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); @@ -373,7 +528,9 @@ finalize (GObject *object) NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); g_free (priv->connection); + g_free (priv->id); g_free (priv->uuid); + g_free (priv->type); g_free (priv->specific_object); g_free (priv->master); @@ -394,9 +551,15 @@ get_property (GObject *object, case PROP_CONNECTION: g_value_set_string (value, nm_active_connection_get_connection (self)); break; + case PROP_ID: + g_value_set_string (value, nm_active_connection_get_id (self)); + break; case PROP_UUID: g_value_set_string (value, nm_active_connection_get_uuid (self)); break; + case PROP_TYPE: + g_value_set_string (value, nm_active_connection_get_connection_type (self)); + break; case PROP_SPECIFIC_OBJECT: g_value_set_boxed (value, nm_active_connection_get_specific_object (self)); break; @@ -409,9 +572,24 @@ get_property (GObject *object, case PROP_DEFAULT: g_value_set_boolean (value, nm_active_connection_get_default (self)); break; + case PROP_IP4_CONFIG: + g_value_set_object (value, nm_active_connection_get_ip4_config (self)); + break; + case PROP_DHCP4_CONFIG: + g_value_set_object (value, nm_active_connection_get_dhcp4_config (self)); + break; case PROP_DEFAULT6: g_value_set_boolean (value, nm_active_connection_get_default6 (self)); break; + case PROP_IP6_CONFIG: + g_value_set_object (value, nm_active_connection_get_ip6_config (self)); + break; + case PROP_DHCP6_CONFIG: + g_value_set_object (value, nm_active_connection_get_dhcp6_config (self)); + break; + case PROP_VPN: + g_value_set_boolean (value, nm_active_connection_get_vpn (self)); + break; case PROP_MASTER: g_value_set_string (value, nm_active_connection_get_master (self)); break; @@ -427,17 +605,21 @@ register_properties (NMActiveConnection *connection) NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); const NMPropertiesInfo property_info[] = { { NM_ACTIVE_CONNECTION_CONNECTION, &priv->connection }, + { NM_ACTIVE_CONNECTION_ID, &priv->id }, { NM_ACTIVE_CONNECTION_UUID, &priv->uuid }, + { NM_ACTIVE_CONNECTION_TYPE, &priv->type }, { NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, &priv->specific_object }, { NM_ACTIVE_CONNECTION_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE }, { NM_ACTIVE_CONNECTION_STATE, &priv->state }, { NM_ACTIVE_CONNECTION_DEFAULT, &priv->is_default }, + { NM_ACTIVE_CONNECTION_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG }, + { NM_ACTIVE_CONNECTION_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG }, { NM_ACTIVE_CONNECTION_DEFAULT6, &priv->is_default6 }, + { NM_ACTIVE_CONNECTION_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG }, + { NM_ACTIVE_CONNECTION_DHCP6_CONFIG, &priv->dhcp6_config, NULL, NM_TYPE_DHCP6_CONFIG }, + { NM_ACTIVE_CONNECTION_VPN, &priv->is_vpn }, { NM_ACTIVE_CONNECTION_MASTER, &priv->master }, - /* not tracked after construction time */ - { "vpn", NULL }, - { NULL }, }; @@ -449,17 +631,11 @@ register_properties (NMActiveConnection *connection) static void constructed (GObject *object) { - NMActiveConnectionPrivate *priv; + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object); - priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_ACTIVE_CONNECTION); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_ACTIVE_CONNECTION); register_properties (NM_ACTIVE_CONNECTION (object)); } @@ -492,6 +668,21 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) NULL, G_PARAM_READABLE)); + /** + * NMActiveConnection:id: + * + * The active connection's ID + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_ID, + g_param_spec_string (NM_ACTIVE_CONNECTION_ID, + "ID", + "ID", + NULL, + G_PARAM_READABLE)); + /** * NMActiveConnection:uuid: * @@ -505,6 +696,21 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) NULL, G_PARAM_READABLE)); + /** + * NMActiveConnection:type: + * + * The active connection's type + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_TYPE, + g_param_spec_string (NM_ACTIVE_CONNECTION_TYPE, + "Type", + "Type", + NULL, + G_PARAM_READABLE)); + /** * NMActiveConnection:specific-object: * @@ -559,6 +765,36 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) FALSE, G_PARAM_READABLE)); + /** + * NMActiveConnection:ip4-config: + * + * The #NMIP4Config of the connection. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_IP4_CONFIG, + g_param_spec_object (NM_ACTIVE_CONNECTION_IP4_CONFIG, + "IP4 Config", + "IP4 Config", + NM_TYPE_IP4_CONFIG, + G_PARAM_READABLE)); + + /** + * NMActiveConnection:dhcp4-config: + * + * The #NMDHCP4Config of the connection. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_DHCP4_CONFIG, + g_param_spec_object (NM_ACTIVE_CONNECTION_DHCP4_CONFIG, + "DHCP4 Config", + "DHCP4 Config", + NM_TYPE_DHCP4_CONFIG, + G_PARAM_READABLE)); + /** * NMActiveConnection:default6: * @@ -572,6 +808,51 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) FALSE, G_PARAM_READABLE)); + /** + * NMActiveConnection:ip6-config: + * + * The #NMIP6Config of the connection. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_IP6_CONFIG, + g_param_spec_object (NM_ACTIVE_CONNECTION_IP6_CONFIG, + "IP6 Config", + "IP6 Config", + NM_TYPE_IP6_CONFIG, + G_PARAM_READABLE)); + + /** + * NMActiveConnection:dhcp6-config: + * + * The #NMDHCP6Config of the connection. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_DHCP6_CONFIG, + g_param_spec_object (NM_ACTIVE_CONNECTION_DHCP6_CONFIG, + "DHCP6 Config", + "DHCP6 Config", + NM_TYPE_DHCP6_CONFIG, + G_PARAM_READABLE)); + + /** + * NMActiveConnection:vpn: + * + * Whether the active connection is a VPN connection. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_VPN, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, + "VPN", + "Is a VPN connection", + FALSE, + G_PARAM_READABLE)); + /** * NMActiveConnection:master: * diff --git a/libnm-glib/nm-active-connection.h b/libnm-glib/nm-active-connection.h index c6777f80..b15e8340 100644 --- a/libnm-glib/nm-active-connection.h +++ b/libnm-glib/nm-active-connection.h @@ -17,7 +17,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2014 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. */ @@ -29,6 +29,10 @@ #include "nm-object.h" #include #include +#include "nm-ip4-config.h" +#include "nm-dhcp4-config.h" +#include "nm-ip6-config.h" +#include "nm-dhcp6-config.h" G_BEGIN_DECLS @@ -40,12 +44,19 @@ G_BEGIN_DECLS #define NM_ACTIVE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) #define NM_ACTIVE_CONNECTION_CONNECTION "connection" +#define NM_ACTIVE_CONNECTION_ID "id" #define NM_ACTIVE_CONNECTION_UUID "uuid" +#define NM_ACTIVE_CONNECTION_TYPE "type" #define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object" #define NM_ACTIVE_CONNECTION_DEVICES "devices" #define NM_ACTIVE_CONNECTION_STATE "state" #define NM_ACTIVE_CONNECTION_DEFAULT "default" +#define NM_ACTIVE_CONNECTION_IP4_CONFIG "ip4-config" +#define NM_ACTIVE_CONNECTION_DHCP4_CONFIG "dhcp4-config" #define NM_ACTIVE_CONNECTION_DEFAULT6 "default6" +#define NM_ACTIVE_CONNECTION_IP6_CONFIG "ip6-config" +#define NM_ACTIVE_CONNECTION_DHCP6_CONFIG "dhcp6-config" +#define NM_ACTIVE_CONNECTION_VPN "vpn" #define NM_ACTIVE_CONNECTION_MASTER "master" typedef struct { @@ -69,13 +80,27 @@ GType nm_active_connection_get_type (void); GObject *nm_active_connection_new (DBusGConnection *connection, const char *path); const char * nm_active_connection_get_connection (NMActiveConnection *connection); +NM_AVAILABLE_IN_0_9_10 +const char * nm_active_connection_get_id (NMActiveConnection *connection); const char * nm_active_connection_get_uuid (NMActiveConnection *connection); +NM_AVAILABLE_IN_0_9_10 +const char * nm_active_connection_get_connection_type (NMActiveConnection *connection); const char * nm_active_connection_get_specific_object (NMActiveConnection *connection); const GPtrArray *nm_active_connection_get_devices (NMActiveConnection *connection); NMActiveConnectionState nm_active_connection_get_state (NMActiveConnection *connection); -gboolean nm_active_connection_get_default (NMActiveConnection *connection); -gboolean nm_active_connection_get_default6 (NMActiveConnection *connection); const char * nm_active_connection_get_master (NMActiveConnection *connection); +gboolean nm_active_connection_get_default (NMActiveConnection *connection); +NM_AVAILABLE_IN_0_9_10 +NMIP4Config * nm_active_connection_get_ip4_config (NMActiveConnection *connection); +NM_AVAILABLE_IN_0_9_10 +NMDHCP4Config *nm_active_connection_get_dhcp4_config (NMActiveConnection *connection); +gboolean nm_active_connection_get_default6 (NMActiveConnection *connection); +NM_AVAILABLE_IN_0_9_10 +NMIP6Config * nm_active_connection_get_ip6_config (NMActiveConnection *connection); +NM_AVAILABLE_IN_0_9_10 +NMDHCP6Config *nm_active_connection_get_dhcp6_config (NMActiveConnection *connection); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_active_connection_get_vpn (NMActiveConnection *connection); G_END_DECLS diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 658a3995..379c7879 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright (C) 2007 - 2013 Red Hat, Inc. */ #include @@ -29,7 +29,6 @@ #include "nm-device-ethernet.h" #include "nm-device-wifi.h" #include "nm-device-private.h" -#include "nm-glib-marshal.h" #include "nm-types-private.h" #include "nm-object-private.h" #include "nm-active-connection.h" @@ -58,6 +57,7 @@ typedef struct { gboolean manager_running; char *version; NMState state; + gboolean startup; GPtrArray *devices; GPtrArray *active_connections; NMConnectivityState connectivity; @@ -87,6 +87,7 @@ enum { PROP_0, PROP_VERSION, PROP_STATE, + PROP_STARTUP, PROP_MANAGER_RUNNING, PROP_NETWORKING_ENABLED, PROP_WIRELESS_ENABLED, @@ -99,6 +100,7 @@ enum { PROP_CONNECTIVITY, PROP_PRIMARY_CONNECTION, PROP_ACTIVATING_CONNECTION, + PROP_DEVICES, LAST_PROP }; @@ -119,8 +121,28 @@ static void proxy_name_owner_changed (DBusGProxy *proxy, const char *new_owner, gpointer user_data); -static void client_device_added (NMObject *client, NMObject *device); -static void client_device_removed (NMObject *client, NMObject *device); +/**********************************************************************/ + +/** + * nm_client_error_quark: + * + * Registers an error quark for #NMClient if necessary. + * + * Returns: the error quark used for #NMClient errors. + * + * Since: 0.9.10 + **/ +GQuark +nm_client_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-client-error-quark"); + return quark; +} + +/**********************************************************************/ static void nm_client_init (NMClient *client) @@ -159,6 +181,7 @@ register_properties (NMClient *client) const NMPropertiesInfo property_info[] = { { NM_CLIENT_VERSION, &priv->version }, { NM_CLIENT_STATE, &priv->state }, + { NM_CLIENT_STARTUP, &priv->startup }, { NM_CLIENT_NETWORKING_ENABLED, &priv->networking_enabled }, { NM_CLIENT_WIRELESS_ENABLED, &priv->wireless_enabled }, { NM_CLIENT_WIRELESS_HARDWARE_ENABLED, &priv->wireless_hw_enabled }, @@ -170,20 +193,13 @@ register_properties (NMClient *client) { NM_CLIENT_CONNECTIVITY, &priv->connectivity }, { NM_CLIENT_PRIMARY_CONNECTION, &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, { NM_CLIENT_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, + { NM_CLIENT_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" }, { NULL }, }; _nm_object_register_properties (NM_OBJECT (client), priv->client_proxy, property_info); - - _nm_object_register_pseudo_property (NM_OBJECT (client), - priv->client_proxy, - "Devices", - &priv->devices, - NM_TYPE_DEVICE, - client_device_added, - client_device_removed); } #define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" @@ -349,7 +365,7 @@ client_recheck_permissions (DBusGProxy *proxy, gpointer user_data) * nm_device_ethernet_get_hw_address(). * * Returns: (transfer none) (element-type NMClient.Device): a #GPtrArray - * containing all the #NMDevices. The returned array is owned by the + * containing all the #NMDevices. The returned array is owned by the * #NMClient object and should not be modified. **/ const GPtrArray * @@ -436,12 +452,15 @@ typedef struct { NMClientAddActivateFn add_act_fn; char *active_path; char *new_connection_path; + guint idle_id; gpointer user_data; } ActivateInfo; static void activate_info_free (ActivateInfo *info) { + if (info->idle_id) + g_source_remove (info->idle_id); g_free (info->active_path); g_free (info->new_connection_path); memset (info, 0, sizeof (*info)); @@ -546,15 +565,32 @@ activate_cb (DBusGProxy *proxy, } } +static gboolean +activate_nm_not_running (gpointer user_data) +{ + ActivateInfo *info = user_data; + GError *error; + + info->idle_id = 0; + + error = g_error_new_literal (NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); + activate_info_complete (info, NULL, error); + activate_info_free (info); + g_clear_error (&error); + return FALSE; +} + /** * nm_client_activate_connection: * @client: a #NMClient - * @connection: an #NMConnection + * @connection: (allow-none): an #NMConnection * @device: (allow-none): the #NMDevice * @specific_object: (allow-none): the object path of a connection-type-specific * object this activation should use. This parameter is currently ignored for * wired and mobile broadband connections, and the value of %NULL should be used - * (ie, no specific object). For WiFi or WiMAX connections, pass the object + * (ie, no specific object). For Wi-Fi or WiMAX connections, pass the object * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can * get using nm_object_get_path(), and which will be used to complete the * details of the newly added connection. @@ -564,10 +600,13 @@ activate_cb (DBusGProxy *proxy, * Starts a connection to a particular network using the configuration settings * from @connection and the network device @device. Certain connection types * also take a "specific object" which is the object path of a connection- - * specific object, like an #NMAccessPoint for WiFi connections, or an + * specific object, like an #NMAccessPoint for Wi-Fi connections, or an * #NMWimaxNsp for WiMAX connections, to which you wish to connect. If the * specific object is not given, NetworkManager can, in some cases, automatically * determine which network to connect to given the settings in @connection. + * + * If @connection is not given for a device-based activation, NetworkManager + * picks the best available connection for the device and activates it. **/ void nm_client_activate_connection (NMClient *client, @@ -583,7 +622,8 @@ nm_client_activate_connection (NMClient *client, g_return_if_fail (NM_IS_CLIENT (client)); if (device) g_return_if_fail (NM_IS_DEVICE (device)); - g_return_if_fail (NM_IS_CONNECTION (connection)); + if (connection) + g_return_if_fail (NM_IS_CONNECTION (connection)); info = g_slice_new0 (ActivateInfo); info->act_fn = callback; @@ -593,9 +633,14 @@ nm_client_activate_connection (NMClient *client, priv = NM_CLIENT_GET_PRIVATE (client); priv->pending_activations = g_slist_prepend (priv->pending_activations, info); + if (priv->manager_running == FALSE) { + info->idle_id = g_idle_add (activate_nm_not_running, info); + return; + } + dbus_g_proxy_begin_call (priv->client_proxy, "ActivateConnection", activate_cb, info, NULL, - DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), + DBUS_TYPE_G_OBJECT_PATH, connection ? nm_connection_get_path (connection) : "/", DBUS_TYPE_G_OBJECT_PATH, device ? nm_object_get_path (NM_OBJECT (device)) : "/", DBUS_TYPE_G_OBJECT_PATH, specific_object ? specific_object : "/", G_TYPE_INVALID); @@ -635,7 +680,7 @@ add_activate_cb (DBusGProxy *proxy, * @specific_object: (allow-none): the object path of a connection-type-specific * object this activation should use. This parameter is currently ignored for * wired and mobile broadband connections, and the value of %NULL should be used - * (ie, no specific object). For WiFi or WiMAX connections, pass the object + * (ie, no specific object). For Wi-Fi or WiMAX connections, pass the object * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can * get using nm_object_get_path(), and which will be used to complete the * details of the newly added connection. @@ -675,12 +720,16 @@ nm_client_add_and_activate_connection (NMClient *client, priv = NM_CLIENT_GET_PRIVATE (client); priv->pending_activations = g_slist_prepend (priv->pending_activations, info); - dbus_g_proxy_begin_call (priv->client_proxy, "AddAndActivateConnection", - add_activate_cb, info, NULL, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, - DBUS_TYPE_G_OBJECT_PATH, nm_object_get_path (NM_OBJECT (device)), - DBUS_TYPE_G_OBJECT_PATH, specific_object ? specific_object : "/", - G_TYPE_INVALID); + if (priv->manager_running) { + dbus_g_proxy_begin_call (priv->client_proxy, "AddAndActivateConnection", + add_activate_cb, info, NULL, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, + DBUS_TYPE_G_OBJECT_PATH, nm_object_get_path (NM_OBJECT (device)), + DBUS_TYPE_G_OBJECT_PATH, specific_object ? specific_object : "/", + G_TYPE_INVALID); + } else + info->idle_id = g_idle_add (activate_nm_not_running, info); + g_hash_table_unref (hash); } @@ -714,8 +763,10 @@ nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active) g_return_if_fail (NM_IS_CLIENT (client)); g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active)); - // FIXME: return errors priv = NM_CLIENT_GET_PRIVATE (client); + if (!priv->manager_running) + return; + path = nm_object_get_path (NM_OBJECT (active)); if (!dbus_g_proxy_call (priv->client_proxy, "DeactivateConnection", &error, DBUS_TYPE_G_OBJECT_PATH, path, @@ -733,7 +784,7 @@ nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active) * Gets the active connections. * * Returns: (transfer none) (element-type NMClient.ActiveConnection): a #GPtrArray - * containing all the active #NMActiveConnections. + * containing all the active #NMActiveConnections. * The returned array is owned by the client and should not be modified. **/ const GPtrArray * @@ -779,17 +830,20 @@ nm_client_wireless_get_enabled (NMClient *client) void nm_client_wireless_set_enabled (NMClient *client, gboolean enabled) { - GValue value = {0,}; + GValue value = G_VALUE_INIT; g_return_if_fail (NM_IS_CLIENT (client)); + if (!NM_CLIENT_GET_PRIVATE (client)->manager_running) + return; + g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, enabled); _nm_object_set_property (NM_OBJECT (client), - NM_DBUS_INTERFACE, - "WirelessEnabled", - &value); + NM_DBUS_INTERFACE, + "WirelessEnabled", + &value); } /** @@ -836,10 +890,13 @@ nm_client_wwan_get_enabled (NMClient *client) void nm_client_wwan_set_enabled (NMClient *client, gboolean enabled) { - GValue value = {0,}; + GValue value = G_VALUE_INIT; g_return_if_fail (NM_IS_CLIENT (client)); + if (!NM_CLIENT_GET_PRIVATE (client)->manager_running) + return; + g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, enabled); @@ -893,10 +950,13 @@ nm_client_wimax_get_enabled (NMClient *client) void nm_client_wimax_set_enabled (NMClient *client, gboolean enabled) { - GValue value = {0,}; + GValue value = G_VALUE_INIT; g_return_if_fail (NM_IS_CLIENT (client)); + if (!NM_CLIENT_GET_PRIVATE (client)->manager_running) + return; + g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, enabled); @@ -963,6 +1023,27 @@ nm_client_get_state (NMClient *client) return NM_CLIENT_GET_PRIVATE (client)->state; } +/** + * nm_client_get_startup: + * @client: a #NMClient + * + * Tests whether the daemon is still in the process of activating + * connections at startup. + * + * Returns: whether the daemon is still starting up + * + * Since: 0.9.10 + **/ +gboolean +nm_client_get_startup (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN); + + _nm_object_ensure_inited (NM_OBJECT (client)); + + return NM_CLIENT_GET_PRIVATE (client)->startup; +} + /** * nm_client_networking_get_enabled: * @client: a #NMClient @@ -996,6 +1077,9 @@ nm_client_networking_set_enabled (NMClient *client, gboolean enable) g_return_if_fail (NM_IS_CLIENT (client)); + if (!NM_CLIENT_GET_PRIVATE (client)->manager_running) + return; + if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "Enable", &err, G_TYPE_BOOLEAN, enable, G_TYPE_INVALID, @@ -1073,28 +1157,30 @@ nm_client_get_permission_result (NMClient *client, NMClientPermission permission gboolean nm_client_get_logging (NMClient *client, char **level, char **domains, GError **error) { - GError *err = NULL; + NMClientPrivate *priv; g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); g_return_val_if_fail (level == NULL || *level == NULL, FALSE); g_return_val_if_fail (domains == NULL || *domains == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (!level && !domains) - return TRUE; - - if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "GetLogging", &err, - G_TYPE_INVALID, - G_TYPE_STRING, level, - G_TYPE_STRING, domains, - G_TYPE_INVALID)) { - if (error) - *error = g_error_copy (err); - g_error_free (err); + priv = NM_CLIENT_GET_PRIVATE (client); + if (!priv->manager_running) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); return FALSE; } - return TRUE; + if (!level && !domains) + return TRUE; + + return dbus_g_proxy_call (priv->client_proxy, "GetLogging", error, + G_TYPE_INVALID, + G_TYPE_STRING, level, + G_TYPE_STRING, domains, + G_TYPE_INVALID); } /** @@ -1114,26 +1200,28 @@ nm_client_get_logging (NMClient *client, char **level, char **domains, GError ** gboolean nm_client_set_logging (NMClient *client, const char *level, const char *domains, GError **error) { - GError *err = NULL; + NMClientPrivate *priv; g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (!level && !domains) - return TRUE; - - if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "SetLogging", &err, - G_TYPE_STRING, level ? level : "", - G_TYPE_STRING, domains ? domains : "", - G_TYPE_INVALID, - G_TYPE_INVALID)) { - if (error) - *error = g_error_copy (err); - g_error_free (err); + priv = NM_CLIENT_GET_PRIVATE (client); + if (!priv->manager_running) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); return FALSE; } - return TRUE; + if (!level && !domains) + return TRUE; + + return dbus_g_proxy_call (priv->client_proxy, "SetLogging", error, + G_TYPE_STRING, level ? level : "", + G_TYPE_STRING, domains ? domains : "", + G_TYPE_INVALID, + G_TYPE_INVALID); } /** @@ -1155,7 +1243,7 @@ nm_client_set_logging (NMClient *client, const char *level, const char *domains, * Returns: (transfer none): the appropriate #NMActiveConnection, if * any * - * Since: 0.9.8.4 + * Since: 0.9.8.6 */ NMActiveConnection * nm_client_get_primary_connection (NMClient *client) @@ -1177,7 +1265,7 @@ nm_client_get_primary_connection (NMClient *client) * Returns: (transfer none): the appropriate #NMActiveConnection, if * any. * - * Since: 0.9.8.4 + * Since: 0.9.8.6 */ NMActiveConnection * nm_client_get_activating_connection (NMClient *client) @@ -1278,11 +1366,13 @@ proxy_name_owner_changed (DBusGProxy *proxy, priv->manager_running = new_running; if (!priv->manager_running) { priv->state = NM_STATE_UNKNOWN; + priv->startup = FALSE; _nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_MANAGER_RUNNING); _nm_object_suppress_property_updates (NM_OBJECT (client), TRUE); poke_wireless_devices_with_rf_status (client); free_devices (client, TRUE); free_active_connections (client, TRUE); + update_permissions (client, NULL); priv->wireless_enabled = FALSE; priv->wireless_hw_enabled = FALSE; priv->wwan_enabled = FALSE; @@ -1299,21 +1389,10 @@ proxy_name_owner_changed (DBusGProxy *proxy, } else { _nm_object_suppress_property_updates (NM_OBJECT (client), FALSE); _nm_object_reload_properties_async (NM_OBJECT (client), updated_properties, client); + client_recheck_permissions (priv->client_proxy, client); } } -static void -client_device_added (NMObject *client, NMObject *device) -{ - g_signal_emit (client, signals[DEVICE_ADDED], 0, device); -} - -static void -client_device_removed (NMObject *client, NMObject *device) -{ - g_signal_emit (client, signals[DEVICE_REMOVED], 0, device); -} - /** * nm_client_get_connectivity: * @client: an #NMClient @@ -1324,7 +1403,7 @@ client_device_removed (NMObject *client, NMObject *device) * connectivity state first before returning any information. * * Returns: the current connectivity state - * Since: 0.9.8.4 + * Since: 0.9.8.6 */ NMConnectivityState nm_client_get_connectivity (NMClient *client) @@ -1353,7 +1432,7 @@ nm_client_get_connectivity (NMClient *client) * if you do not want to block. * * Returns: the (new) current connectivity state - * Since: 0.9.8.4 + * Since: 0.9.8.6 */ NMConnectivityState nm_client_check_connectivity (NMClient *client, @@ -1404,11 +1483,9 @@ check_connectivity_cb (DBusGProxy *proxy, CheckConnectivityData *ccd = g_simple_async_result_get_op_res_gpointer (simple); GError *error = NULL; - if (g_cancellable_set_error_if_cancelled (ccd->cancellable, &error)) - g_simple_async_result_take_error (simple, error); - else if (!dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_UINT, &ccd->connectivity, - G_TYPE_INVALID)) + if (!dbus_g_proxy_end_call (proxy, call, &error, + G_TYPE_UINT, &ccd->connectivity, + G_TYPE_INVALID)) g_simple_async_result_take_error (simple, error); g_simple_async_result_complete (simple); @@ -1441,7 +1518,7 @@ check_connectivity_cancelled_cb (GCancellable *cancellable, * which (immediately) returns the most recent known state without * re-checking, and nm_client_check_connectivity(), which blocks. * - * Since: 0.9.8.4 + * Since: 0.9.8.6 */ void nm_client_check_connectivity_async (NMClient *client, @@ -1468,6 +1545,7 @@ nm_client_check_connectivity_async (NMClient *client, ccd->cancelled_id = g_signal_connect (cancellable, "cancelled", G_CALLBACK (check_connectivity_cancelled_cb), simple); + g_simple_async_result_set_check_cancellable (simple, cancellable); } ccd->call = dbus_g_proxy_begin_call (priv->client_proxy, "CheckConnectivity", @@ -1485,7 +1563,7 @@ nm_client_check_connectivity_async (NMClient *client, * call. * * Returns: the (new) current connectivity state - * Since: 0.9.8.4 + * Since: 0.9.8.6 */ NMConnectivityState nm_client_check_connectivity_finish (NMClient *client, @@ -1521,31 +1599,21 @@ nm_client_check_connectivity_finish (NMClient *client, * control them. To access and modify network configuration data, use the * #NMRemoteSettings object. * - * Returns: a new #NMClient + * Returns: a new #NMClient or NULL on an error **/ NMClient * nm_client_new (void) { - DBusGConnection *connection; - GError *err = NULL; NMClient *client; -#ifdef LIBNM_GLIB_TEST - connection = dbus_g_bus_get (DBUS_BUS_SESSION, &err); -#else - connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); -#endif - if (!connection) { - g_warning ("Couldn't connect to system bus: %s", err->message); - g_error_free (err); - return NULL; - } + client = g_object_new (NM_TYPE_CLIENT, NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, NULL); + + /* NMObject's constructor() can fail on a D-Bus connection error. So we can + * get NULL here instead of a valid NMClient object. + */ + if (client) + _nm_object_ensure_inited (NM_OBJECT (client)); - client = g_object_new (NM_TYPE_CLIENT, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, - NULL); - _nm_object_ensure_inited (NM_OBJECT (client)); return client; } @@ -1571,39 +1639,31 @@ client_inited (GObject *source, GAsyncResult *result, gpointer user_data) * * Creates a new #NMClient and begins asynchronously initializing it. * @callback will be called when it is done; use - * nm_client_new_finish() to get the result. + * nm_client_new_finish() to get the result. Note that on an error, + * the callback can be invoked with two first parameters as NULL. * * NOTE: #NMClient provides information about devices and a mechanism to * control them. To access and modify network configuration data, use the * #NMRemoteSettings object. **/ void -nm_client_new_async (GCancellable *cancellable, GAsyncReadyCallback callback, +nm_client_new_async (GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data) { - DBusGConnection *connection; - GError *err = NULL; NMClient *client; GSimpleAsyncResult *simple; - simple = g_simple_async_result_new (NULL, callback, user_data, nm_client_new_async); - -#ifdef LIBNM_GLIB_TEST - connection = dbus_g_bus_get (DBUS_BUS_SESSION, &err); -#else - connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); -#endif - if (!connection) { - g_simple_async_result_take_error (simple, err); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); + client = g_object_new (NM_TYPE_CLIENT, NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, NULL); + /* When client is NULL, do no continue with initialization and run callback + * directly with result == NULL indicating NMClient creation failure. + */ + if (!client) { + callback (NULL, NULL, user_data); return; } - client = g_object_new (NM_TYPE_CLIENT, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, - NULL); + simple = g_simple_async_result_new (NULL, callback, user_data, nm_client_new_async); g_async_initable_init_async (G_ASYNC_INITABLE (client), G_PRIORITY_DEFAULT, cancellable, client_inited, simple); } @@ -1622,6 +1682,16 @@ nm_client_new_finish (GAsyncResult *result, GError **error) { GSimpleAsyncResult *simple; + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!result) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_UNKNOWN, + "NMClient initialization failed (or you passed NULL 'result' by mistake)"); + return NULL; + } + g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, nm_client_new_async), NULL); simple = G_SIMPLE_ASYNC_RESULT (result); @@ -1732,20 +1802,18 @@ constructor (GType type, static void constructed (GObject *object) { - DBusGConnection *connection; - NMClientPrivate *priv; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); + GError *error = NULL; - nm_utils_init (NULL); + if (!nm_utils_init (&error)) { + g_warning ("Couldn't initilize nm-utils/crypto system: %d %s", + error->code, error->message); + g_clear_error (&error); + } G_OBJECT_CLASS (nm_client_parent_class)->constructed (object); - priv = NM_CLIENT_GET_PRIVATE (object); - connection = nm_object_get_connection (NM_OBJECT (object)); - - priv->client_proxy = dbus_g_proxy_new_for_name (connection, - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE); + priv->client_proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE); register_properties (NM_CLIENT (object)); @@ -1757,18 +1825,23 @@ constructed (GObject *object) object, NULL); - priv->bus_proxy = dbus_g_proxy_new_for_name (connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - - dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->bus_proxy, - "NameOwnerChanged", - G_CALLBACK (proxy_name_owner_changed), - object, NULL); + if (_nm_object_is_connection_private (NM_OBJECT (object))) + priv->manager_running = TRUE; + else { + priv->bus_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + g_assert (priv->bus_proxy); + + dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->bus_proxy, + "NameOwnerChanged", + G_CALLBACK (proxy_name_owner_changed), + object, NULL); + } g_signal_connect (object, "notify::" NM_CLIENT_WIRELESS_ENABLED, G_CALLBACK (wireless_enabled_cb), NULL); @@ -1789,13 +1862,15 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) if (!nm_client_parent_initable_iface->init (initable, cancellable, error)) return FALSE; - if (!dbus_g_proxy_call (priv->bus_proxy, - "NameHasOwner", error, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_INVALID, - G_TYPE_BOOLEAN, &priv->manager_running, - G_TYPE_INVALID)) - return FALSE; + if (!_nm_object_is_connection_private (NM_OBJECT (client))) { + if (!dbus_g_proxy_call (priv->bus_proxy, + "NameHasOwner", error, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, &priv->manager_running, + G_TYPE_INVALID)) + return FALSE; + } if (priv->manager_running && !get_permissions_sync (client, error)) return FALSE; @@ -1851,6 +1926,22 @@ init_async_got_properties (GObject *source, GAsyncResult *result, gpointer user_ init_async_complete (init_data); } +static void +finish_init (NMClientInitData *init_data) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (init_data->client); + + nm_client_parent_async_initable_iface->init_async (G_ASYNC_INITABLE (init_data->client), + G_PRIORITY_DEFAULT, NULL, /* FIXME cancellable */ + init_async_got_properties, init_data); + init_data->properties_pending = TRUE; + + dbus_g_proxy_begin_call (priv->client_proxy, "GetPermissions", + init_async_got_permissions, init_data, NULL, + G_TYPE_INVALID); + init_data->permissions_pending = TRUE; +} + static void init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) @@ -1872,15 +1963,7 @@ init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call, return; } - nm_client_parent_async_initable_iface->init_async (G_ASYNC_INITABLE (init_data->client), - G_PRIORITY_DEFAULT, NULL, /* FIXME cancellable */ - init_async_got_properties, init_data); - init_data->properties_pending = TRUE; - - dbus_g_proxy_begin_call (priv->client_proxy, "GetPermissions", - init_async_got_permissions, init_data, NULL, - G_TYPE_INVALID); - init_data->permissions_pending = TRUE; + finish_init (init_data); } static void @@ -1897,12 +1980,16 @@ init_async (GAsyncInitable *initable, int io_priority, user_data, init_async); g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); - /* Check if NM is running */ - dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner", - init_async_got_manager_running, - init_data, NULL, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_INVALID); + if (_nm_object_is_connection_private (NM_OBJECT (init_data->client))) + finish_init (init_data); + else { + /* Check if NM is running */ + dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner", + init_async_got_manager_running, + init_data, NULL, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID); + } } static gboolean @@ -1935,8 +2022,7 @@ dispose (GObject *object) g_clear_object (&priv->primary_connection); g_clear_object (&priv->activating_connection); - g_slist_foreach (priv->pending_activations, (GFunc) activate_info_free, NULL); - g_slist_free (priv->pending_activations); + g_slist_free_full (priv->pending_activations, (GDestroyNotify) activate_info_free); priv->pending_activations = NULL; g_hash_table_destroy (priv->permissions); @@ -2015,6 +2101,9 @@ get_property (GObject *object, case PROP_STATE: g_value_set_uint (value, nm_client_get_state (self)); break; + case PROP_STARTUP: + g_value_set_boolean (value, nm_client_get_startup (self)); + break; case PROP_MANAGER_RUNNING: g_value_set_boolean (value, priv->manager_running); break; @@ -2051,6 +2140,9 @@ get_property (GObject *object, case PROP_ACTIVATING_CONNECTION: g_value_set_object (value, priv->activating_connection); break; + case PROP_DEVICES: + g_value_set_boxed (value, nm_client_get_devices (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2099,6 +2191,21 @@ nm_client_class_init (NMClientClass *client_class) NM_STATE_UNKNOWN, NM_STATE_CONNECTED_GLOBAL, NM_STATE_UNKNOWN, G_PARAM_READABLE)); + /** + * NMClient:startup: + * + * Whether the daemon is still starting up. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_STARTUP, + g_param_spec_boolean (NM_CLIENT_STARTUP, + "Startup", + "Whether the daemon is still starting up", + FALSE, + G_PARAM_READABLE)); + /** * NMClient::manager-running: * @@ -2222,7 +2329,7 @@ nm_client_class_init (NMClientClass *client_class) * * The network connectivity state. * - * Since: 0.9.8.4 + * Since: 0.9.8.6 */ g_object_class_install_property (object_class, PROP_CONNECTIVITY, @@ -2238,7 +2345,7 @@ nm_client_class_init (NMClientClass *client_class) * The #NMActiveConnection of the device with the default route; * see nm_client_get_primary_connection() for more details. * - * Since: 0.9.8.4 + * Since: 0.9.8.6 **/ g_object_class_install_property (object_class, PROP_PRIMARY_CONNECTION, @@ -2254,7 +2361,7 @@ nm_client_class_init (NMClientClass *client_class) * The #NMActiveConnection of the activating connection that is * likely to become the new #NMClient:primary-connection. * - * Since: 0.9.8.4 + * Since: 0.9.8.6 **/ g_object_class_install_property (object_class, PROP_ACTIVATING_CONNECTION, @@ -2264,6 +2371,21 @@ nm_client_class_init (NMClientClass *client_class) NM_TYPE_ACTIVE_CONNECTION, G_PARAM_READABLE)); + /** + * NMClient:devices: + * + * List of known network devices. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_DEVICES, + g_param_spec_boxed (NM_CLIENT_DEVICES, + "Devices", + "Devices", + NM_TYPE_OBJECT_ARRAY, + G_PARAM_READABLE)); + /* signals */ /** @@ -2278,8 +2400,7 @@ nm_client_class_init (NMClientClass *client_class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMClientClass, device_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); @@ -2295,8 +2416,7 @@ nm_client_class_init (NMClientClass *client_class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMClientClass, device_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); @@ -2312,8 +2432,7 @@ nm_client_class_init (NMClientClass *client_class) g_signal_new ("permission-changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - _nm_glib_marshal_VOID__UINT_UINT, + 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); } diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index b4da609f..1baabecc 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -45,6 +45,7 @@ G_BEGIN_DECLS #define NM_CLIENT_VERSION "version" #define NM_CLIENT_STATE "state" +#define NM_CLIENT_STARTUP "startup" #define NM_CLIENT_MANAGER_RUNNING "manager-running" #define NM_CLIENT_NETWORKING_ENABLED "networking-enabled" #define NM_CLIENT_WIRELESS_ENABLED "wireless-enabled" @@ -57,13 +58,14 @@ G_BEGIN_DECLS #define NM_CLIENT_CONNECTIVITY "connectivity" #define NM_CLIENT_PRIMARY_CONNECTION "primary-connection" #define NM_CLIENT_ACTIVATING_CONNECTION "activating-connection" +#define NM_CLIENT_DEVICES "devices" /** * NMClientPermission: * @NM_CLIENT_PERMISSION_NONE: unknown or no permission * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK: controls whether networking * can be globally enabled or disabled - * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI: controls whether WiFi can be + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI: controls whether Wi-Fi can be * globally enabled or disabled * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN: controls whether WWAN (3G) can be * globally enabled or disabled @@ -74,8 +76,8 @@ G_BEGIN_DECLS * @NM_CLIENT_PERMISSION_NETWORK_CONTROL: controls whether networking connections * can be started, stopped, and changed * @NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED: controls whether a password - * protected WiFi hotspot can be created - * @NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN: controls whether an open WiFi hotspot + * protected Wi-Fi hotspot can be created + * @NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN: controls whether an open Wi-Fi hotspot * can be created * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM: controls whether connections * that are available to all users can be modified @@ -124,6 +126,22 @@ typedef enum { NM_CLIENT_PERMISSION_RESULT_NO } NMClientPermissionResult; +/** + * NMClientError: + * @NM_CLIENT_ERROR_UNKNOWN: unknown or unclassified error + * @NM_CLIENT_ERROR_MANAGER_NOT_RUNNING: an operation that requires NetworkManager + * failed because NetworkManager is not running + * + * Describes errors that may result from operations involving a #NMClient. + **/ +typedef enum { + NM_CLIENT_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, /*< nick=ManagerNotRunning >*/ +} NMClientError; + +#define NM_CLIENT_ERROR nm_client_error_quark () +NM_AVAILABLE_IN_0_9_10 +GQuark nm_client_error_quark (void); typedef struct { NMObject parent; @@ -206,6 +224,8 @@ gboolean nm_client_wimax_hardware_get_enabled (NMClient *client); const char *nm_client_get_version (NMClient *client); NMState nm_client_get_state (NMClient *client); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_client_get_startup (NMClient *client); gboolean nm_client_get_manager_running (NMClient *client); const GPtrArray *nm_client_get_active_connections (NMClient *client); void nm_client_sleep (NMClient *client, gboolean sleep_); diff --git a/libnm-glib/nm-dbus-helpers-private.h b/libnm-glib/nm-dbus-helpers-private.h new file mode 100644 index 00000000..81c77203 --- /dev/null +++ b/libnm-glib/nm-dbus-helpers-private.h @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * libnm_glib -- Access network status & information from glib applications + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2013 Red Hat, Inc. + */ + +#ifndef NM_DBUS_HELPERS_PRIVATE_H +#define NM_DBUS_HELPERS_PRIVATE_H + +#include +#include +#include + +DBusGConnection *_nm_dbus_new_connection (GError **error); + +gboolean _nm_dbus_is_connection_private (DBusGConnection *connection); + +DBusGProxy * _nm_dbus_new_proxy_for_connection (DBusGConnection *connection, + const char *path, + const char *interface); + +#endif /* NM_DBUS_HELPERS_PRIVATE_H */ diff --git a/libnm-glib/nm-dbus-helpers.c b/libnm-glib/nm-dbus-helpers.c new file mode 100644 index 00000000..731ad0c8 --- /dev/null +++ b/libnm-glib/nm-dbus-helpers.c @@ -0,0 +1,107 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * libnm_glib -- Access network status & information from glib applications + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2013 Red Hat, Inc. + */ + +#include +#include +#include +#include +#include +#include "nm-dbus-helpers-private.h" +#include "NetworkManager.h" + +static dbus_int32_t priv_slot = -1; + +static gboolean +_ensure_dbus_data_slot (void) +{ + static gsize init_value = 0; + gboolean success = TRUE; + + if (g_once_init_enter (&init_value)) { + success = dbus_connection_allocate_data_slot (&priv_slot); + g_once_init_leave (&init_value, 1); + } + return success; +} + +DBusGConnection * +_nm_dbus_new_connection (GError **error) +{ + DBusGConnection *connection = NULL; + + if (!_ensure_dbus_data_slot ()) { + g_set_error (error, DBUS_GERROR, DBUS_GERROR_FAILED, "failed to allocated data slot"); + return NULL; + } + +#if HAVE_DBUS_GLIB_100 + /* If running as root try the private bus first */ + if (0 == geteuid ()) { + connection = dbus_g_connection_open ("unix:path=" NMRUNDIR "/private", error); + if (connection) { + DBusConnection *dbus_connection = dbus_g_connection_get_connection (connection); + + /* Mark this connection as private */ + dbus_connection_set_data (dbus_connection, priv_slot, GUINT_TO_POINTER (TRUE), NULL); + dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE); + return connection; + } + /* Fall back to a bus if for some reason private socket isn't available */ + g_clear_error (error); + } +#endif + + if (connection == NULL) { +#ifdef LIBNM_GLIB_TEST + connection = dbus_g_bus_get (DBUS_BUS_SESSION, error); +#else + connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, error); +#endif + } + + return connection; +} + +gboolean +_nm_dbus_is_connection_private (DBusGConnection *connection) +{ + if (!_ensure_dbus_data_slot ()) + return FALSE; + return !!dbus_connection_get_data (dbus_g_connection_get_connection (connection), priv_slot); +} + +DBusGProxy * +_nm_dbus_new_proxy_for_connection (DBusGConnection *connection, + const char *path, + const char *interface) +{ + /* Private connections can't use dbus_g_proxy_new_for_name() or + * dbus_g_proxy_new_for_name_owner() because peer-to-peer connections don't + * have either a bus daemon or name owners, both of which those functions + * require. + */ + if (_nm_dbus_is_connection_private (connection)) + return dbus_g_proxy_new_for_peer (connection, path, interface); + + return dbus_g_proxy_new_for_name (connection, NM_DBUS_SERVICE, path, interface); +} + diff --git a/libnm-glib/nm-device-adsl.c b/libnm-glib/nm-device-adsl.c index bef3ceae..b3f9691e 100644 --- a/libnm-glib/nm-device-adsl.c +++ b/libnm-glib/nm-device-adsl.c @@ -46,7 +46,6 @@ enum { PROP_CARRIER, LAST_PROP }; -#define DBUS_PROP_CARRIER "Carrier" /** * nm_device_adsl_error_quark: @@ -131,7 +130,13 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro return FALSE; } - return TRUE; + return NM_DEVICE_CLASS (nm_device_adsl_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_ADSL; } /******************************************************************/ @@ -159,17 +164,11 @@ register_properties (NMDeviceAdsl *device) static void constructed (GObject *object) { - NMDeviceAdslPrivate *priv; + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructed (object); - priv = NM_DEVICE_ADSL_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_ADSL); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_ADSL); register_properties (NM_DEVICE_ADSL (object)); } @@ -228,6 +227,7 @@ nm_device_adsl_class_init (NMDeviceAdslClass *adsl_class) object_class->finalize = finalize; object_class->get_property = get_property; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; /* properties */ /** diff --git a/libnm-glib/nm-device-bond.c b/libnm-glib/nm-device-bond.c index 6261db91..b2af2ec3 100644 --- a/libnm-glib/nm-device-bond.c +++ b/libnm-glib/nm-device-bond.c @@ -56,10 +56,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_CARRIER "Carrier" -#define DBUS_PROP_SLAVES "Slaves" - /** * nm_device_bond_error_quark: * @@ -144,7 +140,7 @@ nm_device_bond_get_carrier (NMDeviceBond *device) * Gets the devices currently slaved to @device. * * Returns: (element-type NMClient.Device): the #GPtrArray containing - * #NMDevices that are slaves of @device. This is the internal + * #NMDevices that are slaves of @device. This is the internal * copy used by the device, and must not be modified. * * Since: 0.9.6.4 @@ -165,8 +161,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro NMSettingBond *s_bond; const char *ctype, *dev_iface_name, *bond_iface_name; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -194,7 +188,19 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro /* FIXME: check slaves? */ - return TRUE; + return NM_DEVICE_CLASS (nm_device_bond_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_BOND; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_bond_get_hw_address (NM_DEVICE_BOND (device)); } /***********************************************************/ @@ -224,17 +230,11 @@ register_properties (NMDeviceBond *device) static void constructed (GObject *object) { - NMDeviceBondPrivate *priv; + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_bond_parent_class)->constructed (object); - priv = NM_DEVICE_BOND_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_BOND); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_BOND); register_properties (NM_DEVICE_BOND (object)); } @@ -246,7 +246,7 @@ dispose (GObject *object) g_clear_object (&priv->proxy); if (priv->slaves) { - g_ptr_array_foreach (priv->slaves, (GFunc) g_object_unref, NULL); + g_ptr_array_set_free_func (priv->slaves, g_object_unref); g_ptr_array_free (priv->slaves, TRUE); priv->slaves = NULL; } @@ -304,6 +304,8 @@ nm_device_bond_class_init (NMDeviceBondClass *eth_class) object_class->finalize = finalize; object_class->get_property = get_property; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; /* properties */ diff --git a/libnm-glib/nm-device-bridge.c b/libnm-glib/nm-device-bridge.c index 9327a931..c8967e20 100644 --- a/libnm-glib/nm-device-bridge.c +++ b/libnm-glib/nm-device-bridge.c @@ -56,10 +56,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_CARRIER "Carrier" -#define DBUS_PROP_SLAVES "Slaves" - /** * nm_device_bridge_error_quark: * @@ -152,7 +148,7 @@ nm_device_bridge_get_carrier (NMDeviceBridge *device) * Gets the devices currently slaved to @device. * * Returns: (element-type NMClient.Device): the #GPtrArray containing - * #NMDevices that are slaves of @device. This is the internal + * #NMDevices that are slaves of @device. This is the internal * copy used by the device, and must not be modified. * * Since: 0.9.8 @@ -173,8 +169,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro NMSettingBridge *s_bridge; const char *ctype, *dev_iface_name, *bridge_iface_name; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -202,7 +196,19 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro /* FIXME: check ports? */ - return TRUE; + return NM_DEVICE_CLASS (nm_device_bridge_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_BRIDGE; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_bridge_get_hw_address (NM_DEVICE_BRIDGE (device)); } /***********************************************************/ @@ -232,17 +238,11 @@ register_properties (NMDeviceBridge *device) static void constructed (GObject *object) { - NMDeviceBridgePrivate *priv; + NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_bridge_parent_class)->constructed (object); - priv = NM_DEVICE_BRIDGE_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_BRIDGE); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_BRIDGE); register_properties (NM_DEVICE_BRIDGE (object)); } @@ -254,7 +254,7 @@ dispose (GObject *object) g_clear_object (&priv->proxy); if (priv->slaves) { - g_ptr_array_foreach (priv->slaves, (GFunc) g_object_unref, NULL); + g_ptr_array_set_free_func (priv->slaves, g_object_unref); g_ptr_array_free (priv->slaves, TRUE); priv->slaves = NULL; } @@ -312,6 +312,8 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *bridge_class) object_class->finalize = finalize; object_class->get_property = get_property; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; /* properties */ diff --git a/libnm-glib/nm-device-bt.c b/libnm-glib/nm-device-bt.c index ccfa83ca..4c39ad04 100644 --- a/libnm-glib/nm-device-bt.c +++ b/libnm-glib/nm-device-bt.c @@ -55,10 +55,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_NAME "Name" -#define DBUS_PROP_BT_CAPABILITIES "BtCapabilities" - /** * nm_device_bt_error_quark: * @@ -182,8 +178,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro NMBluetoothCapabilities dev_caps; NMBluetoothCapabilities bt_type; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -226,7 +220,19 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro return FALSE; } - return TRUE; + return NM_DEVICE_CLASS (nm_device_bt_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_BLUETOOTH; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_bt_get_hw_address (NM_DEVICE_BT (device)); } /************************************************************/ @@ -260,11 +266,7 @@ constructed (GObject *object) G_OBJECT_CLASS (nm_device_bt_parent_class)->constructed (object); - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_BLUETOOTH); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_BLUETOOTH); register_properties (NM_DEVICE_BT (object)); } @@ -329,6 +331,8 @@ nm_device_bt_class_init (NMDeviceBtClass *bt_class) object_class->finalize = finalize; object_class->get_property = get_property; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; /* properties */ diff --git a/libnm-glib/nm-device-ethernet.c b/libnm-glib/nm-device-ethernet.c index e9d1b4ad..8f317115 100644 --- a/libnm-glib/nm-device-ethernet.c +++ b/libnm-glib/nm-device-ethernet.c @@ -58,11 +58,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_PERM_HW_ADDRESS "PermHwAddress" -#define DBUS_PROP_SPEED "Speed" -#define DBUS_PROP_CARRIER "Carrier" - /** * nm_device_ethernet_error_quark: * @@ -183,8 +178,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro const char *ctype; gboolean is_pppoe = FALSE; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -201,7 +194,7 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro /* Wired setting optional for PPPoE */ if (!is_pppoe && !s_wired) { g_set_error (error, NM_DEVICE_ETHERNET_ERROR, NM_DEVICE_ETHERNET_ERROR_INVALID_ETHERNET_CONNECTION, - "The connection was not a valid ethernet connection."); + "The connection was not a valid Ethernet connection."); return FALSE; } @@ -230,7 +223,19 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro } } - return TRUE; + return NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_WIRED; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)); } /***********************************************************/ @@ -261,17 +266,11 @@ register_properties (NMDeviceEthernet *device) static void constructed (GObject *object) { - NMDeviceEthernetPrivate *priv; + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_ethernet_parent_class)->constructed (object); - priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_WIRED); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_WIRED); register_properties (NM_DEVICE_ETHERNET (object)); } @@ -339,6 +338,8 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class) object_class->finalize = finalize; object_class->get_property = get_property; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; /* properties */ diff --git a/libnm-glib/nm-device-ethernet.h b/libnm-glib/nm-device-ethernet.h index 4028d62c..a68a97ec 100644 --- a/libnm-glib/nm-device-ethernet.h +++ b/libnm-glib/nm-device-ethernet.h @@ -38,8 +38,8 @@ G_BEGIN_DECLS /** * NMDeviceEthernetError: * @NM_DEVICE_ETHERNET_ERROR_UNKNOWN: unknown or unclassified error - * @NM_DEVICE_ETHERNET_ERROR_NOT_ETHERNET_CONNECTION: the connection was not of ethernet or PPPoE type - * @NM_DEVICE_ETHERNET_ERROR_INVALID_ETHERNET_CONNECTION: the ethernet connection was invalid + * @NM_DEVICE_ETHERNET_ERROR_NOT_ETHERNET_CONNECTION: the connection was not of Ethernet or PPPoE type + * @NM_DEVICE_ETHERNET_ERROR_INVALID_ETHERNET_CONNECTION: the Ethernet connection was invalid * @NM_DEVICE_ETHERNET_ERROR_INVALID_DEVICE_MAC: the device's MAC was invalid * @NM_DEVICE_ETHERNET_ERROR_MAC_MISMATCH: the MACs of the connection and the device mismatched */ diff --git a/libnm-glib/nm-device-generic.c b/libnm-glib/nm-device-generic.c new file mode 100644 index 00000000..2a45294f --- /dev/null +++ b/libnm-glib/nm-device-generic.c @@ -0,0 +1,289 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * libnm_glib -- Access network status & information from glib applications + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include + +#include + +#include "nm-device-generic.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-setting-generic.h" + +G_DEFINE_TYPE (NMDeviceGeneric, nm_device_generic, NM_TYPE_DEVICE) + +#define NM_DEVICE_GENERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericPrivate)) + +typedef struct { + DBusGProxy *proxy; + + char *hw_address; + char *type_description; +} NMDeviceGenericPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_TYPE_DESCRIPTION, + + LAST_PROP +}; + +/** + * nm_device_generic_error_quark: + * + * Registers an error quark for #NMDeviceGeneric if necessary. + * + * Returns: the error quark used for #NMDeviceGeneric errors. + * + * Since: 0.9.10 + **/ +GQuark +nm_device_generic_error_quark (void) +{ + static GQuark quark = 0; + + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_static_string ("nm-device-generic-error-quark"); + return quark; +} + +/** + * nm_device_generic_new: + * @connection: the #DBusGConnection + * @path: the DBus object path of the device + * + * Creates a new #NMDeviceGeneric. + * + * Returns: (transfer full): a new device + * + * Since: 0.9.10 + **/ +GObject * +nm_device_generic_new (DBusGConnection *connection, const char *path) +{ + GObject *device; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + + device = g_object_new (NM_TYPE_DEVICE_GENERIC, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); + _nm_object_ensure_inited (NM_OBJECT (device)); + return device; +} + +/** + * nm_device_generic_get_hw_address: + * @device: a #NMDeviceGeneric + * + * Gets the hardware address of the #NMDeviceGeneric + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 0.9.10 + **/ +const char * +nm_device_generic_get_hw_address (NMDeviceGeneric *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_GENERIC (device), NULL); + + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GENERIC_GET_PRIVATE (device)->hw_address; +} + +/***********************************************************/ + +static const char * +get_type_description (NMDevice *device) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (device); + + _nm_object_ensure_inited (NM_OBJECT (device)); + return priv->type_description; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_generic_get_hw_address (NM_DEVICE_GENERIC (device)); +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingConnection *s_con; + const char *ctype, *iface_name; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + ctype = nm_setting_connection_get_connection_type (s_con); + if (strcmp (ctype, NM_SETTING_GENERIC_SETTING_NAME) != 0) { + g_set_error (error, NM_DEVICE_GENERIC_ERROR, NM_DEVICE_GENERIC_ERROR_NOT_GENERIC_CONNECTION, + "The connection was not a generic connection."); + return FALSE; + } + + iface_name = nm_setting_connection_get_interface_name (s_con); + if (!iface_name) { + g_set_error (error, NM_DEVICE_GENERIC_ERROR, NM_DEVICE_GENERIC_ERROR_MISSING_INTERFACE_NAME, + "The connection did not specify an interface name."); + return FALSE; + } + + return NM_DEVICE_CLASS (nm_device_generic_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_GENERIC; +} + +/***********************************************************/ + +static void +nm_device_generic_init (NMDeviceGeneric *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_GENERIC); +} + +static void +register_properties (NMDeviceGeneric *device) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (device); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_GENERIC_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_GENERIC_TYPE_DESCRIPTION, &priv->type_description }, + { NULL }, + }; + + _nm_object_register_properties (NM_OBJECT (device), + priv->proxy, + property_info); +} + +static void +constructed (GObject *object) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + G_OBJECT_CLASS (nm_device_generic_parent_class)->constructed (object); + + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_GENERIC); + register_properties (NM_DEVICE_GENERIC (object)); +} + +static void +dispose (GObject *object) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + g_clear_object (&priv->proxy); + + G_OBJECT_CLASS (nm_device_generic_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + g_free (priv->hw_address); + g_free (priv->type_description); + + G_OBJECT_CLASS (nm_device_generic_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + _nm_object_ensure_inited (NM_OBJECT (object)); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, priv->hw_address); + break; + case PROP_TYPE_DESCRIPTION: + g_value_set_string (value, priv->type_description); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_generic_class_init (NMDeviceGenericClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMDeviceGenericPrivate)); + + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + + device_class->get_type_description = get_type_description; + device_class->get_hw_address = get_hw_address; + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceGeneric:hw-address: + * + * The hardware address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_GENERIC_HW_ADDRESS, + "Hardware Address", + "Hardware address", + NULL, + G_PARAM_READABLE)); + + /** + * NMDeviceGeneric:type-description: + * + * A description of the specific type of device this is, or %NULL + * if not known. + **/ + g_object_class_install_property + (object_class, PROP_TYPE_DESCRIPTION, + g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, + "Type Description", + "Type description", + NULL, + G_PARAM_READABLE)); +} + diff --git a/libnm-glib/nm-device-generic.h b/libnm-glib/nm-device-generic.h new file mode 100644 index 00000000..a343d988 --- /dev/null +++ b/libnm-glib/nm-device-generic.h @@ -0,0 +1,81 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * libnm_glib -- Access network status & information from glib applications + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef NM_DEVICE_GENERIC_H +#define NM_DEVICE_GENERIC_H + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_GENERIC (nm_device_generic_get_type ()) +#define NM_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGeneric)) +#define NM_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) +#define NM_IS_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_GENERIC)) +#define NM_IS_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_GENERIC)) +#define NM_DEVICE_GENERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) + +/** + * NMDeviceGenericError: + * @NM_DEVICE_GENERIC_ERROR_UNKNOWN: unknown or unclassified error + * @NM_DEVICE_GENERIC_ERROR_NOT_GENERIC_CONNECTION: the connection was not of generic type + * @NM_DEVICE_GENERIC_ERROR_MISSING_INTERFACE_NAME: the connection did not specify the interface name + */ +typedef enum { + NM_DEVICE_GENERIC_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ + NM_DEVICE_GENERIC_ERROR_NOT_GENERIC_CONNECTION, /*< nick=NotGenericConnection >*/ + NM_DEVICE_GENERIC_ERROR_MISSING_INTERFACE_NAME, /*< nick=MissingInterfaceName >*/ +} NMDeviceGenericError; + +#define NM_DEVICE_GENERIC_ERROR nm_device_generic_error_quark () +GQuark nm_device_generic_error_quark (void); + +#define NM_DEVICE_GENERIC_HW_ADDRESS "hw-address" +#define NM_DEVICE_GENERIC_TYPE_DESCRIPTION "type-description" + +typedef struct { + NMDevice parent; +} NMDeviceGeneric; + +typedef struct { + NMDeviceClass parent; + + /* Padding for future expansion */ + void (*_reserved1) (void); + void (*_reserved2) (void); + void (*_reserved3) (void); + void (*_reserved4) (void); + void (*_reserved5) (void); + void (*_reserved6) (void); +} NMDeviceGenericClass; + +NM_AVAILABLE_IN_0_9_10 +GType nm_device_generic_get_type (void); + +NM_AVAILABLE_IN_0_9_10 +GObject *nm_device_generic_new (DBusGConnection *connection, const char *path); + +const char *nm_device_generic_get_hw_address (NMDeviceGeneric *device); + +G_END_DECLS + +#endif /* NM_DEVICE_GENERIC_H */ diff --git a/libnm-glib/nm-device-infiniband.c b/libnm-glib/nm-device-infiniband.c index d611993b..b60b2d82 100644 --- a/libnm-glib/nm-device-infiniband.c +++ b/libnm-glib/nm-device-infiniband.c @@ -54,9 +54,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_CARRIER "Carrier" - /** * nm_device_infiniband_error_quark: * @@ -143,8 +140,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro const GByteArray *mac; guint8 *hwaddr, hwaddr_buf[INFINIBAND_ALEN]; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -171,14 +166,28 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro return FALSE; } mac = nm_setting_infiniband_get_mac_address (s_infiniband); - if (mac && hwaddr && memcmp (mac->data, hwaddr, INFINIBAND_ALEN)) { + + /* We only match against the last 8 bytes */ + if (mac && hwaddr && memcmp (mac->data + INFINIBAND_ALEN - 8, hwaddr + INFINIBAND_ALEN - 8, 8)) { g_set_error (error, NM_DEVICE_INFINIBAND_ERROR, NM_DEVICE_INFINIBAND_ERROR_MAC_MISMATCH, "The MACs of the device and the connection didn't match."); return FALSE; } } - return TRUE; + return NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_INFINIBAND; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_infiniband_get_hw_address (NM_DEVICE_INFINIBAND (device)); } /***********************************************************/ @@ -207,17 +216,11 @@ register_properties (NMDeviceInfiniband *device) static void constructed (GObject *object) { - NMDeviceInfinibandPrivate *priv; + NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_infiniband_parent_class)->constructed (object); - priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_INFINIBAND); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_INFINIBAND); register_properties (NM_DEVICE_INFINIBAND (object)); } @@ -278,6 +281,8 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *eth_class) object_class->finalize = finalize; object_class->get_property = get_property; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; /* properties */ diff --git a/libnm-glib/nm-device-modem.c b/libnm-glib/nm-device-modem.c index f7a9230e..b3b357cf 100644 --- a/libnm-glib/nm-device-modem.c +++ b/libnm-glib/nm-device-modem.c @@ -33,7 +33,6 @@ #include "nm-device-modem.h" #include "nm-device-private.h" #include "nm-object-private.h" -#include "nm-glib-marshal.h" G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) @@ -55,9 +54,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_MODEM_CAPS "ModemCapabilities" -#define DBUS_PROP_CURRENT_CAPS "CurrentCapabilities" - /** * nm_device_modem_error_quark: * @@ -88,7 +84,6 @@ nm_device_modem_error_quark (void) NMDeviceModemCapabilities nm_device_modem_get_modem_capabilities (NMDeviceModem *self) { - g_return_val_if_fail (self != NULL, NM_DEVICE_MODEM_CAPABILITY_NONE); g_return_val_if_fail (NM_IS_DEVICE_MODEM (self), NM_DEVICE_MODEM_CAPABILITY_NONE); _nm_object_ensure_inited (NM_OBJECT (self)); @@ -109,13 +104,31 @@ nm_device_modem_get_modem_capabilities (NMDeviceModem *self) NMDeviceModemCapabilities nm_device_modem_get_current_capabilities (NMDeviceModem *self) { - g_return_val_if_fail (self != NULL, NM_DEVICE_MODEM_CAPABILITY_NONE); g_return_val_if_fail (NM_IS_DEVICE_MODEM (self), NM_DEVICE_MODEM_CAPABILITY_NONE); _nm_object_ensure_inited (NM_OBJECT (self)); return NM_DEVICE_MODEM_GET_PRIVATE (self)->current_caps; } +static const char * +get_type_description (NMDevice *device) +{ + NMDeviceModemCapabilities caps; + + caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); + if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) + return "gsm"; + else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) + return "cdma"; + else + return NULL; +} + +#define MODEM_CAPS_3GPP(caps) (caps & (NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | \ + NM_DEVICE_MODEM_CAPABILITY_LTE)) + +#define MODEM_CAPS_3GPP2(caps) (caps & (NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) + static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { @@ -125,8 +138,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro const char *ctype; NMDeviceModemCapabilities current_caps; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -147,14 +158,27 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro } current_caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); - if ( !(s_gsm && (current_caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)) - && !(s_cdma && (current_caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO))) { + if (!(s_gsm && MODEM_CAPS_3GPP (current_caps)) && !(s_cdma && MODEM_CAPS_3GPP2 (current_caps))) { g_set_error (error, NM_DEVICE_MODEM_ERROR, NM_DEVICE_MODEM_ERROR_MISSING_DEVICE_CAPS, "The device missed capabilities required by the GSM/CDMA connection."); return FALSE; } - return TRUE; + return NM_DEVICE_CLASS (nm_device_modem_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + NMDeviceModemCapabilities caps; + + caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); + if (caps & (NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | NM_DEVICE_MODEM_CAPABILITY_LTE)) + return NM_TYPE_SETTING_GSM; + else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) + return NM_TYPE_SETTING_CDMA; + else + return G_TYPE_INVALID; } /*******************************************************************/ @@ -183,17 +207,11 @@ register_properties (NMDeviceModem *device) static void constructed (GObject *object) { - NMDeviceModemPrivate *priv; + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_modem_parent_class)->constructed (object); - priv = NM_DEVICE_MODEM_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_MODEM); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_MODEM); register_properties (NM_DEVICE_MODEM (object)); } @@ -242,7 +260,10 @@ nm_device_modem_class_init (NMDeviceModemClass *modem_class) object_class->constructed = constructed; object_class->get_property = get_property; object_class->dispose = dispose; + + device_class->get_type_description = get_type_description; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; /** * NMDeviceModem:modem-capabilities: diff --git a/libnm-glib/nm-device-olpc-mesh.c b/libnm-glib/nm-device-olpc-mesh.c index 7ca36890..d1789eb9 100644 --- a/libnm-glib/nm-device-olpc-mesh.c +++ b/libnm-glib/nm-device-olpc-mesh.c @@ -55,10 +55,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_COMPANION "Companion" -#define DBUS_PROP_ACTIVE_CHANNEL "ActiveChannel" - /** * nm_device_olpc_mesh_error_quark: * @@ -154,6 +150,12 @@ nm_device_olpc_mesh_get_active_channel (NMDeviceOlpcMesh *device) return NM_DEVICE_OLPC_MESH_GET_PRIVATE (device)->active_channel; } +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_olpc_mesh_get_hw_address (NM_DEVICE_OLPC_MESH (device)); +} + static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { @@ -161,8 +163,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro NMSettingOlpcMesh *s_olpc_mesh; const char *ctype; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -180,7 +180,13 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro return FALSE; } - return TRUE; + return NM_DEVICE_CLASS (nm_device_olpc_mesh_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_OLPC_MESH; } /**************************************************************/ @@ -210,17 +216,11 @@ register_properties (NMDeviceOlpcMesh *device) static void constructed (GObject *object) { - NMDeviceOlpcMeshPrivate *priv; + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->constructed (object); - priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_OLPC_MESH); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_OLPC_MESH); register_properties (NM_DEVICE_OLPC_MESH (object)); } @@ -285,6 +285,8 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *olpc_mesh_class) object_class->finalize = finalize; object_class->get_property = get_property; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; /* properties */ diff --git a/libnm-glib/nm-device-team.c b/libnm-glib/nm-device-team.c new file mode 100644 index 00000000..f739e1d8 --- /dev/null +++ b/libnm-glib/nm-device-team.c @@ -0,0 +1,356 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2013 Jiri Pirko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include + +#include "nm-device-team.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-types.h" + +G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) + +#define NM_DEVICE_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TEAM, NMDeviceTeamPrivate)) + +typedef struct { + DBusGProxy *proxy; + + char *hw_address; + gboolean carrier; + GPtrArray *slaves; +} NMDeviceTeamPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + PROP_SLAVES, + + LAST_PROP +}; + +/** + * nm_device_team_error_quark: + * + * Registers an error quark for #NMDeviceTeam if necessary. + * + * Returns: the error quark used for #NMDeviceTeam errors. + * + * Since: 0.9.10 + **/ +GQuark +nm_device_team_error_quark (void) +{ + static GQuark quark = 0; + + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_static_string ("nm-device-team-error-quark"); + return quark; +} + +/** + * nm_device_team_new: + * @connection: the #DBusGConnection + * @path: the DBus object path of the device + * + * Creates a new #NMDeviceTeam. + * + * Returns: (transfer full): a new device + * + * Since: 0.9.10 + **/ +GObject * +nm_device_team_new (DBusGConnection *connection, const char *path) +{ + GObject *device; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + + device = g_object_new (NM_TYPE_DEVICE_TEAM, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); + _nm_object_ensure_inited (NM_OBJECT (device)); + return device; +} + +/** + * nm_device_team_get_hw_address: + * @device: a #NMDeviceTeam + * + * Gets the hardware (MAC) address of the #NMDeviceTeam + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + * + * Since: 0.9.10 + **/ +const char * +nm_device_team_get_hw_address (NMDeviceTeam *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TEAM (device), NULL); + + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_TEAM_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_team_get_carrier: + * @device: a #NMDeviceTeam + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + * + * Since: 0.9.10 + **/ +gboolean +nm_device_team_get_carrier (NMDeviceTeam *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TEAM (device), FALSE); + + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_TEAM_GET_PRIVATE (device)->carrier; +} + +/** + * nm_device_team_get_slaves: + * @device: a #NMDeviceTeam + * + * Gets the devices currently enslaved to @device. + * + * Returns: (element-type NMClient.Device): the #GPtrArray containing + * #NMDevices that are slaves of @device. This is the internal + * copy used by the device, and must not be modified. + * + * Since: 0.9.10 + **/ +const GPtrArray * +nm_device_team_get_slaves (NMDeviceTeam *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TEAM (device), FALSE); + + _nm_object_ensure_inited (NM_OBJECT (device)); + return handle_ptr_array_return (NM_DEVICE_TEAM_GET_PRIVATE (device)->slaves); +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_team_get_hw_address (NM_DEVICE_TEAM (device)); +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingConnection *s_con; + NMSettingTeam *s_team; + const char *ctype, *dev_iface_name, *team_iface_name; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + ctype = nm_setting_connection_get_connection_type (s_con); + if (strcmp (ctype, NM_SETTING_TEAM_SETTING_NAME) != 0) { + g_set_error (error, NM_DEVICE_TEAM_ERROR, NM_DEVICE_TEAM_ERROR_NOT_TEAM_CONNECTION, + "The connection was not a team connection."); + return FALSE; + } + + s_team = nm_connection_get_setting_team (connection); + if (!s_team) { + g_set_error (error, NM_DEVICE_TEAM_ERROR, NM_DEVICE_TEAM_ERROR_INVALID_TEAM_CONNECTION, + "The connection was not a valid team connection."); + return FALSE; + } + + dev_iface_name = nm_device_get_iface (device); + team_iface_name = nm_setting_team_get_interface_name (s_team); + if (g_strcmp0 (dev_iface_name, team_iface_name) != 0) { + g_set_error (error, NM_DEVICE_TEAM_ERROR, NM_DEVICE_TEAM_ERROR_INTERFACE_MISMATCH, + "The interfaces of the device and the connection didn't match."); + return FALSE; + } + + /* FIXME: check slaves? */ + + return NM_DEVICE_CLASS (nm_device_team_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_TEAM; +} + +/***********************************************************/ + +static void +nm_device_team_init (NMDeviceTeam *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_TEAM); +} + +static void +register_properties (NMDeviceTeam *device) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_TEAM_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_TEAM_CARRIER, &priv->carrier }, + { NM_DEVICE_TEAM_SLAVES, &priv->slaves, NULL, NM_TYPE_DEVICE }, + { NULL }, + }; + + _nm_object_register_properties (NM_OBJECT (device), + priv->proxy, + property_info); +} + +static void +constructed (GObject *object) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); + + G_OBJECT_CLASS (nm_device_team_parent_class)->constructed (object); + + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_TEAM); + register_properties (NM_DEVICE_TEAM (object)); +} + +static void +dispose (GObject *object) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); + + g_clear_object (&priv->proxy); + + if (priv->slaves) { + g_ptr_array_set_free_func (priv->slaves, g_object_unref); + g_ptr_array_free (priv->slaves, TRUE); + priv->slaves = NULL; + } + + G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); + + g_free (priv->hw_address); + + G_OBJECT_CLASS (nm_device_team_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceTeam *device = NM_DEVICE_TEAM (object); + + _nm_object_ensure_inited (NM_OBJECT (object)); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_team_get_hw_address (device)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_team_get_carrier (device)); + break; + case PROP_SLAVES: + g_value_set_boxed (value, nm_device_team_get_slaves (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_team_class_init (NMDeviceTeamClass *eth_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (eth_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (eth_class); + + g_type_class_add_private (eth_class, sizeof (NMDeviceTeamPrivate)); + + /* virtual methods */ + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceTeam:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_TEAM_HW_ADDRESS, + "Active MAC Address", + "Currently set hardware MAC address", + NULL, + G_PARAM_READABLE)); + + /** + * NMDeviceTeam:carrier: + * + * Whether the device has carrier. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_TEAM_CARRIER, + "Carrier", + "Carrier", + FALSE, + G_PARAM_READABLE)); + + /** + * NMDeviceTeam:slaves: + * + * The devices (#NMDevice) enslaved to the team device. + **/ + g_object_class_install_property + (object_class, PROP_SLAVES, + g_param_spec_boxed (NM_DEVICE_TEAM_SLAVES, + "Slaves", + "Slaves", + NM_TYPE_OBJECT_ARRAY, + G_PARAM_READABLE)); +} diff --git a/libnm-glib/nm-device-team.h b/libnm-glib/nm-device-team.h new file mode 100644 index 00000000..054f9ae2 --- /dev/null +++ b/libnm-glib/nm-device-team.h @@ -0,0 +1,85 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2013 Jiri Pirko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef NM_DEVICE_TEAM_H +#define NM_DEVICE_TEAM_H + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_TEAM (nm_device_team_get_type ()) +#define NM_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeam)) +#define NM_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) +#define NM_IS_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_TEAM)) +#define NM_IS_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_TEAM)) +#define NM_DEVICE_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) + +/** + * NMDeviceTeamError: + * @NM_DEVICE_TEAM_ERROR_UNKNOWN: unknown or unclassified error + * @NM_DEVICE_TEAM_ERROR_NOT_TEAM_CONNECTION: the connection was not of team type + * @NM_DEVICE_TEAM_ERROR_INVALID_TEAM_CONNECTION: the team connection was invalid + * @NM_DEVICE_TEAM_ERROR_INTERFACE_MISMATCH: the interfaces of the connection and the device mismatched + */ +typedef enum { + NM_DEVICE_TEAM_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ + NM_DEVICE_TEAM_ERROR_NOT_TEAM_CONNECTION, /*< nick=NotTeamConnection >*/ + NM_DEVICE_TEAM_ERROR_INVALID_TEAM_CONNECTION, /*< nick=InvalidTeamConnection >*/ + NM_DEVICE_TEAM_ERROR_INTERFACE_MISMATCH, /*< nick=InterfaceMismatch >*/ +} NMDeviceTeamError; + +#define NM_DEVICE_TEAM_ERROR nm_device_team_error_quark () +NM_AVAILABLE_IN_0_9_10 +GQuark nm_device_team_error_quark (void); + +#define NM_DEVICE_TEAM_HW_ADDRESS "hw-address" +#define NM_DEVICE_TEAM_CARRIER "carrier" +#define NM_DEVICE_TEAM_SLAVES "slaves" + +typedef struct { + NMDevice parent; +} NMDeviceTeam; + +typedef struct { + NMDeviceClass parent; + + /* Padding for future expansion */ + void (*_reserved1) (void); + void (*_reserved2) (void); + void (*_reserved3) (void); + void (*_reserved4) (void); + void (*_reserved5) (void); + void (*_reserved6) (void); +} NMDeviceTeamClass; + +NM_AVAILABLE_IN_0_9_10 +GType nm_device_team_get_type (void); + +NM_AVAILABLE_IN_0_9_10 +GObject *nm_device_team_new (DBusGConnection *connection, const char *path); + +const char *nm_device_team_get_hw_address (NMDeviceTeam *device); +gboolean nm_device_team_get_carrier (NMDeviceTeam *device); +const GPtrArray *nm_device_team_get_slaves (NMDeviceTeam *device); + +G_END_DECLS + +#endif /* NM_DEVICE_TEAM_H */ diff --git a/libnm-glib/nm-device-vlan.c b/libnm-glib/nm-device-vlan.c index 13ca3ac3..2a84b946 100644 --- a/libnm-glib/nm-device-vlan.c +++ b/libnm-glib/nm-device-vlan.c @@ -55,10 +55,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_CARRIER "Carrier" -#define DBUS_PROP_VLAN_ID "VlanId" - /** * nm_device_vlan_error_quark: * @@ -156,9 +152,10 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro { NMSettingConnection *s_con; NMSettingVlan *s_vlan; + NMSettingWired *s_wired; const char *ctype, *dev_iface_name, *vlan_iface_name; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + const GByteArray *mac_address; + char *mac_address_str; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -191,7 +188,33 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro return FALSE; } - return TRUE; + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) + mac_address = nm_setting_wired_get_mac_address (s_wired); + else + mac_address = NULL; + if (mac_address) { + mac_address_str = nm_utils_hwaddr_ntoa_len (mac_address->data, mac_address->len); + if (!g_strcmp0 (mac_address_str, NM_DEVICE_VLAN_GET_PRIVATE (device)->hw_address)) { + g_set_error (error, NM_DEVICE_VLAN_ERROR, NM_DEVICE_VLAN_ERROR_MAC_MISMATCH, + "The hardware address of the device and the connection didn't match."); + } + g_free (mac_address_str); + } + + return NM_DEVICE_CLASS (nm_device_vlan_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_VLAN; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_vlan_get_hw_address (NM_DEVICE_VLAN (device)); } /***********************************************************/ @@ -221,17 +244,11 @@ register_properties (NMDeviceVlan *device) static void constructed (GObject *object) { - NMDeviceVlanPrivate *priv; + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_vlan_parent_class)->constructed (object); - priv = NM_DEVICE_VLAN_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_VLAN); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_VLAN); register_properties (NM_DEVICE_VLAN (object)); } @@ -295,6 +312,8 @@ nm_device_vlan_class_init (NMDeviceVlanClass *eth_class) object_class->finalize = finalize; object_class->get_property = get_property; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; /* properties */ diff --git a/libnm-glib/nm-device-vlan.h b/libnm-glib/nm-device-vlan.h index 6ccbb028..96087109 100644 --- a/libnm-glib/nm-device-vlan.h +++ b/libnm-glib/nm-device-vlan.h @@ -41,6 +41,7 @@ G_BEGIN_DECLS * @NM_DEVICE_VLAN_ERROR_INVALID_VLAN_CONNECTION: the VLAN connection was invalid * @NM_DEVICE_VLAN_ERROR_ID_MISMATCH: the VLAN identifiers of the connection and the device mismatched * @NM_DEVICE_VLAN_ERROR_INTERFACE_MISMATCH: the interfaces of the connection and the device mismatched + * @NM_DEVICE_VLAN_ERROR_MAC_MISMATCH: the MACs of the connection and the device mismatched */ typedef enum { NM_DEVICE_VLAN_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ @@ -48,6 +49,7 @@ typedef enum { NM_DEVICE_VLAN_ERROR_INVALID_VLAN_CONNECTION, /*< nick=InvalidVlanConnection >*/ NM_DEVICE_VLAN_ERROR_ID_MISMATCH, /*< nick=IdMismatch >*/ NM_DEVICE_VLAN_ERROR_INTERFACE_MISMATCH, /*< nick=InterfaceMismatch >*/ + NM_DEVICE_VLAN_ERROR_MAC_MISMATCH, /*< nick=MacMismatch >*/ } NMDeviceVlanError; #define NM_DEVICE_VLAN_ERROR nm_device_vlan_error_quark () diff --git a/libnm-glib/nm-device-wifi.c b/libnm-glib/nm-device-wifi.c index 47594a50..b9cc31d8 100644 --- a/libnm-glib/nm-device-wifi.c +++ b/libnm-glib/nm-device-wifi.c @@ -73,24 +73,17 @@ enum { PROP_BITRATE, PROP_ACTIVE_ACCESS_POINT, PROP_WIRELESS_CAPABILITIES, + PROP_ACCESS_POINTS, LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_PERM_HW_ADDRESS "PermHwAddress" -#define DBUS_PROP_MODE "Mode" -#define DBUS_PROP_BITRATE "Bitrate" -#define DBUS_PROP_ACTIVE_ACCESS_POINT "ActiveAccessPoint" -#define DBUS_PROP_WIRELESS_CAPABILITIES "WirelessCapabilities" - enum { ACCESS_POINT_ADDED, ACCESS_POINT_REMOVED, LAST_SIGNAL }; - static guint signals[LAST_SIGNAL] = { 0 }; /** @@ -117,7 +110,7 @@ nm_device_wifi_error_quark (void) * * Creates a new #NMDeviceWifi. * - * Returns: (transfer full): a new WiFi device + * Returns: (transfer full): a new Wi-Fi device **/ GObject * nm_device_wifi_new (DBusGConnection *connection, const char *path) @@ -192,9 +185,9 @@ nm_device_wifi_get_mode (NMDeviceWifi *device) * nm_device_wifi_get_bitrate: * @device: a #NMDeviceWifi * - * Gets the bit rate of the #NMDeviceWifi. + * Gets the bit rate of the #NMDeviceWifi in kbit/s. * - * Returns: the bit rate + * Returns: the bit rate (kbit/s) **/ guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *device) @@ -223,7 +216,7 @@ nm_device_wifi_get_bitrate (NMDeviceWifi *device) * nm_device_wifi_get_capabilities: * @device: a #NMDeviceWifi * - * Gets the WIFI capabilities of the #NMDeviceWifi. + * Gets the Wi-Fi capabilities of the #NMDeviceWifi. * * Returns: the capabilities **/ @@ -278,7 +271,7 @@ nm_device_wifi_get_active_access_point (NMDeviceWifi *device) * Gets all the scanned access points of the #NMDeviceWifi. * * Returns: (element-type NMClient.AccessPoint): a #GPtrArray containing all the - * scanned #NMAccessPoints. + * scanned #NMAccessPoints. * The returned array is owned by the client and should not be modified. **/ const GPtrArray * @@ -389,31 +382,6 @@ nm_device_wifi_request_scan_simple (NMDeviceWifi *device, g_hash_table_unref (options); } -static void -access_point_added (NMObject *self, NMObject *ap) -{ - g_signal_emit (self, signals[ACCESS_POINT_ADDED], 0, ap); -} - -static void -access_point_removed (NMObject *self_obj, NMObject *ap_obj) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (self_obj); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMAccessPoint *ap = NM_ACCESS_POINT (ap_obj); - - if (ap == priv->active_ap) { - g_object_unref (priv->active_ap); - priv->active_ap = NULL; - _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT); - - priv->rate = 0; - _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_BITRATE); - } - - g_signal_emit (self, signals[ACCESS_POINT_REMOVED], 0, ap); -} - static void clean_up_aps (NMDeviceWifi *self, gboolean notify) { @@ -491,8 +459,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro NMDeviceWifiCapabilities wifi_caps; const char *key_mgmt; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -554,7 +520,19 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro } } - return TRUE; + return NM_DEVICE_CLASS (nm_device_wifi_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_WIRELESS; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device)); } /**************************************************************/ @@ -594,6 +572,9 @@ get_property (GObject *object, case PROP_WIRELESS_CAPABILITIES: g_value_set_uint (value, nm_device_wifi_get_capabilities (self)); break; + case PROP_ACCESS_POINTS: + g_value_set_boxed (value, nm_device_wifi_get_access_points (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -637,36 +618,38 @@ register_properties (NMDeviceWifi *device) { NM_DEVICE_WIFI_BITRATE, &priv->rate }, { NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, &priv->active_ap, NULL, NM_TYPE_ACCESS_POINT }, { NM_DEVICE_WIFI_CAPABILITIES, &priv->wireless_caps }, + { NM_DEVICE_WIFI_ACCESS_POINTS, &priv->aps, NULL, NM_TYPE_ACCESS_POINT, "access-point" }, { NULL }, }; _nm_object_register_properties (NM_OBJECT (device), priv->proxy, property_info); +} + +static void +access_point_removed (NMDeviceWifi *self, NMAccessPoint *ap) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + if (ap == priv->active_ap) { + g_object_unref (priv->active_ap); + priv->active_ap = NULL; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT); - _nm_object_register_pseudo_property (NM_OBJECT (device), - priv->proxy, - "AccessPoints", - &priv->aps, - NM_TYPE_ACCESS_POINT, - access_point_added, - access_point_removed); + priv->rate = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_BITRATE); + } } static void constructed (GObject *object) { - NMDeviceWifiPrivate *priv; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_wifi_parent_class)->constructed (object); - priv = NM_DEVICE_WIFI_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_WIRELESS); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_WIRELESS); register_properties (NM_DEVICE_WIFI (object)); g_signal_connect (NM_DEVICE (object), @@ -727,6 +710,9 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) object_class->dispose = dispose; object_class->finalize = finalize; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + wifi_class->access_point_removed = access_point_removed; /* properties */ @@ -772,7 +758,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) /** * NMDeviceWifi:bitrate: * - * The bit rate of the device. + * The bit rate of the device in kbit/s. **/ g_object_class_install_property (object_class, PROP_BITRATE, @@ -808,14 +794,29 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) 0, G_MAXUINT32, 0, G_PARAM_READABLE)); + /** + * NMDeviceWifi:access-points: + * + * List of all Wi-Fi access points the device can see. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_ACCESS_POINTS, + g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, + "AccessPoints", + "Access Points", + NM_TYPE_OBJECT_ARRAY, + G_PARAM_READABLE)); + /* signals */ /** * NMDeviceWifi::access-point-added: - * @device: the wifi device that received the signal + * @device: the Wi-Fi device that received the signal * @ap: the new access point * - * Notifies that a #NMAccessPoint is added to the wifi device. + * Notifies that a #NMAccessPoint is added to the Wi-Fi device. **/ signals[ACCESS_POINT_ADDED] = g_signal_new ("access-point-added", @@ -829,10 +830,10 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) /** * NMDeviceWifi::access-point-removed: - * @device: the wifi device that received the signal + * @device: the Wi-Fi device that received the signal * @ap: the removed access point * - * Notifies that a #NMAccessPoint is removed from the wifi device. + * Notifies that a #NMAccessPoint is removed from the Wi-Fi device. **/ signals[ACCESS_POINT_REMOVED] = g_signal_new ("access-point-removed", diff --git a/libnm-glib/nm-device-wifi.h b/libnm-glib/nm-device-wifi.h index 76d76b4d..f9b30d92 100644 --- a/libnm-glib/nm-device-wifi.h +++ b/libnm-glib/nm-device-wifi.h @@ -67,6 +67,7 @@ GQuark nm_device_wifi_error_quark (void); #define NM_DEVICE_WIFI_BITRATE "bitrate" #define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point" #define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities" +#define NM_DEVICE_WIFI_ACCESS_POINTS "access-points" typedef struct { NMDevice parent; diff --git a/libnm-glib/nm-device-wimax.c b/libnm-glib/nm-device-wimax.c index 881fce5f..0b052804 100644 --- a/libnm-glib/nm-device-wimax.c +++ b/libnm-glib/nm-device-wimax.c @@ -66,25 +66,17 @@ enum { PROP_CINR, PROP_TX_POWER, PROP_BSID, + PROP_NSPS, LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_ACTIVE_NSP "ActiveNsp" -#define DBUS_PROP_CENTER_FREQUENCY "CenterFrequency" -#define DBUS_PROP_RSSI "Rssi" -#define DBUS_PROP_CINR "Cinr" -#define DBUS_PROP_TX_POWER "TxPower" -#define DBUS_PROP_BSID "Bsid" - enum { NSP_ADDED, NSP_REMOVED, LAST_SIGNAL }; - static guint signals[LAST_SIGNAL] = { 0 }; /** @@ -189,7 +181,7 @@ nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax) * Gets all the scanned NSPs of the #NMDeviceWimax. * * Returns: (element-type NMClient.WimaxNsp): a #GPtrArray containing - * all the scanned #NMWimaxNsps. + * all the scanned #NMWimaxNsps. * The returned array is owned by the client and should not be modified. **/ const GPtrArray * @@ -236,28 +228,6 @@ nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, return nsp; } -static void -nsp_added (NMObject *self, NMObject *nsp) -{ - g_signal_emit (self, signals[NSP_ADDED], 0, nsp); -} - -static void -nsp_removed (NMObject *self_obj, NMObject *nsp_obj) -{ - NMDeviceWimax *self = NM_DEVICE_WIMAX (self_obj); - NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); - NMWimaxNsp *nsp = NM_WIMAX_NSP (nsp_obj); - - if (nsp == priv->active_nsp) { - g_object_unref (priv->active_nsp); - priv->active_nsp = NULL; - _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP); - } - - g_signal_emit (self, signals[NSP_REMOVED], 0, nsp); -} - static void clean_up_nsps (NMDeviceWimax *self, gboolean notify) { @@ -390,8 +360,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro const char *hw_str; struct ether_addr *hw_mac; - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -426,7 +394,19 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro } } - return TRUE; + return NM_DEVICE_CLASS (nm_device_wimax_parent_class)->connection_compatible (device, connection, error); +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_WIMAX; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device)); } /**************************************************************/ @@ -469,6 +449,9 @@ get_property (GObject *object, case PROP_BSID: g_value_set_string (value, nm_device_wimax_get_bsid (self)); break; + case PROP_NSPS: + g_value_set_boxed (value, nm_device_wimax_get_nsps (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -544,43 +527,42 @@ register_properties (NMDeviceWimax *wimax) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); const NMPropertiesInfo property_info[] = { - { NM_DEVICE_WIMAX_HW_ADDRESS, &priv->hw_address }, - { NM_DEVICE_WIMAX_ACTIVE_NSP, &priv->active_nsp, NULL, NM_TYPE_WIMAX_NSP }, + { NM_DEVICE_WIMAX_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_WIMAX_ACTIVE_NSP, &priv->active_nsp, NULL, NM_TYPE_WIMAX_NSP }, { NM_DEVICE_WIMAX_CENTER_FREQUENCY, &priv->center_freq }, - { NM_DEVICE_WIMAX_RSSI, &priv->rssi }, - { NM_DEVICE_WIMAX_CINR, &priv->cinr }, - { NM_DEVICE_WIMAX_TX_POWER, &priv->tx_power }, - { NM_DEVICE_WIMAX_BSID, &priv->bsid }, + { NM_DEVICE_WIMAX_RSSI, &priv->rssi }, + { NM_DEVICE_WIMAX_CINR, &priv->cinr }, + { NM_DEVICE_WIMAX_TX_POWER, &priv->tx_power }, + { NM_DEVICE_WIMAX_BSID, &priv->bsid }, + { NM_DEVICE_WIMAX_NSPS, &priv->nsps, NULL, NM_TYPE_WIMAX_NSP, "nsp" }, { NULL }, }; _nm_object_register_properties (NM_OBJECT (wimax), priv->proxy, property_info); +} + +static void +nsp_removed (NMDeviceWimax *self, NMWimaxNsp *nsp) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); - _nm_object_register_pseudo_property (NM_OBJECT (wimax), - priv->proxy, - "NspList", - &priv->nsps, - NM_TYPE_WIMAX_NSP, - nsp_added, - nsp_removed); + if (nsp == priv->active_nsp) { + g_object_unref (priv->active_nsp); + priv->active_nsp = NULL; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP); + } } static void constructed (GObject *object) { - NMDeviceWimaxPrivate *priv; + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_wimax_parent_class)->constructed (object); - priv = NM_DEVICE_WIMAX_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_WIMAX); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_WIMAX); register_properties (NM_DEVICE_WIMAX (object)); g_signal_connect (object, @@ -623,6 +605,9 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) object_class->get_property = get_property; object_class->dispose = dispose; device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + wimax_class->nsp_removed = nsp_removed; /* properties */ @@ -727,6 +712,21 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) NULL, G_PARAM_READABLE)); + /** + * NMDeviceWimax:nsps: + * + * List of all WiMAX Network Service Providers the device can see. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_NSPS, + g_param_spec_boxed (NM_DEVICE_WIMAX_NSPS, + "NSPs", + "Network Service Providers", + NM_TYPE_OBJECT_ARRAY, + G_PARAM_READABLE)); + /* signals */ /** diff --git a/libnm-glib/nm-device-wimax.h b/libnm-glib/nm-device-wimax.h index c0550d19..b2282d4f 100644 --- a/libnm-glib/nm-device-wimax.h +++ b/libnm-glib/nm-device-wimax.h @@ -62,6 +62,7 @@ GQuark nm_device_wimax_error_quark (void); #define NM_DEVICE_WIMAX_CINR "cinr" #define NM_DEVICE_WIMAX_TX_POWER "tx-power" #define NM_DEVICE_WIMAX_BSID "bsid" +#define NM_DEVICE_WIMAX_NSPS "nsps" typedef struct { NMDevice parent; diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index 1c4fd736..b328ba3b 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -23,6 +23,7 @@ #include +#include #include #include "NetworkManager.h" @@ -35,17 +36,20 @@ #include "nm-device-wimax.h" #include "nm-device-infiniband.h" #include "nm-device-bond.h" +#include "nm-device-team.h" #include "nm-device-bridge.h" #include "nm-device-vlan.h" +#include "nm-device-generic.h" #include "nm-device.h" #include "nm-device-private.h" #include "nm-object-private.h" #include "nm-object-cache.h" #include "nm-remote-connection.h" #include "nm-types.h" -#include "nm-glib-marshal.h" #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" +#include "nm-utils.h" +#include "nm-dbus-helpers-private.h" static GType _nm_device_type_for_path (DBusGConnection *connection, const char *path); @@ -53,6 +57,7 @@ static void _nm_device_type_for_path_async (DBusGConnection *connection, const char *path, NMObjectTypeCallbackFunc callback, gpointer user_data); +gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error); G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT, _nm_object_register_type_func (g_define_type_id, _nm_device_type_for_path, @@ -73,6 +78,7 @@ typedef struct { char *driver; char *driver_version; char *firmware_version; + char *type_description; NMDeviceCapabilities capabilities; gboolean managed; gboolean firmware_missing; @@ -89,8 +95,12 @@ typedef struct { GPtrArray *available_connections; GUdevClient *client; - char *product; - char *vendor; + char *product, *short_product; + char *vendor, *short_vendor; + char *description, *bus_name; + + char *physical_port_id; + guint32 mtu; } NMDevicePrivate; enum { @@ -116,6 +126,8 @@ enum { PROP_DEVICE_TYPE, PROP_ACTIVE_CONNECTION, PROP_AVAILABLE_CONNECTIONS, + PROP_PHYSICAL_PORT_ID, + PROP_MTU, LAST_PROP }; @@ -128,6 +140,24 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +/** + * nm_device_error_quark: + * + * Registers an error quark for #NMDevice if necessary. + * + * Returns: the error quark used for #NMDevice errors. + * + * Since: 0.9.10 + **/ +GQuark +nm_device_error_quark (void) +{ + static GQuark quark = 0; + + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_static_string ("nm-device-error-quark"); + return quark; +} static void nm_device_init (NMDevice *device) @@ -178,6 +208,8 @@ register_properties (NMDevice *device) { NM_DEVICE_STATE_REASON, &priv->state, demarshal_state_reason }, { NM_DEVICE_ACTIVE_CONNECTION, &priv->active_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, { NM_DEVICE_AVAILABLE_CONNECTIONS, &priv->available_connections, NULL, NM_TYPE_REMOTE_CONNECTION }, + { NM_DEVICE_PHYSICAL_PORT_ID, &priv->physical_port_id }, + { NM_DEVICE_MTU, &priv->mtu }, /* Properties that exist in D-Bus but that we don't track */ { "ip4-address", NULL }, @@ -282,10 +314,14 @@ _nm_device_gtype_from_dtype (NMDeviceType dtype) return NM_TYPE_DEVICE_INFINIBAND; case NM_DEVICE_TYPE_BOND: return NM_TYPE_DEVICE_BOND; + case NM_DEVICE_TYPE_TEAM: + return NM_TYPE_DEVICE_TEAM; case NM_DEVICE_TYPE_BRIDGE: return NM_TYPE_DEVICE_BRIDGE; case NM_DEVICE_TYPE_VLAN: return NM_TYPE_DEVICE_VLAN; + case NM_DEVICE_TYPE_GENERIC: + return NM_TYPE_DEVICE_GENERIC; default: g_warning ("Unknown device type %d", dtype); return G_TYPE_INVALID; @@ -305,14 +341,11 @@ constructed (GObject *object) /* Catch a subclass setting the wrong type */ g_warn_if_fail (G_OBJECT_TYPE (object) == _nm_device_gtype_from_dtype (priv->device_type)); - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE); + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE); register_properties (NM_DEVICE (object)); - dbus_g_object_register_marshaller (_nm_glib_marshal_VOID__UINT_UINT_UINT, + dbus_g_object_register_marshaller (g_cclosure_marshal_generic, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); @@ -365,7 +398,13 @@ finalize (GObject *object) g_free (priv->driver_version); g_free (priv->firmware_version); g_free (priv->product); + g_free (priv->short_product); g_free (priv->vendor); + g_free (priv->short_vendor); + g_free (priv->description); + g_free (priv->bus_name); + g_free (priv->type_description); + g_free (priv->physical_port_id); G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); } @@ -450,6 +489,12 @@ get_property (GObject *object, case PROP_VENDOR: g_value_set_string (value, nm_device_get_vendor (device)); break; + case PROP_PHYSICAL_PORT_ID: + g_value_set_string (value, nm_device_get_physical_port_id (device)); + break; + case PROP_MTU: + g_value_set_uint (value, nm_device_get_mtu (device)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -496,6 +541,8 @@ nm_device_class_init (NMDeviceClass *device_class) object_class->dispose = dispose; object_class->finalize = finalize; + device_class->connection_compatible = connection_compatible; + /* properties */ /** @@ -534,7 +581,7 @@ nm_device_class_init (NMDeviceClass *device_class) (object_class, PROP_DEVICE_TYPE, g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "Device Type", - "Numeric device type (ie ethernet, wifi, etc)", + "Numeric device type (ie Ethernet, Wi-Fi, etc)", NM_DEVICE_TYPE_UNKNOWN, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, G_PARAM_READABLE)); /** @@ -779,6 +826,37 @@ nm_device_class_init (NMDeviceClass *device_class) NULL, G_PARAM_READABLE)); + /** + * NMDevice:physical-port-id: + * + * The physical port ID of the device. (See + * nm_device_get_physical_port_id().) + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_PHYSICAL_PORT_ID, + g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, + "Physical Port ID", + "Physical port ID", + NULL, + G_PARAM_READABLE)); + + /** + * NMDevice:mtu: + * + * The MTU of the device. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_DEVICE_MTU, + "MTU", + "MTU", + 0, G_MAXUINT32, 1500, + G_PARAM_READABLE)); + /* signals */ /** @@ -795,8 +873,7 @@ nm_device_class_init (NMDeviceClass *device_class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMDeviceClass, state_changed), - NULL, NULL, - _nm_glib_marshal_VOID__UINT_UINT_UINT, + NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); } @@ -830,27 +907,25 @@ _nm_device_type_for_path (DBusGConnection *connection, { DBusGProxy *proxy; GError *err = NULL; - GValue value = {0,}; + GValue value = G_VALUE_INIT; NMDeviceType nm_dtype; - proxy = dbus_g_proxy_new_for_name (connection, - NM_DBUS_SERVICE, - path, - "org.freedesktop.DBus.Properties"); + proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties"); if (!proxy) { g_warning ("%s: couldn't create D-Bus object proxy.", __func__); return G_TYPE_INVALID; } if (!dbus_g_proxy_call (proxy, - "Get", &err, - G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, - G_TYPE_STRING, "DeviceType", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, G_TYPE_INVALID)) { - g_object_unref (proxy); + "Get", &err, + G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, + G_TYPE_STRING, "DeviceType", + G_TYPE_INVALID, + G_TYPE_VALUE, &value, G_TYPE_INVALID)) { g_warning ("Error in get_property: %s\n", err->message); g_error_free (err); + g_object_unref (proxy); + return G_TYPE_INVALID; } g_object_unref (proxy); @@ -935,8 +1010,7 @@ _nm_device_type_for_path_async (DBusGConnection *connection, async_data->callback = callback; async_data->user_data = user_data; - proxy = dbus_g_proxy_new_for_name (connection, NM_DBUS_SERVICE, path, - "org.freedesktop.DBus.Properties"); + proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties"); dbus_g_proxy_begin_call (proxy, "Get", async_got_type, async_data, NULL, G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, @@ -985,7 +1059,7 @@ nm_device_get_ip_iface (NMDevice *device) * nm_device_get_device_type: * @device: a #NMDevice * - * Returns the numeric type of the #NMDevice, ie ethernet, wifi, etc. + * Returns the numeric type of the #NMDevice, ie Ethernet, Wi-Fi, etc. * * Returns: the device type **/ @@ -1070,6 +1144,65 @@ nm_device_get_firmware_version (NMDevice *device) return NM_DEVICE_GET_PRIVATE (device)->firmware_version; } +/** + * nm_device_get_type_description: + * @device: a #NMDevice + * + * Gets a (non-localized) description of the type of device that + * @device is. + * + * Returns: the type description of the device. This is the internal + * string used by the device, and must not be modified. + * + * Since: 0.9.10 + **/ +const char * +nm_device_get_type_description (NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + const char *desc, *typename; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + if (priv->type_description) + return priv->type_description; + + if (NM_DEVICE_GET_CLASS (device)->get_type_description) { + desc = NM_DEVICE_GET_CLASS (device)->get_type_description (device); + if (desc) + return desc; + } + + typename = G_OBJECT_TYPE_NAME (device); + if (g_str_has_prefix (typename, "NMDevice")) + typename += 8; + priv->type_description = g_ascii_strdown (typename, -1); + + return priv->type_description; +} + +/** + * nm_device_get_hw_address: + * @device: a #NMDevice + * + * Gets the current a hardware address (MAC) for the @device. + * + * Returns: the current MAC of the device, or %NULL. + * This is the internal string used by the device, and must not be modified. + * + * Since: 0.9.10 + **/ +const char * +nm_device_get_hw_address (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + if (NM_DEVICE_GET_CLASS (device)->get_hw_address) + return NM_DEVICE_GET_CLASS (device)->get_hw_address (device); + + return NULL; +} + /** * nm_device_get_capabilities: * @device: a #NMDevice @@ -1131,7 +1264,7 @@ nm_device_get_autoconnect (NMDevice *device) void nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect) { - GValue value = {0,}; + GValue value = G_VALUE_INIT; g_return_if_fail (NM_IS_DEVICE (device)); @@ -1172,6 +1305,10 @@ nm_device_get_firmware_missing (NMDevice *device) * * Gets the current #NMIP4Config associated with the #NMDevice. * + * Note that as of NetworkManager 0.9.10, you can alternatively use + * nm_active_connection_get_ip4_config(), which also works with VPN + * connections. + * * Returns: (transfer none): the #NMIP4Config or %NULL if the device is not activated. **/ NMIP4Config * @@ -1189,6 +1326,10 @@ nm_device_get_ip4_config (NMDevice *device) * * Gets the current #NMDHCP4Config associated with the #NMDevice. * + * Note that as of NetworkManager 0.9.10, you can alternatively use + * nm_active_connection_get_dhcp4_config(), which also works with VPN + * connections. + * * Returns: (transfer none): the #NMDHCP4Config or %NULL if the device is not activated or not * using DHCP. **/ @@ -1207,6 +1348,10 @@ nm_device_get_dhcp4_config (NMDevice *device) * * Gets the current #NMIP6Config associated with the #NMDevice. * + * Note that as of NetworkManager 0.9.10, you can alternatively use + * nm_active_connection_get_ip6_config(), which also works with VPN + * connections. + * * Returns: (transfer none): the #NMIP6Config or %NULL if the device is not activated. **/ NMIP6Config * @@ -1224,6 +1369,10 @@ nm_device_get_ip6_config (NMDevice *device) * * Gets the current #NMDHCP6Config associated with the #NMDevice. * + * Note that as of NetworkManager 0.9.10, you can alternatively use + * nm_active_connection_get_dhcp6_config(), which also works with VPN + * connections. + * * Returns: (transfer none): the #NMDHCP6Config or %NULL if the device is not activated or not * using DHCP. **/ @@ -1314,33 +1463,6 @@ nm_device_get_available_connections (NMDevice *device) return handle_ptr_array_return (NM_DEVICE_GET_PRIVATE (device)->available_connections); } -/* From hostap, Copyright (c) 2002-2005, Jouni Malinen */ - -static int hex2num (char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - return -1; -} - -static int hex2byte (const char *hex) -{ - int a, b; - a = hex2num(*hex++); - if (a < 0) - return -1; - b = hex2num(*hex++); - if (b < 0) - return -1; - return (a << 4) | b; -} - -/* End from hostap */ - static char * get_decoded_property (GUdevDevice *device, const char *property) { @@ -1356,7 +1478,7 @@ get_decoded_property (GUdevDevice *device, const char *property) n = unescaped = g_malloc0 (len + 1); while (*p) { if ((len >= 4) && (*p == '\\') && (*(p+1) == 'x')) { - *n++ = (char) hex2byte (p + 2); + *n++ = (char) nm_utils_hex2byte (p + 2); p += 4; len -= 4; } else { @@ -1368,23 +1490,31 @@ get_decoded_property (GUdevDevice *device, const char *property) return unescaped; } +static gboolean +ensure_udev_client (NMDevice *device) +{ + static const char *const subsys[3] = { "net", "tty", NULL }; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + + if (!priv->client) + priv->client = g_udev_client_new (subsys); + + return priv->client != NULL; +} + static char * _get_udev_property (NMDevice *device, const char *enc_prop, /* ID_XXX_ENC */ const char *db_prop) /* ID_XXX_FROM_DATABASE */ { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - const char *subsys[3] = { "net", "tty", NULL }; GUdevDevice *udev_device = NULL, *tmpdev, *olddev; const char *ifname; guint32 count = 0; char *enc_value = NULL, *db_value = NULL; - if (!priv->client) { - priv->client = g_udev_client_new (subsys); - if (!priv->client) - return NULL; - } + if (!ensure_udev_client (device)) + return NULL; ifname = nm_device_get_iface (device); if (!ifname) @@ -1424,7 +1554,7 @@ _get_udev_property (NMDevice *device, /* Balance the initial g_udev_client_query_by_subsystem_and_name() */ g_object_unref (udev_device); - /* Prefer the the encoded value which comes directly from the device + /* Prefer the encoded value which comes directly from the device * over the hwdata database value. */ if (enc_value) { @@ -1487,6 +1617,479 @@ nm_device_get_vendor (NMDevice *device) return priv->vendor; } +static const char * const ignored_words[] = { + "Semiconductor", + "Components", + "Corporation", + "Communications", + "Company", + "Corp.", + "Corp", + "Co.", + "Inc.", + "Inc", + "Incorporated", + "Ltd.", + "Limited.", + "Intel?", + "chipset", + "adapter", + "[hex]", + "NDIS", + "Module", + NULL +}; + +static const char * const ignored_phrases[] = { + "Multiprotocol MAC/baseband processor", + "Wireless LAN Controller", + "Wireless LAN Adapter", + "Wireless Adapter", + "Network Connection", + "Wireless Cardbus Adapter", + "Wireless CardBus Adapter", + "54 Mbps Wireless PC Card", + "Wireless PC Card", + "Wireless PC", + "PC Card with XJACK(r) Antenna", + "Wireless cardbus", + "Wireless LAN PC Card", + "Technology Group Ltd.", + "Communication S.p.A.", + "Business Mobile Networks BV", + "Mobile Broadband Minicard Composite Device", + "Mobile Communications AB", + "(PC-Suite Mode)", + NULL +}; + +static char * +fixup_desc_string (const char *desc) +{ + char *p, *temp; + char **words, **item; + GString *str; + int i; + + if (!desc) + return NULL; + + p = temp = g_strdup (desc); + while (*p) { + if (*p == '_' || *p == ',') + *p = ' '; + p++; + } + + /* Attempt to shorten ID by ignoring certain phrases */ + for (i = 0; ignored_phrases[i]; i++) { + p = strstr (temp, ignored_phrases[i]); + if (p) { + guint32 ignored_len = strlen (ignored_phrases[i]); + + memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */ + } + } + + /* Attempt to shorten ID by ignoring certain individual words */ + words = g_strsplit (temp, " ", 0); + str = g_string_new_len (NULL, strlen (temp)); + g_free (temp); + + for (item = words; *item; item++) { + gboolean ignore = FALSE; + + if (**item == '\0') + continue; + + for (i = 0; ignored_words[i]; i++) { + if (!strcmp (*item, ignored_words[i])) { + ignore = TRUE; + break; + } + } + + if (!ignore) { + if (str->len) + g_string_append_c (str, ' '); + g_string_append (str, *item); + } + } + g_strfreev (words); + + temp = str->str; + g_string_free (str, FALSE); + + return temp; +} + +static void +get_description (NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + const char *dev_product; + const char *dev_vendor; + char *pdown; + char *vdown; + GString *str; + + dev_product = nm_device_get_product (device); + priv->short_product = fixup_desc_string (dev_product); + + dev_vendor = nm_device_get_vendor (device); + priv->short_vendor = fixup_desc_string (dev_vendor); + + if (!dev_product || !dev_vendor) { + priv->description = g_strdup (nm_device_get_iface (device)); + return; + } + + str = g_string_new_len (NULL, strlen (priv->short_vendor) + strlen (priv->short_product) + 1); + + /* Another quick hack; if all of the fixed up vendor string + * is found in product, ignore the vendor. + */ + pdown = g_ascii_strdown (priv->short_product, -1); + vdown = g_ascii_strdown (priv->short_vendor, -1); + if (!strstr (pdown, vdown)) { + g_string_append (str, priv->short_vendor); + g_string_append_c (str, ' '); + } + g_free (pdown); + g_free (vdown); + + g_string_append (str, priv->short_product); + + priv->description = g_string_free (str, FALSE); +} + +static const char * +get_short_vendor (NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + priv = NM_DEVICE_GET_PRIVATE (device); + + if (!priv->description) + get_description (device); + + return priv->short_vendor; +} + +/** + * nm_device_get_description: + * @device: an #NMDevice + * + * Gets a description of @device, incorporating the results of + * nm_device_get_short_vendor() and nm_device_get_short_product(). + * + * Returns: a description of @device. If either the vendor or the + * product name is unknown, this returns the interface name. + * + * Since: 0.9.10 + */ +const char * +nm_device_get_description (NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + priv = NM_DEVICE_GET_PRIVATE (device); + + if (!priv->description) + get_description (device); + + return priv->description; +} + +static const char * +get_type_name (NMDevice *device) +{ + switch (nm_device_get_device_type (device)) { + case NM_DEVICE_TYPE_ETHERNET: + return _("Ethernet"); + case NM_DEVICE_TYPE_WIFI: + return _("Wi-Fi"); + case NM_DEVICE_TYPE_BT: + return _("Bluetooth"); + case NM_DEVICE_TYPE_OLPC_MESH: + return _("OLPC Mesh"); + case NM_DEVICE_TYPE_WIMAX: + return _("WiMAX"); + case NM_DEVICE_TYPE_MODEM: + return _("Mobile Broadband"); + case NM_DEVICE_TYPE_INFINIBAND: + return _("InfiniBand"); + case NM_DEVICE_TYPE_BOND: + return _("Bond"); + case NM_DEVICE_TYPE_TEAM: + return _("Team"); + case NM_DEVICE_TYPE_BRIDGE: + return _("Bridge"); + case NM_DEVICE_TYPE_VLAN: + return _("VLAN"); + case NM_DEVICE_TYPE_ADSL: + return _("ADSL"); + default: + return _("Unknown"); + } +} + +static char * +get_device_type_name_with_iface (NMDevice *device) +{ + const char *type_name = get_type_name (device); + + switch (nm_device_get_device_type (device)) { + case NM_DEVICE_TYPE_BOND: + case NM_DEVICE_TYPE_TEAM: + case NM_DEVICE_TYPE_BRIDGE: + case NM_DEVICE_TYPE_VLAN: + return g_strdup_printf ("%s (%s)", type_name, nm_device_get_iface (device)); + default: + return g_strdup (type_name); + } +} + +static char * +get_device_generic_type_name_with_iface (NMDevice *device) +{ + switch (nm_device_get_device_type (device)) { + case NM_DEVICE_TYPE_ETHERNET: + case NM_DEVICE_TYPE_INFINIBAND: + return g_strdup (_("Wired")); + default: + return get_device_type_name_with_iface (device); + } +} + +static const char * +get_bus_name (NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + GUdevDevice *udevice; + const char *ifname, *bus; + + if (priv->bus_name) + goto out; + + if (!ensure_udev_client (device)) + return NULL; + + ifname = nm_device_get_iface (device); + if (!ifname) + return NULL; + + udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname); + if (!udevice) + udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname); + if (!udevice) + return NULL; + + bus = g_udev_device_get_property (udevice, "ID_BUS"); + if (!g_strcmp0 (bus, "pci")) + priv->bus_name = g_strdup (_("PCI")); + else if (!g_strcmp0 (bus, "usb")) + priv->bus_name = g_strdup (_("USB")); + else { + /* Use "" instead of NULL so we can tell later that we've + * already tried. + */ + priv->bus_name = g_strdup (""); + } + +out: + if (*priv->bus_name) + return priv->bus_name; + else + return NULL; +} + +static gboolean +find_duplicates (char **names, + gboolean *duplicates, + int num_devices) +{ + int i, j; + gboolean found_any = FALSE; + + memset (duplicates, 0, num_devices * sizeof (gboolean)); + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) + continue; + for (j = i + 1; j < num_devices; j++) { + if (duplicates[j]) + continue; + if (!strcmp (names[i], names[j])) + duplicates[i] = duplicates[j] = found_any = TRUE; + } + } + + return found_any; +} + +/** + * nm_device_disambiguate_names: + * @devices: (array length=num_devices): an array of #NMDevice + * @num_devices: length of @devices + * + * Generates a list of short-ish unique presentation names for the + * devices in @devices. + * + * Returns: (transfer full) (array zero-terminated=1): the device names + * + * Since: 0.9.10 + */ +char ** +nm_device_disambiguate_names (NMDevice **devices, + int num_devices) +{ + char **names; + gboolean *duplicates; + int i; + + names = g_new (char *, num_devices + 1); + duplicates = g_new (gboolean, num_devices); + + /* Generic device name */ + for (i = 0; i < num_devices; i++) + names[i] = get_device_generic_type_name_with_iface (devices[i]); + if (!find_duplicates (names, duplicates, num_devices)) + goto done; + + /* Try specific names (eg, "Ethernet" and "InfiniBand" rather + * than "Wired") + */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + g_free (names[i]); + names[i] = get_device_type_name_with_iface (devices[i]); + } + } + if (!find_duplicates (names, duplicates, num_devices)) + goto done; + + /* Try prefixing bus name (eg, "PCI Ethernet" vs "USB Ethernet") */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + const char *bus = get_bus_name (devices[i]); + char *name; + + if (!bus) + continue; + + g_free (names[i]); + name = get_device_type_name_with_iface (devices[i]); + /* Translators: the first %s is a bus name (eg, "USB") or + * product name, the second is a device type (eg, + * "Ethernet"). You can change this to something like + * "%2$s (%1$s)" if there's no grammatical way to combine + * the strings otherwise. + */ + names[i] = g_strdup_printf (C_("long device name", "%s %s"), + bus, name); + g_free (name); + } + } + if (!find_duplicates (names, duplicates, num_devices)) + goto done; + + /* Try prefixing vendor name */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + const char *vendor = get_short_vendor (devices[i]); + char *name; + + if (!vendor) + continue; + + g_free (names[i]); + name = get_device_type_name_with_iface (devices[i]); + names[i] = g_strdup_printf (C_("long device name", "%s %s"), + vendor, + get_type_name (devices[i])); + g_free (name); + } + } + if (!find_duplicates (names, duplicates, num_devices)) + goto done; + + /* We have multiple identical network cards, so we have to differentiate + * them by interface name. + */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + const char *interface = nm_device_get_iface (devices[i]); + + if (!interface) + continue; + + g_free (names[i]); + names[i] = g_strdup_printf ("%s (%s)", + get_type_name (devices[i]), + interface); + } + } + +done: + g_free (duplicates); + names[num_devices] = NULL; + return names; +} + +/** + * nm_device_get_physical_port_id: + * @device: a #NMDevice + * + * Gets the physical port ID of the #NMDevice. If non-%NULL, this is + * an opaque string that can be used to recognize when + * seemingly-unrelated #NMDevices are actually just different virtual + * ports on a single physical port. (Eg, NPAR / SR-IOV.) + * + * Returns: the physical port ID of the device, or %NULL if the port + * ID is unknown. This is the internal string used by the device and + * must not be modified. + * + * Since: 0.9.10 + **/ +const char * +nm_device_get_physical_port_id (NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + priv = NM_DEVICE_GET_PRIVATE (device); + + _nm_object_ensure_inited (NM_OBJECT (device)); + if (priv->physical_port_id && *priv->physical_port_id) + return priv->physical_port_id; + else + return NULL; +} + +/** + * nm_device_get_mtu: + * @device: a #NMDevice + * + * Gets the MTU of the #NMDevice. + * + * Returns: the MTU of the device. + * + * Since: 0.9.10 + **/ +guint32 +nm_device_get_mtu (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), 0); + + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->mtu; +} + typedef struct { NMDevice *device; NMDeviceDeactivateFn fn; @@ -1555,8 +2158,8 @@ nm_device_disconnect (NMDevice *device, * * Validates a given connection for a given #NMDevice object and returns * whether the connection may be activated with the device. For example if - * @device is a WiFi device that supports only WEP encryption, the connection - * will only be valid if it is a WiFi connection which describes a WEP or open + * @device is a Wi-Fi device that supports only WEP encryption, the connection + * will only be valid if it is a Wi-Fi connection which describes a WEP or open * network, and will not be valid if it describes a WPA network, or if it is * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the * device. @@ -1570,6 +2173,26 @@ nm_device_connection_valid (NMDevice *device, NMConnection *connection) return nm_device_connection_compatible (device, connection, NULL); } +gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingConnection *s_con; + const char *config_iface, *device_iface; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + config_iface = nm_setting_connection_get_interface_name (s_con); + device_iface = nm_device_get_iface (device); + if (config_iface && g_strcmp0 (config_iface, device_iface) != 0) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INTERFACE_MISMATCH, + "The interface names of the device and the connection didn't match."); + return FALSE; + } + + return TRUE; +} + /** * nm_device_connection_compatible: * @device: an #NMDevice to validate @connection against @@ -1578,8 +2201,8 @@ nm_device_connection_valid (NMDevice *device, NMConnection *connection) * * Validates a given connection for a given #NMDevice object and returns * whether the connection may be activated with the device. For example if - * @device is a WiFi device that supports only WEP encryption, the connection - * will only be valid if it is a WiFi connection which describes a WEP or open + * @device is a Wi-Fi device that supports only WEP encryption, the connection + * will only be valid if it is a Wi-Fi connection which describes a WEP or open * network, and will not be valid if it describes a WPA network, or if it is * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the * device. @@ -1594,9 +2217,11 @@ nm_device_connection_valid (NMDevice *device, NMConnection *connection) gboolean nm_device_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { - if (NM_DEVICE_GET_CLASS (device)->connection_compatible) - return NM_DEVICE_GET_CLASS (device)->connection_compatible (device, connection, error); - return FALSE; + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return NM_DEVICE_GET_CLASS (device)->connection_compatible (device, connection, error); } /** @@ -1606,10 +2231,10 @@ nm_device_connection_compatible (NMDevice *device, NMConnection *connection, GEr * * Filters a given list of connections for a given #NMDevice object and return * connections which may be activated with the device. For example if @device - * is a WiFi device that supports only WEP encryption, the returned list will - * contain any WiFi connections in @connections that allow connection to + * is a Wi-Fi device that supports only WEP encryption, the returned list will + * contain any Wi-Fi connections in @connections that allow connection to * unencrypted or WEP-enabled SSIDs. The returned list will not contain - * Ethernet, Bluetooth, WiFi WPA connections, or any other connection that is + * Ethernet, Bluetooth, Wi-Fi WPA connections, or any other connection that is * incompatible with the device. To get the full list of connections see * nm_remote_settings_list_connections(). * @@ -1636,3 +2261,22 @@ nm_device_filter_connections (NMDevice *device, const GSList *connections) return g_slist_reverse (filtered); } +/** + * nm_device_get_setting_type: + * @device: an #NMDevice + * + * Gets the (primary) #NMSetting subtype associated with connections + * that can be used on @device. + * + * Returns: @device's associated #NMSetting type + * + * Since: 0.9.10 + */ +GType +nm_device_get_setting_type (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), G_TYPE_INVALID); + g_return_val_if_fail (NM_DEVICE_GET_CLASS (device)->get_setting_type != NULL, G_TYPE_INVALID); + + return NM_DEVICE_GET_CLASS (device)->get_setting_type (device); +} diff --git a/libnm-glib/nm-device.h b/libnm-glib/nm-device.h index c49675bc..ed0f6876 100644 --- a/libnm-glib/nm-device.h +++ b/libnm-glib/nm-device.h @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright (C) 2007 - 2013 Red Hat, Inc. */ #ifndef NM_DEVICE_H @@ -45,6 +45,21 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE)) #define NM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE, NMDeviceClass)) +/** + * NMDeviceError: + * @NM_DEVICE_ERROR_UNKNOWN: unknown or unclassified error + * @NM_DEVICE_ERROR_INTERFACE_MISMATCH: the interface names of the connection and the + * device mismatched + */ +typedef enum { + NM_DEVICE_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ + NM_DEVICE_ERROR_INTERFACE_MISMATCH, /*< nick=InterfaceMismatch >*/ +} NMDeviceError; + +#define NM_DEVICE_ERROR nm_device_error_quark () +NM_AVAILABLE_IN_0_9_10 +GQuark nm_device_error_quark (void); + #define NM_DEVICE_DEVICE_TYPE "device-type" #define NM_DEVICE_UDI "udi" #define NM_DEVICE_INTERFACE "interface" @@ -66,6 +81,8 @@ G_BEGIN_DECLS #define NM_DEVICE_AVAILABLE_CONNECTIONS "available-connections" #define NM_DEVICE_VENDOR "vendor" #define NM_DEVICE_PRODUCT "product" +#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" +#define NM_DEVICE_MTU "mtu" typedef struct { NMObject parent; @@ -84,13 +101,15 @@ typedef struct { NMConnection *connection, GError **error); + const char * (*get_type_description) (NMDevice *device); + const char * (*get_hw_address) (NMDevice *device); + + GType (*get_setting_type) (NMDevice *device); + /* Padding for future expansion */ void (*_reserved1) (void); void (*_reserved2) (void); void (*_reserved3) (void); - void (*_reserved4) (void); - void (*_reserved5) (void); - void (*_reserved6) (void); } NMDeviceClass; GType nm_device_get_type (void); @@ -104,6 +123,10 @@ const char * nm_device_get_udi (NMDevice *device); const char * nm_device_get_driver (NMDevice *device); const char * nm_device_get_driver_version (NMDevice *device); const char * nm_device_get_firmware_version (NMDevice *device); +NM_AVAILABLE_IN_0_9_10 +const char * nm_device_get_type_description (NMDevice *device); +NM_AVAILABLE_IN_0_9_10 +const char * nm_device_get_hw_address (NMDevice *device); NMDeviceCapabilities nm_device_get_capabilities (NMDevice *device); gboolean nm_device_get_managed (NMDevice *device); gboolean nm_device_get_autoconnect (NMDevice *device); @@ -117,8 +140,18 @@ NMDeviceState nm_device_get_state (NMDevice *device); NMDeviceState nm_device_get_state_reason (NMDevice *device, NMDeviceStateReason *reason); NMActiveConnection * nm_device_get_active_connection(NMDevice *device); const GPtrArray * nm_device_get_available_connections(NMDevice *device); -const char * nm_device_get_product (NMDevice *device); -const char * nm_device_get_vendor (NMDevice *device); +NM_AVAILABLE_IN_0_9_10 +const char * nm_device_get_physical_port_id (NMDevice *device); +NM_AVAILABLE_IN_0_9_10 +guint32 nm_device_get_mtu (NMDevice *device); + +const char * nm_device_get_product (NMDevice *device); +const char * nm_device_get_vendor (NMDevice *device); +NM_AVAILABLE_IN_0_9_10 +const char * nm_device_get_description (NMDevice *device); +NM_AVAILABLE_IN_0_9_10 +char ** nm_device_disambiguate_names (NMDevice **devices, + int num_devices); typedef void (*NMDeviceDeactivateFn) (NMDevice *device, GError *error, gpointer user_data); @@ -136,6 +169,9 @@ gboolean nm_device_connection_compatible (NMDevice *device, NMConnection *connection, GError **error); +NM_AVAILABLE_IN_0_9_10 +GType nm_device_get_setting_type (NMDevice *device); + G_END_DECLS #endif /* NM_DEVICE_H */ diff --git a/libnm-glib/nm-dhcp4-config.c b/libnm-glib/nm-dhcp4-config.c index b8d7dcdd..a861d982 100644 --- a/libnm-glib/nm-dhcp4-config.c +++ b/libnm-glib/nm-dhcp4-config.c @@ -51,26 +51,23 @@ nm_dhcp4_config_init (NMDHCP4Config *config) { } -static void -copy_options (gpointer key, gpointer data, gpointer user_data) -{ - GHashTable *options = (GHashTable *) user_data; - GValue *value = (GValue *) data; - - g_hash_table_insert (options, g_strdup (key), g_value_dup_string (value)); -} - static gboolean demarshal_dhcp4_options (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) { NMDHCP4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); GHashTable *new_options; + GHashTableIter iter; + const char *key; + GValue *opt; g_hash_table_remove_all (priv->options); new_options = g_value_get_boxed (value); - if (new_options) - g_hash_table_foreach (new_options, copy_options, priv->options); + if (new_options) { + g_hash_table_iter_init (&iter, new_options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &opt)) + g_hash_table_insert (priv->options, g_strdup (key), g_value_dup_string (opt)); + } _nm_object_queue_notify (object, NM_DHCP4_CONFIG_OPTIONS); return TRUE; @@ -93,21 +90,13 @@ register_properties (NMDHCP4Config *config) static void constructed (GObject *object) { - DBusGConnection *connection; - NMDHCP4ConfigPrivate *priv; + NMDHCP4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); G_OBJECT_CLASS (nm_dhcp4_config_parent_class)->constructed (object); - priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - connection = nm_object_get_connection (NM_OBJECT (object)); - - priv->proxy = dbus_g_proxy_new_for_name (connection, - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DHCP4_CONFIG); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DHCP4_CONFIG); register_properties (NM_DHCP4_CONFIG (object)); } diff --git a/libnm-glib/nm-dhcp6-config.c b/libnm-glib/nm-dhcp6-config.c index fd1e6526..ef6006b0 100644 --- a/libnm-glib/nm-dhcp6-config.c +++ b/libnm-glib/nm-dhcp6-config.c @@ -51,26 +51,23 @@ nm_dhcp6_config_init (NMDHCP6Config *config) { } -static void -copy_options (gpointer key, gpointer data, gpointer user_data) -{ - GHashTable *options = (GHashTable *) user_data; - GValue *value = (GValue *) data; - - g_hash_table_insert (options, g_strdup (key), g_value_dup_string (value)); -} - static gboolean demarshal_dhcp6_options (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) { NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object); GHashTable *new_options; + GHashTableIter iter; + const char *key; + GValue *opt; g_hash_table_remove_all (priv->options); new_options = g_value_get_boxed (value); - if (new_options) - g_hash_table_foreach (new_options, copy_options, priv->options); + if (new_options) { + g_hash_table_iter_init (&iter, new_options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &opt)) + g_hash_table_insert (priv->options, g_strdup (key), g_value_dup_string (opt)); + } _nm_object_queue_notify (object, NM_DHCP6_CONFIG_OPTIONS); return TRUE; @@ -93,21 +90,13 @@ register_properties (NMDHCP6Config *config) static void constructed (GObject *object) { - DBusGConnection *connection; - NMDHCP6ConfigPrivate *priv; + NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object); G_OBJECT_CLASS (nm_dhcp6_config_parent_class)->constructed (object); - priv = NM_DHCP6_CONFIG_GET_PRIVATE (object); priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - connection = nm_object_get_connection (NM_OBJECT (object)); - - priv->proxy = dbus_g_proxy_new_for_name (connection, - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DHCP6_CONFIG); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DHCP6_CONFIG); register_properties (NM_DHCP6_CONFIG (object)); } diff --git a/libnm-glib/nm-glib-enum-types.c b/libnm-glib/nm-glib-enum-types.c index c2e92bee..8e8b0ff9 100644 --- a/libnm-glib/nm-glib-enum-types.c +++ b/libnm-glib/nm-glib-enum-types.c @@ -15,8 +15,10 @@ #include "nm-device-bt.h" #include "nm-device-olpc-mesh.h" #include "nm-device-bond.h" +#include "nm-device-team.h" #include "nm-device-bridge.h" #include "nm-device-vlan.h" +#include "nm-device-generic.h" #include "nm-access-point.h" #include "nm-ip4-config.h" #include "nm-device-modem.h" @@ -103,6 +105,44 @@ nm_client_permission_result_get_type (void) return g_define_type_id__volatile; } GType +nm_client_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CLIENT_ERROR_UNKNOWN, "NM_CLIENT_ERROR_UNKNOWN", "UnknownError" }, + { NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, "NM_CLIENT_ERROR_MANAGER_NOT_RUNNING", "ManagerNotRunning" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMClientError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_device_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DEVICE_ERROR_UNKNOWN, "NM_DEVICE_ERROR_UNKNOWN", "UnknownError" }, + { NM_DEVICE_ERROR_INTERFACE_MISMATCH, "NM_DEVICE_ERROR_INTERFACE_MISMATCH", "InterfaceMismatch" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDeviceError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_device_ethernet_error_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -255,6 +295,27 @@ nm_device_bond_error_get_type (void) return g_define_type_id__volatile; } GType +nm_device_team_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DEVICE_TEAM_ERROR_UNKNOWN, "NM_DEVICE_TEAM_ERROR_UNKNOWN", "UnknownError" }, + { NM_DEVICE_TEAM_ERROR_NOT_TEAM_CONNECTION, "NM_DEVICE_TEAM_ERROR_NOT_TEAM_CONNECTION", "NotTeamConnection" }, + { NM_DEVICE_TEAM_ERROR_INVALID_TEAM_CONNECTION, "NM_DEVICE_TEAM_ERROR_INVALID_TEAM_CONNECTION", "InvalidTeamConnection" }, + { NM_DEVICE_TEAM_ERROR_INTERFACE_MISMATCH, "NM_DEVICE_TEAM_ERROR_INTERFACE_MISMATCH", "InterfaceMismatch" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDeviceTeamError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_device_bridge_error_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -288,6 +349,7 @@ nm_device_vlan_error_get_type (void) { NM_DEVICE_VLAN_ERROR_INVALID_VLAN_CONNECTION, "NM_DEVICE_VLAN_ERROR_INVALID_VLAN_CONNECTION", "InvalidVlanConnection" }, { NM_DEVICE_VLAN_ERROR_ID_MISMATCH, "NM_DEVICE_VLAN_ERROR_ID_MISMATCH", "IdMismatch" }, { NM_DEVICE_VLAN_ERROR_INTERFACE_MISMATCH, "NM_DEVICE_VLAN_ERROR_INTERFACE_MISMATCH", "InterfaceMismatch" }, + { NM_DEVICE_VLAN_ERROR_MAC_MISMATCH, "NM_DEVICE_VLAN_ERROR_MAC_MISMATCH", "MacMismatch" }, { 0, NULL, NULL } }; GType g_define_type_id = @@ -298,6 +360,26 @@ nm_device_vlan_error_get_type (void) return g_define_type_id__volatile; } GType +nm_device_generic_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DEVICE_GENERIC_ERROR_UNKNOWN, "NM_DEVICE_GENERIC_ERROR_UNKNOWN", "UnknownError" }, + { NM_DEVICE_GENERIC_ERROR_NOT_GENERIC_CONNECTION, "NM_DEVICE_GENERIC_ERROR_NOT_GENERIC_CONNECTION", "NotGenericConnection" }, + { NM_DEVICE_GENERIC_ERROR_MISSING_INTERFACE_NAME, "NM_DEVICE_GENERIC_ERROR_MISSING_INTERFACE_NAME", "MissingInterfaceName" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDeviceGenericError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_device_modem_error_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -319,6 +401,25 @@ nm_device_modem_error_get_type (void) return g_define_type_id__volatile; } GType +nm_remote_connection_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_REMOTE_CONNECTION_ERROR_UNKNOWN, "NM_REMOTE_CONNECTION_ERROR_UNKNOWN", "UnknownError" }, + { NM_REMOTE_CONNECTION_ERROR_DISCONNECTED, "NM_REMOTE_CONNECTION_ERROR_DISCONNECTED", "Disconnected" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMRemoteConnectionError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_remote_settings_error_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -329,6 +430,7 @@ nm_remote_settings_error_get_type (void) { NM_REMOTE_SETTINGS_ERROR_UNKNOWN, "NM_REMOTE_SETTINGS_ERROR_UNKNOWN", "UnknownError" }, { NM_REMOTE_SETTINGS_ERROR_CONNECTION_REMOVED, "NM_REMOTE_SETTINGS_ERROR_CONNECTION_REMOVED", "ConnectionRemoved" }, { NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE, "NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE", "ConnectionUnavailable" }, + { NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE, "NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE", "ServiceUnavailable" }, { 0, NULL, NULL } }; GType g_define_type_id = @@ -362,6 +464,26 @@ nm_secret_agent_error_get_type (void) return g_define_type_id__volatile; } GType +nm_secret_agent_capabilities_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_SECRET_AGENT_CAPABILITY_NONE, "NM_SECRET_AGENT_CAPABILITY_NONE", "none" }, + { NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, "NM_SECRET_AGENT_CAPABILITY_VPN_HINTS", "vpn-hints" }, + { NM_SECRET_AGENT_CAPABILITY_LAST, "NM_SECRET_AGENT_CAPABILITY_LAST", "last" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMSecretAgentCapabilities"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType nm_secret_agent_get_secrets_flags_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; diff --git a/libnm-glib/nm-glib-enum-types.h b/libnm-glib/nm-glib-enum-types.h index f33db002..9353d381 100644 --- a/libnm-glib/nm-glib-enum-types.h +++ b/libnm-glib/nm-glib-enum-types.h @@ -15,6 +15,10 @@ GType nm_client_permission_get_type (void) G_GNUC_CONST; #define NM_TYPE_CLIENT_PERMISSION (nm_client_permission_get_type ()) GType nm_client_permission_result_get_type (void) G_GNUC_CONST; #define NM_TYPE_CLIENT_PERMISSION_RESULT (nm_client_permission_result_get_type ()) +GType nm_client_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CLIENT_ERROR (nm_client_error_get_type ()) +GType nm_device_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_ERROR (nm_device_error_get_type ()) GType nm_device_ethernet_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_DEVICE_ETHERNET_ERROR (nm_device_ethernet_error_get_type ()) GType nm_device_infiniband_error_get_type (void) G_GNUC_CONST; @@ -29,16 +33,24 @@ GType nm_device_olpc_mesh_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_DEVICE_OLPC_MESH_ERROR (nm_device_olpc_mesh_error_get_type ()) GType nm_device_bond_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_DEVICE_BOND_ERROR (nm_device_bond_error_get_type ()) +GType nm_device_team_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_TEAM_ERROR (nm_device_team_error_get_type ()) GType nm_device_bridge_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_DEVICE_BRIDGE_ERROR (nm_device_bridge_error_get_type ()) GType nm_device_vlan_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_DEVICE_VLAN_ERROR (nm_device_vlan_error_get_type ()) +GType nm_device_generic_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_GENERIC_ERROR (nm_device_generic_error_get_type ()) GType nm_device_modem_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_DEVICE_MODEM_ERROR (nm_device_modem_error_get_type ()) +GType nm_remote_connection_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_REMOTE_CONNECTION_ERROR (nm_remote_connection_error_get_type ()) GType nm_remote_settings_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_REMOTE_SETTINGS_ERROR (nm_remote_settings_error_get_type ()) GType nm_secret_agent_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_SECRET_AGENT_ERROR (nm_secret_agent_error_get_type ()) +GType nm_secret_agent_capabilities_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SECRET_AGENT_CAPABILITIES (nm_secret_agent_capabilities_get_type ()) GType nm_secret_agent_get_secrets_flags_get_type (void) G_GNUC_CONST; #define NM_TYPE_SECRET_AGENT_GET_SECRETS_FLAGS (nm_secret_agent_get_secrets_flags_get_type ()) GType nm_device_wimax_error_get_type (void) G_GNUC_CONST; diff --git a/libnm-glib/nm-glib-marshal.c b/libnm-glib/nm-glib-marshal.c deleted file mode 100644 index 4f4e4c86..00000000 --- a/libnm-glib/nm-glib-marshal.c +++ /dev/null @@ -1,204 +0,0 @@ -#include "nm-glib-marshal.h" - -#include - - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_schar (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#define g_marshal_value_peek_variant(v) g_value_get_variant (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* VOID:POINTER,POINTER (nm-glib-marshal.list:1) */ -void -_nm_glib_marshal_VOID__POINTER_POINTER (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__POINTER_POINTER) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer data2); - register GMarshalFunc_VOID__POINTER_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_pointer (param_values + 1), - g_marshal_value_peek_pointer (param_values + 2), - data2); -} - -/* VOID:STRING,STRING,STRING (nm-glib-marshal.list:2) */ -void -_nm_glib_marshal_VOID__STRING_STRING_STRING (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__STRING_STRING_STRING) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer arg_3, - gpointer data2); - register GMarshalFunc_VOID__STRING_STRING_STRING callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__STRING_STRING_STRING) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_string (param_values + 1), - g_marshal_value_peek_string (param_values + 2), - g_marshal_value_peek_string (param_values + 3), - data2); -} - -/* VOID:UINT,UINT (nm-glib-marshal.list:3) */ -void -_nm_glib_marshal_VOID__UINT_UINT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__UINT_UINT) (gpointer data1, - guint arg_1, - guint arg_2, - gpointer data2); - register GMarshalFunc_VOID__UINT_UINT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__UINT_UINT) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), - data2); -} - -/* VOID:UINT,UINT,UINT (nm-glib-marshal.list:4) */ -void -_nm_glib_marshal_VOID__UINT_UINT_UINT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__UINT_UINT_UINT) (gpointer data1, - guint arg_1, - guint arg_2, - guint arg_3, - gpointer data2); - register GMarshalFunc_VOID__UINT_UINT_UINT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__UINT_UINT_UINT) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_uint (param_values + 2), - g_marshal_value_peek_uint (param_values + 3), - data2); -} - diff --git a/libnm-glib/nm-glib-marshal.h b/libnm-glib/nm-glib-marshal.h deleted file mode 100644 index 01a96a87..00000000 --- a/libnm-glib/nm-glib-marshal.h +++ /dev/null @@ -1,44 +0,0 @@ - -#ifndef ___nm_glib_marshal_MARSHAL_H__ -#define ___nm_glib_marshal_MARSHAL_H__ - -#include - -G_BEGIN_DECLS - -/* VOID:POINTER,POINTER (nm-glib-marshal.list:1) */ -extern void _nm_glib_marshal_VOID__POINTER_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:STRING,STRING,STRING (nm-glib-marshal.list:2) */ -extern void _nm_glib_marshal_VOID__STRING_STRING_STRING (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:UINT,UINT (nm-glib-marshal.list:3) */ -extern void _nm_glib_marshal_VOID__UINT_UINT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -/* VOID:UINT,UINT,UINT (nm-glib-marshal.list:4) */ -extern void _nm_glib_marshal_VOID__UINT_UINT_UINT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -G_END_DECLS - -#endif /* ___nm_glib_marshal_MARSHAL_H__ */ - diff --git a/libnm-glib/nm-ip4-config.c b/libnm-glib/nm-ip4-config.c index 80751c31..ec523a03 100644 --- a/libnm-glib/nm-ip4-config.c +++ b/libnm-glib/nm-ip4-config.c @@ -37,19 +37,23 @@ G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_OBJECT) typedef struct { DBusGProxy *proxy; + char *gateway; GSList *addresses; + GSList *routes; GArray *nameservers; GPtrArray *domains; - GSList *routes; + GPtrArray *searches; GArray *wins; } NMIP4ConfigPrivate; enum { PROP_0, + PROP_GATEWAY, PROP_ADDRESSES, + PROP_ROUTES, PROP_NAMESERVERS, PROP_DOMAINS, - PROP_ROUTES, + PROP_SEARCHES, PROP_WINS_SERVERS, LAST_PROP @@ -65,8 +69,7 @@ demarshal_ip4_address_array (NMObject *object, GParamSpec *pspec, GValue *value, { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); - g_slist_foreach (priv->addresses, (GFunc) nm_ip4_address_unref, NULL); - g_slist_free (priv->addresses); + g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref); priv->addresses = NULL; priv->addresses = nm_utils_ip4_addresses_from_gvalue (value); @@ -90,12 +93,12 @@ demarshal_ip4_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointe } static gboolean -demarshal_domains (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_string_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) { if (!_nm_string_array_demarshal (value, (GPtrArray **) field)) return FALSE; - _nm_object_queue_notify (object, NM_IP4_CONFIG_DOMAINS); + _nm_object_queue_notify (object, pspec->name); return TRUE; } @@ -104,8 +107,7 @@ demarshal_ip4_routes_array (NMObject *object, GParamSpec *pspec, GValue *value, { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); - g_slist_foreach (priv->routes, (GFunc) nm_ip4_route_unref, NULL); - g_slist_free (priv->routes); + g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref); priv->routes = NULL; priv->routes = nm_utils_ip4_routes_from_gvalue (value); @@ -119,10 +121,12 @@ register_properties (NMIP4Config *config) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); const NMPropertiesInfo property_info[] = { + { NM_IP4_CONFIG_GATEWAY, &priv->gateway, }, { NM_IP4_CONFIG_ADDRESSES, &priv->addresses, demarshal_ip4_address_array }, - { NM_IP4_CONFIG_NAMESERVERS, &priv->nameservers, demarshal_ip4_array }, - { NM_IP4_CONFIG_DOMAINS, &priv->domains, demarshal_domains }, { NM_IP4_CONFIG_ROUTES, &priv->routes, demarshal_ip4_routes_array }, + { NM_IP4_CONFIG_NAMESERVERS, &priv->nameservers, demarshal_ip4_array }, + { NM_IP4_CONFIG_DOMAINS, &priv->domains, demarshal_string_array }, + { NM_IP4_CONFIG_SEARCHES, &priv->searches, demarshal_string_array }, { NM_IP4_CONFIG_WINS_SERVERS, &priv->wins, demarshal_ip4_array }, { NULL }, }; @@ -135,19 +139,11 @@ register_properties (NMIP4Config *config) static void constructed (GObject *object) { - DBusGConnection *connection; - NMIP4ConfigPrivate *priv; + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); G_OBJECT_CLASS (nm_ip4_config_parent_class)->constructed (object); - priv = NM_IP4_CONFIG_GET_PRIVATE (object); - connection = nm_object_get_connection (NM_OBJECT (object)); - - priv->proxy = dbus_g_proxy_new_for_name (connection, - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_IP4_CONFIG); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_IP4_CONFIG); register_properties (NM_IP4_CONFIG (object)); } @@ -156,11 +152,10 @@ finalize (GObject *object) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); - g_slist_foreach (priv->addresses, (GFunc) nm_ip4_address_unref, NULL); - g_slist_free (priv->addresses); + g_free (priv->gateway); - g_slist_foreach (priv->routes, (GFunc) nm_ip4_route_unref, NULL); - g_slist_free (priv->routes); + g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref); + g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref); if (priv->nameservers) g_array_free (priv->nameservers, TRUE); @@ -169,10 +164,15 @@ finalize (GObject *object) g_array_free (priv->wins, TRUE); if (priv->domains) { - g_ptr_array_foreach (priv->domains, (GFunc) g_free, NULL); + g_ptr_array_set_free_func (priv->domains, g_free); g_ptr_array_free (priv->domains, TRUE); } + if (priv->searches) { + g_ptr_array_set_free_func (priv->searches, g_free); + g_ptr_array_free (priv->searches, TRUE); + } + g_object_unref (priv->proxy); G_OBJECT_CLASS (nm_ip4_config_parent_class)->finalize (object); @@ -190,17 +190,23 @@ get_property (GObject *object, _nm_object_ensure_inited (NM_OBJECT (object)); switch (prop_id) { + case PROP_GATEWAY: + g_value_set_string (value, nm_ip4_config_get_gateway (self)); + break; case PROP_ADDRESSES: nm_utils_ip4_addresses_to_gvalue (priv->addresses, value); break; + case PROP_ROUTES: + nm_utils_ip4_routes_to_gvalue (priv->routes, value); + break; case PROP_NAMESERVERS: g_value_set_boxed (value, nm_ip4_config_get_nameservers (self)); break; case PROP_DOMAINS: g_value_set_boxed (value, nm_ip4_config_get_domains (self)); break; - case PROP_ROUTES: - nm_utils_ip4_routes_to_gvalue (priv->routes, value); + case PROP_SEARCHES: + g_value_set_boxed (value, nm_ip4_config_get_searches (self)); break; case PROP_WINS_SERVERS: g_value_set_boxed (value, nm_ip4_config_get_wins_servers (self)); @@ -225,30 +231,57 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) /* properties */ + /** + * NMIP4Config:gateway: + * + * The IP4 gateway address of the configuration as string. + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_GATEWAY, + g_param_spec_string (NM_IP4_CONFIG_GATEWAY, + "Gateway", + "Gateway", + NULL, + G_PARAM_READABLE)); + /** * NMIP4Config:addresses: * - * The #GPtrArray containing #NMSettingIP4Addresses of the configuration. + * The #GPtrArray containing #NMIP4Addresses of the configuration. + **/ + g_object_class_install_property + (object_class, PROP_ADDRESSES, + g_param_spec_pointer (NM_IP4_CONFIG_ADDRESSES, + "Addresses", + "Addresses", + G_PARAM_READABLE)); + + /** + * NMIP4Config:routes: + * + * The #GPtrArray containing #NMSettingIP4Routes of the configuration. **/ g_object_class_install_property - (object_class, PROP_ADDRESSES, - g_param_spec_pointer (NM_IP4_CONFIG_ADDRESSES, - "Addresses", - "Addresses", - G_PARAM_READABLE)); + (object_class, PROP_ROUTES, + g_param_spec_pointer (NM_IP4_CONFIG_ROUTES, + "Routes", + "Routes", + G_PARAM_READABLE)); /** * NMIP4Config:nameservers: * - * The #GArray containing name servers (%guint32es) of the configuration. + * The #GArray containing name servers (#guint32s) of the configuration. **/ g_object_class_install_property - (object_class, PROP_NAMESERVERS, - g_param_spec_boxed (NM_IP4_CONFIG_NAMESERVERS, - "Nameservers", - "Nameservers", - NM_TYPE_UINT_ARRAY, - G_PARAM_READABLE)); + (object_class, PROP_NAMESERVERS, + g_param_spec_boxed (NM_IP4_CONFIG_NAMESERVERS, + "Nameservers", + "Nameservers", + NM_TYPE_UINT_ARRAY, + G_PARAM_READABLE)); /** * NMIP4Config:domains: @@ -256,37 +289,40 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) * The #GPtrArray containing domain strings of the configuration. **/ g_object_class_install_property - (object_class, PROP_DOMAINS, - g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS, - "Domains", - "Domains", - NM_TYPE_STRING_ARRAY, - G_PARAM_READABLE)); + (object_class, PROP_DOMAINS, + g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS, + "Domains", + "Domains", + NM_TYPE_STRING_ARRAY, + G_PARAM_READABLE)); /** - * NMIP4Config:routes: + * NMIP4Config:searches: + * + * The #GPtrArray containing dns search strings of the configuration. * - * The #GPtrArray containing #NMSettingIP4Routes of the configuration. + * Since: 0.9.10 **/ g_object_class_install_property - (object_class, PROP_ROUTES, - g_param_spec_pointer (NM_IP4_CONFIG_ROUTES, - "Routes", - "Routes", - G_PARAM_READABLE)); + (object_class, PROP_SEARCHES, + g_param_spec_boxed (NM_IP4_CONFIG_SEARCHES, + "Searches", + "DNS searches", + NM_TYPE_STRING_ARRAY, + G_PARAM_READABLE)); /** * NMIP4Config:wins-servers: * - * The #GArray containing WINS servers (%guint32es) of the configuration. + * The #GArray containing WINS servers (#guint32s) of the configuration. **/ g_object_class_install_property - (object_class, PROP_WINS_SERVERS, - g_param_spec_boxed (NM_IP4_CONFIG_WINS_SERVERS, - "WINS Servers", - "WINS Servers", - NM_TYPE_UINT_ARRAY, - G_PARAM_READABLE)); + (object_class, PROP_WINS_SERVERS, + g_param_spec_boxed (NM_IP4_CONFIG_WINS_SERVERS, + "WINS Servers", + "WINS Servers", + NM_TYPE_UINT_ARRAY, + G_PARAM_READABLE)); } /** @@ -302,9 +338,28 @@ GObject * nm_ip4_config_new (DBusGConnection *connection, const char *object_path) { return (GObject *) g_object_new (NM_TYPE_IP4_CONFIG, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, object_path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, object_path, + NULL); +} + +/** + * nm_ip4_config_get_gateway: + * @config: a #NMIP4Config + * + * Gets the IP4 gateway address. + * + * Returns: the IP4 address of the gateway. + * + * Since: 0.9.10 + **/ +const char * +nm_ip4_config_get_gateway (NMIP4Config *config) +{ + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); + + _nm_object_ensure_inited (NM_OBJECT (config)); + return NM_IP4_CONFIG_GET_PRIVATE (config)->gateway; } /** @@ -331,8 +386,9 @@ nm_ip4_config_get_addresses (NMIP4Config *config) * * Gets the domain name servers (DNS). * - * Returns: (element-type guint32): the #GArray containing %guint32s. This is the internal copy used by the - * configuration and must not be modified. + * Returns: (element-type guint32): the #GArray containing #guint32s. + * This is the internal copy used by the configuration and must not be + * modified. **/ const GArray * nm_ip4_config_get_nameservers (NMIP4Config *config) @@ -361,14 +417,35 @@ nm_ip4_config_get_domains (NMIP4Config *config) return handle_ptr_array_return (NM_IP4_CONFIG_GET_PRIVATE (config)->domains); } +/** + * nm_ip4_config_get_searches: + * @config: a #NMIP4Config + * + * Gets the dns searches. + * + * Returns: (element-type utf8): the #GPtrArray containing dns searches as strings. This is the + * internal copy used by the configuration, and must not be modified. + * + * Since: 0.9.10 + **/ +const GPtrArray * +nm_ip4_config_get_searches (NMIP4Config *config) +{ + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); + + _nm_object_ensure_inited (NM_OBJECT (config)); + return handle_ptr_array_return (NM_IP4_CONFIG_GET_PRIVATE (config)->searches); +} + /** * nm_ip4_config_get_wins_servers: * @config: a #NMIP4Config * * Gets the Windows Internet Name Service servers (WINS). * - * Returns: (element-type guint32): the #GArray containing %guint32s. - * This is the internal copy used by the configuration and must not be modified. + * Returns: (element-type guint32): the #GArray containing #guint32s. + * This is the internal copy used by the configuration and must not be + * modified. **/ const GArray * nm_ip4_config_get_wins_servers (NMIP4Config *config) @@ -386,7 +463,7 @@ nm_ip4_config_get_wins_servers (NMIP4Config *config) * Gets the routes. * * Returns: (element-type NetworkManager.IP4Route): the #GSList containing - * #NMIP4Routes. This is the internal copy used by the configuration, + * #NMIP4Routes. This is the internal copy used by the configuration, * and must not be modified. **/ const GSList * diff --git a/libnm-glib/nm-ip4-config.h b/libnm-glib/nm-ip4-config.h index b76fdf8b..aa2e66eb 100644 --- a/libnm-glib/nm-ip4-config.h +++ b/libnm-glib/nm-ip4-config.h @@ -54,20 +54,26 @@ typedef struct { void (*_reserved6) (void); } NMIP4ConfigClass; +#define NM_IP4_CONFIG_GATEWAY "gateway" #define NM_IP4_CONFIG_ADDRESSES "addresses" +#define NM_IP4_CONFIG_ROUTES "routes" #define NM_IP4_CONFIG_NAMESERVERS "nameservers" #define NM_IP4_CONFIG_DOMAINS "domains" -#define NM_IP4_CONFIG_ROUTES "routes" +#define NM_IP4_CONFIG_SEARCHES "searches" #define NM_IP4_CONFIG_WINS_SERVERS "wins-servers" GType nm_ip4_config_get_type (void); GObject *nm_ip4_config_new (DBusGConnection *connection, const char *object_path); +NM_AVAILABLE_IN_0_9_10 +const char * nm_ip4_config_get_gateway (NMIP4Config *config); const GSList * nm_ip4_config_get_addresses (NMIP4Config *config); +const GSList * nm_ip4_config_get_routes (NMIP4Config *config); const GArray * nm_ip4_config_get_nameservers (NMIP4Config *config); const GPtrArray *nm_ip4_config_get_domains (NMIP4Config *config); -const GSList * nm_ip4_config_get_routes (NMIP4Config *config); +NM_AVAILABLE_IN_0_9_10 +const GPtrArray *nm_ip4_config_get_searches (NMIP4Config *config); const GArray * nm_ip4_config_get_wins_servers (NMIP4Config *config); G_END_DECLS diff --git a/libnm-glib/nm-ip6-config.c b/libnm-glib/nm-ip6-config.c index 9efc32ee..7c9cfca7 100644 --- a/libnm-glib/nm-ip6-config.c +++ b/libnm-glib/nm-ip6-config.c @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2008 - 2011 Red Hat, Inc. + * Copyright (C) 2008 - 2014 Red Hat, Inc. */ #include @@ -37,18 +37,22 @@ G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_OBJECT) typedef struct { DBusGProxy *proxy; + char *gateway; GSList *addresses; + GSList *routes; GSList *nameservers; GPtrArray *domains; - GSList *routes; + GPtrArray *searches; } NMIP6ConfigPrivate; enum { PROP_0, + PROP_GATEWAY, PROP_ADDRESSES, + PROP_ROUTES, PROP_NAMESERVERS, PROP_DOMAINS, - PROP_ROUTES, + PROP_SEARCHES, LAST_PROP }; @@ -76,8 +80,7 @@ demarshal_ip6_address_array (NMObject *object, GParamSpec *pspec, GValue *value, { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object); - g_slist_foreach (priv->addresses, (GFunc) nm_ip6_address_unref, NULL); - g_slist_free (priv->addresses); + g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip6_address_unref); priv->addresses = NULL; priv->addresses = nm_utils_ip6_addresses_from_gvalue (value); @@ -108,13 +111,22 @@ demarshal_domains (NMObject *object, GParamSpec *pspec, GValue *value, gpointer return TRUE; } +static gboolean +demarshal_searches (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +{ + if (!_nm_string_array_demarshal (value, (GPtrArray **) field)) + return FALSE; + + _nm_object_queue_notify (object, NM_IP6_CONFIG_SEARCHES); + return TRUE; +} + static gboolean demarshal_ip6_routes_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object); - g_slist_foreach (priv->routes, (GFunc) nm_ip6_route_unref, NULL); - g_slist_free (priv->routes); + g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip6_route_unref); priv->routes = NULL; priv->routes = nm_utils_ip6_routes_from_gvalue (value); @@ -128,10 +140,12 @@ register_properties (NMIP6Config *config) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); const NMPropertiesInfo property_info[] = { + { NM_IP6_CONFIG_GATEWAY, &priv->gateway, }, { NM_IP6_CONFIG_ADDRESSES, &priv->addresses, demarshal_ip6_address_array }, + { NM_IP6_CONFIG_ROUTES, &priv->routes, demarshal_ip6_routes_array }, { NM_IP6_CONFIG_NAMESERVERS, &priv->nameservers, demarshal_ip6_nameserver_array }, { NM_IP6_CONFIG_DOMAINS, &priv->domains, demarshal_domains }, - { NM_IP6_CONFIG_ROUTES, &priv->routes, demarshal_ip6_routes_array }, + { NM_IP6_CONFIG_SEARCHES, &priv->searches, demarshal_searches }, { NULL }, }; @@ -140,6 +154,25 @@ register_properties (NMIP6Config *config) property_info); } +/** + * nm_ip6_config_get_gateway: + * @config: a #NMIP6Config + * + * Gets the IP6 gateway. + * + * Returns: the IPv6 gateway of the configuration. + * + * Since: 0.9.10 + **/ +const char * +nm_ip6_config_get_gateway (NMIP6Config *config) +{ + g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL); + + _nm_object_ensure_inited (NM_OBJECT (config)); + return NM_IP6_CONFIG_GET_PRIVATE (config)->gateway; +} + /** * nm_ip6_config_get_addresses: * @config: a #NMIP6Config @@ -159,6 +192,56 @@ nm_ip6_config_get_addresses (NMIP6Config *config) return NM_IP6_CONFIG_GET_PRIVATE (config)->addresses; } +/** + * nm_ip6_config_get_num_nameservers: + * @config: a #NMIP6Config + * + * Gets the number of the domain name servers in the configuration. + * + * Returns: the number of domain name servers + * + * Since: 0.9.10 + **/ +guint32 +nm_ip6_config_get_num_nameservers (NMIP6Config *config) +{ + g_return_val_if_fail (NM_IS_IP6_CONFIG (config), 0); + + _nm_object_ensure_inited (NM_OBJECT (config)); + return g_slist_length (NM_IP6_CONFIG_GET_PRIVATE (config)->nameservers); +} + +/** + * nm_ip6_config_get_nameserver: + * @config: a #NMIP6Config + * @idx: index of the nameserver to return + * + * Gets the domain name server at index @idx in the configuration. + * + * Returns: (array fixed-size=16) (element-type guint8) (transfer none): + * the IPv6 address of domain name server at index @iidx + * + * Since: 0.9.10 + **/ +const struct in6_addr * +nm_ip6_config_get_nameserver (NMIP6Config *config, guint32 idx) +{ + NMIP6ConfigPrivate *priv; + GSList *item; + guint32 i = 0; + + g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL); + + _nm_object_ensure_inited (NM_OBJECT (config)); + priv = NM_IP6_CONFIG_GET_PRIVATE (config); + + for (item = priv->nameservers; item && i < idx; i++) + item = item->next; + + g_return_val_if_fail (item, NULL); + return item ? (const struct in6_addr *) item->data : NULL; +} + /* FIXME: like in libnm_util, in6_addr is not introspectable, so skipping here */ /** * nm_ip6_config_get_nameservers: (skip) @@ -197,6 +280,26 @@ nm_ip6_config_get_domains (NMIP6Config *config) return handle_ptr_array_return (NM_IP6_CONFIG_GET_PRIVATE (config)->domains); } +/** + * nm_ip6_config_get_searches: + * @config: a #NMIP6Config + * + * Gets the dns searches. + * + * Returns: (element-type utf8): the #GPtrArray containing dns searches as strings. + * This is the internal copy used by the configuration, and must not be modified. + * + * Since: 0.9.10 + **/ +const GPtrArray * +nm_ip6_config_get_searches (NMIP6Config *config) +{ + g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL); + + _nm_object_ensure_inited (NM_OBJECT (config)); + return handle_ptr_array_return (NM_IP6_CONFIG_GET_PRIVATE (config)->searches); +} + /** * nm_ip6_config_get_routes: * @config: a #NMIP6Config @@ -204,7 +307,7 @@ nm_ip6_config_get_domains (NMIP6Config *config) * Gets the routes. * * Returns: (element-type NetworkManager.IP6Route): the #GSList containing - * #NMIP6Routes. This is the internal copy used by the configuration, + * #NMIP6Routes. This is the internal copy used by the configuration, * and must not be modified. **/ const GSList * @@ -219,19 +322,11 @@ nm_ip6_config_get_routes (NMIP6Config *config) static void constructed (GObject *object) { - DBusGConnection *connection; - NMIP6ConfigPrivate *priv; + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object); G_OBJECT_CLASS (nm_ip6_config_parent_class)->constructed (object); - priv = NM_IP6_CONFIG_GET_PRIVATE (object); - connection = nm_object_get_connection (NM_OBJECT (object)); - - priv->proxy = dbus_g_proxy_new_for_name (connection, - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_IP6_CONFIG); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_IP6_CONFIG); register_properties (NM_IP6_CONFIG (object)); } @@ -240,20 +335,22 @@ finalize (GObject *object) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object); - g_slist_foreach (priv->addresses, (GFunc) nm_ip6_address_unref, NULL); - g_slist_free (priv->addresses); - - g_slist_foreach (priv->routes, (GFunc) nm_ip6_route_unref, NULL); - g_slist_free (priv->routes); + g_free (priv->gateway); - g_slist_foreach (priv->nameservers, (GFunc) g_free, NULL); - g_slist_free (priv->nameservers); + g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip6_address_unref); + g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip6_route_unref); + g_slist_free_full (priv->nameservers, g_free); if (priv->domains) { - g_ptr_array_foreach (priv->domains, (GFunc) g_free, NULL); + g_ptr_array_set_free_func (priv->domains, g_free); g_ptr_array_free (priv->domains, TRUE); } + if (priv->searches) { + g_ptr_array_set_free_func (priv->searches, g_free); + g_ptr_array_free (priv->searches, TRUE); + } + g_object_unref (priv->proxy); G_OBJECT_CLASS (nm_ip6_config_parent_class)->finalize (object); @@ -271,17 +368,23 @@ get_property (GObject *object, _nm_object_ensure_inited (NM_OBJECT (object)); switch (prop_id) { + case PROP_GATEWAY: + g_value_set_string (value, nm_ip6_config_get_gateway (self)); + break; case PROP_ADDRESSES: nm_utils_ip6_addresses_to_gvalue (priv->addresses, value); break; + case PROP_ROUTES: + nm_utils_ip6_routes_to_gvalue (priv->routes, value); + break; case PROP_NAMESERVERS: g_value_set_boxed (value, nm_ip6_config_get_nameservers (self)); break; case PROP_DOMAINS: g_value_set_boxed (value, nm_ip6_config_get_domains (self)); break; - case PROP_ROUTES: - nm_utils_ip6_routes_to_gvalue (priv->routes, value); + case PROP_SEARCHES: + g_value_set_boxed (value, nm_ip6_config_get_searches (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -308,6 +411,21 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) /* properties */ + /** + * NMIP6Config:gateway: + * + * The IPv6 gateway as string + * + * Since: 0.9.10 + **/ + g_object_class_install_property + (object_class, PROP_GATEWAY, + g_param_spec_string (NM_IP6_CONFIG_GATEWAY, + "Gateway", + "Gateway", + NULL, + G_PARAM_READABLE)); + /** * NMIP6Config:addresses: * @@ -316,12 +434,27 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) * #NMSettingIP6Address objects that is more usable than the raw data. **/ g_object_class_install_property - (object_class, PROP_ADDRESSES, - g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, - "Addresses", - "Addresses", - NM_TYPE_IP6_ADDRESS_OBJECT_ARRAY, - G_PARAM_READABLE)); + (object_class, PROP_ADDRESSES, + g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, + "Addresses", + "Addresses", + NM_TYPE_IP6_ADDRESS_OBJECT_ARRAY, + G_PARAM_READABLE)); + + /** + * NMIP6Config:routes: + * + * The #GPtrArray containing the IPv6 routes; use + * nm_utils_ip6_routes_from_gvalue() to return a #GSList of + * #NMSettingIP6Address objects that is more usable than the raw data. + **/ + g_object_class_install_property + (object_class, PROP_ROUTES, + g_param_spec_boxed (NM_IP6_CONFIG_ROUTES, + "Routes", + "Routes", + NM_TYPE_IP6_ROUTE_OBJECT_ARRAY, + G_PARAM_READABLE)); /** * NMIP6Config:nameservers: @@ -330,12 +463,12 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) * contain the addresses of nameservers of the configuration. **/ g_object_class_install_property - (object_class, PROP_NAMESERVERS, - g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS, - "Nameservers", - "Nameservers", - NM_TYPE_IP6_ADDRESS_ARRAY, - G_PARAM_READABLE)); + (object_class, PROP_NAMESERVERS, + g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS, + "Nameservers", + "Nameservers", + NM_TYPE_IP6_ADDRESS_ARRAY, + G_PARAM_READABLE)); /** * NMIP6Config:domains: @@ -343,26 +476,27 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) * The #GPtrArray containing domain strings of the configuration. **/ g_object_class_install_property - (object_class, PROP_DOMAINS, - g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, - "Domains", - "Domains", - NM_TYPE_STRING_ARRAY, - G_PARAM_READABLE)); + (object_class, PROP_DOMAINS, + g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, + "Domains", + "Domains", + NM_TYPE_STRING_ARRAY, + G_PARAM_READABLE)); /** - * NMIP6Config:routes: + * NMIP6Config:searches: * - * The #GPtrArray containing the IPv6 routes; use - * nm_utils_ip6_routes_from_gvalue() to return a #GSList of - * #NMSettingIP6Address objects that is more usable than the raw data. + * The #GPtrArray containing dns search strings of the configuration. + * + * Since: 0.9.10 **/ g_object_class_install_property - (object_class, PROP_ROUTES, - g_param_spec_boxed (NM_IP6_CONFIG_ROUTES, - "Routes", - "Routes", - NM_TYPE_IP6_ROUTE_OBJECT_ARRAY, - G_PARAM_READABLE)); + (object_class, PROP_SEARCHES, + g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, + "Searches", + "DNS Searches", + NM_TYPE_STRING_ARRAY, + G_PARAM_READABLE)); + } diff --git a/libnm-glib/nm-ip6-config.h b/libnm-glib/nm-ip6-config.h index 9692c655..feef69f1 100644 --- a/libnm-glib/nm-ip6-config.h +++ b/libnm-glib/nm-ip6-config.h @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 - 2014 Red Hat, Inc. */ #ifndef NM_IP6_CONFIG_H @@ -54,19 +54,29 @@ typedef struct { void (*_reserved6) (void); } NMIP6ConfigClass; +#define NM_IP6_CONFIG_GATEWAY "gateway" #define NM_IP6_CONFIG_ADDRESSES "addresses" +#define NM_IP6_CONFIG_ROUTES "routes" #define NM_IP6_CONFIG_NAMESERVERS "nameservers" #define NM_IP6_CONFIG_DOMAINS "domains" -#define NM_IP6_CONFIG_ROUTES "routes" +#define NM_IP6_CONFIG_SEARCHES "searches" GType nm_ip6_config_get_type (void); GObject *nm_ip6_config_new (DBusGConnection *connection, const char *object_path); -const GSList * nm_ip6_config_get_addresses (NMIP6Config *config); -const GSList * nm_ip6_config_get_nameservers (NMIP6Config *config); -const GPtrArray *nm_ip6_config_get_domains (NMIP6Config *config); -const GSList * nm_ip6_config_get_routes (NMIP6Config *config); +NM_AVAILABLE_IN_0_9_10 +const char * nm_ip6_config_get_gateway (NMIP6Config *config); +const GSList * nm_ip6_config_get_addresses (NMIP6Config *config); +const GSList * nm_ip6_config_get_routes (NMIP6Config *config); +NM_AVAILABLE_IN_0_9_10 +guint32 nm_ip6_config_get_num_nameservers (NMIP6Config *config); +NM_AVAILABLE_IN_0_9_10 +const struct in6_addr *nm_ip6_config_get_nameserver (NMIP6Config *config, guint32 idx); +const GSList * nm_ip6_config_get_nameservers (NMIP6Config *config); +const GPtrArray * nm_ip6_config_get_domains (NMIP6Config *config); +NM_AVAILABLE_IN_0_9_10 +const GPtrArray * nm_ip6_config_get_searches (NMIP6Config *config); G_END_DECLS diff --git a/libnm-glib/nm-object-private.h b/libnm-glib/nm-object-private.h index 7ec2162f..3253c2ec 100644 --- a/libnm-glib/nm-object-private.h +++ b/libnm-glib/nm-object-private.h @@ -37,8 +37,14 @@ typedef struct { gpointer field; PropertyMarshalFunc func; GType object_type; + const char *signal_prefix; } NMPropertiesInfo; +DBusGProxy *_nm_object_new_proxy (NMObject *self, + const char *path, + const char *interface); + +gboolean _nm_object_is_connection_private (NMObject *self); void _nm_object_register_properties (NMObject *object, DBusGProxy *proxy, @@ -53,17 +59,6 @@ gboolean _nm_object_reload_properties_finish (NMObject *object, GAsyncResult *result, GError **error); -typedef void (*NMPseudoPropertyChangedFunc) (NMObject *self, NMObject *changed); -void _nm_object_register_pseudo_property (NMObject *object, - DBusGProxy *proxy, - const char *name, - gpointer field, - GType object_type, - NMPseudoPropertyChangedFunc added_func, - NMPseudoPropertyChangedFunc removed_func); -void _nm_object_reload_pseudo_property (NMObject *object, - const char *name); - void _nm_object_queue_notify (NMObject *object, const char *property); void _nm_object_suppress_property_updates (NMObject *object, gboolean suppress); diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c index 93919d61..61282cfb 100644 --- a/libnm-glib/nm-object.c +++ b/libnm-glib/nm-object.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "NetworkManager.h" #include "nm-object.h" @@ -32,7 +33,7 @@ #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" #include "nm-types.h" -#include "nm-glib-marshal.h" +#include "nm-dbus-helpers-private.h" static gboolean debug = FALSE; #define dbgmsg(f,...) if (G_UNLIKELY (debug)) { g_message (f, ## __VA_ARGS__ ); } @@ -52,30 +53,21 @@ static GHashTable *type_funcs, *type_async_funcs; typedef struct { PropertyMarshalFunc func; GType object_type; - gpointer field; + const char *signal_prefix; } PropertyInfo; static void reload_complete (NMObject *object); -typedef struct { - PropertyInfo pi; - - NMObject *self; - DBusGProxy *proxy; - - char *get_method; - NMPseudoPropertyChangedFunc added_func; - NMPseudoPropertyChangedFunc removed_func; -} PseudoPropertyInfo; - typedef struct { DBusGConnection *connection; + DBusGProxy *bus_proxy; + gboolean nm_running; + char *path; DBusGProxy *properties_proxy; GSList *property_interfaces; GSList *property_tables; - GHashTable *pseudo_properties; NMObject *parent; gboolean suppress_property_updates; @@ -121,6 +113,27 @@ nm_object_error_quark (void) return quark; } +static void +proxy_name_owner_changed (DBusGProxy *proxy, + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) +{ + NMObject *self = NM_OBJECT (user_data); + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + + if (g_strcmp0 (name, NM_DBUS_SERVICE) == 0) { + gboolean old_good = (old_owner && old_owner[0]); + gboolean new_good = (new_owner && new_owner[0]); + + if (!old_good && new_good) + priv->nm_running = TRUE; + else if (old_good && !new_good) + priv->nm_running = FALSE; + } +} + static void nm_object_init (NMObject *object) { @@ -128,15 +141,15 @@ nm_object_init (NMObject *object) static GObject* constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) + guint n_construct_params, + GObjectConstructParam *construct_params) { GObject *object; NMObjectPrivate *priv; object = G_OBJECT_CLASS (nm_object_parent_class)->constructor (type, - n_construct_params, - construct_params); + n_construct_params, + construct_params); priv = NM_OBJECT_GET_PRIVATE (object); @@ -154,15 +167,31 @@ constructor (GType type, static void constructed (GObject *object) { + NMObject *self = NM_OBJECT (object); NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); if (G_OBJECT_CLASS (nm_object_parent_class)->constructed) G_OBJECT_CLASS (nm_object_parent_class)->constructed (object); - priv->properties_proxy = dbus_g_proxy_new_for_name (priv->connection, - NM_DBUS_SERVICE, - priv->path, - "org.freedesktop.DBus.Properties"); + priv->properties_proxy = _nm_object_new_proxy (self, NULL, "org.freedesktop.DBus.Properties"); + + if (_nm_object_is_connection_private (self)) + priv->nm_running = TRUE; + else { + priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + g_assert (priv->bus_proxy); + + dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->bus_proxy, + "NameOwnerChanged", + G_CALLBACK (proxy_name_owner_changed), + object, NULL); + } } static gboolean @@ -170,25 +199,68 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (initable); + if (priv->bus_proxy) { + if (!dbus_g_proxy_call (priv->bus_proxy, + "NameHasOwner", error, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, &priv->nm_running, + G_TYPE_INVALID)) + return FALSE; + } + priv->inited = TRUE; return _nm_object_reload_properties (NM_OBJECT (initable), error); } +/* Takes ownership of @error */ +static void +init_async_complete (GSimpleAsyncResult *simple, GError *error) +{ + if (error) + g_simple_async_result_take_error (simple, error); + else + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + static void init_async_got_properties (GObject *object, GAsyncResult *result, gpointer user_data) { - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); GSimpleAsyncResult *simple = user_data; GError *error = NULL; - priv->inited = TRUE; - if (_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error)) - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - else - g_simple_async_result_take_error (simple, error); + NM_OBJECT_GET_PRIVATE (object)->inited = TRUE; + if (!_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error)) + g_assert (error); + init_async_complete (simple, error); +} - g_simple_async_result_complete (simple); - g_object_unref (simple); +static void +init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMObject *self; + NMObjectPrivate *priv; + GError *error = NULL; + + self = NM_OBJECT (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); + priv = NM_OBJECT_GET_PRIVATE (self); + + if (!dbus_g_proxy_end_call (proxy, call, &error, + G_TYPE_BOOLEAN, &priv->nm_running, + G_TYPE_INVALID)) { + init_async_complete (simple, error); + } else if (!priv->nm_running) { + priv->inited = TRUE; + init_async_complete (simple, NULL); + } else + _nm_object_reload_properties_async (self, init_async_got_properties, simple); + + /* g_async_result_get_source_object() adds a ref */ + g_object_unref (self); } static void @@ -196,10 +268,21 @@ init_async (GAsyncInitable *initable, int io_priority, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (initable); GSimpleAsyncResult *simple; simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); - _nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple); + + if (_nm_object_is_connection_private (NM_OBJECT (initable))) + _nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple); + else { + /* Check if NM is running */ + dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner", + init_async_got_manager_running, + simple, NULL, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID); + } } static gboolean @@ -223,15 +306,14 @@ dispose (GObject *object) priv->notify_id = 0; } - g_slist_foreach (priv->notify_props, (GFunc) g_free, NULL); - g_slist_free (priv->notify_props); + g_slist_free_full (priv->notify_props, g_free); priv->notify_props = NULL; - g_slist_foreach (priv->property_interfaces, (GFunc) g_free, NULL); - g_slist_free (priv->property_interfaces); + g_slist_free_full (priv->property_interfaces, g_free); priv->property_interfaces = NULL; g_clear_object (&priv->properties_proxy); + g_clear_object (&priv->bus_proxy); if (priv->connection) { dbus_g_connection_unref (priv->connection); @@ -246,13 +328,9 @@ finalize (GObject *object) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - g_slist_foreach (priv->property_tables, (GFunc) g_hash_table_destroy, NULL); - g_slist_free (priv->property_tables); + g_slist_free_full (priv->property_tables, (GDestroyNotify) g_hash_table_destroy); g_free (priv->path); - if (priv->pseudo_properties) - g_hash_table_destroy (priv->pseudo_properties); - G_OBJECT_CLASS (nm_object_parent_class)->finalize (object); } @@ -261,15 +339,13 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - DBusGConnection *connection; switch (prop_id) { case PROP_CONNECTION: /* Construct only */ - connection = (DBusGConnection *) g_value_get_boxed (value); - if (!connection) - connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); - priv->connection = dbus_g_connection_ref (connection); + priv->connection = g_value_dup_boxed (value); + if (!priv->connection) + priv->connection = _nm_dbus_new_connection (NULL); break; case PROP_PATH: /* Construct only */ @@ -367,8 +443,7 @@ nm_object_class_init (NMObjectClass *nm_object_class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMObjectClass, object_creation_failed), - NULL, NULL, - _nm_glib_marshal_VOID__POINTER_POINTER, + NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); } @@ -669,31 +744,120 @@ typedef struct { const char *property_name; } ObjectCreatedData; +/* Places items from 'needles' that are not in 'haystack' into 'diff' */ +static void +array_diff (GPtrArray *needles, GPtrArray *haystack, GPtrArray *diff) +{ + guint i, j; + GObject *obj; + + g_assert (needles); + g_assert (haystack); + g_assert (diff); + + for (i = 0; i < needles->len; i++) { + obj = g_ptr_array_index (needles, i); + + for (j = 0; j < haystack->len; j++) { + if (g_ptr_array_index (haystack, j) == obj) + break; + } + + if (j == haystack->len) + g_ptr_array_add (diff, obj); + } +} + +static void +emit_added_removed_signal (NMObject *self, + const char *signal_prefix, + NMObject *changed, + gboolean added) +{ + char buf[50]; + int ret; + + ret = g_snprintf (buf, sizeof (buf), "%s-%s", signal_prefix, added ? "added" : "removed"); + g_assert (ret < sizeof (buf)); + g_signal_emit_by_name (self, buf, changed); +} + static void object_property_complete (ObjectCreatedData *odata) { NMObject *self = odata->self; NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); PropertyInfo *pi = odata->pi; + gboolean different = TRUE; if (odata->array) { - GPtrArray **array = pi->field; + GPtrArray *old = *((GPtrArray **) pi->field); + GPtrArray *new; int i; - if (*array) - g_boxed_free (NM_TYPE_OBJECT_ARRAY, *array); - *array = g_ptr_array_sized_new (odata->length); + /* Build up new array */ + new = g_ptr_array_sized_new (odata->length); for (i = 0; i < odata->length; i++) - add_to_object_array_unique (*array, odata->objects[i]); + add_to_object_array_unique (new, odata->objects[i]); + + if (pi->signal_prefix) { + GPtrArray *added = g_ptr_array_sized_new (3); + GPtrArray *removed = g_ptr_array_sized_new (3); + + if (old) { + /* Find objects in 'old' that do not exist in 'new' */ + array_diff (old, new, removed); + + /* Find objects in 'new' that do not exist in old */ + array_diff (new, old, added); + } else { + for (i = 0; i < new->len; i++) + g_ptr_array_add (added, g_ptr_array_index (new, i)); + } + + *((GPtrArray **) pi->field) = new; + + /* Emit added & removed */ + for (i = 0; i < removed->len; i++) { + emit_added_removed_signal (self, + pi->signal_prefix, + g_ptr_array_index (removed, i), + FALSE); + } + + for (i = 0; i < added->len; i++) { + emit_added_removed_signal (self, + pi->signal_prefix, + g_ptr_array_index (added, i), + TRUE); + } + + different = removed->len || added->len; + g_ptr_array_free (added, TRUE); + g_ptr_array_free (removed, TRUE); + } else { + /* No added/removed signals to send, just replace the property with + * the new values. + */ + *((GPtrArray **) pi->field) = new; + different = TRUE; + } + + /* Free old array last since it will release references, thus freeing + * any objects in the 'removed' array. + */ + if (old) + g_boxed_free (NM_TYPE_OBJECT_ARRAY, old); } else { GObject **obj_p = pi->field; + different = (*obj_p != odata->objects[0]); if (*obj_p) g_object_unref (*obj_p); *obj_p = odata->objects[0]; } - if (odata->property_name) + if (different && odata->property_name) _nm_object_queue_notify (self, odata->property_name); if (priv->reload_results && --priv->reload_remaining == 0) @@ -1045,6 +1209,7 @@ _nm_object_register_properties (NMObject *object, pi->func = tmp->func ? tmp->func : demarshal_generic; pi->object_type = tmp->object_type; pi->field = tmp->field; + pi->signal_prefix = tmp->signal_prefix; g_hash_table_insert (instance, g_strdup (tmp->name), pi); } } @@ -1055,10 +1220,8 @@ _nm_object_reload_properties (NMObject *object, GError **error) NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); GHashTable *props = NULL; GSList *p; - GHashTableIter pp; - gpointer name, info; - if (!priv->property_interfaces) + if (!priv->property_interfaces || !priv->nm_running) return TRUE; for (p = priv->property_interfaces; p; p = p->next) { @@ -1073,12 +1236,6 @@ _nm_object_reload_properties (NMObject *object, GError **error) g_hash_table_destroy (props); } - if (priv->pseudo_properties) { - g_hash_table_iter_init (&pp, priv->pseudo_properties); - while (g_hash_table_iter_next (&pp, &name, &info)) - _nm_object_reload_pseudo_property (object, name); - } - return TRUE; } @@ -1116,20 +1273,23 @@ _nm_object_reload_property (NMObject *object, const char *interface, const char *prop_name) { - GValue value = { 0, }; + GValue value = G_VALUE_INIT; GError *err = NULL; g_return_if_fail (NM_IS_OBJECT (object)); g_return_if_fail (interface != NULL); g_return_if_fail (prop_name != NULL); + if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) + return; + if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, - "Get", 15000, &err, - G_TYPE_STRING, interface, - G_TYPE_STRING, prop_name, - G_TYPE_INVALID, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { + "Get", 15000, &err, + G_TYPE_STRING, interface, + G_TYPE_STRING, prop_name, + G_TYPE_INVALID, + G_TYPE_VALUE, &value, + G_TYPE_INVALID)) { dbgmsg ("%s: Error getting '%s' for %s: (%d) %s\n", __func__, prop_name, @@ -1146,15 +1306,18 @@ _nm_object_reload_property (NMObject *object, void _nm_object_set_property (NMObject *object, - const char *interface, - const char *prop_name, - GValue *value) + const char *interface, + const char *prop_name, + GValue *value) { g_return_if_fail (NM_IS_OBJECT (object)); g_return_if_fail (interface != NULL); g_return_if_fail (prop_name != NULL); g_return_if_fail (G_IS_VALUE (value)); + if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) + return; + if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, "Set", 2000, NULL, G_TYPE_STRING, interface, @@ -1168,163 +1331,6 @@ _nm_object_set_property (NMObject *object, } } -static void -pseudo_property_object_created (GObject *obj, const char *path, gpointer user_data) -{ - PseudoPropertyInfo *ppi = user_data; - - if (obj) { - GPtrArray **list_p = (GPtrArray **)ppi->pi.field; - - if (!*list_p) - *list_p = g_ptr_array_new (); - add_to_object_array_unique (*list_p, obj); - ppi->added_func (ppi->self, NM_OBJECT (obj)); - } -} - -static void -pseudo_property_added (DBusGProxy *proxy, const char *path, gpointer user_data) -{ - PseudoPropertyInfo *ppi = user_data; - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (ppi->self); - NMObject *obj; - - if (priv->suppress_property_updates) - return; - - obj = _nm_object_cache_get (path); - if (obj) - pseudo_property_object_created (G_OBJECT (obj), path, ppi); - else { - _nm_object_create_async (ppi->pi.object_type, priv->connection, path, - pseudo_property_object_created, ppi); - } -} - -static void -pseudo_property_removed (DBusGProxy *proxy, const char *path, gpointer user_data) -{ - PseudoPropertyInfo *ppi = user_data; - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (ppi->self); - GPtrArray *list = *(GPtrArray **)ppi->pi.field; - NMObject *obj = NULL; - int i; - - if (!list || priv->suppress_property_updates) - return; - - for (i = 0; i < list->len; i++) { - obj = list->pdata[i]; - if (!strcmp (path, nm_object_get_path (obj))) { - g_ptr_array_remove_index (list, i); - ppi->removed_func (ppi->self, obj); - g_object_unref (obj); - return; - } - } -} - -static void -free_pseudo_property (PseudoPropertyInfo *ppi) -{ - g_object_unref (ppi->proxy); - g_free (ppi->get_method); - g_slice_free (PseudoPropertyInfo, ppi); -} - -void -_nm_object_register_pseudo_property (NMObject *object, - DBusGProxy *proxy, - const char *name, - gpointer field, - GType object_type, - NMPseudoPropertyChangedFunc added_func, - NMPseudoPropertyChangedFunc removed_func) -{ - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - PseudoPropertyInfo *ppi; - int basename_len; - char *added_signal, *removed_signal; - - g_return_if_fail (NM_IS_OBJECT (object)); - g_return_if_fail (proxy != NULL); - - ppi = g_slice_new0 (PseudoPropertyInfo); - ppi->pi.field = field; - ppi->pi.object_type = object_type; - ppi->self = object; - ppi->proxy = g_object_ref (proxy); - ppi->added_func = added_func; - ppi->removed_func = removed_func; - - basename_len = strlen (name); - if (basename_len > 4 && !strcmp (name + basename_len - 4, "List")) - basename_len -= 4; - else if (basename_len > 1 && name[basename_len - 1] == 's') - basename_len--; - else - g_assert_not_reached (); - - ppi->get_method = g_strdup_printf ("Get%s", name); - added_signal = g_strdup_printf ("%.*sAdded", basename_len, name); - removed_signal = g_strdup_printf ("%.*sRemoved", basename_len, name); - - if (!priv->pseudo_properties) { - priv->pseudo_properties = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) free_pseudo_property); - } - g_hash_table_insert (priv->pseudo_properties, g_strdup (name), ppi); - - dbus_g_proxy_add_signal (proxy, added_signal, - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (proxy, added_signal, - G_CALLBACK (pseudo_property_added), - ppi, NULL); - - dbus_g_proxy_add_signal (proxy, removed_signal, - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (proxy, removed_signal, - G_CALLBACK (pseudo_property_removed), - ppi, NULL); - - g_free (added_signal); - g_free (removed_signal); -} - -void -_nm_object_reload_pseudo_property (NMObject *object, - const char *name) -{ - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - PseudoPropertyInfo *ppi; - GPtrArray *temp; - GError *error = NULL; - GValue value = { 0, }; - - g_return_if_fail (NM_IS_OBJECT (object)); - g_return_if_fail (name != NULL); - - ppi = g_hash_table_lookup (priv->pseudo_properties, name); - g_return_if_fail (ppi != NULL); - - if (!dbus_g_proxy_call (ppi->proxy, ppi->get_method, &error, - G_TYPE_INVALID, - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &temp, - G_TYPE_INVALID)) { - g_warning ("%s: error calling %s: %s", __func__, ppi->get_method, error->message); - g_error_free (error); - return; - } - - g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH); - g_value_take_boxed (&value, temp); - handle_object_array_property (object, NULL, &value, &ppi->pi, TRUE); - g_value_unset (&value); -} - static void reload_complete (NMObject *object) { @@ -1378,36 +1384,6 @@ reload_got_properties (DBusGProxy *proxy, DBusGProxyCall *call, reload_complete (object); } -static void -reload_got_pseudo_property (DBusGProxy *proxy, DBusGProxyCall *call, - gpointer user_data) -{ - PseudoPropertyInfo *ppi = user_data; - NMObject *object = ppi->self; - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - GPtrArray *temp; - GValue value = { 0, }; - GError *error = NULL; - - if (dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &temp, - G_TYPE_INVALID)) { - g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH); - g_value_take_boxed (&value, temp); - if (!priv->suppress_property_updates) - handle_object_array_property (object, NULL, &value, &ppi->pi, FALSE); - g_value_unset (&value); - } else { - if (priv->reload_error) - g_error_free (error); - else - priv->reload_error = error; - } - - if (--priv->reload_remaining == 0) - reload_complete (object); -} - void _nm_object_reload_properties_async (NMObject *object, GAsyncReadyCallback callback, gpointer user_data) { @@ -1418,7 +1394,7 @@ _nm_object_reload_properties_async (NMObject *object, GAsyncReadyCallback callba simple = g_simple_async_result_new (G_OBJECT (object), callback, user_data, _nm_object_reload_properties_async); - if (!priv->property_interfaces && !priv->pseudo_properties) { + if (!priv->property_interfaces) { g_simple_async_result_complete_in_idle (simple); g_object_unref (simple); return; @@ -1440,21 +1416,6 @@ _nm_object_reload_properties_async (NMObject *object, GAsyncReadyCallback callba G_TYPE_STRING, p->data, G_TYPE_INVALID); } - - if (priv->pseudo_properties) { - GHashTableIter iter; - gpointer key, value; - PseudoPropertyInfo *ppi; - - g_hash_table_iter_init (&iter, priv->pseudo_properties); - while (g_hash_table_iter_next (&iter, &key, &value)) { - ppi = value; - priv->reload_remaining++; - dbus_g_proxy_begin_call (ppi->proxy, ppi->get_method, - reload_got_pseudo_property, ppi, NULL, - G_TYPE_INVALID); - } - } } gboolean @@ -1471,3 +1432,18 @@ _nm_object_reload_properties_finish (NMObject *object, GAsyncResult *result, GEr return g_simple_async_result_get_op_res_gboolean (simple); } + +DBusGProxy * +_nm_object_new_proxy (NMObject *self, const char *path, const char *interface) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + + return _nm_dbus_new_proxy_for_connection (priv->connection, path ? path : priv->path, interface); +} + +gboolean +_nm_object_is_connection_private (NMObject *self) +{ + return _nm_dbus_is_connection_private (NM_OBJECT_GET_PRIVATE (self)->connection); +} + diff --git a/libnm-glib/nm-object.h b/libnm-glib/nm-object.h index eac713c6..ae97184f 100644 --- a/libnm-glib/nm-object.h +++ b/libnm-glib/nm-object.h @@ -28,6 +28,8 @@ #include #include +#include + G_BEGIN_DECLS #define NM_TYPE_OBJECT (nm_object_get_type ()) diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 9cadf2f7..38911a43 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -23,14 +23,17 @@ #include #include +#include #include #include #include #include "nm-remote-connection.h" #include "nm-remote-connection-private.h" +#include "nm-object-private.h" #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" +#include "nm-dbus-helpers-private.h" #define NM_REMOTE_CONNECTION_BUS "bus" #define NM_REMOTE_CONNECTION_DBUS_CONNECTION "dbus-connection" @@ -49,6 +52,7 @@ enum { PROP_BUS, PROP_DBUS_CONNECTION, PROP_DBUS_PATH, + PROP_UNSAVED, LAST_PROP }; @@ -62,10 +66,14 @@ enum { }; static guint signals[LAST_SIGNAL] = { 0 }; +typedef struct RemoteCall RemoteCall; +typedef void (*RemoteCallFetchResultCb) (RemoteCall *call, DBusGProxyCall *proxy_call, GError *error); -typedef struct { + +typedef struct RemoteCall { NMRemoteConnection *self; DBusGProxyCall *call; + RemoteCallFetchResultCb fetch_result_cb; GFunc callback; gpointer user_data; } RemoteCall; @@ -73,44 +81,156 @@ typedef struct { typedef struct { DBusGConnection *bus; DBusGProxy *proxy; + DBusGProxy *props_proxy; + gboolean proxy_is_destroyed; GSList *calls; + gboolean inited; + gboolean unsaved; + gboolean visible; } NMRemoteConnectionPrivate; #define NM_REMOTE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionPrivate)) +/** + * nm_remote_connection_error_quark: + * + * Registers an error quark for #NMRemoteConnection if necessary. + * + * Returns: the error quark used for #NMRemoteConnection errors. + **/ +GQuark +nm_remote_connection_error_quark (void) +{ + static GQuark quark = 0; + + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_static_string ("nm-remote-connection-error-quark"); + return quark; +} + /****************************************************************/ static void -remote_call_complete (NMRemoteConnection *self, RemoteCall *call) +_nm_remote_connection_ensure_inited (NMRemoteConnection *self) { NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + GError *error = NULL; - priv->calls = g_slist_remove (priv->calls, call); - /* Don't need to cancel it since this function should only be called from - * the dispose handler (where the proxy will be destroyed immediately after) - * or from the call's completion callback. - */ - memset (call, 0, sizeof (RemoteCall)); - g_free (call); + if (!priv->inited) { + if (!g_initable_init (G_INITABLE (self), NULL, &error)) { + /* Don't warn when the call times out because the settings service can't + * be activated or whatever. + */ + if (!g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY)) { + g_warning ("%s: (NMRemoteConnection) error initializing: %s\n", + __func__, error->message); + } + g_error_free (error); + } + priv->inited = TRUE; + } } +/****************************************************************/ + static void -update_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) +remote_call_dbus_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) { RemoteCall *call = user_data; - NMRemoteConnectionCommitFunc func = (NMRemoteConnectionCommitFunc) call->callback; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); GError *error = NULL; - NMRemoteConnection *self = g_object_ref (call->self); - dbus_g_proxy_end_call (proxy, proxy_call, &error, - G_TYPE_INVALID); - if (func != NULL) - (*func)(call->self, error, call->user_data); + g_assert ( (!proxy && !proxy_call && priv->proxy_is_destroyed) || + ( proxy && proxy_call && !priv->proxy_is_destroyed && proxy == priv->proxy) ); + + if (priv->proxy_is_destroyed) { + error = g_error_new_literal (NM_REMOTE_CONNECTION_ERROR, + NM_REMOTE_CONNECTION_ERROR_DISCONNECTED, + _("Disconnected by D-Bus")); + } + call->fetch_result_cb (call, proxy_call, error); g_clear_error (&error); - remote_call_complete (call->self, call); - g_object_unref (self); + + priv->calls = g_slist_remove (priv->calls, call); + g_object_unref (call->self); + g_free (call); +} + +static gboolean +remote_call_cleanup_cb (void *user_data) +{ + remote_call_dbus_cb (NULL, NULL, user_data); + return G_SOURCE_REMOVE; +} + +static RemoteCall * +remote_call_new (NMRemoteConnection *self, + RemoteCallFetchResultCb fetch_result_cb, + GFunc callback, + gpointer user_data) +{ + RemoteCall *call; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + + g_assert (fetch_result_cb); + + if (priv->proxy_is_destroyed && !callback) + return NULL; + + call = g_malloc0 (sizeof (RemoteCall)); + call->self = g_object_ref (self); + call->fetch_result_cb = fetch_result_cb; + call->user_data = user_data; + call->callback = callback; + + if (priv->proxy_is_destroyed) { + g_idle_add (remote_call_cleanup_cb, call); + return NULL; + } + priv->calls = g_slist_prepend (priv->calls, call); + return call; +} + +static void +proxy_set_destroyed (NMRemoteConnection *self) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + + if (priv->proxy_is_destroyed) { + g_assert (!priv->calls); + return; + } + + priv->proxy_is_destroyed = TRUE; + + priv->calls = g_slist_reverse (priv->calls); + while (priv->calls) + remote_call_dbus_cb (NULL, NULL, priv->calls->data); +} + +static void +proxy_destroy_cb (DBusGProxy* proxy, gpointer user_data) { + proxy_set_destroyed (user_data); +} + +/****************************************************************/ + +static void +result_cb (RemoteCall *call, DBusGProxyCall *proxy_call, GError *error) +{ + NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; + GError *local_error = NULL; + + if (!error) { + dbus_g_proxy_end_call (NM_REMOTE_CONNECTION_GET_PRIVATE (call->self)->proxy, + proxy_call, &local_error, G_TYPE_INVALID); + error = local_error; + } + if (func) + (*func) (call->self, error, call->user_data); + g_clear_error (&local_error); } /** @@ -120,54 +240,105 @@ update_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) * commit completes * @user_data: (closure): caller-specific data to be passed to @callback * - * Save any local changes to the settings and properties of this connection and - * save them in the settings service. + * Send any local changes to the settings and properties of this connection to + * NetworkManager, which will immediately save them to disk. **/ void nm_remote_connection_commit_changes (NMRemoteConnection *self, - NMRemoteConnectionCommitFunc callback, + NMRemoteConnectionResultFunc callback, gpointer user_data) { NMRemoteConnectionPrivate *priv; - GHashTable *settings = NULL; RemoteCall *call; + GHashTable *settings; - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); - g_return_if_fail (callback != NULL); priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); - call = g_malloc0 (sizeof (RemoteCall)); - call->self = self; - call->callback = (GFunc) callback; - call->user_data = user_data; + call = remote_call_new (self, result_cb, (GFunc) callback, user_data); + if (!call) + return; settings = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ALL); - call->call = dbus_g_proxy_begin_call (priv->proxy, "Update", - update_cb, call, NULL, + remote_call_dbus_cb, call, NULL, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, settings, G_TYPE_INVALID); g_assert (call->call); - priv->calls = g_slist_append (priv->calls, call); + g_hash_table_destroy (settings); +} +/** + * nm_remote_connection_commit_changes_unsaved: + * @connection: the #NMRemoteConnection + * @callback: (scope async) (allow-none): a function to be called when the + * commit completes + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Send any local changes to the settings and properties of this connection to + * NetworkManager. The changes are not saved to disk until either + * nm_remote_connection_save() or nm_remote_connection_commit_changes() is + * called. + * + * Since: 0.9.10 + **/ +void +nm_remote_connection_commit_changes_unsaved (NMRemoteConnection *connection, + NMRemoteConnectionResultFunc callback, + gpointer user_data) +{ + NMRemoteConnectionPrivate *priv; + GHashTable *settings = NULL; + RemoteCall *call; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + call = remote_call_new (connection, result_cb, (GFunc) callback, user_data); + if (!call) + return; + + settings = nm_connection_to_hash (NM_CONNECTION (connection), NM_SETTING_HASH_FLAG_ALL); + call->call = dbus_g_proxy_begin_call (priv->proxy, "UpdateUnsaved", + remote_call_dbus_cb, call, NULL, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, settings, + G_TYPE_INVALID); + g_assert (call->call); g_hash_table_destroy (settings); } -static void -delete_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) +/** + * nm_remote_connection_save: + * @connection: the #NMRemoteConnection + * @callback: (scope async) (allow-none): a function to be called when the + * save completes + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Saves the connection to disk if the connection has changes that have not yet + * been written to disk, or if the connection has never been saved. + * + * Since: 0.9.10 + **/ +void +nm_remote_connection_save (NMRemoteConnection *connection, + NMRemoteConnectionResultFunc callback, + gpointer user_data) { - RemoteCall *call = user_data; - NMRemoteConnectionDeleteFunc func = (NMRemoteConnectionDeleteFunc) call->callback; - GError *error = NULL; + NMRemoteConnectionPrivate *priv; + RemoteCall *call; - dbus_g_proxy_end_call (proxy, proxy_call, &error, - G_TYPE_INVALID); - if (func != NULL) - (*func)(call->self, error, call->user_data); - g_clear_error (&error); - remote_call_complete (call->self, call); + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + call = remote_call_new (connection, result_cb, (GFunc) callback, user_data); + if (!call) + return; + + call->call = dbus_g_proxy_begin_call (priv->proxy, "Save", remote_call_dbus_cb, call, NULL, G_TYPE_INVALID); + g_assert (call->call); } /** @@ -180,47 +351,48 @@ delete_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) **/ void nm_remote_connection_delete (NMRemoteConnection *self, - NMRemoteConnectionDeleteFunc callback, + NMRemoteConnectionResultFunc callback, gpointer user_data) { NMRemoteConnectionPrivate *priv; RemoteCall *call; - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); - call = g_malloc0 (sizeof (RemoteCall)); - call->self = self; - call->callback = (GFunc) callback; - call->user_data = user_data; + call = remote_call_new (self, result_cb, (GFunc) callback, user_data); + if (!call) + return; call->call = dbus_g_proxy_begin_call (priv->proxy, "Delete", - delete_cb, call, NULL, + remote_call_dbus_cb, call, NULL, G_TYPE_INVALID); g_assert (call->call); - priv->calls = g_slist_append (priv->calls, call); } static void -get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) +get_secrets_cb (RemoteCall *call, DBusGProxyCall *proxy_call, GError *error) { - RemoteCall *call = user_data; NMRemoteConnectionGetSecretsFunc func = (NMRemoteConnectionGetSecretsFunc) call->callback; GHashTable *secrets = NULL; - GError *error = NULL; - - dbus_g_proxy_end_call (proxy, proxy_call, &error, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets, - G_TYPE_INVALID); - (*func)(call->self, error ? NULL : secrets, error, call->user_data); + GError *local_error = NULL; + + if (!error) { + dbus_g_proxy_end_call (NM_REMOTE_CONNECTION_GET_PRIVATE (call->self)->proxy, + proxy_call, &local_error, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets, + G_TYPE_INVALID); + error = local_error; + } + if (func) + (*func) (call->self, error ? NULL : secrets, error, call->user_data); + g_clear_error (&local_error); if (secrets) g_hash_table_destroy (secrets); - g_clear_error (&error); - remote_call_complete (call->self, call); } + /** * nm_remote_connection_get_secrets: * @connection: the #NMRemoteConnection @@ -240,23 +412,39 @@ nm_remote_connection_get_secrets (NMRemoteConnection *self, NMRemoteConnectionPrivate *priv; RemoteCall *call; - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); g_return_if_fail (callback != NULL); priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); - call = g_malloc0 (sizeof (RemoteCall)); - call->self = self; - call->callback = (GFunc) callback; - call->user_data = user_data; + call = remote_call_new (self, get_secrets_cb, (GFunc) callback, user_data); + if (!call) + return; call->call = dbus_g_proxy_begin_call (priv->proxy, "GetSecrets", - get_secrets_cb, call, NULL, + remote_call_dbus_cb, call, NULL, G_TYPE_STRING, setting_name, G_TYPE_INVALID); g_assert (call->call); - priv->calls = g_slist_append (priv->calls, call); +} + +/** + * nm_remote_connection_get_unsaved: + * @connection: the #NMRemoteConnection + * + * Returns: %TRUE if the remote connection contains changes that have not + * been saved to disk, %FALSE if the connection is the same as its on-disk + * representation. + * + * Since: 0.9.10 + **/ +gboolean +nm_remote_connection_get_unsaved (NMRemoteConnection *connection) +{ + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + _nm_remote_connection_ensure_inited (connection); + return NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->unsaved; } /****************************************************************/ @@ -328,9 +516,11 @@ updated_cb (DBusGProxy *proxy, gpointer user_data) NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); /* The connection got updated; request the replacement settings */ - dbus_g_proxy_begin_call (priv->proxy, "GetSettings", - updated_get_settings_cb, self, NULL, - G_TYPE_INVALID); + if (!priv->proxy_is_destroyed) { + dbus_g_proxy_begin_call (priv->proxy, "GetSettings", + updated_get_settings_cb, self, NULL, + G_TYPE_INVALID); + } } static void @@ -339,6 +529,25 @@ removed_cb (DBusGProxy *proxy, gpointer user_data) g_signal_emit (G_OBJECT (user_data), signals[REMOVED], 0); } +static void +properties_changed_cb (DBusGProxy *proxy, + GHashTable *properties, + gpointer user_data) +{ + NMRemoteConnection *self = NM_REMOTE_CONNECTION (user_data); + GHashTableIter iter; + const char *key; + GValue *value; + + g_hash_table_iter_init (&iter, properties); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { + if (!strcmp (key, "Unsaved")) { + NM_REMOTE_CONNECTION_GET_PRIVATE (self)->unsaved = g_value_get_boolean (value); + g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_UNSAVED); + } + } +} + /****************************************************************/ /** @@ -366,16 +575,16 @@ nm_remote_connection_new (DBusGConnection *bus, static void constructed (GObject *object) { - NMRemoteConnectionPrivate *priv; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object); + + G_OBJECT_CLASS (nm_remote_connection_parent_class)->constructed (object); - priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object); g_assert (priv->bus); g_assert (nm_connection_get_path (NM_CONNECTION (object))); - priv->proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE, - nm_connection_get_path (NM_CONNECTION (object)), - NM_DBUS_IFACE_SETTINGS_CONNECTION); + priv->proxy = _nm_dbus_new_proxy_for_connection (priv->bus, + nm_connection_get_path (NM_CONNECTION (object)), + NM_DBUS_IFACE_SETTINGS_CONNECTION); g_assert (priv->proxy); dbus_g_proxy_set_default_timeout (priv->proxy, G_MAXINT); @@ -384,23 +593,54 @@ constructed (GObject *object) dbus_g_proxy_add_signal (priv->proxy, "Removed", G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->proxy, "Removed", G_CALLBACK (removed_cb), object, NULL); + + g_signal_connect (priv->proxy, "destroy", G_CALLBACK (proxy_destroy_cb), object); + + /* Monitor properties */ + dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->proxy, "PropertiesChanged", + DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->proxy, "PropertiesChanged", + G_CALLBACK (properties_changed_cb), + object, + NULL); + + priv->props_proxy = _nm_dbus_new_proxy_for_connection (priv->bus, + nm_connection_get_path (NM_CONNECTION (object)), + DBUS_INTERFACE_PROPERTIES); + g_assert (priv->props_proxy); } static gboolean init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (initable); - GHashTable *settings; + GHashTable *hash; if (!dbus_g_proxy_call (priv->proxy, "GetSettings", error, G_TYPE_INVALID, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &hash, G_TYPE_INVALID)) return FALSE; - priv->visible = TRUE; - replace_settings (NM_REMOTE_CONNECTION (initable), settings); - g_hash_table_destroy (settings); + replace_settings (NM_REMOTE_CONNECTION (initable), hash); + g_hash_table_destroy (hash); + + /* Get properties */ + hash = NULL; + if (!dbus_g_proxy_call (priv->props_proxy, "GetAll", error, + G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS_CONNECTION, + G_TYPE_INVALID, + DBUS_TYPE_G_MAP_OF_VARIANT, &hash, + G_TYPE_INVALID)) + return FALSE; + properties_changed_cb (priv->props_proxy, hash, NM_REMOTE_CONNECTION (initable)); + g_hash_table_destroy (hash); + return TRUE; } @@ -409,6 +649,38 @@ typedef struct { GSimpleAsyncResult *result; } NMRemoteConnectionInitData; +static void +init_async_complete (NMRemoteConnectionInitData *init_data, GError *error) +{ + if (error) + g_simple_async_result_take_error (init_data->result, error); + else { + g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); + NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection)->inited = TRUE; + } + + g_simple_async_result_complete (init_data->result); + g_object_unref (init_data->result); + g_slice_free (NMRemoteConnectionInitData, init_data); +} + +static void +init_async_got_properties (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +{ + NMRemoteConnectionInitData *init_data = user_data; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection); + GHashTable *props; + GError *error = NULL; + + if (dbus_g_proxy_end_call (proxy, call, &error, + DBUS_TYPE_G_MAP_OF_VARIANT, &props, + G_TYPE_INVALID)) { + properties_changed_cb (priv->props_proxy, props, init_data->connection); + g_hash_table_destroy (props); + } + init_async_complete (init_data, error); +} + static void init_get_settings_cb (DBusGProxy *proxy, DBusGProxyCall *call, @@ -423,17 +695,19 @@ init_get_settings_cb (DBusGProxy *proxy, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, G_TYPE_INVALID); if (error) { - g_simple_async_result_take_error (init_data->result, error); - } else { - priv->visible = TRUE; - replace_settings (init_data->connection, settings); - g_hash_table_destroy (settings); - g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); + init_async_complete (init_data, error); + return; } - g_simple_async_result_complete (init_data->result); - g_object_unref (init_data->result); - g_slice_free (NMRemoteConnectionInitData, init_data); + priv->visible = TRUE; + replace_settings (init_data->connection, settings); + g_hash_table_destroy (settings); + + /* Grab properties */ + dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", + init_async_got_properties, init_data, NULL, + G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS_CONNECTION, + G_TYPE_INVALID); } static void @@ -453,7 +727,6 @@ init_async (GAsyncInitable *initable, int io_priority, dbus_g_proxy_begin_call (priv->proxy, "GetSettings", init_get_settings_cb, init_data, NULL, G_TYPE_INVALID); - } static gboolean @@ -509,6 +782,22 @@ constructor (GType type, guint n_construct_properties, constructor (type, n_construct_properties, construct_properties); } +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + _nm_remote_connection_ensure_inited (NM_REMOTE_CONNECTION (object)); + + switch (prop_id) { + case PROP_UNSAVED: + g_value_set_boolean (value, NM_REMOTE_CONNECTION_GET_PRIVATE (object)->unsaved); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) @@ -519,8 +808,15 @@ set_property (GObject *object, guint prop_id, case PROP_BUS: case PROP_DBUS_CONNECTION: /* Construct only */ - if (g_value_get_boxed (value)) - priv->bus = dbus_g_connection_ref ((DBusGConnection *) g_value_get_boxed (value)); + /* priv->bus is set from either of two properties so that it (a) remains + * backwards compatible with the previous "bus" property, and that (b) + * it can be created just like an NMObject using the "dbus-connection", + * even though it's not a subclass of NMObject. So don't overwrite the + * a valid value that the other property set with NULL, if one of the + * properties isn't specified at construction time. + */ + if (!priv->bus) + priv->bus = g_value_dup_boxed (value); break; case PROP_DBUS_PATH: /* Don't need to do anything; see constructor(). */ @@ -535,12 +831,15 @@ static void dispose (GObject *object) { NMRemoteConnection *self = NM_REMOTE_CONNECTION (object); - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object); + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); - while (g_slist_length (priv->calls)) - remote_call_complete (self, priv->calls->data); + proxy_set_destroyed (self); - g_clear_object (&priv->proxy); + if (priv->proxy) { + g_signal_handlers_disconnect_by_func (priv->proxy, proxy_destroy_cb, object); + g_clear_object (&priv->proxy); + } + g_clear_object (&priv->props_proxy); if (priv->bus) { dbus_g_connection_unref (priv->bus); @@ -559,6 +858,7 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) /* virtual methods */ object_class->constructor = constructor; + object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; object_class->constructed = constructed; @@ -588,6 +888,21 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + /** + * NMRemoteConnection:unsaved: + * + * %TRUE if the remote connection contains changes that have not been saved + * to disk, %FALSE if the connection is the same as its on-disk representation. + * + * Since: 0.9.10 + **/ + g_object_class_install_property (object_class, PROP_UNSAVED, + g_param_spec_boolean (NM_REMOTE_CONNECTION_UNSAVED, + "Unsaved", + "Unsaved", + FALSE, + G_PARAM_READABLE)); + /* Signals */ /** * NMRemoteConnection::updated: diff --git a/libnm-glib/nm-remote-connection.h b/libnm-glib/nm-remote-connection.h index eebf9160..911885c4 100644 --- a/libnm-glib/nm-remote-connection.h +++ b/libnm-glib/nm-remote-connection.h @@ -38,6 +38,24 @@ G_BEGIN_DECLS #define NM_IS_REMOTE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_REMOTE_CONNECTION)) #define NM_REMOTE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass)) + +/** + * NMRemoteConnectionError: + * @NM_REMOTE_CONNECTION_ERROR_UNKNOWN: unknown or unclassified error + * @NM_REMOTE_CONNECTION_ERROR_DISCONNECTED: dbus disconnected + */ +typedef enum { + NM_REMOTE_CONNECTION_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ + NM_REMOTE_CONNECTION_ERROR_DISCONNECTED, /*< nick=Disconnected >*/ +} NMRemoteConnectionError; + +#define NM_REMOTE_CONNECTION_ERROR (nm_remote_connection_error_quark ()) +GQuark nm_remote_connection_error_quark (void); + +/* Properties */ +#define NM_REMOTE_CONNECTION_UNSAVED "unsaved" + +/* Signals */ #define NM_REMOTE_CONNECTION_UPDATED "updated" #define NM_REMOTE_CONNECTION_REMOVED "removed" @@ -64,30 +82,21 @@ typedef struct { } NMRemoteConnectionClass; /** - * NMRemoteConnectionCommitFunc: - * @connection: the connection for which updates are to be committed + * NMRemoteConnectionResultFunc: + * @connection: the connection for which an operation was performed * @error: on failure, a descriptive error - * @user_data: user data passed to nm_remote_connection_commit_changes() + * @user_data: user data passed to function which began the operation * - * Called when NetworkManager has committed outstanding changes to a connection - * to backing storage as a result of nm_remote_connection_commit_changes(). + * Called when NetworkManager has finished an asynchronous operation on a + * connection, like commit changes, deleting, saving, etc. */ -typedef void (*NMRemoteConnectionCommitFunc) (NMRemoteConnection *connection, +typedef void (*NMRemoteConnectionResultFunc) (NMRemoteConnection *connection, GError *error, gpointer user_data); -/** - * NMRemoteConnectionDeleteFunc: - * @connection: the connection to be deleted - * @error: on failure, a descriptive error - * @user_data: user data passed to nm_remote_connection_delete() - * - * Called when NetworkManager has deleted a connection as a result of - * nm_remote_connection_delete(). - */ -typedef void (*NMRemoteConnectionDeleteFunc) (NMRemoteConnection *connection, - GError *error, - gpointer user_data); +/* Backwards compatibility */ +typedef NMRemoteConnectionResultFunc NMRemoteConnectionCommitFunc; +typedef NMRemoteConnectionResultFunc NMRemoteConnectionDeleteFunc; /** * NMRemoteConnectionGetSecretsFunc: @@ -112,17 +121,31 @@ NMRemoteConnection *nm_remote_connection_new (DBusGConnection *bus, const char *path); void nm_remote_connection_commit_changes (NMRemoteConnection *connection, - NMRemoteConnectionCommitFunc callback, + NMRemoteConnectionResultFunc callback, gpointer user_data); +NM_AVAILABLE_IN_0_9_10 +void nm_remote_connection_commit_changes_unsaved (NMRemoteConnection *connection, + NMRemoteConnectionResultFunc callback, + gpointer user_data); + +NM_AVAILABLE_IN_0_9_10 +void nm_remote_connection_save (NMRemoteConnection *connection, + NMRemoteConnectionResultFunc callback, + gpointer user_data); + void nm_remote_connection_delete (NMRemoteConnection *connection, - NMRemoteConnectionDeleteFunc callback, + NMRemoteConnectionResultFunc callback, gpointer user_data); void nm_remote_connection_get_secrets (NMRemoteConnection *connection, const char *setting_name, NMRemoteConnectionGetSecretsFunc callback, gpointer user_data); + +NM_AVAILABLE_IN_0_9_10 +gboolean nm_remote_connection_get_unsaved (NMRemoteConnection *connection); + G_END_DECLS #endif /* __NM_REMOTE_CONNECTION__ */ diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 34817e2c..3a2a3e68 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -25,11 +25,100 @@ #include #include -#include "nm-glib-marshal.h" #include "nm-dbus-glib-types.h" #include "nm-remote-settings.h" #include "nm-remote-connection-private.h" +#include "nm-object-private.h" +#include "nm-dbus-helpers-private.h" #include "nm-glib-compat.h" +#include "nm-object-private.h" + +/** + * SECTION:nm-remote-settings + * @Short_description: A helper for NetworkManager's settings API + * @Title: NMRemoteSettings + * @See_also:#NMRemoteConnection, #NMClient + * + * The #NMRemoteSettings object represents NetworkManager's "settings" service, + * which stores network configuration and allows authenticated clients to + * add, delete, and modify that configuration. The data required to connect + * to a specific network is called a "connection" and encapsulated by the + * #NMConnection object. Once a connection is known to NetworkManager, having + * either been added by a user or read from on-disk storage, the + * #NMRemoteSettings object creates a #NMRemoteConnection object which + * represents this stored connection. Use the #NMRemoteConnection object to + * perform any operations like modification or deletion. + * + * To add a new network connection to the NetworkManager settings service, first + * build up a template #NMConnection object. Since this connection is not yet + * added to NetworkManager, it is known only to your program and is not yet + * an #NMRemoteConnection. Then ask #NMRemoteSettings to add your connection. + * When the connection is added successfully, the supplied callback is called + * and returns to your program the new #NMRemoteConnection which represents + * the stored object known to NetworkManager. + * + * |[ + * static void + * added_cb (NMRemoteSettings *settings, + * NMRemoteConnection *remote, + * GError *error, + * gpointer user_data) + * { + * if (error) + * g_print ("Error adding connection: %s", error->message); + * else { + * g_print ("Added: %s\n", nm_connection_get_path (NM_CONNECTION (remote))); + * /* Use 'remote' with nm_remote_connection_commit_changes() to save + * * changes and nm_remote_connection_delete() to delete the connection */ + * } + * } + * + * static gboolean + * add_wired_connection (const char *human_name) + * { + * NMConnection *connection; + * NMSettingConnection *s_con; + * NMSettingWired *s_wired; + * char *uuid; + * gboolean success; + * + * connection = nm_connection_new (); + * + * /* Build up the 'connection' setting */ + * s_con = (NMSettingConnection *) nm_setting_connection_new (); + * uuid = nm_utils_uuid_generate (); + * g_object_set (G_OBJECT (s_con), + * NM_SETTING_CONNECTION_UUID, uuid, + * NM_SETTING_CONNECTION_ID, human_name, + * NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + * NULL); + * g_free (uuid); + * nm_connection_add_setting (connection, NM_SETTING (s_con)); + * + * /* Add the required 'wired' setting as this is a wired connection */ + * nm_connection_add_setting (connection, nm_setting_wired_new ()); + * + * /* Add an 'ipv4' setting using AUTO configuration (eg DHCP) */ + * s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + * g_object_set (G_OBJECT (s_ip4), + * NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + * NULL); + * nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + * + * /* Ask NetworkManager to store the connection */ + * success = nm_remote_settings_add_connection (settings, connection, added_cb, loop); + * + * /* Release the template connection; the actual stored connection will + * * be returned in added_cb() */ + * g_object_unref (connection); + * + * /* Let glib event loop run and added_cb() will be called when NetworkManager + * * is done adding the new connection. */ + * + * return success; + * } + * ]| + */ static void nm_remote_settings_initable_iface_init (GInitableIface *iface); static void nm_remote_settings_async_initable_iface_init (GAsyncInitableIface *iface); @@ -43,6 +132,7 @@ G_DEFINE_TYPE_WITH_CODE (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT, typedef struct { DBusGConnection *bus; + gboolean private_bus; gboolean inited; DBusGProxy *proxy; @@ -60,8 +150,7 @@ typedef struct { DBusGProxy *dbus_proxy; - guint fetch_id; - gboolean fetching; + DBusGProxyCall *listcon_call; } NMRemoteSettingsPrivate; enum { @@ -171,6 +260,45 @@ add_connection_info_complete (NMRemoteSettings *self, add_connection_info_dispose (self, info); } +/** + * nm_remote_settings_get_connection_by_id: + * @settings: the %NMRemoteSettings + * @id: the id of the remote connection + * + * Returns the first matching %NMRemoteConnection matching a given @id. + * + * Returns: (transfer none): the remote connection object on success, or %NULL if no + * matching object was found. + * + * Since: 0.9.10 + **/ +NMRemoteConnection * +nm_remote_settings_get_connection_by_id (NMRemoteSettings *settings, const char *id) +{ + NMRemoteSettingsPrivate *priv; + + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); + g_return_val_if_fail (id != NULL, NULL); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + _nm_remote_settings_ensure_inited (settings); + + if (priv->service_running) { + GHashTableIter iter; + NMConnection *candidate; + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &candidate)) { + + if (!strcmp (id, nm_connection_get_id (candidate))) + return NM_REMOTE_CONNECTION (candidate); + } + } + + return NULL; +} + /** * nm_remote_settings_get_connection_by_path: * @settings: the %NMRemoteSettings @@ -186,7 +314,6 @@ nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, const cha { NMRemoteSettingsPrivate *priv; - g_return_val_if_fail (settings != NULL, NULL); g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); g_return_val_if_fail (path != NULL, NULL); @@ -214,7 +341,6 @@ nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings, const cha GHashTableIter iter; NMRemoteConnection *candidate; - g_return_val_if_fail (settings != NULL, NULL); g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); g_return_val_if_fail (uuid != NULL, NULL); @@ -363,9 +489,10 @@ connection_inited (GObject *source, GAsyncResult *result, gpointer user_data) g_signal_emit (self, signals[NEW_CONNECTION], 0, remote); } else { if (addinfo) { - local = g_error_new_literal (NM_REMOTE_SETTINGS_ERROR, - NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE, - "Connection not visible or not available"); + local = g_error_new (NM_REMOTE_SETTINGS_ERROR, + NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE, + "Connection not visible or not available: %s", + error ? error->message : "(unknown)"); add_connection_info_complete (self, addinfo, local); g_error_free (local); } @@ -382,10 +509,8 @@ connection_inited (GObject *source, GAsyncResult *result, gpointer user_data) /* Let listeners know that all connections have been found */ priv->init_left--; - if (priv->init_left == 0) { - priv->fetching = FALSE; + if (priv->init_left == 0) g_signal_emit (self, signals[CONNECTIONS_READ], 0); - } } static NMRemoteConnection * @@ -431,12 +556,15 @@ fetch_connections_done (DBusGProxy *proxy, GError *error = NULL; int i; + g_warn_if_fail (priv->listcon_call == call); + priv->listcon_call = NULL; + if (!dbus_g_proxy_end_call (proxy, call, &error, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &connections, G_TYPE_INVALID)) { - /* Ignore settings service spawn errors */ if ( !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN) - && !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NAME_HAS_NO_OWNER)) { + && !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NAME_HAS_NO_OWNER) + && priv->service_running) { g_warning ("%s: error fetching connections: (%d) %s.", __func__, error->code, @@ -445,16 +573,14 @@ fetch_connections_done (DBusGProxy *proxy, g_clear_error (&error); /* We tried to read connections and failed */ - priv->fetching = FALSE; g_signal_emit (self, signals[CONNECTIONS_READ], 0); return; } /* Let listeners know we are done getting connections */ - if (connections->len == 0) { - priv->fetching = FALSE; + if (connections->len == 0) g_signal_emit (self, signals[CONNECTIONS_READ], 0); - } else { + else { priv->init_left = connections->len; for (i = 0; i < connections->len; i++) { char *path = g_ptr_array_index (connections, i); @@ -467,20 +593,6 @@ fetch_connections_done (DBusGProxy *proxy, g_ptr_array_free (connections, TRUE); } -static gboolean -fetch_connections (gpointer user_data) -{ - NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - - priv->fetch_id = 0; - - dbus_g_proxy_begin_call (priv->proxy, "ListConnections", - fetch_connections_done, self, NULL, - G_TYPE_INVALID); - return FALSE; -} - /** * nm_remote_settings_list_connections: * @settings: the %NMRemoteSettings @@ -500,7 +612,6 @@ nm_remote_settings_list_connections (NMRemoteSettings *settings) GHashTableIter iter; gpointer value; - g_return_val_if_fail (settings != NULL, NULL); g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); @@ -543,7 +654,14 @@ add_connection_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data * @user_data: (closure): caller-specific data passed to @callback * * Requests that the remote settings service add the given settings to a new - * connection. + * connection. The connection is immediately written to disk. @connection is + * untouched by this function and only serves as a template of the settings to + * add. The #NMRemoteConnection object that represents what NetworkManager + * actually added is returned to @callback when the addition operation is complete. + * + * Note that the #NMRemoteConnection returned in @callback may not contain + * identical settings to @connection as NetworkManager may perform automatic + * completion and/or normalization of connection properties. * * Returns: %TRUE if the request was successful, %FALSE if it failed **/ @@ -557,9 +675,7 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, AddConnectionInfo *info; GHashTable *new_settings; - g_return_val_if_fail (settings != NULL, FALSE); g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); - g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); g_return_val_if_fail (callback != NULL, FALSE); @@ -567,6 +683,9 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, _nm_remote_settings_ensure_inited (settings); + if (!priv->service_running) + return FALSE; + info = g_malloc0 (sizeof (AddConnectionInfo)); info->self = settings; info->callback = callback; @@ -586,6 +705,171 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, return TRUE; } +/** + * nm_remote_settings_add_connection_unsaved: + * @settings: the %NMRemoteSettings + * @connection: the connection to add. Note that this object's settings will be + * added, not the object itself + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the remote settings service add the given settings to a new + * connection. The connection is not written to disk, which may be done at + * a later time by calling the connection's nm_remote_connection_commit_changes() + * method. + * + * Returns: %TRUE if the request was successful, %FALSE if it failed + * + * Since: 0.9.10 + **/ +gboolean +nm_remote_settings_add_connection_unsaved (NMRemoteSettings *settings, + NMConnection *connection, + NMRemoteSettingsAddConnectionFunc callback, + gpointer user_data) +{ + NMRemoteSettingsPrivate *priv; + AddConnectionInfo *info; + GHashTable *new_settings; + + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (callback != NULL, FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + _nm_remote_settings_ensure_inited (settings); + + if (!priv->service_running) + return FALSE; + + info = g_malloc0 (sizeof (AddConnectionInfo)); + info->self = settings; + info->callback = callback; + info->callback_data = user_data; + + new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + dbus_g_proxy_begin_call (priv->proxy, "AddConnectionUnsaved", + add_connection_done, + info, + NULL, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings, + G_TYPE_INVALID); + g_hash_table_destroy (new_settings); + + priv->add_list = g_slist_append (priv->add_list, info); + + return TRUE; +} + +/** + * nm_remote_settings_load_connections: + * @settings: the %NMRemoteSettings + * @filenames: %NULL-terminated array of filenames to load + * @failures: (out) (transfer full): on return, a %NULL-terminated array of + * filenames that failed to load + * @error: return location for #GError + * + * Requests that the remote settings service load or reload the given files, + * adding or updating the connections described within. + * + * The changes to the indicated files will not yet be reflected in + * @settings's connections array when the function returns. + * + * If all of the indicated files were successfully loaded, the + * function will return %TRUE, and @failures will be set to %NULL. If + * NetworkManager tried to load the files, but some (or all) failed, + * then @failures will be set to a %NULL-terminated array of the + * filenames that failed to load. + + * Returns: %TRUE if NetworkManager at least tried to load @filenames, + * %FALSE if an error occurred (eg, permission denied). + * + * Since: 0.9.10 + **/ +gboolean +nm_remote_settings_load_connections (NMRemoteSettings *settings, + char **filenames, + char ***failures, + GError **error) +{ + NMRemoteSettingsPrivate *priv; + char **my_failures = NULL; + gboolean ret; + + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + g_return_val_if_fail (filenames != NULL, FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + _nm_remote_settings_ensure_inited (settings); + + if (!priv->service_running) { + g_set_error_literal (error, NM_REMOTE_SETTINGS_ERROR, + NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE, + "NetworkManager is not running."); + return FALSE; + } + + if (!dbus_g_proxy_call (priv->proxy, "LoadConnections", error, + G_TYPE_STRV, filenames, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, &ret, + G_TYPE_STRV, &my_failures, + G_TYPE_INVALID)) + ret = FALSE; + + if (failures) { + if (my_failures && !*my_failures) + g_clear_pointer (&my_failures, g_free); + *failures = my_failures; + } else + g_strfreev (my_failures); + + return ret; +} + +/** + * nm_remote_settings_reload_connections: + * @settings: the #NMRemoteSettings + * @error: return location for #GError + * + * Requests that the remote settings service reload all connection + * files from disk, adding, updating, and removing connections until + * the in-memory state matches the on-disk state. + * + * Return value: %TRUE on success, %FALSE on failure + * + * Since: 0.9.10 + **/ +gboolean +nm_remote_settings_reload_connections (NMRemoteSettings *settings, + GError **error) +{ + NMRemoteSettingsPrivate *priv; + gboolean success; + + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + _nm_remote_settings_ensure_inited (settings); + + if (!priv->service_running) { + g_set_error_literal (error, NM_REMOTE_SETTINGS_ERROR, + NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE, + "NetworkManager is not running."); + return FALSE; + } + + if (!dbus_g_proxy_call (priv->proxy, "ReloadConnections", error, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, &success, + G_TYPE_INVALID)) + return FALSE; + return success; +} + static void clear_one_hash (GHashTable *table) { @@ -595,7 +879,7 @@ clear_one_hash (GHashTable *table) /* Build up the list of connections; we can't emit "removed" during hash * table iteration because emission of the "removed" signal may trigger code - * that explicitly removes the the connection from the hash table somewhere + * that explicitly removes the connection from the hash table somewhere * else. */ g_hash_table_iter_init (&iter, table); @@ -609,17 +893,6 @@ clear_one_hash (GHashTable *table) g_hash_table_remove_all (table); } -static gboolean -remove_connections (gpointer user_data) -{ - NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - - clear_one_hash (priv->pending); - clear_one_hash (priv->connections); - return FALSE; -} - typedef struct { NMRemoteSettings *settings; NMRemoteSettingsSaveHostnameFunc callback; @@ -663,7 +936,6 @@ nm_remote_settings_save_hostname (NMRemoteSettings *settings, NMRemoteSettingsPrivate *priv; SaveHostnameInfo *info; - g_return_val_if_fail (settings != NULL, FALSE); g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); g_return_val_if_fail (hostname != NULL, FALSE); g_return_val_if_fail (callback != NULL, FALSE); @@ -672,6 +944,9 @@ nm_remote_settings_save_hostname (NMRemoteSettings *settings, _nm_remote_settings_ensure_inited (settings); + if (!priv->service_running) + return FALSE; + info = g_malloc0 (sizeof (SaveHostnameInfo)); info->settings = settings; info->callback = callback; @@ -740,21 +1015,23 @@ name_owner_changed (DBusGProxy *proxy, const char *sname = NM_DBUS_SERVICE; if (!strcmp (name, sname)) { - if (priv->fetch_id) - g_source_remove (priv->fetch_id); - if (new_owner && strlen (new_owner) > 0) { - priv->fetch_id = g_idle_add (fetch_connections, self); priv->service_running = TRUE; + priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections", + fetch_connections_done, self, NULL, + G_TYPE_INVALID); + dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", nm_appeared_got_properties, self, NULL, G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS, G_TYPE_INVALID); } else { - priv->fetch_id = g_idle_add (remove_connections, self); priv->service_running = FALSE; + clear_one_hash (priv->pending); + clear_one_hash (priv->connections); + /* Clear properties */ g_free (priv->hostname); priv->hostname = NULL; @@ -762,6 +1039,11 @@ name_owner_changed (DBusGProxy *proxy, priv->can_modify = FALSE; g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_CAN_MODIFY); + + if (priv->listcon_call) { + dbus_g_proxy_cancel_call (priv->proxy, priv->listcon_call); + priv->listcon_call = NULL; + } } g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_SERVICE_RUNNING); } @@ -784,7 +1066,11 @@ name_owner_changed (DBusGProxy *proxy, NMRemoteSettings * nm_remote_settings_new (DBusGConnection *bus) { - return g_object_new (NM_TYPE_REMOTE_SETTINGS, NM_REMOTE_SETTINGS_BUS, bus, NULL); + NMRemoteSettings *self; + + self = g_object_new (NM_TYPE_REMOTE_SETTINGS, NM_REMOTE_SETTINGS_BUS, bus, NULL); + _nm_remote_settings_ensure_inited (self); + return self; } static void @@ -880,29 +1166,30 @@ constructed (GObject *object) priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object); - /* D-Bus proxy for clearing connections on NameOwnerChanged */ - priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); - g_assert (priv->dbus_proxy); + if (priv->private_bus == FALSE) { + /* D-Bus proxy for clearing connections on NameOwnerChanged */ + priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + g_assert (priv->dbus_proxy); + + dbus_g_object_register_marshaller (g_cclosure_marshal_generic, + G_TYPE_NONE, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->dbus_proxy, + "NameOwnerChanged", + G_CALLBACK (name_owner_changed), + object, NULL); + } - dbus_g_object_register_marshaller (_nm_glib_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->dbus_proxy, - "NameOwnerChanged", - G_CALLBACK (name_owner_changed), - object, NULL); - - priv->proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE, - NM_DBUS_PATH_SETTINGS, - NM_DBUS_IFACE_SETTINGS); + priv->proxy = _nm_dbus_new_proxy_for_connection (priv->bus, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_IFACE_SETTINGS); g_assert (priv->proxy); dbus_g_proxy_set_default_timeout (priv->proxy, G_MAXINT); @@ -914,19 +1201,14 @@ constructed (GObject *object) object, NULL); - priv->fetching = TRUE; - priv->fetch_id = g_idle_add (fetch_connections, object); - - /* D-Bus properties proxy */ - priv->props_proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE, - NM_DBUS_PATH_SETTINGS, - "org.freedesktop.DBus.Properties"); + priv->props_proxy = _nm_dbus_new_proxy_for_connection (priv->bus, + NM_DBUS_PATH_SETTINGS, + "org.freedesktop.DBus.Properties"); g_assert (priv->props_proxy); /* Monitor properties */ - dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, + dbus_g_object_register_marshaller (g_cclosure_marshal_generic, G_TYPE_NONE, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); @@ -946,20 +1228,27 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); GHashTable *props; - if (!dbus_g_proxy_call (priv->dbus_proxy, "NameHasOwner", error, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_INVALID, - G_TYPE_BOOLEAN, &priv->service_running, - G_TYPE_INVALID)) { - priv->service_running = FALSE; - return FALSE; - } + if (priv->private_bus == FALSE) { + if (!dbus_g_proxy_call (priv->dbus_proxy, "NameHasOwner", error, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, &priv->service_running, + G_TYPE_INVALID)) { + priv->service_running = FALSE; + return FALSE; + } - /* If NM isn't running we'll grab properties from name_owner_changed() - * when it starts. - */ - if (!priv->service_running) - return TRUE; + /* If NM isn't running we'll grab properties from name_owner_changed() + * when it starts. + */ + if (!priv->service_running) + return TRUE; + } else + priv->service_running = TRUE; + + priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections", + fetch_connections_done, NM_REMOTE_SETTINGS (initable), NULL, + G_TYPE_INVALID); /* Get properties */ if (!dbus_g_proxy_call (priv->props_proxy, "GetAll", error, @@ -1019,14 +1308,23 @@ init_async_got_properties (DBusGProxy *proxy, DBusGProxyCall *call, } else g_simple_async_result_take_error (init_data->result, error); - if (priv->fetching) { - /* Still creating initial connections; wait for that to complete */ - g_signal_connect (init_data->settings, "connections-read", - G_CALLBACK (init_read_connections), init_data); - return; - } + /* Read connections and wait for the result */ + priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections", + fetch_connections_done, init_data->settings, NULL, + G_TYPE_INVALID); + g_signal_connect (init_data->settings, "connections-read", + G_CALLBACK (init_read_connections), init_data); +} - init_async_complete (init_data); +static void +init_get_properties (NMRemoteSettingsInitData *init_data) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (init_data->settings); + + dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", + init_async_got_properties, init_data, NULL, + G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS, + G_TYPE_INVALID); } static void @@ -1051,10 +1349,7 @@ init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call, return; } - dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", - init_async_got_properties, init_data, NULL, - G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS, - G_TYPE_INVALID); + init_get_properties (init_data); } static void @@ -1070,12 +1365,16 @@ init_async (GAsyncInitable *initable, int io_priority, init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); - /* Check if NM is running */ - dbus_g_proxy_begin_call (priv->dbus_proxy, "NameHasOwner", - init_async_got_manager_running, - init_data, NULL, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_INVALID); + if (priv->private_bus) + init_get_properties (init_data); + else { + /* Check if NM is running */ + dbus_g_proxy_begin_call (priv->dbus_proxy, "NameHasOwner", + init_async_got_manager_running, + init_data, NULL, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID); + } } static gboolean @@ -1095,11 +1394,6 @@ dispose (GObject *object) NMRemoteSettings *self = NM_REMOTE_SETTINGS (object); NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - if (priv->fetch_id) { - g_source_remove (priv->fetch_id); - priv->fetch_id = 0; - } - while (g_slist_length (priv->add_list)) add_connection_info_dispose (self, (AddConnectionInfo *) priv->add_list->data); @@ -1133,15 +1427,15 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object); - DBusGConnection *connection; switch (prop_id) { case PROP_BUS: /* Construct only */ - connection = (DBusGConnection *) g_value_get_boxed (value); - if (!connection) - connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); - priv->bus = dbus_g_connection_ref (connection); + priv->bus = g_value_dup_boxed (value); + if (!priv->bus) { + priv->bus = _nm_dbus_new_connection (NULL); + priv->private_bus = _nm_dbus_is_connection_private (priv->bus); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1228,8 +1522,7 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMRemoteSettingsClass, new_connection), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTIONS_READ] = @@ -1237,8 +1530,7 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMRemoteSettingsClass, connections_read), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); } diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h index 20235c0d..5ca646e6 100644 --- a/libnm-glib/nm-remote-settings.h +++ b/libnm-glib/nm-remote-settings.h @@ -45,6 +45,8 @@ G_BEGIN_DECLS * was removed before it was completely initialized * @NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE: the #NMRemoteConnection object * is not visible or otherwise unreadable + * @NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE: NetworkManager is not running. + * (Since 0.9.10) * * Describes errors that may result from operations involving a #NMRemoteSettings. * @@ -53,6 +55,7 @@ typedef enum { NM_REMOTE_SETTINGS_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ NM_REMOTE_SETTINGS_ERROR_CONNECTION_REMOVED, /*< nick=ConnectionRemoved >*/ NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE, /*< nick=ConnectionUnavailable >*/ + NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE, /*< nick=ServiceUnavailable >*/ } NMRemoteSettingsError; #define NM_REMOTE_SETTINGS_ERROR nm_remote_settings_error_quark () @@ -76,6 +79,11 @@ typedef void (*NMRemoteSettingsAddConnectionFunc) (NMRemoteSettings *settings, GError *error, gpointer user_data); +typedef void (*NMRemoteSettingsLoadConnectionsFunc) (NMRemoteSettings *settings, + char **failures, + GError *error, + gpointer user_data); + typedef void (*NMRemoteSettingsSaveHostnameFunc) (NMRemoteSettings *settings, GError *error, gpointer user_data); @@ -116,6 +124,9 @@ NMRemoteSettings *nm_remote_settings_new_finish (GAsyncResult *result, GSList *nm_remote_settings_list_connections (NMRemoteSettings *settings); +NMRemoteConnection *nm_remote_settings_get_connection_by_id (NMRemoteSettings *settings, + const char *id); + NMRemoteConnection * nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, const char *path); @@ -127,6 +138,22 @@ gboolean nm_remote_settings_add_connection (NMRemoteSettings *settings, NMRemoteSettingsAddConnectionFunc callback, gpointer user_data); +NM_AVAILABLE_IN_0_9_10 +gboolean nm_remote_settings_add_connection_unsaved (NMRemoteSettings *settings, + NMConnection *connection, + NMRemoteSettingsAddConnectionFunc callback, + gpointer user_data); + +NM_AVAILABLE_IN_0_9_10 +gboolean nm_remote_settings_load_connections (NMRemoteSettings *settings, + char **filenames, + char ***failures, + GError **error); + +NM_AVAILABLE_IN_0_9_10 +gboolean nm_remote_settings_reload_connections (NMRemoteSettings *settings, + GError **error); + gboolean nm_remote_settings_save_hostname (NMRemoteSettings *settings, const char *hostname, NMRemoteSettingsSaveHostnameFunc callback, diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index e7dcbbb5..f58f95fe 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -23,13 +23,10 @@ #include #include "nm-glib-compat.h" - -#include - +#include "NetworkManager.h" #include "nm-secret-agent.h" #include "nm-glib-enum-types.h" -#include "nm-glib-marshal.h" -#include "NetworkManager.h" +#include "nm-dbus-helpers-private.h" static void impl_secret_agent_get_secrets (NMSecretAgent *self, GHashTable *connection_hash, @@ -66,8 +63,10 @@ static gboolean auto_register_cb (gpointer user_data); typedef struct { gboolean registered; + NMSecretAgentCapabilities capabilities; DBusGConnection *bus; + gboolean private_bus; DBusGProxy *dbus_proxy; DBusGProxy *manager_proxy; DBusGProxyCall *reg_call; @@ -88,6 +87,7 @@ enum { PROP_IDENTIFIER, PROP_AUTO_REGISTER, PROP_REGISTERED, + PROP_CAPABILITIES, LAST_PROP }; @@ -228,6 +228,12 @@ verify_sender (NMSecretAgent *self, g_return_val_if_fail (context != NULL, FALSE); + /* Private bus connection is always to NetworkManager, which is always + * UID 0. + */ + if (priv->private_bus) + return TRUE; + /* Verify the sender's UID is 0, and that the sender is the same as * NetworkManager's bus name owner. */ @@ -526,6 +532,22 @@ impl_secret_agent_delete_secrets (NMSecretAgent *self, /**************************************************************/ +static void +reg_result (NMSecretAgent *self, GError *error) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + if (error) { + /* If registration failed we shouldn't expose ourselves on the bus */ + _internal_unregister (self); + } else { + priv->registered = TRUE; + g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_REGISTERED); + } + + g_signal_emit (self, signals[REGISTRATION_RESULT], 0, error); +} + static void reg_request_cb (DBusGProxy *proxy, DBusGProxyCall *call, @@ -537,16 +559,37 @@ reg_request_cb (DBusGProxy *proxy, priv->reg_call = NULL; - if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) { - priv->registered = TRUE; - g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_REGISTERED); - } else { - /* If registration failed we shouldn't expose ourselves on the bus */ - _internal_unregister (self); + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + reg_result (self, error); + g_clear_error (&error); +} + +static void +reg_with_caps_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + NMSecretAgent *self = NM_SECRET_AGENT (user_data); + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + priv->reg_call = NULL; + + if (dbus_g_proxy_end_call (proxy, call, NULL, G_TYPE_INVALID)) { + reg_result (self, NULL); + return; } - g_signal_emit (self, signals[REGISTRATION_RESULT], 0, error); - g_clear_error (&error); + /* Might be an old NetworkManager that doesn't support capabilities; + * fall back to old Register() method instead. + */ + priv->reg_call = dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy, + "Register", + reg_request_cb, + self, + NULL, + 5000, + G_TYPE_STRING, priv->identifier, + G_TYPE_INVALID); } /** @@ -569,7 +612,6 @@ nm_secret_agent_register (NMSecretAgent *self) NMSecretAgentPrivate *priv; NMSecretAgentClass *class; - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE); priv = NM_SECRET_AGENT_GET_PRIVATE (self); @@ -585,6 +627,9 @@ nm_secret_agent_register (NMSecretAgent *self) g_return_val_if_fail (class->save_secrets != NULL, FALSE); g_return_val_if_fail (class->delete_secrets != NULL, FALSE); + if (!priv->nm_owner && !priv->private_bus) + return FALSE; + priv->suppress_auto = FALSE; /* Export our secret agent interface before registering with the manager */ @@ -593,14 +638,14 @@ nm_secret_agent_register (NMSecretAgent *self) G_OBJECT (self)); priv->reg_call = dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy, - "Register", - reg_request_cb, + "RegisterWithCapabilities", + reg_with_caps_cb, self, NULL, 5000, G_TYPE_STRING, priv->identifier, + G_TYPE_UINT, priv->capabilities, G_TYPE_INVALID); - return TRUE; } @@ -619,7 +664,6 @@ nm_secret_agent_unregister (NMSecretAgent *self) { NMSecretAgentPrivate *priv; - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE); priv = NM_SECRET_AGENT_GET_PRIVATE (self); @@ -628,6 +672,9 @@ nm_secret_agent_unregister (NMSecretAgent *self) g_return_val_if_fail (priv->bus != NULL, FALSE); g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); + if (!priv->nm_owner && !priv->private_bus) + return FALSE; + dbus_g_proxy_call_no_reply (priv->manager_proxy, "Unregister", G_TYPE_INVALID); _internal_unregister (self); @@ -645,7 +692,6 @@ nm_secret_agent_unregister (NMSecretAgent *self) gboolean nm_secret_agent_get_registered (NMSecretAgent *self) { - g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE); return NM_SECRET_AGENT_GET_PRIVATE (self)->registered; @@ -692,9 +738,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, NMSecretAgentGetSecretsFunc callback, gpointer user_data) { - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SECRET_AGENT (self)); - g_return_if_fail (connection != NULL); g_return_if_fail (NM_IS_CONNECTION (connection)); g_return_if_fail (nm_connection_get_path (connection)); g_return_if_fail (setting_name != NULL); @@ -729,9 +773,7 @@ nm_secret_agent_save_secrets (NMSecretAgent *self, NMSecretAgentSaveSecretsFunc callback, gpointer user_data) { - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SECRET_AGENT (self)); - g_return_if_fail (connection != NULL); g_return_if_fail (NM_IS_CONNECTION (connection)); g_return_if_fail (nm_connection_get_path (connection)); @@ -760,9 +802,7 @@ nm_secret_agent_delete_secrets (NMSecretAgent *self, NMSecretAgentDeleteSecretsFunc callback, gpointer user_data) { - g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SECRET_AGENT (self)); - g_return_if_fail (connection != NULL); g_return_if_fail (NM_IS_CONNECTION (connection)); g_return_if_fail (nm_connection_get_path (connection)); @@ -807,44 +847,46 @@ nm_secret_agent_init (NMSecretAgent *self) NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); GError *error = NULL; - priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + priv->bus = _nm_dbus_new_connection (&error); if (!priv->bus) { g_warning ("Couldn't connect to system bus: %s", error->message); g_error_free (error); return; } - - priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - if (!priv->dbus_proxy) { - g_warning ("Couldn't create messagebus proxy."); - return; + priv->private_bus = _nm_dbus_is_connection_private (priv->bus); + + if (priv->private_bus == FALSE) { + priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + g_assert (priv->dbus_proxy); + + dbus_g_object_register_marshaller (g_cclosure_marshal_generic, + G_TYPE_NONE, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->dbus_proxy, + "NameOwnerChanged", + G_CALLBACK (name_owner_changed), + self, NULL); + + get_nm_owner (self); } - dbus_g_object_register_marshaller (_nm_glib_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->dbus_proxy, - "NameOwnerChanged", - G_CALLBACK (name_owner_changed), - self, NULL); - - priv->manager_proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE, - NM_DBUS_PATH_AGENT_MANAGER, - NM_DBUS_INTERFACE_AGENT_MANAGER); + priv->manager_proxy = _nm_dbus_new_proxy_for_connection (priv->bus, + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER); if (!priv->manager_proxy) { g_warning ("Couldn't create NM agent manager proxy."); return; } - priv->auto_register_id = g_idle_add (auto_register_cb, self); + if (priv->nm_owner || priv->private_bus) + priv->auto_register_id = g_idle_add (auto_register_cb, self); } static void @@ -865,6 +907,9 @@ get_property (GObject *object, case PROP_REGISTERED: g_value_set_boolean (value, priv->registered); break; + case PROP_CAPABILITIES: + g_value_set_flags (value, priv->capabilities); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -892,6 +937,9 @@ set_property (GObject *object, case PROP_AUTO_REGISTER: priv->auto_register = g_value_get_boolean (value); break; + case PROP_CAPABILITIES: + priv->capabilities = g_value_get_flags (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -994,6 +1042,20 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) FALSE, G_PARAM_READABLE)); + /** + * NMSecretAgent:capabilities: + * + * A bitfield of %NMSecretAgentCapabilities. + **/ + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_flags (NM_SECRET_AGENT_CAPABILITIES, + "Capabilities", + "Capabilities", + NM_TYPE_SECRET_AGENT_CAPABILITIES, + NM_SECRET_AGENT_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /** * NMSecretAgent::registration-result: * @agent: the agent that received the signal @@ -1006,8 +1068,7 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) g_signal_new (NM_SECRET_AGENT_REGISTRATION_RESULT, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_POINTER); dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index eabe9866..c70f8d07 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -55,6 +55,26 @@ typedef enum { NM_SECRET_AGENT_ERROR_NO_SECRETS, /*< nick=NoSecrets >*/ } NMSecretAgentError; +/** + * NMSecretAgentCapabilities: + * @NM_SECRET_AGENT_CAPABILITY_NONE: the agent supports no special capabilities + * @NM_SECRET_AGENT_CAPABILITY_VPN_HINTS: the agent supports sending hints given + * by the NMSecretAgentClass::get_secrets() class method to VPN plugin + * authentication dialogs. + * @NM_SECRET_AGENT_CAPABILITY_LAST: bounds checking value; should not be used. + * + * #NMSecretAgentCapabilities indicate various capabilities of the agent. + * + * Since: 0.9.10 + */ +typedef enum /*< flags >*/ { + NM_SECRET_AGENT_CAPABILITY_NONE = 0x0, + NM_SECRET_AGENT_CAPABILITY_VPN_HINTS = 0x1, + + /* boundary value */ + NM_SECRET_AGENT_CAPABILITY_LAST = NM_SECRET_AGENT_CAPABILITY_VPN_HINTS +} NMSecretAgentCapabilities; + /** * NMSecretAgentGetSecretsFlags: * @NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE: no special behavior; by default no @@ -91,6 +111,7 @@ typedef enum /*< flags >*/ { #define NM_SECRET_AGENT_IDENTIFIER "identifier" #define NM_SECRET_AGENT_AUTO_REGISTER "auto-register" #define NM_SECRET_AGENT_REGISTERED "registered" +#define NM_SECRET_AGENT_CAPABILITIES "capabilities" #define NM_SECRET_AGENT_REGISTRATION_RESULT "registration-result" @@ -120,7 +141,7 @@ typedef struct { * return them, or to return an error, this function should be called with * those secrets or the error. * - * To easily create the hash table to return the WiFi PSK, you could do + * To easily create the hash table to return the Wi-Fi PSK, you could do * something like this: * * Creating a secrets hash diff --git a/libnm-glib/nm-types.c b/libnm-glib/nm-types.c index 098af8d8..f9ba6d24 100644 --- a/libnm-glib/nm-types.c +++ b/libnm-glib/nm-types.c @@ -363,8 +363,7 @@ _nm_ip6_address_array_demarshal (GValue *value, GSList **dest) return FALSE; if (*dest) { - g_slist_foreach (*dest, (GFunc) g_free, NULL); - g_slist_free (*dest); + g_slist_free_full (*dest, g_free); *dest = NULL; } diff --git a/libnm-glib/nm-vpn-connection.c b/libnm-glib/nm-vpn-connection.c index 1fe59e5e..12814cf2 100644 --- a/libnm-glib/nm-vpn-connection.c +++ b/libnm-glib/nm-vpn-connection.c @@ -25,7 +25,6 @@ #include "nm-vpn-connection.h" #include "NetworkManager.h" #include "nm-utils.h" -#include "nm-glib-marshal.h" #include "nm-object-private.h" #include "nm-active-connection.h" @@ -47,9 +46,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_VPN_STATE "VpnState" -#define DBUS_PROP_BANNER "Banner" - enum { VPN_STATE_CHANGED, @@ -136,6 +132,7 @@ vpn_state_changed_proxy (DBusGProxy *proxy, if (priv->vpn_state != vpn_state) { priv->vpn_state = vpn_state; g_signal_emit (connection, signals[VPN_STATE_CHANGED], 0, vpn_state, reason); + g_object_notify (G_OBJECT (connection), NM_VPN_CONNECTION_VPN_STATE); } } @@ -167,18 +164,13 @@ register_properties (NMVPNConnection *connection) static void constructed (GObject *object) { - NMVPNConnectionPrivate *priv; + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); G_OBJECT_CLASS (nm_vpn_connection_parent_class)->constructed (object); - priv = NM_VPN_CONNECTION_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_VPN_CONNECTION); + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_VPN_CONNECTION); - dbus_g_object_register_marshaller (_nm_glib_marshal_VOID__UINT_UINT, + dbus_g_object_register_marshaller (g_cclosure_marshal_generic, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); @@ -272,8 +264,7 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMVPNConnectionClass, vpn_state_changed), - NULL, NULL, - _nm_glib_marshal_VOID__UINT_UINT, + NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); } diff --git a/libnm-glib/nm-vpn-enum-types.c b/libnm-glib/nm-vpn-enum-types.c index 0dc5ed23..45418518 100644 --- a/libnm-glib/nm-vpn-enum-types.c +++ b/libnm-glib/nm-vpn-enum-types.c @@ -26,6 +26,7 @@ nm_vpn_plugin_error_get_type (void) { NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, "NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS", "BadArguments" }, { NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, "NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED", "LaunchFailed" }, { NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID, "NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, "NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED", "InteractiveNotSupported" }, { 0, NULL, NULL } }; GType g_define_type_id = diff --git a/libnm-glib/nm-vpn-plugin-ui-interface.h b/libnm-glib/nm-vpn-plugin-ui-interface.h index 068d8f89..2753de44 100644 --- a/libnm-glib/nm-vpn-plugin-ui-interface.h +++ b/libnm-glib/nm-vpn-plugin-ui-interface.h @@ -68,7 +68,7 @@ typedef enum /*< flags >*/ { /* Short display name of the VPN plugin */ #define NM_VPN_PLUGIN_UI_INTERFACE_NAME "name" -/* Longer description of the the VPN plugin */ +/* Longer description of the VPN plugin */ #define NM_VPN_PLUGIN_UI_INTERFACE_DESC "desc" /* D-Bus service name of the plugin's VPN service */ @@ -86,10 +86,10 @@ typedef enum /*< flags >*/ { * information to UI programs. **/ typedef enum { - /*< private >*/ + /* private */ NM_VPN_PLUGIN_UI_INTERFACE_PROP_FIRST = 0x1000, - /*< public >*/ + /* public */ NM_VPN_PLUGIN_UI_INTERFACE_PROP_NAME = NM_VPN_PLUGIN_UI_INTERFACE_PROP_FIRST, NM_VPN_PLUGIN_UI_INTERFACE_PROP_DESC, NM_VPN_PLUGIN_UI_INTERFACE_PROP_SERVICE @@ -170,6 +170,7 @@ char *nm_vpn_plugin_ui_interface_get_suggested_name (NMVpnPluginUiInterface *ifa NMConnection *connection); /* Deprecated and no longer used */ +NM_DEPRECATED_IN_0_9_10 gboolean nm_vpn_plugin_ui_interface_delete_connection (NMVpnPluginUiInterface *iface, NMConnection *connection, GError **error); @@ -220,6 +221,7 @@ gboolean nm_vpn_plugin_ui_widget_interface_update_connection (NMVpnPluginUiWidge GError **error); /* Deprecated and no longer used */ +NM_DEPRECATED_IN_0_9_10 gboolean nm_vpn_plugin_ui_widget_interface_save_secrets (NMVpnPluginUiWidgetInterface *iface, NMConnection *connection, GError **error); diff --git a/libnm-glib/nm-vpn-plugin.c b/libnm-glib/nm-vpn-plugin.c index dd4d7b3a..d5241696 100644 --- a/libnm-glib/nm-vpn-plugin.c +++ b/libnm-glib/nm-vpn-plugin.c @@ -31,13 +31,22 @@ static gboolean impl_vpn_plugin_connect (NMVPNPlugin *plugin, GHashTable *connection, - GError **err); + GError **error); + +static gboolean impl_vpn_plugin_connect_interactive (NMVPNPlugin *plugin, + GHashTable *connection, + GHashTable *details, + GError **error); static gboolean impl_vpn_plugin_need_secrets (NMVPNPlugin *plugin, GHashTable *connection, char **service_name, GError **err); +static gboolean impl_vpn_plugin_new_secrets (NMVPNPlugin *plugin, + GHashTable *connection, + GError **err); + static gboolean impl_vpn_plugin_disconnect (NMVPNPlugin *plugin, GError **err); @@ -59,7 +68,6 @@ static gboolean impl_vpn_plugin_set_failure (NMVPNPlugin *plugin, #include "nm-vpn-plugin-glue.h" -#define NM_VPN_PLUGIN_CONNECT_TIMER 60 #define NM_VPN_PLUGIN_QUIT_TIMER 20 G_DEFINE_ABSTRACT_TYPE (NMVPNPlugin, nm_vpn_plugin, G_TYPE_OBJECT) @@ -75,6 +83,7 @@ typedef struct { guint connect_timer; guint quit_timer; guint fail_stop_id; + gboolean interactive; gboolean got_config; gboolean has_ip4, got_ip4; @@ -94,6 +103,7 @@ enum { LOGIN_BANNER, FAILURE, QUIT, + SECRETS_REQUIRED, LAST_SIGNAL }; @@ -276,60 +286,28 @@ fail_stop (gpointer data) return FALSE; } -static gboolean -nm_vpn_plugin_connect (NMVPNPlugin *plugin, - NMConnection *connection, - GError **err) +static void +schedule_fail_stop (NMVPNPlugin *plugin) { NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); - 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, connection, err); - if (!ret) { - /* Stop the plugin from and idle handler so that the Connect - * method return gets sent before the STOP StateChanged signal. - */ - if (priv->fail_stop_id) - g_source_remove (priv->fail_stop_id); - priv->fail_stop_id = g_idle_add (fail_stop, plugin); - } - break; - default: - g_assert_not_reached (); - break; - } + if (priv->fail_stop_id) + g_source_remove (priv->fail_stop_id); + priv->fail_stop_id = g_idle_add (fail_stop, plugin); +} - return ret; +static void +_g_value_set (GValue *dst, GValue *src) +{ + if (src) { + GType type = G_VALUE_TYPE (src); + + if (G_IS_VALUE (dst)) + g_value_unset (dst); + g_value_init (dst, type); + g_value_copy (src, dst); + } else if (G_IS_VALUE (dst)) + g_value_unset (dst); } void @@ -356,26 +334,10 @@ nm_vpn_plugin_set_config (NMVPNPlugin *plugin, /* Record the items that need to also be inserted into the * ip4config, for compatibility with older daemons. */ - val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_BANNER); - if (val) { - g_value_init (&priv->banner, G_VALUE_TYPE (val)); - g_value_copy (val, &priv->banner); - } - val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_TUNDEV); - if (val) { - g_value_init (&priv->tundev, G_VALUE_TYPE (val)); - g_value_copy (val, &priv->tundev); - } - val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY); - if (val) { - g_value_init (&priv->gateway, G_VALUE_TYPE (val)); - g_value_copy (val, &priv->gateway); - } - val = g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_MTU); - if (val) { - g_value_init (&priv->mtu, G_VALUE_TYPE (val)); - g_value_copy (val, &priv->mtu); - } + _g_value_set (&priv->banner, g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_BANNER)); + _g_value_set (&priv->tundev, g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_TUNDEV)); + _g_value_set (&priv->gateway, g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY)); + _g_value_set (&priv->mtu, g_hash_table_lookup (config, NM_VPN_PLUGIN_CONFIG_MTU)); g_signal_emit (plugin, signals[CONFIG], 0, config); } @@ -446,30 +408,102 @@ nm_vpn_plugin_set_ip6_config (NMVPNPlugin *plugin, nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED); } +static void +connect_timer_removed (gpointer data) +{ + NM_VPN_PLUGIN_GET_PRIVATE (data)->connect_timer = 0; +} + +static void +connect_timer_start (NMVPNPlugin *plugin) +{ + NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); + + priv->connect_timer = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, + 60, + connect_timer_expired, + plugin, + connect_timer_removed); +} static gboolean -impl_vpn_plugin_connect (NMVPNPlugin *plugin, - GHashTable *properties, - GError **error) +_connect_generic (NMVPNPlugin *plugin, + GHashTable *properties, + GHashTable *details, + GError **error) { + NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); + NMVPNPluginClass *vpn_class = NM_VPN_PLUGIN_GET_CLASS (plugin); NMConnection *connection; gboolean success = FALSE; + GError *local = NULL; + + if (priv->state != NM_VPN_SERVICE_STATE_STOPPED && + priv->state != NM_VPN_SERVICE_STATE_INIT) { + g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not start connection: wrong plugin state %d", + priv->state); + return FALSE; + } - connection = nm_connection_new_from_hash (properties, error); + connection = nm_connection_new_from_hash (properties, &local); if (!connection) { - g_warning ("%s: Invalid connection: '%s' / '%s' invalid: %d", - __func__, - g_type_name (nm_connection_lookup_setting_type_by_quark ((*error)->domain)), - (*error)->message, - (*error)->code); + g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: (%d) %s", + local->code, local->message); + g_clear_error (&local); + return FALSE; + } + + + priv->interactive = FALSE; + if (details && !vpn_class->connect_interactive) { + g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Plugin does not implement ConnectInteractive()"); + return FALSE; + } + + nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); + + if (details) { + priv->interactive = TRUE; + success = vpn_class->connect_interactive (plugin, connection, details, error); + } else + success = vpn_class->connect (plugin, connection, error); + + if (success) { + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start (plugin); } else { - success = nm_vpn_plugin_connect (plugin, connection, error); - g_object_unref (connection); + /* Stop the plugin from an idle handler so that the Connect + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop (plugin); } + g_object_unref (connection); return success; } +static gboolean +impl_vpn_plugin_connect (NMVPNPlugin *plugin, + GHashTable *connection, + GError **error) +{ + return _connect_generic (plugin, connection, NULL, error); +} + +static gboolean +impl_vpn_plugin_connect_interactive (NMVPNPlugin *plugin, + GHashTable *connection, + GHashTable *details, + GError **error) +{ + return _connect_generic (plugin, connection, details, error); +} + +/***************************************************************/ + static gboolean impl_vpn_plugin_need_secrets (NMVPNPlugin *plugin, GHashTable *properties, @@ -524,6 +558,94 @@ out: return ret; } +static gboolean +impl_vpn_plugin_new_secrets (NMVPNPlugin *plugin, + GHashTable *properties, + GError **error) +{ + NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); + NMConnection *connection; + GError *local = NULL; + gboolean success; + + if (priv->state != NM_VPN_SERVICE_STATE_STARTING) { + g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not accept new secrets: wrong plugin state %d", + priv->state); + return FALSE; + } + + connection = nm_connection_new_from_hash (properties, &local); + if (!connection) { + g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: (%d) %s", + local->code, local->message); + g_clear_error (&local); + return FALSE; + } + + if (!NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets) { + g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Could not accept new secrets: plugin cannot process interactive secrets"); + g_object_unref (connection); + return FALSE; + } + + success = NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets (plugin, connection, error); + if (success) { + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start (plugin); + } else { + /* Stop the plugin from and idle handler so that the NewSecrets + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop (plugin); + } + + g_object_unref (connection); + return success; +} + +/** + * nm_vpn_plugin_secrets_required: + * @plugin: the #NMVPNPlugin + * @message: an information message about why secrets are required, if any + * @hints: VPN specific secret names for required new secrets + * + * Called by VPN plugin implementations to signal to NetworkManager that secrets + * are required during the connection process. This signal may be used to + * request new secrets when the secrets originally provided by NetworkManager + * are insufficient, or the VPN process indicates that it needs additional + * information to complete the request. + * + * Since: 0.9.10 + */ +void +nm_vpn_plugin_secrets_required (NMVPNPlugin *plugin, + const char *message, + const char **hints) +{ + NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); + + /* Plugin must be able to accept the new secrets if it calls this method */ + g_return_if_fail (NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets); + + /* Plugin cannot call this method if NetworkManager didn't originally call + * ConnectInteractive(). + */ + g_return_if_fail (priv->interactive == TRUE); + + /* Cancel the connect timer since secrets might take a while. It'll + * get restarted when the secrets come back via NewSecrets(). + */ + if (priv->connect_timer) + g_source_remove (priv->connect_timer); + + g_signal_emit (plugin, signals[SECRETS_REQUIRED], 0, message, hints); +} + +/***************************************************************/ + static gboolean impl_vpn_plugin_disconnect (NMVPNPlugin *plugin, GError **err) @@ -766,12 +888,6 @@ finalize (GObject *object) 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) { @@ -793,13 +909,6 @@ state_changed (NMVPNPlugin *plugin, NMVPNServiceState state) g_source_remove (priv->fail_stop_id); priv->fail_stop_id = 0; } - - /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ - priv->connect_timer = g_timeout_add_seconds_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_seconds_full (G_PRIORITY_DEFAULT, @@ -873,6 +982,14 @@ nm_vpn_plugin_class_init (NMVPNPluginClass *plugin_class) G_TYPE_NONE, 1, G_TYPE_UINT); + signals[SECRETS_REQUIRED] = + g_signal_new ("secrets-required", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + NULL, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRV); + signals[CONFIG] = g_signal_new ("config", G_OBJECT_CLASS_TYPE (object_class), @@ -934,7 +1051,7 @@ nm_vpn_plugin_class_init (NMVPNPluginClass *plugin_class) G_TYPE_NONE); dbus_g_error_domain_register (NM_VPN_PLUGIN_ERROR, - NULL, + NM_DBUS_VPN_ERROR_PREFIX, 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 index dee726f7..4f020f31 100644 --- a/libnm-glib/nm-vpn-plugin.h +++ b/libnm-glib/nm-vpn-plugin.h @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2013 Red Hat, Inc. */ #ifndef NM_VPN_PLUGIN_H @@ -63,19 +63,23 @@ G_BEGIN_DECLS * @NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID: the operation could not be performed * because the connection was invalid. Usually means that the connection's * VPN setting was missing some required data item or secret. + * @NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED: the operation could not be + * performed as the plugin does not support interactive operations, such as + * ConnectInteractive() or NewSecrets() * * Returned by the VPN service plugin to indicate errors. **/ typedef enum { - NM_VPN_PLUGIN_ERROR_GENERAL, /*< nick=General >*/ - NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS, /*< nick=StartingInProgress >*/ - NM_VPN_PLUGIN_ERROR_ALREADY_STARTED, /*< nick=AlreadyStarted >*/ - NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, /*< nick=StoppingInProgress >*/ - NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, /*< nick=AlreadyStopped >*/ - NM_VPN_PLUGIN_ERROR_WRONG_STATE, /*< nick=WrongState >*/ - NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, /*< nick=BadArguments >*/ - NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, /*< nick=LaunchFailed >*/ - NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_VPN_PLUGIN_ERROR_GENERAL, /*< nick=General >*/ + NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS, /*< nick=StartingInProgress >*/ + NM_VPN_PLUGIN_ERROR_ALREADY_STARTED, /*< nick=AlreadyStarted >*/ + NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, /*< nick=StoppingInProgress >*/ + NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, /*< nick=AlreadyStopped >*/ + NM_VPN_PLUGIN_ERROR_WRONG_STATE, /*< nick=WrongState >*/ + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, /*< nick=BadArguments >*/ + NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, /*< nick=LaunchFailed >*/ + NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED /*< nick=InteractiveNotSupported >*/ } NMVPNPluginError; #define NM_VPN_PLUGIN_ERROR (nm_vpn_plugin_error_quark ()) @@ -121,11 +125,19 @@ typedef struct { void (*ip6_config) (NMVPNPlugin *plugin, GHashTable *config); + /* more methods */ + gboolean (*new_secrets) (NMVPNPlugin *plugin, + NMConnection *connection, + GError **error); + + gboolean (*connect_interactive) (NMVPNPlugin *plugin, + NMConnection *connection, + GHashTable *details, + GError **error); + /* Padding for future expansion */ void (*_reserved1) (void); void (*_reserved2) (void); - void (*_reserved3) (void); - void (*_reserved4) (void); } NMVPNPluginClass; GType nm_vpn_plugin_get_type (void); @@ -137,6 +149,11 @@ NMVPNServiceState nm_vpn_plugin_get_state (NMVPNPlugin *plugin); void nm_vpn_plugin_set_state (NMVPNPlugin *plugin, NMVPNServiceState state); +NM_AVAILABLE_IN_0_9_10 +void nm_vpn_plugin_secrets_required (NMVPNPlugin *plugin, + const char *message, + const char **hints); + void nm_vpn_plugin_set_login_banner (NMVPNPlugin *plugin, const char *banner); diff --git a/libnm-glib/nm-wimax-nsp.c b/libnm-glib/nm-wimax-nsp.c index baa4b3e1..f747aff3 100644 --- a/libnm-glib/nm-wimax-nsp.c +++ b/libnm-glib/nm-wimax-nsp.c @@ -55,10 +55,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_NAME "Name" -#define DBUS_PROP_SIGNAL_QUALITY "SignalQuality" -#define DBUS_PROP_NETWORK_TYPE "NetworkType" - /** * nm_wimax_nsp_new: * @connection: the #DBusGConnection @@ -278,17 +274,11 @@ register_properties (NMWimaxNsp *nsp) static void constructed (GObject *object) { - NMWimaxNspPrivate *priv; + NMWimaxNspPrivate *priv = NM_WIMAX_NSP_GET_PRIVATE (object); G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->constructed (object); - priv = NM_WIMAX_NSP_GET_PRIVATE (object); - - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_WIMAX_NSP); - + priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_WIMAX_NSP); register_properties (NM_WIMAX_NSP (object)); } diff --git a/libnm-glib/tests/Makefile.am b/libnm-glib/tests/Makefile.am index 07994481..38f449ac 100644 --- a/libnm-glib/tests/Makefile.am +++ b/libnm-glib/tests/Makefile.am @@ -5,20 +5,29 @@ AM_CPPFLAGS = \ -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/libnm-glib + -I$(top_srcdir)/libnm-glib \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) + +noinst_PROGRAMS = test-nm-client test-remote-settings-client + +####### NMClient and non-settings tests ####### -noinst_PROGRAMS = test-remote-settings-client +test_nm_client_SOURCES = \ + test-nm-client.c + +test_nm_client_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib-test.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) ####### remote settings client test ####### test_remote_settings_client_SOURCES = \ test-remote-settings-client.c -test_remote_settings_client_CPPFLAGS = \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(AM_CPPFLAGS) - test_remote_settings_client_LDADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-glib/libnm-glib-test.la \ @@ -27,11 +36,18 @@ test_remote_settings_client_LDADD = \ ########################################### +TEST_NM_BIN = test-fake-nm.py TEST_RSS_BIN = test-remote-settings-service.py -EXTRA_DIST = $(TEST_RSS_BIN) +EXTRA_DIST = $(TEST_RSS_BIN) $(TEST_NM_BIN) -check-local: test-remote-settings-client - $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN) +check-local: test-nm-client test-remote-settings-client + if test -z "$$DBUS_SESSION_BUS_ADDRESS" ; then \ + dbus-launch --exit-with-session $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \ + dbus-launch --exit-with-session $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \ + else \ + $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \ + $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \ + fi; endif diff --git a/libnm-glib/tests/Makefile.in b/libnm-glib/tests/Makefile.in index e9ea17b1..28acdea0 100644 --- a/libnm-glib/tests/Makefile.in +++ b/libnm-glib/tests/Makefile.in @@ -78,13 +78,14 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@ENABLE_TESTS_TRUE@noinst_PROGRAMS = \ +@ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-nm-client$(EXEEXT) \ @ENABLE_TESTS_TRUE@ test-remote-settings-client$(EXEEXT) subdir = libnm-glib/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -103,13 +104,12 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am__test_remote_settings_client_SOURCES_DIST = \ - test-remote-settings-client.c -@ENABLE_TESTS_TRUE@am_test_remote_settings_client_OBJECTS = test_remote_settings_client-test-remote-settings-client.$(OBJEXT) -test_remote_settings_client_OBJECTS = \ - $(am_test_remote_settings_client_OBJECTS) +am__test_nm_client_SOURCES_DIST = test-nm-client.c +@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS = \ +@ENABLE_TESTS_TRUE@ test-nm-client.$(OBJEXT) +test_nm_client_OBJECTS = $(am_test_nm_client_OBJECTS) am__DEPENDENCIES_1 = -@ENABLE_TESTS_TRUE@test_remote_settings_client_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@test_nm_client_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib-test.la \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @@ -117,6 +117,16 @@ AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = +am__test_remote_settings_client_SOURCES_DIST = \ + test-remote-settings-client.c +@ENABLE_TESTS_TRUE@am_test_remote_settings_client_OBJECTS = \ +@ENABLE_TESTS_TRUE@ test-remote-settings-client.$(OBJEXT) +test_remote_settings_client_OBJECTS = \ + $(am_test_remote_settings_client_OBJECTS) +@ENABLE_TESTS_TRUE@test_remote_settings_client_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib-test.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -151,8 +161,10 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(test_remote_settings_client_SOURCES) -DIST_SOURCES = $(am__test_remote_settings_client_SOURCES_DIST) +SOURCES = $(test_nm_client_SOURCES) \ + $(test_remote_settings_client_SOURCES) +DIST_SOURCES = $(am__test_nm_client_SOURCES_DIST) \ + $(am__test_remote_settings_client_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -203,12 +215,15 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ DSYMUTIL = @DSYMUTIL@ @@ -233,7 +248,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ @@ -278,12 +292,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -300,6 +318,8 @@ MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ @@ -327,11 +347,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -346,6 +371,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ VAPIGEN = @VAPIGEN@ VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ @@ -408,6 +434,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ target_alias = @target_alias@ @@ -418,23 +445,33 @@ with_dhclient = @with_dhclient@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ @ENABLE_TESTS_TRUE@ -I$(top_builddir)/include \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-util \ @ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-glib +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-glib \ +@ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ +@ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ +@ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) + + +####### NMClient and non-settings tests ####### +@ENABLE_TESTS_TRUE@test_nm_client_SOURCES = \ +@ENABLE_TESTS_TRUE@ test-nm-client.c + +@ENABLE_TESTS_TRUE@test_nm_client_LDADD = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib-test.la \ +@ENABLE_TESTS_TRUE@ $(GLIB_LIBS) \ +@ENABLE_TESTS_TRUE@ $(DBUS_LIBS) ####### remote settings client test ####### @ENABLE_TESTS_TRUE@test_remote_settings_client_SOURCES = \ @ENABLE_TESTS_TRUE@ test-remote-settings-client.c -@ENABLE_TESTS_TRUE@test_remote_settings_client_CPPFLAGS = \ -@ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(AM_CPPFLAGS) - @ENABLE_TESTS_TRUE@test_remote_settings_client_LDADD = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib-test.la \ @@ -443,8 +480,9 @@ with_resolvconf = @with_resolvconf@ ########################################### +@ENABLE_TESTS_TRUE@TEST_NM_BIN = test-fake-nm.py @ENABLE_TESTS_TRUE@TEST_RSS_BIN = test-remote-settings-service.py -@ENABLE_TESTS_TRUE@EXTRA_DIST = $(TEST_RSS_BIN) +@ENABLE_TESTS_TRUE@EXTRA_DIST = $(TEST_RSS_BIN) $(TEST_NM_BIN) all: all-am .SUFFIXES: @@ -489,6 +527,10 @@ clean-noinstPROGRAMS: echo " rm -f" $$list; \ rm -f $$list +test-nm-client$(EXEEXT): $(test_nm_client_OBJECTS) $(test_nm_client_DEPENDENCIES) $(EXTRA_test_nm_client_DEPENDENCIES) + @rm -f test-nm-client$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_nm_client_OBJECTS) $(test_nm_client_LDADD) $(LIBS) + test-remote-settings-client$(EXEEXT): $(test_remote_settings_client_OBJECTS) $(test_remote_settings_client_DEPENDENCIES) $(EXTRA_test_remote_settings_client_DEPENDENCIES) @rm -f test-remote-settings-client$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_remote_settings_client_OBJECTS) $(test_remote_settings_client_LDADD) $(LIBS) @@ -499,7 +541,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nm-client.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-remote-settings-client.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -522,20 +565,6 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -test_remote_settings_client-test-remote-settings-client.o: test-remote-settings-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_remote_settings_client-test-remote-settings-client.o -MD -MP -MF $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo -c -o test_remote_settings_client-test-remote-settings-client.o `test -f 'test-remote-settings-client.c' || echo '$(srcdir)/'`test-remote-settings-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-remote-settings-client.c' object='test_remote_settings_client-test-remote-settings-client.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_remote_settings_client-test-remote-settings-client.o `test -f 'test-remote-settings-client.c' || echo '$(srcdir)/'`test-remote-settings-client.c - -test_remote_settings_client-test-remote-settings-client.obj: test-remote-settings-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_remote_settings_client-test-remote-settings-client.obj -MD -MP -MF $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo -c -o test_remote_settings_client-test-remote-settings-client.obj `if test -f 'test-remote-settings-client.c'; then $(CYGPATH_W) 'test-remote-settings-client.c'; else $(CYGPATH_W) '$(srcdir)/test-remote-settings-client.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Tpo $(DEPDIR)/test_remote_settings_client-test-remote-settings-client.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-remote-settings-client.c' object='test_remote_settings_client-test-remote-settings-client.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_remote_settings_client_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_remote_settings_client-test-remote-settings-client.obj `if test -f 'test-remote-settings-client.c'; then $(CYGPATH_W) 'test-remote-settings-client.c'; else $(CYGPATH_W) '$(srcdir)/test-remote-settings-client.c'; fi` - mostlyclean-libtool: -rm -f *.lo @@ -748,8 +777,14 @@ uninstall-am: tags tags-am uninstall uninstall-am -@ENABLE_TESTS_TRUE@check-local: test-remote-settings-client -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN) +@ENABLE_TESTS_TRUE@check-local: test-nm-client test-remote-settings-client +@ENABLE_TESTS_TRUE@ if test -z "$$DBUS_SESSION_BUS_ADDRESS" ; then \ +@ENABLE_TESTS_TRUE@ dbus-launch --exit-with-session $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \ +@ENABLE_TESTS_TRUE@ dbus-launch --exit-with-session $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \ +@ENABLE_TESTS_TRUE@ else \ +@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \ +@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \ +@ENABLE_TESTS_TRUE@ fi; # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/libnm-glib/tests/test-fake-nm.py b/libnm-glib/tests/test-fake-nm.py new file mode 100755 index 00000000..46ca3ff0 --- /dev/null +++ b/libnm-glib/tests/test-fake-nm.py @@ -0,0 +1,776 @@ +#!/usr/bin/env python +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +from __future__ import print_function + +from gi.repository import GLib, GObject +import sys +import dbus +import dbus.service +import dbus.mainloop.glib +import random + +mainloop = GObject.MainLoop() +quit_id = 0 + +# NM State +NM_STATE_UNKNOWN = 0 +NM_STATE_ASLEEP = 10 +NM_STATE_DISCONNECTED = 20 +NM_STATE_DISCONNECTING = 30 +NM_STATE_CONNECTING = 40 +NM_STATE_CONNECTED_LOCAL = 50 +NM_STATE_CONNECTED_SITE = 60 +NM_STATE_CONNECTED_GLOBAL = 70 + +# Device state +NM_DEVICE_STATE_UNKNOWN = 0 +NM_DEVICE_STATE_UNMANAGED = 10 +NM_DEVICE_STATE_UNAVAILABLE = 20 +NM_DEVICE_STATE_DISCONNECTED = 30 +NM_DEVICE_STATE_PREPARE = 40 +NM_DEVICE_STATE_CONFIG = 50 +NM_DEVICE_STATE_NEED_AUTH = 60 +NM_DEVICE_STATE_IP_CONFIG = 70 +NM_DEVICE_STATE_IP_CHECK = 80 +NM_DEVICE_STATE_SECONDARIES = 90 +NM_DEVICE_STATE_ACTIVATED = 100 +NM_DEVICE_STATE_DEACTIVATING = 110 +NM_DEVICE_STATE_FAILED = 120 + +NM_DEVICE_TYPE_UNKNOWN = 0 +NM_DEVICE_TYPE_ETHERNET = 1 +NM_DEVICE_TYPE_WIFI = 2 +NM_DEVICE_TYPE_UNUSED1 = 3 +NM_DEVICE_TYPE_UNUSED2 = 4 +NM_DEVICE_TYPE_BT = 5 +NM_DEVICE_TYPE_OLPC_MESH = 6 +NM_DEVICE_TYPE_WIMAX = 7 +NM_DEVICE_TYPE_MODEM = 8 +NM_DEVICE_TYPE_INFINIBAND = 9 +NM_DEVICE_TYPE_BOND = 10 +NM_DEVICE_TYPE_VLAN = 11 +NM_DEVICE_TYPE_ADSL = 12 +NM_DEVICE_TYPE_BRIDGE = 13 +NM_DEVICE_TYPE_GENERIC = 14 +NM_DEVICE_TYPE_TEAM = 15 + +######################################################### +IFACE_DBUS = 'org.freedesktop.DBus' + +class UnknownInterfaceException(dbus.DBusException): + _dbus_error_name = IFACE_DBUS + '.UnknownInterface' + +class UnknownPropertyException(dbus.DBusException): + _dbus_error_name = IFACE_DBUS + '.UnknownProperty' + +def to_path_array(src): + array = dbus.Array([], signature=dbus.Signature('o')) + for o in src: + array.append(o.path) + return array + +def to_path(src): + if src: + return dbus.ObjectPath(src.path) + return dbus.ObjectPath("/") + +class ExportedObj(dbus.service.Object): + def __init__(self, bus, object_path): + dbus.service.Object.__init__(self, bus, object_path) + self._bus = bus + self.path = object_path + self.__dbus_ifaces = {} + + def add_dbus_interface(self, dbus_iface, get_props_func): + self.__dbus_ifaces[dbus_iface] = get_props_func + + def _get_dbus_properties(self, iface): + return self.__dbus_ifaces[iface]() + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') + def GetAll(self, iface): + if iface not in self.__dbus_ifaces.keys(): + raise UnknownInterfaceException() + return self._get_dbus_properties(iface) + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') + def Get(self, iface, name): + if iface not in self.__dbus_ifaces.keys(): + raise UnknownInterfaceException() + props = self._get_dbus_properties(iface) + if not name in props.keys(): + raise UnknownPropertyException() + return props[name] + +################################################################### +IFACE_DEVICE = 'org.freedesktop.NetworkManager.Device' + +PD_UDI = "Udi" +PD_IFACE = "Interface" +PD_DRIVER = "Driver" +PD_STATE = "State" +PD_ACTIVE_CONNECTION = "ActiveConnection" +PD_IP4_CONFIG = "Ip4Config" +PD_IP6_CONFIG = "Ip6Config" +PD_DHCP4_CONFIG = "Dhcp4Config" +PD_DHCP6_CONFIG = "Dhcp6Config" +PD_MANAGED = "Managed" +PD_AUTOCONNECT = "Autoconnect" +PD_DEVICE_TYPE = "DeviceType" +PD_AVAILABLE_CONNECTIONS = "AvailableConnections" + +class Device(ExportedObj): + counter = 1 + + def __init__(self, bus, iface, devtype): + object_path = "/org/freedesktop/NetworkManager/Devices/%d" % Device.counter + Device.counter = Device.counter + 1 + ExportedObj.__init__(self, bus, object_path) + self.add_dbus_interface(IFACE_DEVICE, self.__get_props) + + self.iface = iface + self.udi = "/sys/devices/virtual/%s" % iface + self.devtype = devtype + self.active_connection = None + self.state = NM_DEVICE_STATE_UNAVAILABLE + self.ip4_config = None + self.ip6_config = None + self.dhcp4_config = None + self.dhcp6_config = None + self.available_connections = [] + + # Properties interface + def __get_props(self): + props = {} + props[PD_UDI] = self.udi + props[PD_IFACE] = self.iface + props[PD_DRIVER] = "virtual" + props[PD_STATE] = dbus.UInt32(self.state) + props[PD_ACTIVE_CONNECTION] = to_path(self.active_connection) + props[PD_IP4_CONFIG] = to_path(self.ip4_config) + props[PD_IP6_CONFIG] = to_path(self.ip6_config) + props[PD_DHCP4_CONFIG] = to_path(self.dhcp4_config) + props[PD_DHCP6_CONFIG] = to_path(self.dhcp6_config) + props[PD_MANAGED] = True + props[PD_AUTOCONNECT] = True + props[PD_DEVICE_TYPE] = dbus.UInt32(self.devtype) + props[PD_AVAILABLE_CONNECTIONS] = to_path_array(self.available_connections) + return props + + # methods + @dbus.service.method(dbus_interface=IFACE_DEVICE, in_signature='', out_signature='') + def Disconnect(self): + pass + + def __notify(self, propname): + props = self._get_dbus_properties(IFACE_DEVICE) + changed = { propname: props[propname] } + Device.PropertiesChanged(self, changed) + + @dbus.service.signal(IFACE_DEVICE, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + + +################################################################### + +def random_mac(): + return '%02X:%02X:%02X:%02X:%02X:%02X' % ( + random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), + random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) + ) + +################################################################### +IFACE_WIRED = 'org.freedesktop.NetworkManager.Device.Wired' + +PE_HW_ADDRESS = "HwAddress" +PE_PERM_HW_ADDRESS = "PermHwAddress" +PE_SPEED = "Speed" +PE_CARRIER = "Carrier" + +class WiredDevice(Device): + def __init__(self, bus, iface): + Device.__init__(self, bus, iface, NM_DEVICE_TYPE_ETHERNET) + self.add_dbus_interface(IFACE_WIRED, self.__get_props) + + self.mac = random_mac() + self.carrier = False + + # Properties interface + def __get_props(self): + props = {} + props[PE_HW_ADDRESS] = self.mac + props[PE_PERM_HW_ADDRESS] = self.mac + props[PE_SPEED] = dbus.UInt32(100) + props[PE_CARRIER] = self.carrier + return props + + def __notify(self, propname): + props = self._get_dbus_properties(IFACE_WIRED) + changed = { propname: props[propname] } + WiredDevice.PropertiesChanged(self, changed) + + @dbus.service.signal(IFACE_WIRED, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + +################################################################### +IFACE_WIFI_AP = 'org.freedesktop.NetworkManager.AccessPoint' + +PP_FLAGS = "Flags" +PP_WPA_FLAGS = "WpaFlags" +PP_RSN_FLAGS = "RsnFlags" +PP_SSID = "Ssid" +PP_FREQUENCY = "Frequency" +PP_HW_ADDRESS = "HwAddress" +PP_MODE = "Mode" +PP_MAX_BITRATE = "MaxBitrate" +PP_STRENGTH = "Strength" + +class WifiAp(ExportedObj): + counter = 0 + + def __init__(self, bus, ssid, mac, flags, wpaf, rsnf, freq): + path = "/org/freedesktop/NetworkManager/AccessPoint/%d" % WifiAp.counter + WifiAp.counter = WifiAp.counter + 1 + ExportedObj.__init__(self, bus, path) + self.add_dbus_interface(IFACE_WIFI_AP, self.__get_props) + + self.ssid = ssid + if mac: + self.bssid = mac + else: + self.bssid = random_mac() + self.flags = flags + self.wpaf = wpaf + self.rsnf = rsnf + self.freq = freq + self.strength = random.randint(0, 100) + self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None) + + def __del__(self): + if self.strength_id > 0: + GLib.source_remove(self.strength_id) + self.strength_id = 0 + + def strength_cb(self, ignored): + self.strength = random.randint(0, 100) + self.__notify(PP_STRENGTH) + return True + + # Properties interface + def __get_props(self): + props = {} + props[PP_FLAGS] = dbus.UInt32(self.flags) + props[PP_WPA_FLAGS] = dbus.UInt32(self.wpaf) + props[PP_RSN_FLAGS] = dbus.UInt32(self.rsnf) + props[PP_SSID] = dbus.ByteArray(self.ssid) + props[PP_FREQUENCY] = dbus.UInt32(self.freq) + props[PP_HW_ADDRESS] = self.bssid + props[PP_MODE] = dbus.UInt32(2) # NM_802_11_MODE_INFRA + props[PP_MAX_BITRATE] = dbus.UInt32(54000) + props[PP_STRENGTH] = dbus.Byte(self.strength) + return props + + def __notify(self, propname): + props = self._get_dbus_properties(IFACE_WIFI_AP) + changed = { propname: props[propname] } + WifiAp.PropertiesChanged(self, changed) + + @dbus.service.signal(IFACE_WIFI_AP, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + +################################################################### +IFACE_WIFI = 'org.freedesktop.NetworkManager.Device.Wireless' + +class ApNotFoundException(dbus.DBusException): + _dbus_error_name = IFACE_WIFI + '.AccessPointNotFound' + +PW_HW_ADDRESS = "HwAddress" +PW_PERM_HW_ADDRESS = "PermHwAddress" +PW_MODE = "Mode" +PW_BITRATE = "Bitrate" +PW_ACCESS_POINTS = "AccessPoints" +PW_ACTIVE_ACCESS_POINT = "ActiveAccessPoint" +PW_WIRELESS_CAPABILITIES = "WirelessCapabilities" + +class WifiDevice(Device): + def __init__(self, bus, iface): + Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIFI) + self.add_dbus_interface(IFACE_WIFI, self.__get_props) + + self.mac = random_mac() + self.aps = [] + self.active_ap = None + + # methods + @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao') + def GetAccessPoints(self): + # only include non-hidden APs + array = [] + for a in self.aps: + if a.ssid(): + array.append(a) + return to_path_array(array) + + @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao') + def GetAllAccessPoints(self): + # include all APs including hidden ones + return to_path_array(self.aps) + + @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='a{sv}', out_signature='') + def RequestScan(self, props): + pass + + @dbus.service.signal(IFACE_WIFI, signature='o') + def AccessPointAdded(self, ap_path): + pass + + def add_ap(self, ap): + self.aps.append(ap) + self.__notify(PW_ACCESS_POINTS) + self.AccessPointAdded(to_path(ap)) + + @dbus.service.signal(IFACE_WIFI, signature='o') + def AccessPointRemoved(self, ap_path): + pass + + def remove_ap(self, ap): + self.aps.remove(ap) + self.__notify(PW_ACCESS_POINTS) + self.AccessPointRemoved(to_path(ap)) + + # Properties interface + def __get_props(self): + props = {} + props[PW_HW_ADDRESS] = self.mac + props[PW_PERM_HW_ADDRESS] = self.mac + props[PW_MODE] = dbus.UInt32(3) # NM_802_11_MODE_INFRA + props[PW_BITRATE] = dbus.UInt32(21000) + props[PW_WIRELESS_CAPABILITIES] = dbus.UInt32(0xFF) + props[PW_ACCESS_POINTS] = to_path_array(self.aps) + props[PW_ACTIVE_ACCESS_POINT] = to_path(self.active_ap) + return props + + def __notify(self, propname): + props = self._get_dbus_properties(IFACE_WIFI) + changed = { propname: props[propname] } + WifiDevice.PropertiesChanged(self, changed) + + @dbus.service.signal(IFACE_WIFI, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + + # test functions + def add_test_ap(self, ssid, mac): + ap = WifiAp(self._bus, ssid, mac, 0x1, 0x1cc, 0x1cc, 2412) + self.add_ap(ap) + return ap.path + + def remove_ap_by_path(self, path): + for ap in self.aps: + if ap.path == path: + self.remove_ap(ap) + return + raise ApNotFoundException("AP %s not found" % path) + + +################################################################### +IFACE_WIMAX_NSP = 'org.freedesktop.NetworkManager.WiMax.Nsp' + +PN_NAME = "Name" +PN_SIGNAL_QUALITY = "SignalQuality" +PN_NETWORK_TYPE = "NetworkType" + +class WimaxNsp(ExportedObj): + counter = 0 + + def __init__(self, bus, name): + path = "/org/freedesktop/NetworkManager/Nsp/%d" % WimaxNsp.counter + WimaxNsp.counter = WimaxNsp.counter + 1 + ExportedObj.__init__(self, bus, path) + self.add_dbus_interface(IFACE_WIMAX_NSP, self.__get_props) + + self.name = name + self.strength = random.randint(0, 100) + self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None) + + def __del__(self): + if self.strength_id > 0: + GLib.source_remove(self.strength_id) + self.strength_id = 0 + + def strength_cb(self, ignored): + self.strength = random.randint(0, 100) + self.__notify(PN_SIGNAL_QUALITY) + return True + + # Properties interface + def __get_props(self): + props = {} + props[PN_NAME] = self.name + props[PN_SIGNAL_QUALITY] = dbus.UInt32(self.strength) + props[PN_NETWORK_TYPE] = dbus.UInt32(0x1) # NM_WIMAX_NSP_NETWORK_TYPE_HOME + return props + + def __notify(self, propname): + props = self._get_dbus_properties(IFACE_WIMAX_NSP) + changed = { propname: props[propname] } + WimaxNsp.PropertiesChanged(self, changed) + + @dbus.service.signal(IFACE_WIMAX_NSP, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + +################################################################### +IFACE_WIMAX = 'org.freedesktop.NetworkManager.Device.WiMax' + +class NspNotFoundException(dbus.DBusException): + _dbus_error_name = IFACE_WIMAX + '.NspNotFound' + +PX_NSPS = "Nsps" +PX_HW_ADDRESS = "HwAddress" +PX_CENTER_FREQUENCY = "CenterFrequency" +PX_RSSI = "Rssi" +PX_CINR = "Cinr" +PX_TX_POWER = "TxPower" +PX_BSID = "Bsid" +PX_ACTIVE_NSP = "ActiveNsp" + +class WimaxDevice(Device): + def __init__(self, bus, iface): + Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIMAX) + self.add_dbus_interface(IFACE_WIMAX, self.__get_props) + + self.mac = random_mac() + self.bsid = random_mac() + self.nsps = [] + self.active_nsp = None + + # methods + @dbus.service.method(dbus_interface=IFACE_WIMAX, in_signature='', out_signature='ao') + def GetNspList(self): + # include all APs including hidden ones + return to_path_array(self.nsps) + + @dbus.service.signal(IFACE_WIMAX, signature='o') + def NspAdded(self, nsp_path): + pass + + def add_nsp(self, nsp): + self.nsps.append(nsp) + self.__notify(PX_NSPS) + self.NspAdded(to_path(nsp)) + + @dbus.service.signal(IFACE_WIMAX, signature='o') + def NspRemoved(self, nsp_path): + pass + + def remove_nsp(self, nsp): + self.nsps.remove(nsp) + self.__notify(PX_NSPS) + self.NspRemoved(to_path(nsp)) + + # Properties interface + def __get_props(self): + props = {} + props[PX_HW_ADDRESS] = self.mac + props[PX_CENTER_FREQUENCY] = dbus.UInt32(2525) + props[PX_RSSI] = dbus.Int32(-48) + props[PX_CINR] = dbus.Int32(24) + props[PX_TX_POWER] = dbus.Int32(9) + props[PX_BSID] = self.bsid + props[PX_NSPS] = to_path_array(self.nsps) + props[PX_ACTIVE_NSP] = to_path(self.active_nsp) + return props + + def __notify(self, propname): + props = self._get_dbus_properties(IFACE_WIMAX) + changed = { propname: props[propname] } + WimaxDevice.PropertiesChanged(self, changed) + + @dbus.service.signal(IFACE_WIMAX, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + + # test functions + def add_test_nsp(self, name): + nsp = WimaxNsp(self._bus, name) + self.add_nsp(nsp) + return nsp.path + + def remove_nsp_by_path(self, path): + for nsp in self.nsps: + if nsp.path == path: + self.remove_nsp(nsp) + return + raise NspNotFoundException("NSP %s not found" % path) + +################################################################### +IFACE_TEST = 'org.freedesktop.NetworkManager.LibnmGlibTest' +IFACE_NM = 'org.freedesktop.NetworkManager' + +class PermissionDeniedException(dbus.DBusException): + _dbus_error_name = IFACE_NM + '.PermissionDenied' + +class UnknownDeviceException(dbus.DBusException): + _dbus_error_name = IFACE_NM + '.UnknownDevice' + +PM_DEVICES = 'Devices' +PM_NETWORKING_ENABLED = 'NetworkingEnabled' +PM_WWAN_ENABLED = 'WwanEnabled' +PM_WWAN_HARDWARE_ENABLED = 'WwanHardwareEnabled' +PM_WIRELESS_ENABLED = 'WirelessEnabled' +PM_WIRELESS_HARDWARE_ENABLED = 'WirelessHardwareEnabled' +PM_WIMAX_ENABLED = 'WimaxEnabled' +PM_WIMAX_HARDWARE_ENABLED = 'WimaxHardwareEnabled' +PM_ACTIVE_CONNECTIONS = 'ActiveConnections' +PM_PRIMARY_CONNECTION = 'PrimaryConnection' +PM_ACTIVATING_CONNECTION = 'ActivatingConnection' +PM_STARTUP = 'Startup' +PM_STATE = 'State' +PM_VERSION = 'Version' +PM_CONNECTIVITY = 'Connectivity' + +class NetworkManager(ExportedObj): + def __init__(self, bus, object_path): + ExportedObj.__init__(self, bus, object_path) + self.add_dbus_interface(IFACE_NM, self.__get_props) + + self.devices = [] + self.active_connections = [] + self.primary_connection = None + self.activating_connection = None + self.state = NM_STATE_DISCONNECTED + self.connectivity = 1 + + @dbus.service.signal(IFACE_NM, signature='u') + def StateChanged(self, new_state): + pass + + def set_state(self, new_state): + self.state = new_state + self.__notify(PM_STATE) + self.StateChanged(dbus.UInt32(self.state)) + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ao') + def GetDevices(self): + return self._get_dbus_properties(IFACE_NM)[PM_DEVICES] + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='s', out_signature='o') + def GetDeviceByIpIface(self, ip_iface): + for d in self.devices: + # ignore iface/ip_iface distinction for now + if d.iface == ip_iface: + return d.path + raise UnknownDeviceException("No device found for the requested iface.") + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='ooo', out_signature='o') + def ActivateConnection(self, conpath, devpath, specific_object): + device = None + for d in self.devices: + if d.path == devpath: + device = d + break + if not device: + raise UnknownDeviceException("No device found for the requested iface.") + raise PermissionDeniedException("Not yet implemented") + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}oo', out_signature='oo') + def AddAndActivateConnection(self, connection, devpath, specific_object): + device = None + for d in self.devices: + if d.path == devpath: + device = d + break + if not device: + raise UnknownDeviceException("No device found for the requested iface.") + raise PermissionDeniedException("Not yet implemented") + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='o', out_signature='') + def DeactivateConnection(self, active_connection): + pass + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='') + def Sleep(self, do_sleep): + if do_sleep: + self.state = NM_STATE_ASLEEP + else: + self.state = NM_STATE_DISCONNECTED + self.__notify(PM_STATE) + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='') + def Enable(self, do_enable): + pass + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='a{ss}') + def GetPermissions(self): + return { "org.freedesktop.NetworkManager.enable-disable-network": "yes", + "org.freedesktop.NetworkManager.sleep-wake": "no", + "org.freedesktop.NetworkManager.enable-disable-wifi": "yes", + "org.freedesktop.NetworkManager.enable-disable-wwan": "yes", + "org.freedesktop.NetworkManager.enable-disable-wimax": "yes", + "org.freedesktop.NetworkManager.network-control": "yes", + "org.freedesktop.NetworkManager.wifi.share.protected": "yes", + "org.freedesktop.NetworkManager.wifi.share.open": "yes", + "org.freedesktop.NetworkManager.settings.modify.own": "yes", + "org.freedesktop.NetworkManager.settings.modify.system": "yes", + "org.freedesktop.NetworkManager.settings.modify.hostname": "yes" } + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='ss', out_signature='') + def SetLogging(self, level, domains): + pass + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ss') + def GetLogging(self): + return ("info", "HW,RFKILL,CORE,DEVICE,WIFI,ETHER") + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='u') + def CheckConnectivity(self): + raise PermissionDeniedException("You fail") + + @dbus.service.signal(IFACE_NM, signature='o') + def DeviceAdded(self, devpath): + pass + + def add_device(self, device): + self.devices.append(device) + self.__notify(PM_DEVICES) + self.DeviceAdded(to_path(device)) + + @dbus.service.signal(IFACE_NM, signature='o') + def DeviceRemoved(self, devpath): + pass + + def remove_device(self, device): + self.devices.remove(device) + self.__notify(PM_DEVICES) + self.DeviceRemoved(to_path(device)) + + ################# D-Bus Properties interface + def __get_props(self): + props = {} + props[PM_DEVICES] = to_path_array(self.devices) + props[PM_NETWORKING_ENABLED] = True + props[PM_WWAN_ENABLED] = True + props[PM_WWAN_HARDWARE_ENABLED] = True + props[PM_WIRELESS_ENABLED] = True + props[PM_WIRELESS_HARDWARE_ENABLED] = True + props[PM_WIMAX_ENABLED] = True + props[PM_WIMAX_HARDWARE_ENABLED] = True + props[PM_ACTIVE_CONNECTIONS] = to_path_array(self.active_connections) + props[PM_PRIMARY_CONNECTION] = to_path(self.primary_connection) + props[PM_ACTIVATING_CONNECTION] = to_path(self.activating_connection) + props[PM_STARTUP] = False + props[PM_STATE] = dbus.UInt32(self.state) + props[PM_VERSION] = "0.9.9.0" + props[PM_CONNECTIVITY] = dbus.UInt32(self.connectivity) + return props + + def __notify(self, propname): + props = self._get_dbus_properties(IFACE_NM) + changed = { propname: props[propname] } + NetworkManager.PropertiesChanged(self, changed) + + @dbus.service.signal(IFACE_NM, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + + ################# Testing methods + @dbus.service.method(IFACE_TEST, in_signature='', out_signature='') + def Quit(self): + mainloop.quit() + + @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') + def AddWiredDevice(self, ifname): + for d in self.devices: + if d.iface == ifname: + raise PermissionDeniedError("Device already added") + dev = WiredDevice(self._bus, ifname) + self.add_device(dev) + return dbus.ObjectPath(dev.path) + + @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') + def AddWifiDevice(self, ifname): + for d in self.devices: + if d.iface == ifname: + raise PermissionDeniedError("Device already added") + dev = WifiDevice(self._bus, ifname) + self.add_device(dev) + return dbus.ObjectPath(dev.path) + + @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') + def AddWimaxDevice(self, ifname): + for d in self.devices: + if d.iface == ifname: + raise PermissionDeniedError("Device already added") + dev = WimaxDevice(self._bus, ifname) + self.add_device(dev) + return dbus.ObjectPath(dev.path) + + @dbus.service.method(IFACE_TEST, in_signature='o', out_signature='') + def RemoveDevice(self, path): + for d in self.devices: + if d.path == path: + self.remove_device(d) + return + raise UnknownDeviceException("Device not found") + + @dbus.service.method(IFACE_TEST, in_signature='sss', out_signature='o') + def AddWifiAp(self, ifname, ssid, mac): + for d in self.devices: + if d.iface == ifname: + return dbus.ObjectPath(d.add_test_ap(ssid, mac)) + raise UnknownDeviceException("Device not found") + + @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='') + def RemoveWifiAp(self, ifname, ap_path): + for d in self.devices: + if d.iface == ifname: + d.remove_ap_by_path(ap_path) + return + raise UnknownDeviceException("Device not found") + + @dbus.service.method(IFACE_TEST, in_signature='ss', out_signature='o') + def AddWimaxNsp(self, ifname, name): + for d in self.devices: + if d.iface == ifname: + return dbus.ObjectPath(d.add_test_nsp(name)) + raise UnknownDeviceException("Device not found") + + @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='') + def RemoveWimaxNsp(self, ifname, nsp_path): + for d in self.devices: + if d.iface == ifname: + d.remove_nsp_by_path(nsp_path) + return + raise UnknownDeviceException("Device not found") + +def quit_cb(user_data): + mainloop.quit() + +def main(): + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + random.seed() + + bus = dbus.SessionBus() + nm = NetworkManager(bus, "/org/freedesktop/NetworkManager") + if not bus.request_name("org.freedesktop.NetworkManager"): + sys.exit(1) + + # quit after inactivity to ensure we don't stick around if tests fail + quit_id = GLib.timeout_add_seconds(20, quit_cb, None) + + try: + mainloop.run() + except Exception as e: + pass + + sys.exit(0) + +if __name__ == '__main__': + main() + diff --git a/libnm-glib/tests/test-nm-client.c b/libnm-glib/tests/test-nm-client.c new file mode 100644 index 00000000..b181c8fa --- /dev/null +++ b/libnm-glib/tests/test-nm-client.c @@ -0,0 +1,953 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 - 2014 Red Hat, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "nm-client.h" +#include "nm-device-wifi.h" +#include "nm-device-ethernet.h" +#include "nm-device-wimax.h" +#include "nm-glib-compat.h" + +static const char *fake_path; +static const char *fake_bin; +static const char *fake_exec; +static GMainLoop *loop = NULL; + +/*******************************************************************/ + +typedef struct { + GDBusConnection *bus; + GDBusProxy *proxy; + GPid pid; + NMClient *client; +} ServiceInfo; + +#define test_assert(condition) \ +do { \ + if (!G_LIKELY (condition)) \ + service_cleanup (); \ + g_assert (condition); \ +} while (0) + +#define test_assert_cmpint(a, b, c) \ +do { \ + if (!G_LIKELY (a b c)) \ + service_cleanup (); \ + g_assert_cmpint (a, b, c); \ +} while (0) + +#define test_assert_cmpstr(a, b, c) \ +do { \ + if (!G_LIKELY (g_str_hash (a) b g_str_hash (c))) \ + service_cleanup (); \ + g_assert_cmpstr (a, b, c); \ +} while (0) + +#define test_assert_no_error(e) \ +do { \ + if (G_UNLIKELY (e)) \ + service_cleanup (); \ + g_assert_no_error (e); \ +} while (0) + +static ServiceInfo * sinfo_static = NULL; + +static void +service_cleanup (void) +{ + ServiceInfo *info = sinfo_static; + + sinfo_static = NULL; + + if (info) { + if (info->proxy) + g_object_unref (info->proxy); + if (info->bus) + g_object_unref (info->bus); + if (info->client) + g_object_unref (info->client); + if (info->pid) + kill (info->pid, SIGTERM); + memset (info, 0, sizeof (*info)); + g_free (info); + } else + g_assert_not_reached (); +} + +static gboolean +name_exists (GDBusConnection *c, const char *name) +{ + GVariant *reply; + gboolean exists = FALSE; + + reply = g_dbus_connection_call_sync (c, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetNameOwner", + g_variant_new ("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + NULL); + if (reply != NULL) { + exists = TRUE; + g_variant_unref (reply); + } + + return exists; +} + +static ServiceInfo * +service_init (void) +{ + ServiceInfo *sinfo; + const char *args[2] = { fake_exec, NULL }; + GError *error = NULL; + int i = 100; + + g_assert (!sinfo_static); + + sinfo = g_malloc0 (sizeof (*sinfo)); + + sinfo_static = sinfo; + + sinfo->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + test_assert (sinfo->bus); + + if (!g_spawn_async (fake_path, (char **) args, NULL, 0, NULL, NULL, &sinfo->pid, &error)) + test_assert_no_error (error); + + /* Wait until the service is registered on the bus */ + while (i > 0) { + g_usleep (G_USEC_PER_SEC / 50); + if (name_exists (sinfo->bus, "org.freedesktop.NetworkManager")) + break; + i--; + } + test_assert (i > 0); + + /* Grab a proxy to our fake NM service to trigger tests */ + sinfo->proxy = g_dbus_proxy_new_sync (sinfo->bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + NM_DBUS_SERVICE, + NM_DBUS_PATH, + "org.freedesktop.NetworkManager.LibnmGlibTest", + NULL, NULL); + test_assert (sinfo->proxy); + + sinfo->client = nm_client_new (); + test_assert (sinfo->client != NULL); + + return sinfo; +} + +static ServiceInfo * +service_get (void) +{ + g_assert (sinfo_static); + return sinfo_static; +} + +#define _sinfo (service_get ()) + +/*******************************************************************/ + +static gboolean +loop_quit (gpointer user_data) +{ + g_main_loop_quit ((GMainLoop *) user_data); + return G_SOURCE_REMOVE; +} + +static gboolean +add_device (const char *method, const char *ifname, char **out_path) +{ + GError *error = NULL; + GVariant *ret; + + ret = g_dbus_proxy_call_sync (_sinfo->proxy, + method, + g_variant_new ("(s)", ifname), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + test_assert_no_error (error); + test_assert (ret); + test_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + if (out_path) + g_variant_get (ret, "(o)", out_path); + g_variant_unref (ret); + return TRUE; +} + +/*******************************************************************/ + +typedef struct { + GMainLoop *loop; + gboolean signaled; + gboolean notified; + guint quit_count; + guint quit_id; +} DeviceAddedInfo; + +static void +device_add_check_quit (DeviceAddedInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +device_added_cb (NMClient *c, + NMDevice *device, + DeviceAddedInfo *info) +{ + test_assert (device); + test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + info->signaled = TRUE; + device_add_check_quit (info); +} + +static void +devices_notify_cb (NMClient *c, + GParamSpec *pspec, + DeviceAddedInfo *info) +{ + const GPtrArray *devices; + NMDevice *device; + + devices = nm_client_get_devices (c); + test_assert (devices); + test_assert_cmpint (devices->len, ==, 1); + + device = g_ptr_array_index (devices, 0); + test_assert (device); + test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + + info->notified = TRUE; + + device_add_check_quit (info); +} + +static void +test_device_added (void) +{ + const GPtrArray *devices; + NMDevice *device; + DeviceAddedInfo info = { loop, FALSE, FALSE, 0, 0 }; + + service_init (); + + /* Give NMClient a chance to initialize */ + g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + devices = nm_client_get_devices (_sinfo->client); + test_assert (devices == NULL); + + /* Tell the test service to add a new device */ + add_device ("AddWiredDevice", "eth0", NULL); + + g_signal_connect (_sinfo->client, + "device-added", + (GCallback) device_added_cb, + &info); + info.quit_count++; + + g_signal_connect (_sinfo->client, + "notify::devices", + (GCallback) devices_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the device */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + test_assert (info.signaled); + test_assert (info.notified); + + g_signal_handlers_disconnect_by_func (_sinfo->client, device_added_cb, &info); + g_signal_handlers_disconnect_by_func (_sinfo->client, devices_notify_cb, &info); + + devices = nm_client_get_devices (_sinfo->client); + test_assert (devices); + test_assert_cmpint (devices->len, ==, 1); + + device = g_ptr_array_index (devices, 0); + test_assert (device); + test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + + service_cleanup (); +} + +/*******************************************************************/ + +static const char *expected_bssid = "66:55:44:33:22:11"; + +typedef struct { + GMainLoop *loop; + gboolean found; + char *ap_path; + gboolean signaled; + gboolean notified; + guint quit_id; + guint quit_count; +} WifiApInfo; + +static void +wifi_check_quit (WifiApInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +wifi_device_added_cb (NMClient *c, + NMDevice *device, + WifiApInfo *info) +{ + test_assert_cmpstr (nm_device_get_iface (device), ==, "wlan0"); + info->found = TRUE; + wifi_check_quit (info); +} + +static void +got_ap_path (WifiApInfo *info, const char *path) +{ + if (info->ap_path) + test_assert_cmpstr (info->ap_path, ==, path); + else + info->ap_path = g_strdup (path); +} + +static void +wifi_ap_added_cb (NMDeviceWifi *w, + NMAccessPoint *ap, + WifiApInfo *info) +{ + test_assert (ap); + test_assert_cmpstr (nm_access_point_get_bssid (ap), ==, expected_bssid); + got_ap_path (info, nm_object_get_path (NM_OBJECT (ap))); + + info->signaled = TRUE; + wifi_check_quit (info); +} + +static void +wifi_ap_add_notify_cb (NMDeviceWifi *w, + GParamSpec *pspec, + WifiApInfo *info) +{ + const GPtrArray *aps; + NMAccessPoint *ap; + + aps = nm_device_wifi_get_access_points (w); + test_assert (aps); + test_assert_cmpint (aps->len, ==, 1); + + ap = g_ptr_array_index (aps, 0); + test_assert (ap); + test_assert_cmpstr (nm_access_point_get_bssid (ap), ==, "66:55:44:33:22:11"); + got_ap_path (info, nm_object_get_path (NM_OBJECT (ap))); + + info->notified = TRUE; + wifi_check_quit (info); +} + +static void +wifi_ap_removed_cb (NMDeviceWifi *w, + NMAccessPoint *ap, + WifiApInfo *info) +{ + test_assert (ap); + test_assert_cmpstr (info->ap_path, ==, nm_object_get_path (NM_OBJECT (ap))); + + info->signaled = TRUE; + wifi_check_quit (info); +} + +static void +wifi_ap_remove_notify_cb (NMDeviceWifi *w, + GParamSpec *pspec, + WifiApInfo *info) +{ + const GPtrArray *aps; + + aps = nm_device_wifi_get_access_points (w); + test_assert (aps == NULL); + + info->notified = TRUE; + wifi_check_quit (info); +} + +static void +test_wifi_ap_added_removed (void) +{ + NMDeviceWifi *wifi; + WifiApInfo info = { loop, FALSE, FALSE, 0, 0 }; + GVariant *ret; + GError *error = NULL; + char *expected_path = NULL; + + service_init (); + + /* Give NMClient a chance to initialize */ + g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + /*************************************/ + /* Add the wifi device */ + add_device ("AddWifiDevice", "wlan0", NULL); + + g_signal_connect (_sinfo->client, + "device-added", + (GCallback) wifi_device_added_cb, + &info); + info.quit_count = 1; + + /* Wait for libnm-glib to find the device */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + test_assert (info.found); + g_signal_handlers_disconnect_by_func (_sinfo->client, wifi_device_added_cb, &info); + + wifi = (NMDeviceWifi *) nm_client_get_device_by_iface (_sinfo->client, "wlan0"); + test_assert (NM_IS_DEVICE_WIFI (wifi)); + + /*************************************/ + /* Add the wifi device */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync (_sinfo->proxy, + "AddWifiAp", + g_variant_new ("(sss)", "wlan0", "test-ap", expected_bssid), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + test_assert_no_error (error); + test_assert (ret); + test_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + g_variant_get (ret, "(o)", &expected_path); + g_variant_unref (ret); + + g_signal_connect (wifi, + "access-point-added", + (GCallback) wifi_ap_added_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wifi, + "notify::access-points", + (GCallback) wifi_ap_add_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the AP */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + test_assert (info.signaled); + test_assert (info.notified); + test_assert (info.ap_path); + test_assert_cmpstr (info.ap_path, ==, expected_path); + g_signal_handlers_disconnect_by_func (wifi, wifi_ap_added_cb, &info); + g_signal_handlers_disconnect_by_func (wifi, wifi_ap_add_notify_cb, &info); + + /*************************************/ + /* Remove the wifi device */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync (_sinfo->proxy, + "RemoveWifiAp", + g_variant_new ("(so)", "wlan0", expected_path), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + test_assert_no_error (error); + g_clear_pointer (&ret, g_variant_unref); + + g_signal_connect (wifi, + "access-point-removed", + (GCallback) wifi_ap_removed_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wifi, + "notify::access-points", + (GCallback) wifi_ap_remove_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the AP */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + test_assert (info.signaled); + test_assert (info.notified); + g_signal_handlers_disconnect_by_func (wifi, wifi_ap_removed_cb, &info); + g_signal_handlers_disconnect_by_func (wifi, wifi_ap_remove_notify_cb, &info); + + g_free (info.ap_path); + g_free (expected_path); + service_cleanup (); +} + +/*******************************************************************/ + +static const char *expected_nsp_name = "Clear"; + +typedef struct { + GMainLoop *loop; + gboolean found; + char *nsp_path; + gboolean signaled; + gboolean notified; + guint quit_id; + guint quit_count; +} WimaxNspInfo; + +static void +wimax_check_quit (WimaxNspInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +wimax_device_added_cb (NMClient *c, + NMDevice *device, + WimaxNspInfo *info) +{ + test_assert_cmpstr (nm_device_get_iface (device), ==, "wmx0"); + info->found = TRUE; + wimax_check_quit (info); +} + +static void +got_nsp_path (WimaxNspInfo *info, const char *path) +{ + if (info->nsp_path) + test_assert_cmpstr (info->nsp_path, ==, path); + else + info->nsp_path = g_strdup (path); +} + +static void +wimax_nsp_added_cb (NMDeviceWimax *w, + NMWimaxNsp *nsp, + WimaxNspInfo *info) +{ + test_assert (nsp); + test_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name); + got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp))); + + info->signaled = TRUE; + wimax_check_quit (info); +} + +static void +wimax_nsp_add_notify_cb (NMDeviceWimax *w, + GParamSpec *pspec, + WimaxNspInfo *info) +{ + const GPtrArray *nsps; + NMWimaxNsp *nsp; + + nsps = nm_device_wimax_get_nsps (w); + test_assert (nsps); + test_assert_cmpint (nsps->len, ==, 1); + + nsp = g_ptr_array_index (nsps, 0); + test_assert (nsp); + test_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name); + got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp))); + + info->notified = TRUE; + wimax_check_quit (info); +} + +static void +wimax_nsp_removed_cb (NMDeviceWimax *w, + NMWimaxNsp *nsp, + WimaxNspInfo *info) +{ + test_assert (nsp); + test_assert_cmpstr (info->nsp_path, ==, nm_object_get_path (NM_OBJECT (nsp))); + + info->signaled = TRUE; + wimax_check_quit (info); +} + +static void +wimax_nsp_remove_notify_cb (NMDeviceWimax *w, + GParamSpec *pspec, + WimaxNspInfo *info) +{ + const GPtrArray *nsps; + + nsps = nm_device_wimax_get_nsps (w); + test_assert (nsps == NULL); + + info->notified = TRUE; + wimax_check_quit (info); +} + +static void +test_wimax_nsp_added_removed (void) +{ + NMDeviceWimax *wimax; + WimaxNspInfo info = { loop, FALSE, FALSE, 0, 0 }; + GVariant *ret; + GError *error = NULL; + char *expected_path = NULL; + + service_init (); + + /* Give NMClient a chance to initialize */ + g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + /*************************************/ + /* Add the wimax device */ + add_device ("AddWimaxDevice", "wmx0", NULL); + + g_signal_connect (_sinfo->client, + "device-added", + (GCallback) wimax_device_added_cb, + &info); + info.quit_count = 1; + + /* Wait for libnm-glib to find the device */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + test_assert (info.found); + g_signal_handlers_disconnect_by_func (_sinfo->client, wimax_device_added_cb, &info); + + wimax = (NMDeviceWimax *) nm_client_get_device_by_iface (_sinfo->client, "wmx0"); + test_assert (NM_IS_DEVICE_WIMAX (wimax)); + + /*************************************/ + /* Add the wimax NSP */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync (_sinfo->proxy, + "AddWimaxNsp", + g_variant_new ("(ss)", "wmx0", expected_nsp_name), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + test_assert_no_error (error); + test_assert (ret); + test_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + g_variant_get (ret, "(o)", &expected_path); + g_variant_unref (ret); + + g_signal_connect (wimax, + "nsp-added", + (GCallback) wimax_nsp_added_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wimax, + "notify::nsps", + (GCallback) wimax_nsp_add_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the AP */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + test_assert (info.signaled); + test_assert (info.notified); + test_assert (info.nsp_path); + test_assert_cmpstr (info.nsp_path, ==, expected_path); + g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_added_cb, &info); + g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_add_notify_cb, &info); + + /*************************************/ + /* Remove the wimax NSP */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync (_sinfo->proxy, + "RemoveWimaxNsp", + g_variant_new ("(so)", "wmx0", expected_path), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + test_assert_no_error (error); + g_clear_pointer (&ret, g_variant_unref); + + g_signal_connect (wimax, + "nsp-removed", + (GCallback) wimax_nsp_removed_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wimax, + "notify::nsps", + (GCallback) wimax_nsp_remove_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm-glib to find the AP */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + test_assert (info.signaled); + test_assert (info.notified); + g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_removed_cb, &info); + g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_remove_notify_cb, &info); + + g_free (info.nsp_path); + g_free (expected_path); + service_cleanup (); +} + +/*******************************************************************/ + +typedef struct { + GMainLoop *loop; + gboolean signaled; + gboolean notified; + guint quit_count; + guint quit_id; +} DaInfo; + +static void +da_check_quit (DaInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +da_device_added_cb (NMClient *c, + NMDevice *device, + DaInfo *info) +{ + da_check_quit (info); +} + +static void +da_device_removed_cb (NMClient *c, + NMDevice *device, + DaInfo *info) +{ + test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + info->signaled = TRUE; + da_check_quit (info); +} + +static void +da_devices_notify_cb (NMClient *c, + GParamSpec *pspec, + DaInfo *info) +{ + const GPtrArray *devices; + NMDevice *device; + guint i; + const char *iface; + + devices = nm_client_get_devices (c); + test_assert (devices); + test_assert_cmpint (devices->len, ==, 2); + + for (i = 0; i < devices->len; i++) { + device = g_ptr_array_index (devices, i); + iface = nm_device_get_iface (device); + + test_assert (!strcmp (iface, "wlan0") || !strcmp (iface, "eth1")); + } + + info->notified = TRUE; + da_check_quit (info); +} + +static void +test_devices_array (void) +{ + DaInfo info = { loop }; + char *paths[3] = { NULL, NULL, NULL }; + NMDevice *device; + const GPtrArray *devices; + GError *error = NULL; + GVariant *ret; + + service_init (); + + /* Give NMClient a chance to initialize */ + g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + /*************************************/ + /* Add some devices */ + add_device ("AddWifiDevice", "wlan0", &paths[0]); + add_device ("AddWiredDevice", "eth0", &paths[1]); + add_device ("AddWiredDevice", "eth1", &paths[2]); + info.quit_count = 3; + + g_signal_connect (_sinfo->client, + "device-added", + (GCallback) da_device_added_cb, + &info); + + /* Wait for libnm-glib to find the device */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + test_assert_cmpint (info.quit_count, ==, 0); + g_signal_handlers_disconnect_by_func (_sinfo->client, da_device_added_cb, &info); + + /* Ensure the devices now exist */ + devices = nm_client_get_devices (_sinfo->client); + test_assert (devices); + test_assert_cmpint (devices->len, ==, 3); + + device = nm_client_get_device_by_iface (_sinfo->client, "wlan0"); + test_assert (NM_IS_DEVICE_WIFI (device)); + + device = nm_client_get_device_by_iface (_sinfo->client, "eth0"); + test_assert (NM_IS_DEVICE_ETHERNET (device)); + + device = nm_client_get_device_by_iface (_sinfo->client, "eth1"); + test_assert (NM_IS_DEVICE_ETHERNET (device)); + + /********************************/ + /* Now remove the device in the middle */ + ret = g_dbus_proxy_call_sync (_sinfo->proxy, + "RemoveDevice", + g_variant_new ("(o)", paths[1]), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + test_assert_no_error (error); + test_assert (ret); + g_variant_unref (ret); + + g_signal_connect (_sinfo->client, + "device-removed", + (GCallback) da_device_removed_cb, + &info); + + g_signal_connect (_sinfo->client, + "notify::devices", + (GCallback) da_devices_notify_cb, + &info); + info.quit_count = 2; + + /* Wait for libnm-glib to find the device */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + test_assert_cmpint (info.quit_count, ==, 0); + g_signal_handlers_disconnect_by_func (_sinfo->client, da_device_removed_cb, &info); + g_signal_handlers_disconnect_by_func (_sinfo->client, da_devices_notify_cb, &info); + + /* Ensure only two are left */ + devices = nm_client_get_devices (_sinfo->client); + test_assert (devices); + test_assert_cmpint (devices->len, ==, 2); + + device = nm_client_get_device_by_iface (_sinfo->client, "wlan0"); + test_assert (NM_IS_DEVICE_WIFI (device)); + + device = nm_client_get_device_by_iface (_sinfo->client, "eth1"); + test_assert (NM_IS_DEVICE_ETHERNET (device)); + + g_free (paths[0]); + g_free (paths[1]); + g_free (paths[2]); + service_cleanup (); +} + +/*******************************************************************/ + +int +main (int argc, char **argv) +{ + g_assert (argc == 3); + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + g_test_init (&argc, &argv, NULL); + + fake_path = argv[1]; + fake_bin = argv[2]; + fake_exec = g_strdup_printf ("%s/%s", argv[1], argv[2]); + + loop = g_main_loop_new (NULL, FALSE); + + g_test_add_func ("/libnm-glib/device-added", test_device_added); + g_test_add_func ("/libnm-glib/wifi-ap-added-removed", test_wifi_ap_added_removed); + g_test_add_func ("/libnm-glib/wimax-nsp-added-removed", test_wimax_nsp_added_removed); + g_test_add_func ("/libnm-glib/devices-array", test_devices_array); + + return g_test_run (); +} + diff --git a/libnm-glib/tests/test-remote-settings-client.c b/libnm-glib/tests/test-remote-settings-client.c index ad62075d..e3ef7f22 100644 --- a/libnm-glib/tests/test-remote-settings-client.c +++ b/libnm-glib/tests/test-remote-settings-client.c @@ -342,17 +342,9 @@ test_remove_connection (void) /*******************************************************************/ -#if GLIB_CHECK_VERSION(2,25,12) -typedef GTestFixtureFunc TCFunc; -#else -typedef void (*TCFunc)(void); -#endif - -#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL) - -int main (int argc, char **argv) +int +main (int argc, char **argv) { - GTestSuite *suite; char *service_argv[3] = { NULL, NULL, NULL }; int ret; GError *error = NULL; @@ -360,7 +352,9 @@ int main (int argc, char **argv) g_assert (argc == 3); +#if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); +#endif g_test_init (&argc, &argv, NULL); @@ -390,12 +384,10 @@ int main (int argc, char **argv) settings = nm_remote_settings_new (bus); test_assert (settings != NULL); - suite = g_test_get_root (); - - g_test_suite_add (suite, TESTCASE (test_add_connection, NULL)); - g_test_suite_add (suite, TESTCASE (test_make_invisible, NULL)); - g_test_suite_add (suite, TESTCASE (test_make_visible, NULL)); - g_test_suite_add (suite, TESTCASE (test_remove_connection, NULL)); + g_test_add_func ("/remote_settings/add_connection", test_add_connection); + g_test_add_func ("/remote_settings/make_invisible", test_make_invisible); + g_test_add_func ("/remote_settings/make_visible", test_make_visible); + g_test_add_func ("/remote_settings/remove_connection", test_remove_connection); ret = g_test_run (); diff --git a/libnm-glib/tests/test-remote-settings-service.py b/libnm-glib/tests/test-remote-settings-service.py index 86542005..439073ad 100755 --- a/libnm-glib/tests/test-remote-settings-service.py +++ b/libnm-glib/tests/test-remote-settings-service.py @@ -1,8 +1,9 @@ #!/usr/bin/env python # -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -import glib -import gobject +from __future__ import print_function + +from gi.repository import GLib, GObject import sys import dbus import dbus.service @@ -21,7 +22,7 @@ class UnknownPropertyException(dbus.DBusException): class PermissionDeniedException(dbus.DBusException): _dbus_error_name = IFACE_SETTINGS + '.PermissionDenied' -mainloop = gobject.MainLoop() +mainloop = GObject.MainLoop() class Connection(dbus.service.Object): def __init__(self, bus, object_path, settings, remove_func): @@ -30,7 +31,25 @@ class Connection(dbus.service.Object): self.settings = settings self.remove_func = remove_func self.visible = True + self.props = {} + self.props['Unsaved'] = False + + # Properties interface + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') + def GetAll(self, iface): + if iface != IFACE_CONNECTION: + raise UnknownInterfaceException() + return self.props + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') + def Get(self, iface, name): + if iface != IFACE_CONNECTION: + raise UnknownInterfaceException() + if not name in self.props.keys(): + raise UnknownPropertyException() + return self.props[name] + # Connection methods @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}') def GetSettings(self): if not self.visible: @@ -72,10 +91,10 @@ class Settings(dbus.service.Object): @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='a{sa{sv}}', out_signature='o') def AddConnection(self, settings): - path = "/org/freedesktop/NetworkManager/Settings/Connection/%d" % self.counter + path = "/org/freedesktop/NetworkManager/Settings/Connection/{0}".format(self.counter) self.counter = self.counter + 1 self.connections[path] = Connection(self.bus, path, settings, self.delete_connection) - print "Added connection %s" % path + print("Added connection {0}".format(path)) return path def delete_connection(self, connection): @@ -114,16 +133,16 @@ def main(): if not bus.request_name("org.freedesktop.NetworkManager"): sys.exit(1) - print "Service started" + print("Service started") - gobject.timeout_add_seconds(20, quit_cb, None) + GLib.timeout_add_seconds(20, quit_cb, None) try: mainloop.run() - except Exception, e: + except Exception as e: pass - print "Service stopped" + print("Service stopped") sys.exit(0) if __name__ == '__main__': -- cgit 1.3.0-6-gf8a5