diff --git a/.gitignore b/.gitignore index cd4fca45a9..c68d11f516 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ *.gcno *.gcda *.la -*.gir +*-*.gir *.typelib **.stamp .dirstamp @@ -177,6 +177,7 @@ test-*.trs /libnm-util/tests/test-setting-8021x /libnm-util/tests/test-setting-dcb +/libnm/fake-typelib/typelibs.c /libnm/nm-settings-ifcfg-rh-docs.xml /libnm/nm-property-docs.xml /libnm/nm-settings-docs.xml diff --git a/.travis.yml b/.travis.yml index 0bcda1ded9..77b623bdab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ addons: coverity_scan: project: name: NetworkManager/NetworkManager - build_command_prepend: sh autogen.sh --with-systemd-logind=no --enable-more-warnings=no + build_command_prepend: sh autogen.sh --with-systemd-logind=no --enable-more-warnings=no --disable-ovs build_command: make -j4 branch_pattern: .*coverity.* diff --git a/Makefile.am b/Makefile.am index 0cc4d7f19f..eafc8ca54d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -737,6 +737,7 @@ libnm_lib_h_pub_real = \ libnm/NetworkManager.h \ libnm/nm-access-point.h \ libnm/nm-active-connection.h \ + libnm/nm-checkpoint.h \ libnm/nm-client.h \ libnm/nm-device-adsl.h \ libnm/nm-device-bond.h \ @@ -792,6 +793,7 @@ libnm_lib_h_priv = \ libnm_lib_c_real = \ libnm/nm-access-point.c \ libnm/nm-active-connection.c \ + libnm/nm-checkpoint.c \ libnm/nm-client.c \ libnm/nm-dbus-helpers.c \ libnm/nm-device-adsl.c \ @@ -858,6 +860,7 @@ nodist_libnminclude_HEADERS += \ noinst_LTLIBRARIES += libnm/libnm-utils.la libnm_libnm_utils_la_CPPFLAGS = \ + $(INTROSPECTION_CFLAGS) \ $(libnm_lib_cppflags) libnm_libnm_utils_la_SOURCES = \ @@ -956,8 +959,34 @@ libnm/libnm.typelib: libnm/libnm.gir $(INTROSPECTION_COMPILER) --includedir=$(srcdir)/libnm-core --includedir=$(builddir)/libnm-core --includedir=$(srcdir)/libnm --includedir=$(builddir)/libnm $< -o $@ INTROSPECTION_GIRS += libnm/NM-1.0.gir + +if WITH_FAKE_TYPELIBS + +libnm/fake-typelib/NetworkManager.typelib: libnm/fake-typelib/NetworkManager.gir libnm/fake-typelib/.dirstamp + $(AM_V_GEN) $(INTROSPECTION_COMPILER) $< -o $@ + +libnm/fake-typelib/NMClient.typelib: libnm/fake-typelib/NMClient.gir libnm/fake-typelib/.dirstamp + $(AM_V_GEN) $(INTROSPECTION_COMPILER) $< -o $@ + +libnm/fake-typelib/typelibs.c: libnm/fake-typelib/typelibs.gresource.xml libnm/fake-typelib/NetworkManager.typelib libnm/fake-typelib/NMClient.typelib + $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $< --target=$@ --sourcedir=$(builddir)/libnm/fake-typelib --generate-source --manual-register + +nodist_libnm_libnm_utils_la_SOURCES = \ + libnm/fake-typelib/typelibs.c + +CLEANFILES += \ + libnm/fake-typelib/typelibs.c \ + libnm/fake-typelib/NMClient.typelib \ + libnm/fake-typelib/NetworkManager.typelib endif +endif + +EXTRA_DIST += \ + libnm/fake-typelib/NetworkManager.gir \ + libnm/fake-typelib/NMClient.gir \ + libnm/fake-typelib/typelibs.gresource.xml + if HAVE_INTROSPECTION libnm_noinst_data = \ @@ -2075,6 +2104,7 @@ EXTRA_DIST += \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wifi_LEAP.cexpected \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wifi_WEP_104_ASCII.cexpected \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected \ + src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Vlan_test-vlan-interface.cexpected \ src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-dcb-test.cexpected \ @@ -4537,6 +4567,7 @@ EXTRA_DIST += \ shared/nm-utils/c-list-util.h \ shared/nm-utils/gsystem-local-alloc.h \ shared/nm-utils/nm-glib.h \ + shared/nm-utils/nm-jansson.h \ shared/nm-utils/nm-obj.h \ shared/nm-utils/nm-macros-internal.h \ shared/nm-utils/nm-shared-utils.c \ diff --git a/Makefile.examples b/Makefile.examples index 63370e2cbc..fc08851ca6 100644 --- a/Makefile.examples +++ b/Makefile.examples @@ -133,6 +133,8 @@ EXTRA_DIST += \ examples/dispatcher/10-ifcfg-rh-routes.sh \ examples/dispatcher/70-wifi-wired-exclusive.sh \ \ + examples/js/get_ips.js \ + \ examples/lua/lgi/add-connection.lua \ examples/lua/lgi/list-connections.lua \ examples/lua/lgi/list-devices.lua \ diff --git a/clients/common/nm-client-utils.c b/clients/common/nm-client-utils.c index bf4dcc77f3..8a28db2dd5 100644 --- a/clients/common/nm-client-utils.c +++ b/clients/common/nm-client-utils.c @@ -399,9 +399,11 @@ nmc_device_reason_to_string (NMDeviceStateReason reason) return _("The device's parent changed"); case NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED: return _("The device parent's management changed"); - case NM_DEVICE_STATE_REASON_OVSDB_FAILED: return _("OpenVSwitch database connection failed"); + case NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE: + return _("A duplicate IP address was detected"); + } /* TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) */ diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 1ed6b433d8..ea339dd62e 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -461,6 +461,7 @@ _get_text_hidden (NMMetaAccessorGetType get_type) return NM_META_TEXT_HIDDEN; } + /*****************************************************************************/ G_GNUC_PRINTF (4, 5) @@ -3642,6 +3643,60 @@ _validate_fcn_team_config (const char *value, char **out_to_free, GError **error RETURN_STR_TO_FREE (json); } +static gboolean +_is_valid_team_runner_tx_hash_element (const char *tx_hash_element) +{ + const char *valid_tx_hashes[] = { "eth", "vlan", "ipv4", "ipv6", "ip", + "l3", "tcp", "udp", "sctp", "l4", NULL }; + if (nmc_string_is_valid (tx_hash_element, valid_tx_hashes, NULL)) + return TRUE; + return FALSE; +} + +static gboolean +_set_fcn_team_runner_tx_hash (ARGS_SET_FCN) +{ + char **strv = NULL; + guint i = 0; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + strv = _nm_utils_strv_cleanup (g_strsplit_set (value, " \t,", 0), + TRUE, TRUE, TRUE); + if (!verify_string_list (strv, property_info->property_name, + _is_valid_team_runner_tx_hash_element, + error)) { + g_strfreev (strv); + return FALSE; + } + + while (strv && strv[i]) + nm_setting_team_add_runner_tx_hash (NM_SETTING_TEAM (setting), strv[i++]); + g_strfreev (strv); + + return TRUE; +} + +static gboolean +_validate_and_remove_team_runner_tx_hash (NMSettingTeam *setting, + const char *tx_hash, + GError **error) +{ + if (!nm_setting_team_remove_runner_tx_hash_by_value (setting, tx_hash)) { + g_set_error (error, 1, 0, + _("the property doesn't contain string '%s'"), + tx_hash); + return FALSE; + } + + return TRUE; +} +DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_team_runner_tx_hash, + NM_SETTING_TEAM, + nm_setting_team_get_num_runner_tx_hash, + nm_setting_team_remove_runner_tx_hash, + _validate_and_remove_team_runner_tx_hash) + static gconstpointer _get_fcn_vlan_flags (ARGS_GET_FCN) { @@ -6000,6 +6055,130 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .validate_fcn = _validate_fcn_team_config, ), ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "disabled", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_MCAST_REJOIN_COUNT, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "disabled", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER, + .property_type = &_pt_gobject_string, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = VALUES_STATIC (NM_SETTING_TEAM_RUNNER_BROADCAST, + NM_SETTING_TEAM_RUNNER_ROUNDROBIN, + NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP, + NM_SETTING_TEAM_RUNNER_LOADBALANCE, + NM_SETTING_TEAM_RUNNER_LACP), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY, + .property_type = &_pt_gobject_string, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = VALUES_STATIC (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL, + NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE, + NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_HASH, + .property_type = DEFINE_PROPERTY_TYPE ( + .get_fcn = _get_fcn_gobject, + .set_fcn = _set_fcn_team_runner_tx_hash, + .remove_fcn = _remove_fcn_team_runner_tx_hash, + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_BALANCER, + .property_type = &_pt_gobject_string, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = VALUES_STATIC ("basic"), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 50, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_ACTIVE, + .property_type = & _pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_FAST_RATE, + .property_type = & _pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_SYS_PRIO, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 255, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_MIN_PORTS, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY, + .property_type = &_pt_gobject_string, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = VALUES_STATIC (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO_STABLE, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_BANDWIDTH, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_COUNT, + NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_PORT_CONFIG), + ), + ), NULL }; @@ -6016,6 +6195,53 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = { .validate_fcn = _validate_fcn_team_config, ), ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_QUEUE_ID, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = -1, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_PRIO, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_STICKY, + .property_type = &_pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LACP_PRIO, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 255, + .nick = "default", + } + ), + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LACP_KEY, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value = 0, + .nick = "default", + } + ), + ), + ), NULL }; diff --git a/clients/common/settings-docs.c.in b/clients/common/settings-docs.c.in index 3547c833a7..3d6f012bf7 100644 --- a/clients/common/settings-docs.c.in +++ b/clients/common/settings-docs.c.in @@ -316,9 +316,28 @@ #define DESCRIBE_DOC_NM_SETTING_SERIAL_SEND_DELAY N_("Time to delay between each byte sent to the modem, in microseconds.") #define DESCRIBE_DOC_NM_SETTING_SERIAL_STOPBITS N_("Number of stop bits for communication on the serial port. Either 1 or 2. The 1 in \"8n1\" for example.") #define DESCRIBE_DOC_NM_SETTING_TEAM_CONFIG N_("The JSON configuration for the team network interface. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_MCAST_REJOIN_COUNT N_("Corresponds to the teamd mcast_rejoin.count.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL N_("Corresponds to the teamd mcast_rejoin.interval.") #define DESCRIBE_DOC_NM_SETTING_TEAM_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".") +#define DESCRIBE_DOC_NM_SETTING_TEAM_NOTIFY_PEERS_COUNT N_("Corresponds to the teamd notify_peers.count.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL N_("Corresponds to the teamd notify_peers.interval.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER N_("Corresponds to the teamd runner.name. Permitted values are: \"roundrobin\", \"broadcast\", \"activebackup\", \"loadbalance\", \"lacp\".") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_ACTIVE N_("Corresponds to the teamd runner.active.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY N_("Corresponds to the teamd runner.agg_select_policy.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_FAST_RATE N_("Corresponds to the teamd runner.fast_rate.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_HWADDR_POLICY N_("Corresponds to the teamd runner.hwaddr_policy.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_MIN_PORTS N_("Corresponds to the teamd runner.min_ports.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_SYS_PRIO N_("Corresponds to the teamd runner.sys_prio.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_BALANCER N_("Corresponds to the teamd runner.tx_balancer.name.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL N_("Corresponds to the teamd runner.tx_balancer.interval.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_HASH N_("Corresponds to the teamd runner.tx_hash.") #define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_CONFIG N_("The JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_LACP_KEY N_("Corresponds to the teamd ports.PORTIFNAME.lacp_key.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_LACP_PRIO N_("Corresponds to the teamd ports.PORTIFNAME.lacp_prio.") #define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_PRIO N_("Corresponds to the teamd ports.PORTIFNAME.prio.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_QUEUE_ID N_("Corresponds to the teamd ports.PORTIFNAME.queue_id. When set to -1 means the parameter is skipped from the json config.") +#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_STICKY N_("Corresponds to the teamd ports.PORTIFNAME.sticky.") #define DESCRIBE_DOC_NM_SETTING_TUN_GROUP N_("The group ID which will own the device. If set to NULL everyone will be able to use the device.") #define DESCRIBE_DOC_NM_SETTING_TUN_MODE N_("The operating mode of the virtual device. Allowed values are NM_SETTING_TUN_MODE_TUN (1) to create a layer 3 device and NM_SETTING_TUN_MODE_TAP (2) to create an Ethernet-like layer 2 one.") #define DESCRIBE_DOC_NM_SETTING_TUN_MULTI_QUEUE N_("If the property is set to TRUE, the interface will support multiple file descriptors (queues) to parallelize packet sending or receiving. Otherwise, the interface will only support a single queue.") diff --git a/configure.ac b/configure.ac index f8dcd13f50..14227e1aac 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ AC_PREREQ([2.63]) dnl The NM version number m4_define([nm_major_version], [1]) -m4_define([nm_minor_version], [10]) -m4_define([nm_micro_version], [0]) +m4_define([nm_minor_version], [11]) +m4_define([nm_micro_version], [1]) m4_define([nm_version], [nm_major_version.nm_minor_version.nm_micro_version]) @@ -322,9 +322,12 @@ GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32 -DGLIB_V AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) +GOBJECT_INTROSPECTION_CHECK([0.9.6]) + AC_ARG_WITH(libnm-glib, AS_HELP_STRING([--without-libnm-glib], - [don't build legacy libraries])) + [don"'"t build legacy libraries])) +fake_typelibs=no if test "$with_libnm_glib" != "no"; then PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.1 dbus-glib-1 >= 0.94, :, [AC_MSG_FAILURE([$DBUS_PKG_ERRORS @@ -333,13 +336,24 @@ Configure with --without-libnm-glib if you do not need the legacy libraries]) ]) with_libnm_glib=yes + + if test "${found_introspection}" = "yes"; then + AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources) + if ! test x"$GLIB_COMPILE_RESOURCES" = x""; then + fake_typelibs=yes + fi + fi fi AM_CONDITIONAL(WITH_LEGACY_LIBRARIES, test "$with_libnm_glib" != "no") +if test "$fake_typelibs" = "yes"; then + AC_DEFINE(WITH_FAKE_TYPELIBS, 1, [Define for libnm to prevent GIR from loading libnm-glib]) +else + AC_DEFINE(WITH_FAKE_TYPELIBS, 0, [Define for libnm to prevent GIR from loading libnm-glib]) +fi +AM_CONDITIONAL(WITH_FAKE_TYPELIBS, test "${fake_typelibs}" = "yes") PKG_CHECK_MODULES([LIBUDEV], [libudev >= 175]) -GOBJECT_INTROSPECTION_CHECK([0.9.6]) - # Qt4 PKG_CHECK_MODULES(QT, [QtCore >= 4 QtDBus QtNetwork], [have_qt=yes],[have_qt=no]) AC_ARG_ENABLE(qt, @@ -1213,6 +1227,22 @@ fi AC_SUBST(SANITIZERS, [$sanitizers]) +AC_MSG_CHECKING([CC support C11 _Generic()]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(void); int foo() { int a = 0; int b = _Generic (a, int: 4); return b + a; }]], + [[foo();]])], + [cc_support_generic=1], + [cc_support_generic=0]) +AC_MSG_RESULT($cc_support_generic) +AC_DEFINE_UNQUOTED(_NM_CC_SUPPORT_GENERIC, $cc_support_generic, [Define whether the compiler supports C11 _Generic()]) + +AC_MSG_CHECKING([CC support gcc __auto_type]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(void); int foo() { int a = 0; __auto_type b = a; return b + a; }]], + [[foo();]])], + [cc_support_auto_type=1], + [cc_support_auto_type=0]) +AC_MSG_RESULT($cc_support_auto_type) +AC_DEFINE_UNQUOTED(_NM_CC_SUPPORT_AUTO_TYPE, $cc_support_auto_type, [Define whether the compiler support gcc __auto_type]) + dnl ------------------------- dnl Vala bindings dnl ------------------------- diff --git a/examples/js/get_ips.js b/examples/js/get_ips.js new file mode 100755 index 0000000000..490ecb2a8a --- /dev/null +++ b/examples/js/get_ips.js @@ -0,0 +1,184 @@ +#!/usr/bin/env gjs + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014,2017 Red Hat, Inc. + */ + +const System = imports.system; +const NM = imports.gi.NM; +const GLib = imports.gi.GLib; + +/* + * This example shows how to get addresses, routes and DNS information + * from NMIP4Config and NMIP6Config (got out of NMDevice) + */ + +function show_addresses (dev, family) +{ + let ip_cfg; + if (family == GLib.SYSDEF_AF_INET) + ip_cfg = dev.get_ip4_config (); + else + ip_cfg = dev.get_ip6_config (); + + if (ip_cfg == null) { + print ("None"); + return; + } + + let nm_addresses = ip_cfg.get_addresses (); + if (nm_addresses.length == 0) { + print ("None"); + return; + } + + for (let nm_address of nm_addresses) { + let addr = nm_address.get_address (); + let prefix = nm_address.get_prefix (); + + print (addr + "/" + prefix); + } +} + +function show_gateway (dev, family) +{ + let ip_cfg; + if ((family == GLib.SYSDEF_AF_INET)) + ip_cfg = dev.get_ip4_config (); + else + ip_cfg = dev.get_ip6_config (); + + let gw; + if (ip_cfg == null) + gw = "None" + else { + gw = ip_cfg.get_gateway (); + if (gw == '') + gw = "None" + } + + print (gw); +} + +function show_routes (dev, family) +{ + let ip_cfg; + if ((family == GLib.SYSDEF_AF_INET)) + ip_cfg = dev.get_ip4_config (); + else + ip_cfg = dev.get_ip6_config (); + + if (ip_cfg == null) { + print ("None"); + return; + } + + let nm_routes = ip_cfg.get_routes (); + if (nm_routes.length == 0) { + print ("None"); + return; + } + + for (let nm_route of nm_routes) { + let dest = nm_route.get_dest (); + let prefix = nm_route.get_prefix (); + let next_hop = nm_route.get_next_hop (); + let metric = nm_route.get_metric (); + + print (dest + "/" + prefix + " " + next_hop + " " + metric); + } +} + +function show_dns (dev, family) +{ + let ip_cfg; + if ((family == GLib.SYSDEF_AF_INET)) + ip_cfg = dev.get_ip4_config (); + else + ip_cfg = dev.get_ip6_config (); + + if (ip_cfg == null) { + print ("None"); + return; + } + + print ("Nameservers: " + ip_cfg.get_nameservers ()); + print ("Domains: " + ip_cfg.get_domains ()); + print ("Searches: " + ip_cfg.get_searches ()); + if ((family == GLib.SYSDEF_AF_INET)) + print ("WINS: " + ip_cfg.get_wins_servers ()); +} + +if (ARGV.length != 1) { + print ("Usage: get_ips.js "); + System.exit (1); +} + + +let dev_iface = ARGV[0]; +let c = NM.Client.new (null); + +let dev = c.get_device_by_iface (dev_iface); + +if (dev == null) { + print ("Device '%s' not found " + dev_iface); + System.exit (1); +} + +print ("Device: " + dev_iface + " - " + dev.get_type_description ()); +print ("---------------------------------------"); +print (); + +print ("IPv4 addresses:"); +print ("---------------"); +show_addresses (dev, GLib.SYSDEF_AF_INET); +print (); + +print ("IPv4 gateway:"); +print ("-------------"); +show_gateway (dev, GLib.SYSDEF_AF_INET); +print (); + +print ("IPv4 routes:"); +print ("------------"); +show_routes (dev, GLib.SYSDEF_AF_INET); +print (); + +print ("IPv6 addresses:"); +print ("---------------"); +show_addresses (dev, GLib.SYSDEF_AF_INET6); +print (); + +print ("IPv6 gateway:"); +print ("-------------"); +show_gateway (dev, GLib.SYSDEF_AF_INET6); +print (); + +print ("IPv6 routes:"); +print ("------------"); +show_routes (dev, GLib.SYSDEF_AF_INET6); +print (); + +print ("IPv4 DNS:"); +print ("------------"); +show_dns (dev, GLib.SYSDEF_AF_INET); +print (); + +print ("IPv6 DNS:"); +print ("------------"); +show_dns (dev, GLib.SYSDEF_AF_INET6); +print (); diff --git a/examples/python/gi/checkpoint.py b/examples/python/gi/checkpoint.py new file mode 100644 index 0000000000..513e6c3a0a --- /dev/null +++ b/examples/python/gi/checkpoint.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- Mode: Python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +# vim: ft=python ts=4 sts=4 sw=4 et ai + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Copyright 2017 Red Hat, Inc. + +import sys + +import gi +gi.require_version('NM', '1.0') +from gi.repository import GLib, NM + +def usage(): + print "Usage: %s [COMMAND [ARG]...]" % sys.argv[0] + print "" + print " COMMANDS: show" + print " create TIMEOUT [DEV]..." + print " destroy PATH|NUMBER" + print " rollback PATH|NUMBER" + print + sys.exit(1) + +def create_cb(client, result, data): + try: + checkpoint = client.checkpoint_create_finish(result) + print("%s" % checkpoint.get_path()) + except Exception, e: + sys.stderr.write("Failed: %s\n" % e.message) + main_loop.quit() + +def do_create(client): + if len(sys.argv) < 3: + sys.exit("Failed: %s\n" % e.message) + + timeout = int(sys.argv[2]) + devices = [] + for arg in sys.argv[3:]: + d = client.get_device_by_iface(arg) + if d is None: + sys.exit("Unknown device %s" % arg) + devices.append(d) + + client.checkpoint_create_async(devices, timeout, 0, None, create_cb, None) + +def destroy_cb(client, result, data): + try: + if client.checkpoint_destroy_finish(result) == True: + print "Success" + except Exception, e: + sys.stderr.write("Failed: %s\n" % e.message) + main_loop.quit() + +def find_checkpoint(client, arg): + try: + num = int(arg) + path = "/org/freedesktop/NetworkManager/Checkpoint/%u" % num + except Exception, e: + path = arg + + for c in client.get_checkpoints(): + if c.get_path() == path: + return c + return None + +def do_destroy(client): + if len(sys.argv) < 3: + sys.exit("Missing checkpoint path") + + checkpoint = find_checkpoint(client, sys.argv[2]) + if checkpoint is None: + sys.exit("Uknown checkpoint %s" % sys.argv[2]) + + client.checkpoint_destroy_async(checkpoint, None, destroy_cb, None) + +def rollback_cb(client, result, data): + try: + res = client.checkpoint_rollback_finish(result) + for path in res: + d = client.get_device_by_path(path) + if d is None: + iface = path + else: + iface = d.get_iface() + print "%s => %s" % (iface, "OK" if res[path] == 0 else "ERROR") + except Exception, e: + sys.stderr.write("Failed: %s\n" % e.message) + main_loop.quit() + +def do_rollback(client): + if len(sys.argv) < 3: + sys.exit("Missing checkpoint path") + + checkpoint = find_checkpoint(client, sys.argv[2]) + if checkpoint is None: + sys.exit("Uknown checkpoint %s" % sys.argv[2]) + + client.checkpoint_rollback_async(checkpoint, None, rollback_cb, None) + +def do_show(client): + for c in client.get_checkpoints(): + print "%s:" % c.get_path() + print " created: %u" % c.get_created() + print " timeout: %u seconds" % c.get_rollback_timeout() + print " devices:", ' '.join(sorted(map(lambda x: x.get_iface(), c.get_devices()))) + +if __name__ == '__main__': + nm_client = NM.Client.new(None) + main_loop = GLib.MainLoop() + + if len(sys.argv) < 2 or sys.argv[1] == 'show': + do_show(nm_client) + sys.exit(0) + elif sys.argv[1] == 'create': + do_create(nm_client) + elif sys.argv[1] == 'destroy': + do_destroy(nm_client) + elif sys.argv[1] == 'rollback': + do_rollback(nm_client) + else: + usage() + + main_loop.run() diff --git a/examples/python/gi/vpn-import.py b/examples/python/gi/vpn-import.py new file mode 100755 index 0000000000..6210908aa5 --- /dev/null +++ b/examples/python/gi/vpn-import.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# -*- Mode: Python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +# vim: ft=python ts=4 sts=4 sw=4 et ai +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright 2014 Red Hat, Inc. +# + +# +# This example imports a VPN connection, by loading the glib based +# VPN plugin. + +import gi +gi.require_version('NM', '1.0') +from gi.repository import GLib, NM + +import sys + +if len(sys.argv) != 2: + print("Expects one argument: the filename") + sys.exit(1) +filename = sys.argv[1] + +connection = None +for vpn_info in NM.VpnPluginInfo.list_load(): + print("TRY: plugin %s" % (vpn_info.get_filename())) + try: + vpn_plugin = vpn_info.load_editor_plugin() + except Exception as e: + print("SKIP: cannot load plugin: %s" % (e)) + continue + try: + connection = vpn_plugin.import_(filename) + except Exception as e: + print("SKIP: failure to import %s" % (e)) + continue + break + +if connection is None: + print("None of the VPN plugins was able to import \"%s\"" % (filename)) + sys.exit(1) + +connection.normalize() + +print("connection imported from \"%s\" using plugin \"%s\" (\"%s\", %s)" % (filename, vpn_info.get_filename(), connection.get_id(), connection.get_uuid())) + +client = NM.Client.new(None) + +main_loop = GLib.MainLoop() + +def added_cb(client, result, data): + try: + client.add_connection_finish(result) + print("The connection profile has been succesfully added to NetworkManager.") + except Exception, e: + print("ERROR: failed to add connection: %s\n" % e) + main_loop.quit() + +client.add_connection_async(connection, True, None, added_cb, None) + +main_loop.run() diff --git a/introspection/org.freedesktop.NetworkManager.xml b/introspection/org.freedesktop.NetworkManager.xml index dceea7f21f..26a618c1bf 100644 --- a/introspection/org.freedesktop.NetworkManager.xml +++ b/introspection/org.freedesktop.NetworkManager.xml @@ -269,6 +269,13 @@ --> + + + + + + diff --git a/libnm/fake-typelib/NetworkManager.gir b/libnm/fake-typelib/NetworkManager.gir new file mode 100644 index 0000000000..d15d29afc7 --- /dev/null +++ b/libnm/fake-typelib/NetworkManager.gir @@ -0,0 +1,10 @@ + + + + + + diff --git a/libnm/fake-typelib/typelibs.gresource.xml b/libnm/fake-typelib/typelibs.gresource.xml new file mode 100644 index 0000000000..9a71d97544 --- /dev/null +++ b/libnm/fake-typelib/typelibs.gresource.xml @@ -0,0 +1,7 @@ + + + + NetworkManager.typelib + NMClient.typelib + + diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 18ff993de4..5e9feaffc8 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1221,3 +1221,41 @@ global: nm_setting_wireless_security_pmf_get_type; nm_setting_wireless_security_wps_method_get_type; } libnm_1_8_0; + +libnm_1_12_0 { +global: + nm_checkpoint_get_created; + nm_checkpoint_get_devices; + nm_checkpoint_get_rollback_timeout; + nm_checkpoint_get_type; + nm_client_checkpoint_create_async; + nm_client_checkpoint_create_finish; + nm_client_checkpoint_destroy_async; + nm_client_checkpoint_destroy_finish; + nm_client_checkpoint_rollback_async; + nm_client_checkpoint_rollback_finish; + nm_client_get_checkpoints; + nm_setting_team_add_runner_tx_hash; + nm_setting_team_get_mcast_rejoin_count; + nm_setting_team_get_mcast_rejoin_interval; + nm_setting_team_get_notify_peers_count; + nm_setting_team_get_notify_peers_interval; + nm_setting_team_get_num_runner_tx_hash; + nm_setting_team_get_runner; + nm_setting_team_get_runner_hwaddr_policy; + nm_setting_team_get_runner_tx_balancer; + nm_setting_team_get_runner_tx_balancer_interval; + nm_setting_team_get_runner_tx_hash; + nm_setting_team_get_runner_active; + nm_setting_team_get_runner_fast_rate; + nm_setting_team_get_runner_sys_prio; + nm_setting_team_get_runner_min_ports; + nm_setting_team_get_runner_agg_select_policy; + nm_setting_team_port_get_queue_id; + nm_setting_team_port_get_prio; + nm_setting_team_port_get_sticky; + nm_setting_team_port_get_lacp_prio; + nm_setting_team_port_get_lacp_key; + nm_setting_team_remove_runner_tx_hash; + nm_setting_team_remove_runner_tx_hash_by_value; +} libnm_1_10_0; diff --git a/libnm/nm-checkpoint.c b/libnm/nm-checkpoint.c new file mode 100644 index 0000000000..264c819538 --- /dev/null +++ b/libnm/nm-checkpoint.c @@ -0,0 +1,219 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * 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. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * . + * + * Copyright 2017 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-checkpoint.h" +#include "nm-core-internal.h" +#include "nm-dbus-interface.h" +#include "nm-device.h" +#include "nm-object-private.h" + +typedef struct { + GPtrArray *devices; + gint64 created; + guint32 rollback_timeout; +} NMCheckpointPrivate; + +struct _NMCheckpoint { + NMObject parent; + NMCheckpointPrivate _priv; +}; + +struct _NMCheckpointClass { + NMObjectClass parent; +}; + +G_DEFINE_TYPE (NMCheckpoint, nm_checkpoint, NM_TYPE_OBJECT) + +#define NM_CHECKPOINT_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMCheckpoint, NM_IS_CHECKPOINT) + +enum { + PROP_0, + PROP_DEVICES, + PROP_CREATED, + PROP_ROLLBACK_TIMEOUT, + + LAST_PROP +}; + +/** + * nm_checkpoint_get_devices: + * @checkpoint: a #NMCheckpoint + * + * The devices that are part of this checkpoint. + * + * Returns: (element-type NMDevice): the devices list. + * + * Since: 1.12 + **/ +const GPtrArray * +nm_checkpoint_get_devices (NMCheckpoint *checkpoint) +{ + g_return_val_if_fail (NM_IS_CHECKPOINT (checkpoint), NULL); + + return NM_CHECKPOINT_GET_PRIVATE (checkpoint)->devices; +} + +/** + * nm_checkpoint_get_created: + * @checkpoint: a #NMCheckpoint + * + * Gets the timestamp (in CLOCK_BOOTTIME milliseconds) + * of checkpoint creation. + * + * Returns: the timestamp of checkpoint creation. + * + * Since: 1.12 + **/ +gint64 +nm_checkpoint_get_created (NMCheckpoint *checkpoint) +{ + g_return_val_if_fail (NM_IS_CHECKPOINT (checkpoint), 0); + + return NM_CHECKPOINT_GET_PRIVATE (checkpoint)->created; +} + +/** + * nm_checkpoint_get_rollback_timeout: + * @checkpoint: a #NMCheckpoint + * + * Gets the the timeout in seconds for automatic rollback. + * + * Returns: the rollback timeout. + * + * Since: 1.12 + **/ +guint32 +nm_checkpoint_get_rollback_timeout (NMCheckpoint *checkpoint) +{ + g_return_val_if_fail (NM_IS_CHECKPOINT (checkpoint), 0); + + return NM_CHECKPOINT_GET_PRIVATE (checkpoint)->rollback_timeout; +} + +/*****************************************************************************/ + +static void +nm_checkpoint_init (NMCheckpoint *checkpoint) +{ +} + +static void +finalize (GObject *object) +{ + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (NM_CHECKPOINT (object)); + + g_ptr_array_unref (priv->devices); + + G_OBJECT_CLASS (nm_checkpoint_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMCheckpoint *checkpoint = NM_CHECKPOINT (object); + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (checkpoint); + + switch (prop_id) { + case PROP_DEVICES: + g_value_take_boxed (value, _nm_utils_copy_object_array (priv->devices)); + break; + case PROP_CREATED: + g_value_set_int64 (value, priv->created); + break; + case PROP_ROLLBACK_TIMEOUT: + g_value_set_uint (value, priv->rollback_timeout); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +init_dbus (NMObject *object) +{ + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (NM_CHECKPOINT (object)); + const NMPropertiesInfo property_info[] = { + { NM_CHECKPOINT_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE }, + { NM_CHECKPOINT_CREATED, &priv->created }, + { NM_CHECKPOINT_ROLLBACK_TIMEOUT, &priv->rollback_timeout }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_checkpoint_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_CHECKPOINT, + property_info); +} + + +static void +nm_checkpoint_class_init (NMCheckpointClass *checkpoint_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (checkpoint_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (checkpoint_class); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + /** + * NMCheckpoint:devices: + * + * The devices that are part of this checkpoint. + * + * Since: 1.12 + **/ + g_object_class_install_property + (object_class, PROP_DEVICES, + g_param_spec_boxed (NM_CHECKPOINT_DEVICES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMCheckpoint:created: + * + * The timestamp (in CLOCK_BOOTTIME milliseconds) of checkpoint creation. + * + * Since: 1.12 + **/ + g_object_class_install_property + (object_class, PROP_CREATED, + g_param_spec_int64 (NM_CHECKPOINT_CREATED, "", "", + G_MININT64, G_MAXINT64, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMCheckpoint:rollback-timeout: + * + * Timeout in seconds for automatic rollback, or zero. + * + * Since: 1.12 + **/ + g_object_class_install_property + (object_class, PROP_ROLLBACK_TIMEOUT, + g_param_spec_uint (NM_CHECKPOINT_ROLLBACK_TIMEOUT, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-checkpoint.h b/libnm/nm-checkpoint.h new file mode 100644 index 0000000000..a0c9d722c5 --- /dev/null +++ b/libnm/nm-checkpoint.h @@ -0,0 +1,53 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * 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. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * . + * + * Copyright 2017 Red Hat, Inc. + */ + +#ifndef __NM_CHECKPOINT_H__ +#define __NM_CHECKPOINT_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_CHECKPOINT (nm_checkpoint_get_type ()) +#define NM_CHECKPOINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CHECKPOINT, NMCheckpoint)) +#define NM_CHECKPOINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CHECKPOINT, NMCheckpointClass)) +#define NM_IS_CHECKPOINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CHECKPOINT)) +#define NM_IS_CHECKPOINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CHECKPOINT)) +#define NM_CHECKPOINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CHECKPOINT, NMCheckpointClass)) + +#define NM_CHECKPOINT_DEVICES "devices" +#define NM_CHECKPOINT_CREATED "created" +#define NM_CHECKPOINT_ROLLBACK_TIMEOUT "rollback-timeout" + +/** + * NMCheckpoint: + */ +typedef struct _NMCheckpointClass NMCheckpointClass; + +GType nm_checkpoint_get_type (void); + +NM_AVAILABLE_IN_1_12 +const GPtrArray *nm_checkpoint_get_devices (NMCheckpoint *checkpoint); +NM_AVAILABLE_IN_1_12 +gint64 nm_checkpoint_get_created (NMCheckpoint *checkpoint); +NM_AVAILABLE_IN_1_12 +guint32 nm_checkpoint_get_rollback_timeout (NMCheckpoint *checkpoint); + +G_END_DECLS + +#endif /* __NM_CHECKPOINT_H__ */ diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 8f9c50e9f7..0cf4d4361c 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -50,6 +50,7 @@ #include "nm-access-point.h" #include "nm-active-connection.h" +#include "nm-checkpoint.h" #include "nm-device-adsl.h" #include "nm-device-bond.h" #include "nm-device-bridge.h" @@ -139,6 +140,7 @@ enum { PROP_DNS_MODE, PROP_DNS_RC_MANAGER, PROP_DNS_CONFIGURATION, + PROP_CHECKPOINTS, LAST_PROP }; @@ -2058,6 +2060,294 @@ dns_notify (GObject *object, } } +static void +checkpoint_create_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMCheckpoint *checkpoint; + GError *error = NULL; + + checkpoint = nm_manager_checkpoint_create_finish (NM_MANAGER (object), result, &error); + if (checkpoint) + g_simple_async_result_set_op_res_gpointer (simple, checkpoint, g_object_unref); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_get_checkpoints: + * @client: a #NMClient + * + * Gets all the active checkpoints. + * + * Returns: (transfer none) (element-type NMCheckpoint): a #GPtrArray + * containing all the #NMCheckpoint. The returned array is owned by the + * #NMClient object and should not be modified. + * + * Since: 1.12 + **/ +const GPtrArray * +nm_client_get_checkpoints (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + if (!nm_client_get_nm_running (client)) + return ∅ + + return nm_manager_get_checkpoints (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_checkpoint_create_async: + * @client: the %NMClient + * @devices: (element-type NMDevice): a list of devices for which a + * checkpoint should be created. + * @rollback_timeout: the rollback timeout in seconds + * @flags: creation flags + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Creates a checkpoint of the current networking configuration + * for given interfaces. An empty @devices argument means all + * devices. If @rollback_timeout is not zero, a rollback is + * automatically performed after the given timeout. + * + * Since: 1.12 + **/ +void +nm_client_checkpoint_create_async (NMClient *client, + const GPtrArray *devices, + guint32 rollback_timeout, + NMCheckpointCreateFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_checkpoint_create_async); + nm_manager_checkpoint_create_async (NM_CLIENT_GET_PRIVATE (client)->manager, + devices, rollback_timeout, flags, + cancellable, checkpoint_create_cb, simple); +} + +/** + * nm_client_checkpoint_create_finish: + * @client: the #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_checkpoint_create_async(). + * + * Returns: (transfer full): the new #NMCheckpoint on success, %NULL on + * failure, in which case @error will be set. + * + * Since: 1.12 + **/ +NMCheckpoint * +nm_client_checkpoint_create_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +static void +checkpoint_destroy_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nm_manager_checkpoint_destroy_finish (NM_MANAGER (object), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_checkpoint_destroy_async: + * @client: the %NMClient + * @checkpoint: a checkpoint + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Destroys an existing checkpoint without performing a rollback. + * + * Since: 1.12 + **/ +void +nm_client_checkpoint_destroy_async (NMClient *client, + NMCheckpoint *checkpoint, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_checkpoint_destroy_async); + nm_manager_checkpoint_destroy_async (NM_CLIENT_GET_PRIVATE (client)->manager, + checkpoint, + cancellable, checkpoint_destroy_cb, simple); +} + +/** + * nm_client_checkpoint_destroy_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_checkpoint_destroy_async(). + * + * Returns: %TRUE on success or %FALSE on failure, in which case + * @error will be set. + * + * Since: 1.12 + **/ +gboolean +nm_client_checkpoint_destroy_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +static void +checkpoint_rollback_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GHashTable *hash; + GError *error = NULL; + + hash = nm_manager_checkpoint_rollback_finish (NM_MANAGER (object), result, &error); + if (hash) + g_simple_async_result_set_op_res_gpointer (simple, hash, (GDestroyNotify) g_hash_table_unref); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_checkpoint_rollback_async: + * @client: the %NMClient + * @checkpoint: a checkpoint + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Performs the rollback of a checkpoint before the timeout is reached. + * + * Since: 1.12 + **/ +void +nm_client_checkpoint_rollback_async (NMClient *client, + NMCheckpoint *checkpoint, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_checkpoint_rollback_async); + nm_manager_checkpoint_rollback_async (NM_CLIENT_GET_PRIVATE (client)->manager, + checkpoint, + cancellable, checkpoint_rollback_cb, simple); +} + +/** + * nm_client_checkpoint_rollback_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_checkpoint_rollback_async(). + * + * Returns: (transfer full) (element-type utf8 guint32): an hash table of + * devices and results. Devices are represented by their original + * D-Bus path; each result is a #NMRollbackResult. + * + * Since: 1.12 + **/ +GHashTable * +nm_client_checkpoint_rollback_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + GHashTable *hash; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else { + hash = g_simple_async_result_get_op_res_gpointer (simple); + return g_hash_table_ref (hash); + } +} + /****************************************************************/ /* Object Initialization */ /****************************************************************/ @@ -2188,6 +2478,8 @@ obj_nm_for_gdbus_object (NMClient *self, GDBusObject *object, GDBusObjectManager type = NM_TYPE_VPN_CONNECTION; else if (strcmp (ifname, NM_DBUS_INTERFACE_WIMAX_NSP) == 0) type = NM_TYPE_WIMAX_NSP; + else if (strcmp (ifname, NM_DBUS_INTERFACE_CHECKPOINT) == 0) + type = NM_TYPE_CHECKPOINT; if (type != G_TYPE_INVALID) break; @@ -2763,6 +3055,12 @@ get_property (GObject *object, guint prop_id, case PROP_ALL_DEVICES: g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_all_devices (self))); break; + case PROP_CHECKPOINTS: + if (priv->manager) + g_object_get_property (G_OBJECT (priv->manager), pspec->name, value); + else + g_value_take_boxed (value, g_ptr_array_new ()); + break; /* Settings properties. */ case PROP_CONNECTIONS: @@ -3169,6 +3467,20 @@ nm_client_class_init (NMClientClass *client_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * NMClient::checkpoints + * + * The list of active checkpoints. + * + * Since: 1.12 + */ + g_object_class_install_property + (object_class, PROP_CHECKPOINTS, + g_param_spec_boxed (NM_MANAGER_CHECKPOINTS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /* signals */ /** diff --git a/libnm/nm-client.h b/libnm/nm-client.h index 3b37b55a10..9833f48294 100644 --- a/libnm/nm-client.h +++ b/libnm/nm-client.h @@ -403,6 +403,45 @@ const char *nm_client_get_dns_rc_manager (NMClient *client); NM_AVAILABLE_IN_1_6 const GPtrArray *nm_client_get_dns_configuration (NMClient *client); + +NM_AVAILABLE_IN_1_12 +const GPtrArray *nm_client_get_checkpoints (NMClient *client); + +NM_AVAILABLE_IN_1_12 +void nm_client_checkpoint_create_async (NMClient *client, + const GPtrArray *devices, + guint32 rollback_timeout, + NMCheckpointCreateFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_12 +NMCheckpoint *nm_client_checkpoint_create_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +NM_AVAILABLE_IN_1_12 +void nm_client_checkpoint_destroy_async (NMClient *client, + NMCheckpoint *checkpoint, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_12 +gboolean nm_client_checkpoint_destroy_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +NM_AVAILABLE_IN_1_12 +void nm_client_checkpoint_rollback_async (NMClient *client, + NMCheckpoint *checkpoint, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NM_AVAILABLE_IN_1_12 +GHashTable *nm_client_checkpoint_rollback_finish (NMClient *client, + GAsyncResult *result, + GError **error); + G_END_DECLS #endif /* __NM_CLIENT_H__ */ diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c index fbbfe2c552..a01228d5bb 100644 --- a/libnm/nm-libnm-utils.c +++ b/libnm/nm-libnm-utils.c @@ -23,6 +23,8 @@ #include "nm-libnm-utils.h" +#include + /*****************************************************************************/ char * @@ -160,3 +162,83 @@ next: nm_assert (g_utf8_validate (desc_full, -1, NULL)); return desc_full; } + +#if WITH_FAKE_TYPELIBS + +/* + * Here we register empty "NMClient" and "NetworkManager" GIR modules as soon + * as we are loaded (if gnome-introspection is being used). This prevents the + * real modules from being loaded because they would in turn load libnm-glib + * and abort() and crash. + * + * For the high level languages that utilize GIR the crash is highly inconvenient + * while the inability to resolve any methods and attributes is potentially + * recoverable. + */ + +GResource *typelibs_get_resource (void); +void typelibs_register_resource (void); + +static void __attribute__((constructor)) +_nm_libnm_utils_init (void) +{ + GITypelib *typelib; + GBytes *data; + const char *namespace; + GModule *self; + GITypelib *(*_g_typelib_new_from_const_memory) (const guint8 *memory, + gsize len, + GError **error) = NULL; + const char *(*_g_irepository_load_typelib) (GIRepository *repository, + GITypelib *typelib, + GIRepositoryLoadFlags flags, + GError **error) = NULL; + const char *names[] = { "/org/freedesktop/libnm/fake-typelib/NetworkManager.typelib", + "/org/freedesktop/libnm/fake-typelib/NMClient.typelib" }; + int i; + + self = g_module_open (NULL, 0); + if (!self) + return; + g_module_symbol (self, "g_typelib_new_from_const_memory", + (gpointer *) &_g_typelib_new_from_const_memory); + if (_g_typelib_new_from_const_memory) { + g_module_symbol (self, "g_irepository_load_typelib", + (gpointer *) &_g_irepository_load_typelib); + } + g_module_close (self); + + if (!_g_typelib_new_from_const_memory || !_g_irepository_load_typelib) + return; + + typelibs_register_resource (); + + for (i = 0; i < 2; i++) { + gs_free_error GError *error = NULL; + + data = g_resource_lookup_data (typelibs_get_resource (), + names[i], + G_RESOURCE_LOOKUP_FLAGS_NONE, + &error); + if (!data) { + g_warning ("Fake typelib %s could not be loaded: %s", names[i], error->message); + return; + } + + typelib = _g_typelib_new_from_const_memory (g_bytes_get_data (data, NULL), + g_bytes_get_size (data), + &error); + if (!typelib) { + g_warning ("Could not create fake typelib instance %s: %s", names[i], error->message); + return; + } + + namespace = _g_irepository_load_typelib (NULL, typelib, 0, &error); + if (!namespace) { + g_warning ("Could not load fake typelib %s: %s", names[i], error->message); + return; + } + } +} + +#endif /* WITH_FAKE_TYPELIBS */ diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c index e664b71072..aa749232be 100644 --- a/libnm/nm-manager.c +++ b/libnm/nm-manager.c @@ -26,6 +26,7 @@ #include #include "nm-utils.h" +#include "nm-checkpoint.h" #include "nm-common-macros.h" #include "nm-device-ethernet.h" #include "nm-device-wifi.h" @@ -61,6 +62,8 @@ typedef struct { GPtrArray *devices; GPtrArray *all_devices; GPtrArray *active_connections; + GPtrArray *checkpoints; + GSList *added_checkpoints; NMConnectivityState connectivity; NMActiveConnection *primary_connection; NMActiveConnection *activating_connection; @@ -107,6 +110,7 @@ enum { PROP_PRIMARY_CONNECTION, PROP_ACTIVATING_CONNECTION, PROP_DEVICES, + PROP_CHECKPOINTS, PROP_METERED, PROP_ALL_DEVICES, @@ -120,6 +124,8 @@ enum { ANY_DEVICE_REMOVED, ACTIVE_CONNECTION_ADDED, ACTIVE_CONNECTION_REMOVED, + CHECKPOINT_ADDED, + CHECKPOINT_REMOVED, PERMISSION_CHANGED, LAST_SIGNAL @@ -129,6 +135,53 @@ static guint signals[LAST_SIGNAL] = { 0 }; /*****************************************************************************/ +typedef struct { + NMManager *manager; + GSimpleAsyncResult *simple; + char *path; +} CheckpointInfo; + +static CheckpointInfo * +find_checkpoint_info (NMManager *manager, const char *path) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + CheckpointInfo *info; + GSList *iter; + + for (iter = priv->added_checkpoints; iter; iter = g_slist_next (iter)) { + info = iter->data; + if (nm_streq (path, info->path)) + return info; + } + + return NULL; +} + +static void +checkpoint_info_complete (NMManager *self, + CheckpointInfo *info, + NMCheckpoint *checkpoint, + GError *error) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + + g_return_if_fail (info); + + if (checkpoint) { + g_simple_async_result_set_op_res_gpointer (info->simple, + g_object_ref (checkpoint), + g_object_unref); + } else + g_simple_async_result_set_from_error (info->simple, error); + g_simple_async_result_complete (info->simple); + + g_object_unref (info->simple); + priv->added_checkpoints = g_slist_remove (priv->added_checkpoints, info); + + g_free (info->path); + g_slice_free (CheckpointInfo, info); +} + static void nm_manager_init (NMManager *manager) { @@ -189,6 +242,7 @@ init_dbus (NMObject *object) { NM_MANAGER_PRIMARY_CONNECTION, &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, { NM_MANAGER_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, { NM_MANAGER_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" }, + { NM_MANAGER_CHECKPOINTS, &priv->checkpoints, NULL, NM_TYPE_CHECKPOINT, "checkpoint" }, { NM_MANAGER_METERED, &priv->metered }, { NM_MANAGER_ALL_DEVICES, &priv->all_devices, NULL, NM_TYPE_DEVICE, "any-device" }, { NULL }, @@ -206,6 +260,23 @@ init_dbus (NMObject *object) G_CALLBACK (manager_recheck_permissions), object, 0); } +static void +object_creation_failed (NMObject *object, const char *failed_path) +{ + NMManager *self = NM_MANAGER (object); + CheckpointInfo *info; + GError *add_error; + + info = find_checkpoint_info (self, failed_path); + if (info) { + add_error = g_error_new_literal (NM_CLIENT_ERROR, + NM_CLIENT_ERROR_OBJECT_CREATION_FAILED, + _("Checkpoint was removed before it was initialized")); + checkpoint_info_complete (self, info, NULL, add_error); + g_error_free (add_error); + } +} + static NMClientPermission nm_permission_to_client (const char *nm) { @@ -1109,6 +1180,21 @@ active_connection_removed (NMManager *self, NMActiveConnection *ac) recheck_pending_activations (self); } +static void +checkpoint_added (NMManager *manager, NMCheckpoint *checkpoint) +{ + CheckpointInfo *info; + + info = find_checkpoint_info (manager, nm_object_get_path (NM_OBJECT (checkpoint))); + if (info) + checkpoint_info_complete (manager, info, checkpoint, NULL); +} + +static void +checkpoint_removed (NMManager *manager, NMCheckpoint *checkpoint) +{ +} + gboolean nm_manager_deactivate_connection (NMManager *manager, NMActiveConnection *active, @@ -1208,6 +1294,226 @@ free_active_connections (NMManager *manager) /*****************************************************************************/ +static const char ** +get_device_paths (const GPtrArray *devices) +{ + const char **array; + guint i; + + array = g_new (const char *, devices->len + 1); + for (i = 0; i < devices->len; i++) + array[i] = nm_object_get_path (NM_OBJECT (devices->pdata[i])); + + array[i] = NULL; + + return array; +} + +const GPtrArray * +nm_manager_get_checkpoints (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + + return NM_MANAGER_GET_PRIVATE (manager)->checkpoints; +} + +static void +checkpoint_created_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + CheckpointInfo *info = user_data; + GError *error = NULL; + + nmdbus_manager_call_checkpoint_create_finish (NMDBUS_MANAGER (object), + &info->path, result, &error); + if (error) { + g_dbus_error_strip_remote_error (error); + checkpoint_info_complete (info->manager, info, NULL, error); + g_clear_error (&error); + } +} + +void +nm_manager_checkpoint_create_async (NMManager *manager, + const GPtrArray *devices, + guint32 rollback_timeout, + NMCheckpointCreateFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + gs_free const char **paths = NULL; + CheckpointInfo *info; + + g_return_if_fail (NM_IS_MANAGER (manager)); + + info = g_slice_new0 (CheckpointInfo); + info->manager = manager; + info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, + nm_manager_checkpoint_create_async); + paths = get_device_paths (devices); + nmdbus_manager_call_checkpoint_create (NM_MANAGER_GET_PRIVATE (manager)->proxy, + paths, + rollback_timeout, + flags, + cancellable, + checkpoint_created_cb, + info); + priv->added_checkpoints = g_slist_append (priv->added_checkpoints, info); +} + +NMCheckpoint * +nm_manager_checkpoint_create_finish (NMManager *manager, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +static void +checkpoint_destroy_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_manager_call_checkpoint_destroy_finish (NMDBUS_MANAGER (object), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +void +nm_manager_checkpoint_destroy_async (NMManager *manager, + NMCheckpoint *checkpoint, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + const char *path; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_MANAGER (manager)); + g_return_if_fail (NM_IS_CHECKPOINT (checkpoint)); + + simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, + nm_manager_checkpoint_destroy_async); + + path = nm_object_get_path (NM_OBJECT (checkpoint)); + nmdbus_manager_call_checkpoint_destroy (NM_MANAGER_GET_PRIVATE (manager)->proxy, + path, + cancellable, + checkpoint_destroy_cb, simple); +} + +gboolean +nm_manager_checkpoint_destroy_finish (NMManager *manager, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), + nm_manager_checkpoint_destroy_async), + FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +static void +checkpoint_rollback_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + GVariant *variant = NULL; + GVariantIter iter; + GHashTable *hash; + const char *path; + guint r; + + if (nmdbus_manager_call_checkpoint_rollback_finish (NMDBUS_MANAGER (object), + &variant, + result, + &error)) { + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_variant_iter_init (&iter, variant); + while (g_variant_iter_next (&iter, "{&su}", &path, &r)) + g_hash_table_insert (hash, g_strdup (path), GUINT_TO_POINTER (r)); + g_simple_async_result_set_op_res_gpointer (simple, hash, (GDestroyNotify) g_hash_table_unref); + } else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +void +nm_manager_checkpoint_rollback_async (NMManager *manager, + NMCheckpoint *checkpoint, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + const char *path; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_MANAGER (manager)); + g_return_if_fail (NM_IS_CHECKPOINT (checkpoint)); + + simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, + nm_manager_checkpoint_rollback_async); + + path = nm_object_get_path (NM_OBJECT (checkpoint)); + nmdbus_manager_call_checkpoint_rollback (NM_MANAGER_GET_PRIVATE (manager)->proxy, + path, + cancellable, + checkpoint_rollback_cb, simple); +} + +GHashTable * +nm_manager_checkpoint_rollback_finish (NMManager *manager, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), + nm_manager_checkpoint_rollback_async), + NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_simple_async_result_get_op_res_gpointer (simple); +} + +/*****************************************************************************/ + static void constructed (GObject *object) { @@ -1472,6 +1778,9 @@ get_property (GObject *object, case PROP_DEVICES: g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_devices (self))); break; + case PROP_CHECKPOINTS: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_checkpoints (self))); + break; case PROP_METERED: g_value_set_uint (value, priv->metered); break; @@ -1500,11 +1809,14 @@ nm_manager_class_init (NMManagerClass *manager_class) object_class->finalize = finalize; nm_object_class->init_dbus = init_dbus; + nm_object_class->object_creation_failed = object_creation_failed; manager_class->device_added = device_added; manager_class->device_removed = device_removed; manager_class->active_connection_added = active_connection_added; manager_class->active_connection_removed = active_connection_removed; + manager_class->checkpoint_added = checkpoint_added; + manager_class->checkpoint_removed = checkpoint_removed; /* properties */ @@ -1612,6 +1924,12 @@ nm_manager_class_init (NMManagerClass *manager_class) G_TYPE_PTR_ARRAY, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_CHECKPOINTS, + g_param_spec_boxed (NM_MANAGER_CHECKPOINTS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMManager:metered: * @@ -1683,6 +2001,23 @@ nm_manager_class_init (NMManagerClass *manager_class) NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); + signals[CHECKPOINT_ADDED] = + g_signal_new ("checkpoint-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, checkpoint_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + signals[CHECKPOINT_REMOVED] = + g_signal_new ("checkpoint-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, checkpoint_removed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + signals[PERMISSION_CHANGED] = g_signal_new ("permission-changed", G_OBJECT_CLASS_TYPE (object_class), diff --git a/libnm/nm-manager.h b/libnm/nm-manager.h index 209a99a00c..852a088972 100644 --- a/libnm/nm-manager.h +++ b/libnm/nm-manager.h @@ -51,6 +51,7 @@ G_BEGIN_DECLS #define NM_MANAGER_PRIMARY_CONNECTION "primary-connection" #define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection" #define NM_MANAGER_DEVICES "devices" +#define NM_MANAGER_CHECKPOINTS "checkpoints" #define NM_MANAGER_METERED "metered" #define NM_MANAGER_ALL_DEVICES "all-devices" @@ -69,6 +70,8 @@ typedef struct { void (*device_removed) (NMManager *manager, NMDevice *device); void (*active_connection_added) (NMManager *manager, NMActiveConnection *ac); void (*active_connection_removed) (NMManager *manager, NMActiveConnection *ac); + void (*checkpoint_added) (NMManager *manager, NMCheckpoint *checkpoint); + void (*checkpoint_removed) (NMManager *manager, NMCheckpoint *checkpoint); void (*permission_changed) (NMManager *manager, NMClientPermission permission, NMClientPermissionResult result); @@ -184,6 +187,34 @@ gboolean nm_manager_deactivate_connection_finish (NMManager *manager, GAsyncResult *result, GError **error); +const GPtrArray *nm_manager_get_checkpoints (NMManager *manager); +void nm_manager_checkpoint_create_async (NMManager *manager, + const GPtrArray *devices, + guint32 rollback_timeout, + NMCheckpointCreateFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMCheckpoint *nm_manager_checkpoint_create_finish (NMManager *manager, + GAsyncResult *result, + GError **error); +void nm_manager_checkpoint_destroy_async (NMManager *manager, + NMCheckpoint *checkpoint, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_manager_checkpoint_destroy_finish (NMManager *manager, + GAsyncResult *result, + GError **error); +void nm_manager_checkpoint_rollback_async (NMManager *manager, + NMCheckpoint *checkpoint, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GHashTable *nm_manager_checkpoint_rollback_finish (NMManager *manager, + GAsyncResult *result, + GError **error); + G_END_DECLS #endif /* __NM_MANAGER_H__ */ diff --git a/libnm/nm-types.h b/libnm/nm-types.h index 4310120fec..dff8cb901f 100644 --- a/libnm/nm-types.h +++ b/libnm/nm-types.h @@ -28,6 +28,7 @@ typedef struct _NMAccessPoint NMAccessPoint; typedef struct _NMActiveConnection NMActiveConnection; +typedef struct _NMCheckpoint NMCheckpoint; typedef struct _NMClient NMClient; typedef struct _NMDevice NMDevice; typedef struct _NMDeviceAdsl NMDeviceAdsl; diff --git a/po/ar.po b/po/ar.po index d281fff00f..7dcc7bbe69 100644 --- a/po/ar.po +++ b/po/ar.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-10 15:29+0100\n" +"POT-Creation-Date: 2017-05-29 17:44+0200\n" "PO-Revision-Date: 2017-04-21 05:04-0400\n" "Last-Translator: Copied by Zanata \n" "Language-Team: Arabic \n" @@ -87,88 +87,459 @@ msgstr "" msgid "nmcli successfully registered as a polkit agent.\n" msgstr "" -#: ../clients/cli/common.c:263 ../clients/cli/common.c:278 +#: ../clients/cli/common.c:149 msgid "GROUP" msgstr "" -#: ../clients/cli/common.c:561 +#: ../clients/cli/common.c:381 +msgid "unmanaged" +msgstr "" + +#: ../clients/cli/common.c:383 +msgid "unavailable" +msgstr "" + +#: ../clients/cli/common.c:385 ../clients/cli/general.c:48 +msgid "disconnected" +msgstr "" + +#: ../clients/cli/common.c:387 +msgid "connecting (prepare)" +msgstr "" + +#: ../clients/cli/common.c:389 +msgid "connecting (configuring)" +msgstr "" + +#: ../clients/cli/common.c:391 +msgid "connecting (need authentication)" +msgstr "" + +#: ../clients/cli/common.c:393 +msgid "connecting (getting IP configuration)" +msgstr "" + +#: ../clients/cli/common.c:395 +msgid "connecting (checking IP connectivity)" +msgstr "" + +#: ../clients/cli/common.c:397 +msgid "connecting (starting secondary connections)" +msgstr "" + +#: ../clients/cli/common.c:399 ../clients/cli/general.c:46 +msgid "connected" +msgstr "" + +#: ../clients/cli/common.c:401 ../clients/cli/connections.c:528 +msgid "deactivating" +msgstr "" + +#: ../clients/cli/common.c:403 +msgid "connection failed" +msgstr "" + +#: ../clients/cli/common.c:405 ../clients/cli/common.c:422 +#: ../clients/cli/connections.c:533 ../clients/cli/connections.c:556 +#: ../clients/cli/devices.c:1153 ../clients/cli/devices.c:1197 +#: ../clients/cli/devices.c:1199 ../clients/cli/general.c:41 +#: ../clients/cli/general.c:79 ../clients/cli/general.c:144 +#: ../clients/cli/general.c:149 ../clients/common/nm-meta-setting-desc.c:1368 +#: ../clients/common/nm-meta-setting-desc.c:1436 +#: ../clients/common/nm-meta-setting-desc.c:2593 +#: ../clients/common/nm-meta-setting-desc.c:2647 +msgid "unknown" +msgstr "" + +#. "CAPABILITIES" +#: ../clients/cli/common.c:414 ../clients/cli/connections.c:876 +#: ../clients/cli/connections.c:878 ../clients/cli/connections.c:880 +#: ../clients/cli/connections.c:913 ../clients/cli/connections.c:980 +#: ../clients/cli/connections.c:981 ../clients/cli/connections.c:983 +#: ../clients/cli/connections.c:4496 ../clients/cli/connections.c:6375 +#: ../clients/cli/connections.c:6376 ../clients/cli/devices.c:827 +#: ../clients/cli/devices.c:1116 ../clients/cli/devices.c:1117 +#: ../clients/cli/devices.c:1118 ../clients/cli/devices.c:1119 +#: ../clients/cli/devices.c:1120 ../clients/cli/devices.c:1157 +#: ../clients/cli/devices.c:1159 ../clients/cli/devices.c:1160 +#: ../clients/cli/devices.c:1190 ../clients/cli/devices.c:1191 +#: ../clients/cli/devices.c:1192 ../clients/cli/devices.c:1193 +#: ../clients/cli/devices.c:1194 ../clients/cli/devices.c:1195 +#: ../clients/cli/devices.c:1196 ../clients/cli/devices.c:1198 +#: ../clients/cli/devices.c:1200 ../clients/cli/general.c:150 +#: ../clients/common/nm-meta-setting-desc.c:574 +#: ../clients/common/nm-meta-setting-desc.c:2586 +msgid "yes" +msgstr "" + +#: ../clients/cli/common.c:416 ../clients/cli/connections.c:876 +#: ../clients/cli/connections.c:878 ../clients/cli/connections.c:880 +#: ../clients/cli/connections.c:980 ../clients/cli/connections.c:981 +#: ../clients/cli/connections.c:983 ../clients/cli/connections.c:4495 +#: ../clients/cli/connections.c:6375 ../clients/cli/connections.c:6376 +#: ../clients/cli/devices.c:827 ../clients/cli/devices.c:1116 +#: ../clients/cli/devices.c:1117 ../clients/cli/devices.c:1118 +#: ../clients/cli/devices.c:1119 ../clients/cli/devices.c:1120 +#: ../clients/cli/devices.c:1157 ../clients/cli/devices.c:1159 +#: ../clients/cli/devices.c:1160 ../clients/cli/devices.c:1190 +#: ../clients/cli/devices.c:1191 ../clients/cli/devices.c:1192 +#: ../clients/cli/devices.c:1193 ../clients/cli/devices.c:1194 +#: ../clients/cli/devices.c:1195 ../clients/cli/devices.c:1196 +#: ../clients/cli/devices.c:1198 ../clients/cli/devices.c:1200 +#: ../clients/cli/general.c:151 ../clients/common/nm-meta-setting-desc.c:574 +#: ../clients/common/nm-meta-setting-desc.c:2589 +#, fuzzy +msgid "no" +msgstr "بلا" + +#: ../clients/cli/common.c:418 +msgid "yes (guessed)" +msgstr "" + +#: ../clients/cli/common.c:420 +msgid "no (guessed)" +msgstr "" + +#: ../clients/cli/common.c:431 +msgid "No reason given" +msgstr "" + +#. We should not really come here +#: ../clients/cli/common.c:434 ../clients/cli/connections.c:3095 +#: ../clients/cli/connections.c:3155 +#, c-format +msgid "Unknown error" +msgstr "" + +#: ../clients/cli/common.c:437 +msgid "Device is now managed" +msgstr "" + +#: ../clients/cli/common.c:440 +msgid "Device is now unmanaged" +msgstr "" + +#: ../clients/cli/common.c:443 +msgid "The device could not be readied for configuration" +msgstr "" + +#: ../clients/cli/common.c:446 +msgid "" +"IP configuration could not be reserved (no available address, timeout, etc.)" +msgstr "" + +#: ../clients/cli/common.c:449 +msgid "The IP configuration is no longer valid" +msgstr "" + +#: ../clients/cli/common.c:452 +msgid "Secrets were required, but not provided" +msgstr "" + +#: ../clients/cli/common.c:455 +msgid "802.1X supplicant disconnected" +msgstr "" + +#: ../clients/cli/common.c:458 +msgid "802.1X supplicant configuration failed" +msgstr "" + +#: ../clients/cli/common.c:461 +msgid "802.1X supplicant failed" +msgstr "" + +#: ../clients/cli/common.c:464 +msgid "802.1X supplicant took too long to authenticate" +msgstr "" + +#: ../clients/cli/common.c:467 +msgid "PPP service failed to start" +msgstr "" + +#: ../clients/cli/common.c:470 +msgid "PPP service disconnected" +msgstr "" + +#: ../clients/cli/common.c:473 +msgid "PPP failed" +msgstr "" + +#: ../clients/cli/common.c:476 +msgid "DHCP client failed to start" +msgstr "" + +#: ../clients/cli/common.c:479 +msgid "DHCP client error" +msgstr "" + +#: ../clients/cli/common.c:482 +msgid "DHCP client failed" +msgstr "" + +#: ../clients/cli/common.c:485 +msgid "Shared connection service failed to start" +msgstr "" + +#: ../clients/cli/common.c:488 +msgid "Shared connection service failed" +msgstr "" + +#: ../clients/cli/common.c:491 +msgid "AutoIP service failed to start" +msgstr "" + +#: ../clients/cli/common.c:494 +msgid "AutoIP service error" +msgstr "" + +#: ../clients/cli/common.c:497 +msgid "AutoIP service failed" +msgstr "" + +#: ../clients/cli/common.c:500 +msgid "The line is busy" +msgstr "" + +#: ../clients/cli/common.c:503 +msgid "No dial tone" +msgstr "" + +#: ../clients/cli/common.c:506 +msgid "No carrier could be established" +msgstr "" + +#: ../clients/cli/common.c:509 +msgid "The dialing request timed out" +msgstr "" + +#: ../clients/cli/common.c:512 +msgid "The dialing attempt failed" +msgstr "" + +#: ../clients/cli/common.c:515 +msgid "Modem initialization failed" +msgstr "" + +#: ../clients/cli/common.c:518 +msgid "Failed to select the specified APN" +msgstr "" + +#: ../clients/cli/common.c:521 +msgid "Not searching for networks" +msgstr "" + +#: ../clients/cli/common.c:524 +msgid "Network registration denied" +msgstr "" + +#: ../clients/cli/common.c:527 +msgid "Network registration timed out" +msgstr "" + +#: ../clients/cli/common.c:530 +msgid "Failed to register with the requested network" +msgstr "" + +#: ../clients/cli/common.c:533 +msgid "PIN check failed" +msgstr "" + +#: ../clients/cli/common.c:536 +msgid "Necessary firmware for the device may be missing" +msgstr "" + +#: ../clients/cli/common.c:539 +msgid "The device was removed" +msgstr "" + +#: ../clients/cli/common.c:542 +msgid "NetworkManager went to sleep" +msgstr "" + +#: ../clients/cli/common.c:545 +msgid "The device's active connection disappeared" +msgstr "" + +#: ../clients/cli/common.c:548 +msgid "Device disconnected by user or client" +msgstr "" + +#: ../clients/cli/common.c:551 +msgid "Carrier/link changed" +msgstr "" + +#: ../clients/cli/common.c:554 +msgid "The device's existing connection was assumed" +msgstr "" + +#: ../clients/cli/common.c:557 +msgid "The supplicant is now available" +msgstr "" + +#: ../clients/cli/common.c:560 +msgid "The modem could not be found" +msgstr "" + +#: ../clients/cli/common.c:563 +msgid "The Bluetooth connection failed or timed out" +msgstr "" + +#: ../clients/cli/common.c:566 +msgid "GSM Modem's SIM card not inserted" +msgstr "" + +#: ../clients/cli/common.c:569 +msgid "GSM Modem's SIM PIN required" +msgstr "" + +#: ../clients/cli/common.c:572 +msgid "GSM Modem's SIM PUK required" +msgstr "" + +#: ../clients/cli/common.c:575 +msgid "GSM Modem's SIM wrong" +msgstr "" + +#: ../clients/cli/common.c:578 +msgid "InfiniBand device does not support connected mode" +msgstr "" + +#: ../clients/cli/common.c:581 +msgid "A dependency of the connection failed" +msgstr "" + +#: ../clients/cli/common.c:584 +msgid "A problem with the RFC 2684 Ethernet over ADSL bridge" +msgstr "" + +#: ../clients/cli/common.c:587 +msgid "ModemManager is unavailable" +msgstr "" + +#: ../clients/cli/common.c:590 +msgid "The Wi-Fi network could not be found" +msgstr "" + +#: ../clients/cli/common.c:593 +msgid "A secondary connection of the base connection failed" +msgstr "" + +#: ../clients/cli/common.c:596 +msgid "DCB or FCoE setup failed" +msgstr "" + +#: ../clients/cli/common.c:599 +msgid "teamd control failed" +msgstr "" + +#: ../clients/cli/common.c:602 +msgid "Modem failed or no longer available" +msgstr "" + +#: ../clients/cli/common.c:605 +msgid "Modem now ready and available" +msgstr "" + +#: ../clients/cli/common.c:608 +msgid "SIM PIN was incorrect" +msgstr "" + +#: ../clients/cli/common.c:611 +msgid "New connection activation was enqueued" +msgstr "" + +#: ../clients/cli/common.c:614 +msgid "The device's parent changed" +msgstr "" + +#: ../clients/cli/common.c:617 +msgid "The device parent's management changed" +msgstr "" + +#. TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) +#: ../clients/cli/common.c:621 ../libnm-glib/nm-device.c:1860 +#: ../libnm/nm-device.c:1560 +msgid "Unknown" +msgstr "" + +#: ../clients/cli/common.c:737 #, c-format msgid "Error: openconnect failed: %s\n" msgstr "" -#: ../clients/cli/common.c:568 +#: ../clients/cli/common.c:744 #, c-format msgid "Error: openconnect failed with status %d\n" msgstr "" -#: ../clients/cli/common.c:570 +#: ../clients/cli/common.c:746 #, c-format msgid "Error: openconnect failed with signal %d\n" msgstr "" -#: ../clients/cli/common.c:651 +#: ../clients/cli/common.c:827 #, c-format msgid "" "Warning: password for '%s' not given in 'passwd-file' and nmcli cannot ask " "without '--ask' option.\n" msgstr "" -#: ../clients/cli/common.c:1117 +#: ../clients/cli/common.c:1291 #, c-format msgid "Error: Could not create NMClient object: %s." msgstr "" -#: ../clients/cli/common.c:1137 +#: ../clients/cli/common.c:1311 msgid "Error: NetworkManager is not running." msgstr "" -#: ../clients/cli/common.c:1234 +#: ../clients/cli/common.c:1408 #, c-format msgid "Error: argument '%s' not understood. Try passing --help instead." msgstr "" -#: ../clients/cli/common.c:1244 +#: ../clients/cli/common.c:1418 msgid "Error: missing argument. Try passing --help." msgstr "" -#: ../clients/cli/common.c:1297 +#: ../clients/cli/common.c:1471 msgid "access denied" msgstr "" #. define some prompts for connection editor -#: ../clients/cli/connections.c:66 +#: ../clients/cli/connections.c:64 msgid "Setting name? " msgstr "" -#: ../clients/cli/connections.c:67 +#: ../clients/cli/connections.c:65 msgid "Property name? " msgstr "" -#: ../clients/cli/connections.c:68 +#: ../clients/cli/connections.c:66 msgid "Enter connection type: " msgstr "" #. define some other prompts -#: ../clients/cli/connections.c:72 +#: ../clients/cli/connections.c:70 #, fuzzy msgid "Connection (name, UUID, or path)" msgstr "إتّصالات VPN" -#: ../clients/cli/connections.c:73 +#: ../clients/cli/connections.c:71 #, fuzzy msgid "VPN connection (name, UUID, or path)" msgstr "إتّصالات VPN" -#: ../clients/cli/connections.c:74 +#: ../clients/cli/connections.c:72 #, fuzzy msgid "Connection(s) (name, UUID, or path)" msgstr "إتّصالات VPN" -#: ../clients/cli/connections.c:75 +#: ../clients/cli/connections.c:73 msgid "Connection(s) (name, UUID, path or apath)" msgstr "" -#: ../clients/cli/connections.c:196 +#: ../clients/cli/connections.c:190 #, c-format msgid "" "Usage: nmcli connection { COMMAND | help }\n" @@ -209,7 +580,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:218 +#: ../clients/cli/connections.c:212 #, c-format msgid "" "Usage: nmcli connection show { ARGUMENTS | help }\n" @@ -236,7 +607,7 @@ msgid "" "well.\n" msgstr "" -#: ../clients/cli/connections.c:239 +#: ../clients/cli/connections.c:233 #, c-format msgid "" "Usage: nmcli connection up { ARGUMENTS | help }\n" @@ -261,7 +632,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:260 +#: ../clients/cli/connections.c:254 #, c-format msgid "" "Usage: nmcli connection down { ARGUMENTS | help }\n" @@ -275,7 +646,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:272 +#: ../clients/cli/connections.c:266 #, c-format msgid "" "Usage: nmcli connection add { ARGUMENTS | help }\n" @@ -326,7 +697,7 @@ msgid "" " [p-key ]\n" "\n" " bluetooth: [addr ]\n" -" [bt-type panu|nap|dun-gsm|dun-cdma]\n" +" [bt-type panu|dun-gsm|dun-cdma]\n" "\n" " vlan: dev \n" " id \n" @@ -427,7 +798,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:390 +#: ../clients/cli/connections.c:384 #, c-format msgid "" "Usage: nmcli connection modify { ARGUMENTS | help }\n" @@ -452,7 +823,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:413 +#: ../clients/cli/connections.c:407 #, c-format msgid "" "Usage: nmcli connection clone { ARGUMENTS | help }\n" @@ -466,7 +837,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:425 +#: ../clients/cli/connections.c:419 #, c-format msgid "" "Usage: nmcli connection edit { ARGUMENTS | help }\n" @@ -482,7 +853,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:440 +#: ../clients/cli/connections.c:434 #, c-format msgid "" "Usage: nmcli connection delete { ARGUMENTS | help }\n" @@ -494,7 +865,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:451 +#: ../clients/cli/connections.c:445 #, c-format msgid "" "Usage: nmcli connection monitor { ARGUMENTS | help }\n" @@ -507,7 +878,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:463 +#: ../clients/cli/connections.c:457 #, c-format msgid "" "Usage: nmcli connection reload { help }\n" @@ -516,7 +887,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:471 +#: ../clients/cli/connections.c:465 #, c-format msgid "" "Usage: nmcli connection load { ARGUMENTS | help }\n" @@ -530,7 +901,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:483 +#: ../clients/cli/connections.c:477 #, c-format msgid "" "Usage: nmcli connection import { ARGUMENTS | help }\n" @@ -545,7 +916,7 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:496 +#: ../clients/cli/connections.c:490 #, c-format msgid "" "Usage: nmcli connection export { ARGUMENTS | help }\n" @@ -557,467 +928,457 @@ msgid "" "\n" msgstr "" -#: ../clients/cli/connections.c:530 +#: ../clients/cli/connections.c:524 msgid "activating" msgstr "" -#: ../clients/cli/connections.c:532 +#: ../clients/cli/connections.c:526 msgid "activated" msgstr "" -#: ../clients/cli/connections.c:534 ../clients/common/nm-client-utils.c:243 -msgid "deactivating" -msgstr "" - -#: ../clients/cli/connections.c:536 +#: ../clients/cli/connections.c:530 msgid "deactivated" msgstr "" -#: ../clients/cli/connections.c:539 ../clients/cli/connections.c:562 -#: ../clients/cli/devices.c:1210 ../clients/cli/devices.c:1254 -#: ../clients/cli/devices.c:1256 ../clients/cli/general.c:41 -#: ../clients/cli/general.c:79 ../clients/cli/general.c:146 -#: ../clients/cli/general.c:151 ../clients/common/nm-client-utils.c:247 -#: ../clients/common/nm-client-utils.c:250 -#: ../clients/common/nm-client-utils.c:266 -#: ../clients/common/nm-client-utils.c:269 -#: ../clients/common/nm-meta-setting-desc.c:1335 -#: ../clients/common/nm-meta-setting-desc.c:1403 -#: ../clients/common/nm-meta-setting-desc.c:2545 -#: ../clients/common/nm-meta-setting-desc.c:2599 -msgid "unknown" -msgstr "" - -#: ../clients/cli/connections.c:548 +#: ../clients/cli/connections.c:542 #, fuzzy msgid "VPN connecting (prepare)" msgstr "إتّصالات VPN" -#: ../clients/cli/connections.c:550 +#: ../clients/cli/connections.c:544 msgid "VPN connecting (need authentication)" msgstr "" -#: ../clients/cli/connections.c:552 +#: ../clients/cli/connections.c:546 #, fuzzy msgid "VPN connecting" msgstr "إتّصالات VPN" -#: ../clients/cli/connections.c:554 +#: ../clients/cli/connections.c:548 msgid "VPN connecting (getting IP configuration)" msgstr "" -#: ../clients/cli/connections.c:556 +#: ../clients/cli/connections.c:550 #, fuzzy msgid "VPN connected" msgstr "إتّصالات VPN" -#: ../clients/cli/connections.c:558 +#: ../clients/cli/connections.c:552 #, fuzzy msgid "VPN connection failed" msgstr "إتّصالات VPN" -#: ../clients/cli/connections.c:560 +#: ../clients/cli/connections.c:554 #, fuzzy msgid "VPN disconnected" msgstr "إتّصالات VPN" -#: ../clients/cli/connections.c:630 +#: ../clients/cli/connections.c:624 #, c-format msgid "Error updating secrets for %s: %s\n" msgstr "" -#: ../clients/cli/connections.c:650 +#: ../clients/cli/connections.c:644 msgid "Connection profile details" msgstr "" -#: ../clients/cli/connections.c:663 ../clients/cli/connections.c:1113 +#: ../clients/cli/connections.c:657 ../clients/cli/connections.c:1107 #, fuzzy, c-format msgid "Error: 'connection show': %s" msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:881 +#: ../clients/cli/connections.c:875 msgid "never" msgstr "" -#. "CAPABILITIES" -#: ../clients/cli/connections.c:882 ../clients/cli/connections.c:884 -#: ../clients/cli/connections.c:886 ../clients/cli/connections.c:919 -#: ../clients/cli/connections.c:986 ../clients/cli/connections.c:987 -#: ../clients/cli/connections.c:989 ../clients/cli/connections.c:4432 -#: ../clients/cli/connections.c:6370 ../clients/cli/connections.c:6371 -#: ../clients/cli/devices.c:884 ../clients/cli/devices.c:1173 -#: ../clients/cli/devices.c:1174 ../clients/cli/devices.c:1175 -#: ../clients/cli/devices.c:1176 ../clients/cli/devices.c:1177 -#: ../clients/cli/devices.c:1214 ../clients/cli/devices.c:1216 -#: ../clients/cli/devices.c:1217 ../clients/cli/devices.c:1247 -#: ../clients/cli/devices.c:1248 ../clients/cli/devices.c:1249 -#: ../clients/cli/devices.c:1250 ../clients/cli/devices.c:1251 -#: ../clients/cli/devices.c:1252 ../clients/cli/devices.c:1253 -#: ../clients/cli/devices.c:1255 ../clients/cli/devices.c:1257 -#: ../clients/cli/general.c:152 ../clients/common/nm-client-utils.c:258 -#: ../clients/common/nm-meta-setting-desc.c:575 -#: ../clients/common/nm-meta-setting-desc.c:2538 -msgid "yes" -msgstr "" - -#: ../clients/cli/connections.c:882 ../clients/cli/connections.c:884 -#: ../clients/cli/connections.c:886 ../clients/cli/connections.c:986 -#: ../clients/cli/connections.c:987 ../clients/cli/connections.c:989 -#: ../clients/cli/connections.c:4431 ../clients/cli/connections.c:6370 -#: ../clients/cli/connections.c:6371 ../clients/cli/devices.c:884 -#: ../clients/cli/devices.c:1173 ../clients/cli/devices.c:1174 -#: ../clients/cli/devices.c:1175 ../clients/cli/devices.c:1176 -#: ../clients/cli/devices.c:1177 ../clients/cli/devices.c:1214 -#: ../clients/cli/devices.c:1216 ../clients/cli/devices.c:1217 -#: ../clients/cli/devices.c:1247 ../clients/cli/devices.c:1248 -#: ../clients/cli/devices.c:1249 ../clients/cli/devices.c:1250 -#: ../clients/cli/devices.c:1251 ../clients/cli/devices.c:1252 -#: ../clients/cli/devices.c:1253 ../clients/cli/devices.c:1255 -#: ../clients/cli/devices.c:1257 ../clients/cli/general.c:153 -#: ../clients/common/nm-client-utils.c:260 -#: ../clients/common/nm-meta-setting-desc.c:575 -#: ../clients/common/nm-meta-setting-desc.c:2541 -#, fuzzy -msgid "no" -msgstr "بلا" - -#: ../clients/cli/connections.c:1103 +#: ../clients/cli/connections.c:1097 msgid "Activate connection details" msgstr "" -#: ../clients/cli/connections.c:1350 +#: ../clients/cli/connections.c:1344 #, c-format msgid "invalid field '%s'; allowed fields: %s and %s, or %s,%s" msgstr "" -#: ../clients/cli/connections.c:1365 ../clients/cli/connections.c:1373 +#: ../clients/cli/connections.c:1359 ../clients/cli/connections.c:1367 #, c-format msgid "'%s' has to be alone" msgstr "" -#: ../clients/cli/connections.c:1573 +#: ../clients/cli/connections.c:1567 #, c-format msgid "incorrect string '%s' of '--order' option" msgstr "" -#: ../clients/cli/connections.c:1599 +#: ../clients/cli/connections.c:1593 #, c-format msgid "incorrect item '%s' in '--order' option" msgstr "" -#: ../clients/cli/connections.c:1629 +#: ../clients/cli/connections.c:1623 #, fuzzy msgid "No connection specified" msgstr "إتّصالات VPN" -#: ../clients/cli/connections.c:1644 +#: ../clients/cli/connections.c:1638 #, c-format msgid "%s argument is missing" msgstr "" -#: ../clients/cli/connections.c:1654 +#: ../clients/cli/connections.c:1648 #, fuzzy, c-format msgid "unknown connection '%s'" msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:1687 +#: ../clients/cli/connections.c:1681 msgid "'--order' argument is missing" msgstr "" -#: ../clients/cli/connections.c:1742 +#: ../clients/cli/connections.c:1736 msgid "NetworkManager active profiles" msgstr "" -#: ../clients/cli/connections.c:1743 +#: ../clients/cli/connections.c:1737 msgid "NetworkManager connection profiles" msgstr "" -#: ../clients/cli/connections.c:1796 ../clients/cli/connections.c:2471 -#: ../clients/cli/connections.c:2483 ../clients/cli/connections.c:2495 -#: ../clients/cli/connections.c:2671 ../clients/cli/connections.c:8431 -#: ../clients/cli/connections.c:8448 ../clients/cli/devices.c:2681 -#: ../clients/cli/devices.c:2692 ../clients/cli/devices.c:2934 +#: ../clients/cli/connections.c:1790 ../clients/cli/connections.c:2558 +#: ../clients/cli/connections.c:2570 ../clients/cli/connections.c:2582 +#: ../clients/cli/connections.c:2758 ../clients/cli/connections.c:8446 +#: ../clients/cli/connections.c:8463 ../clients/cli/devices.c:2624 +#: ../clients/cli/devices.c:2634 ../clients/cli/devices.c:2876 +#: ../clients/cli/devices.c:2886 ../clients/cli/devices.c:2904 +#: ../clients/cli/devices.c:2913 ../clients/cli/devices.c:2934 #: ../clients/cli/devices.c:2945 ../clients/cli/devices.c:2963 -#: ../clients/cli/devices.c:2972 ../clients/cli/devices.c:2993 -#: ../clients/cli/devices.c:3004 ../clients/cli/devices.c:3022 -#: ../clients/cli/devices.c:3400 ../clients/cli/devices.c:3410 -#: ../clients/cli/devices.c:3418 ../clients/cli/devices.c:3430 -#: ../clients/cli/devices.c:3445 ../clients/cli/devices.c:3453 -#: ../clients/cli/devices.c:3627 ../clients/cli/devices.c:3638 -#: ../clients/cli/devices.c:3810 +#: ../clients/cli/devices.c:3341 ../clients/cli/devices.c:3351 +#: ../clients/cli/devices.c:3359 ../clients/cli/devices.c:3371 +#: ../clients/cli/devices.c:3386 ../clients/cli/devices.c:3394 +#: ../clients/cli/devices.c:3568 ../clients/cli/devices.c:3579 +#: ../clients/cli/devices.c:3751 #, c-format msgid "Error: %s argument is missing." msgstr "" -#: ../clients/cli/connections.c:1815 +#: ../clients/cli/connections.c:1809 #, c-format msgid "Error: %s - no such connection profile." msgstr "" -#: ../clients/cli/connections.c:1879 ../clients/cli/connections.c:2458 -#: ../clients/cli/connections.c:2522 ../clients/cli/connections.c:7941 -#: ../clients/cli/connections.c:8052 ../clients/cli/connections.c:8562 -#: ../clients/cli/devices.c:1582 ../clients/cli/devices.c:1868 -#: ../clients/cli/devices.c:2037 ../clients/cli/devices.c:2145 -#: ../clients/cli/devices.c:2334 ../clients/cli/devices.c:3590 -#: ../clients/cli/devices.c:3816 ../clients/cli/general.c:928 +#: ../clients/cli/connections.c:1873 ../clients/cli/connections.c:2545 +#: ../clients/cli/connections.c:2609 ../clients/cli/connections.c:7956 +#: ../clients/cli/connections.c:8067 ../clients/cli/connections.c:8577 +#: ../clients/cli/devices.c:1525 ../clients/cli/devices.c:1811 +#: ../clients/cli/devices.c:1980 ../clients/cli/devices.c:2088 +#: ../clients/cli/devices.c:2277 ../clients/cli/devices.c:3531 +#: ../clients/cli/devices.c:3757 ../clients/cli/general.c:926 #, c-format msgid "Error: %s." msgstr "" -#: ../clients/cli/connections.c:1977 +#: ../clients/cli/connections.c:1971 #, c-format msgid "no active connection on device '%s'" msgstr "" -#: ../clients/cli/connections.c:1985 +#: ../clients/cli/connections.c:1979 msgid "no active connection or device" msgstr "" -#: ../clients/cli/connections.c:2005 +#: ../clients/cli/connections.c:1999 #, fuzzy, c-format msgid "device '%s' not compatible with connection '%s':" msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:2041 +#: ../clients/cli/connections.c:2035 #, c-format msgid "device '%s' not compatible with connection '%s'" msgstr "" -#: ../clients/cli/connections.c:2044 +#: ../clients/cli/connections.c:2038 #, fuzzy, c-format msgid "no device found for connection '%s'" msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:2072 -#, c-format -msgid "Connection successfully activated (%s) (D-Bus active path: %s)\n" +#: ../clients/cli/connections.c:2058 +msgid "Unknown reason" msgstr "" -#: ../clients/cli/connections.c:2076 ../clients/cli/connections.c:2224 -#: ../clients/cli/connections.c:6249 +#: ../clients/cli/connections.c:2060 +#, fuzzy +msgid "The connection was disconnected" +msgstr "لا يمكن إضافة اتصال VPN" + +#: ../clients/cli/connections.c:2062 +#, fuzzy +msgid "Disconnected by user" +msgstr "إتّصالات VPN" + +#: ../clients/cli/connections.c:2064 +msgid "The base network connection was interrupted" +msgstr "" + +#: ../clients/cli/connections.c:2066 +msgid "The VPN service stopped unexpectedly" +msgstr "" + +#: ../clients/cli/connections.c:2068 +msgid "The VPN service returned invalid configuration" +msgstr "" + +#: ../clients/cli/connections.c:2070 +#, fuzzy +msgid "The connection attempt timed out" +msgstr "إتّصالات VPN" + +#: ../clients/cli/connections.c:2072 +msgid "The VPN service did not start in time" +msgstr "" + +#: ../clients/cli/connections.c:2074 +msgid "The VPN service failed to start" +msgstr "" + +#: ../clients/cli/connections.c:2076 +msgid "No valid secrets" +msgstr "" + +#: ../clients/cli/connections.c:2078 +msgid "Invalid secrets" +msgstr "" + +#: ../clients/cli/connections.c:2080 +#, fuzzy +msgid "The connection was removed" +msgstr "حذف اتصال VPN \"%s\"؟" + +#: ../clients/cli/connections.c:2082 +#, fuzzy +msgid "Master connection failed" +msgstr "إتّصالات VPN" + +#: ../clients/cli/connections.c:2084 +msgid "Could not create a software link" +msgstr "" + +#: ../clients/cli/connections.c:2086 +msgid "The device disappeared" +msgstr "" + +#: ../clients/cli/connections.c:2089 +msgid "Invalid reason" +msgstr "" + +#: ../clients/cli/connections.c:2115 ../clients/cli/connections.c:2307 +#: ../clients/cli/connections.c:6263 #, c-format msgid "Connection successfully activated (D-Bus active path: %s)\n" msgstr "" -#: ../clients/cli/connections.c:2083 ../clients/cli/connections.c:2204 +#: ../clients/cli/connections.c:2146 ../clients/cli/connections.c:2287 #, c-format msgid "Error: Connection activation failed: %s" msgstr "" -#: ../clients/cli/connections.c:2119 +#: ../clients/cli/connections.c:2173 +#, c-format +msgid "" +"Connection successfully activated (master waiting for slaves) (D-Bus active " +"path: %s)\n" +msgstr "" + +#: ../clients/cli/connections.c:2202 #, c-format msgid "Error: Timeout expired (%d seconds)" msgstr "" -#: ../clients/cli/connections.c:2285 +#: ../clients/cli/connections.c:2368 #, c-format msgid "failed to read passwd-file '%s': %s" msgstr "" -#: ../clients/cli/connections.c:2297 +#: ../clients/cli/connections.c:2380 #, c-format msgid "missing colon in 'password' entry '%s'" msgstr "" -#: ../clients/cli/connections.c:2305 +#: ../clients/cli/connections.c:2388 #, c-format msgid "missing dot in 'password' entry '%s'" msgstr "" -#: ../clients/cli/connections.c:2318 +#: ../clients/cli/connections.c:2401 #, c-format msgid "invalid setting name in 'password' entry '%s'" msgstr "" -#: ../clients/cli/connections.c:2374 +#: ../clients/cli/connections.c:2457 #, c-format msgid "unknown device '%s'." msgstr "" -#: ../clients/cli/connections.c:2379 +#: ../clients/cli/connections.c:2462 msgid "neither a valid connection nor device given" msgstr "" -#: ../clients/cli/connections.c:2505 ../clients/cli/devices.c:1533 -#: ../clients/cli/devices.c:2699 ../clients/cli/devices.c:3035 -#: ../clients/cli/devices.c:3644 +#: ../clients/cli/connections.c:2592 ../clients/cli/devices.c:1476 +#: ../clients/cli/devices.c:2641 ../clients/cli/devices.c:2976 +#: ../clients/cli/devices.c:3585 #, c-format msgid "Unknown parameter: %s\n" msgstr "" -#: ../clients/cli/connections.c:2530 +#: ../clients/cli/connections.c:2617 msgid "preparing" msgstr "" -#: ../clients/cli/connections.c:2550 +#: ../clients/cli/connections.c:2637 #, c-format msgid "Connection '%s' (%s) successfully deleted.\n" msgstr "" -#: ../clients/cli/connections.c:2566 +#: ../clients/cli/connections.c:2653 #, c-format msgid "Connection '%s' successfully deactivated (D-Bus active path: %s)\n" msgstr "" -#: ../clients/cli/connections.c:2647 ../clients/cli/connections.c:8167 -#: ../clients/cli/connections.c:8199 ../clients/cli/connections.c:8356 +#: ../clients/cli/connections.c:2734 ../clients/cli/connections.c:8182 +#: ../clients/cli/connections.c:8214 ../clients/cli/connections.c:8371 #, c-format msgid "Error: No connection specified." msgstr "" -#: ../clients/cli/connections.c:2688 +#: ../clients/cli/connections.c:2775 #, c-format msgid "Error: '%s' is not an active connection.\n" msgstr "" -#: ../clients/cli/connections.c:2689 +#: ../clients/cli/connections.c:2776 #, c-format msgid "Error: not all active connections found." msgstr "" -#: ../clients/cli/connections.c:2698 +#: ../clients/cli/connections.c:2785 #, c-format msgid "Error: no active connection provided." msgstr "" -#: ../clients/cli/connections.c:2732 +#: ../clients/cli/connections.c:2819 #, c-format msgid "Connection '%s' deactivation failed: %s\n" msgstr "" -#: ../clients/cli/connections.c:2988 ../clients/cli/connections.c:3045 -#: ../clients/common/nm-client-utils.c:169 +#: ../clients/cli/connections.c:3075 ../clients/cli/connections.c:3132 +#: ../clients/common/nm-client-utils.c:165 #, c-format msgid "'%s' not among [%s]" msgstr "" -#. We should not really come here -#: ../clients/cli/connections.c:3008 ../clients/cli/connections.c:3068 -#: ../clients/common/nm-client-utils.c:279 -#, c-format -msgid "Unknown error" -msgstr "" - -#: ../clients/cli/connections.c:3202 +#: ../clients/cli/connections.c:3289 #, c-format msgid "Warning: master='%s' doesn't refer to any existing profile.\n" msgstr "" -#: ../clients/cli/connections.c:3539 +#: ../clients/cli/connections.c:3626 #, c-format msgid "Error: invalid property '%s': %s." msgstr "" -#: ../clients/cli/connections.c:3556 +#: ../clients/cli/connections.c:3643 #, c-format msgid "Error: failed to modify %s.%s: %s." msgstr "" -#: ../clients/cli/connections.c:3575 +#: ../clients/cli/connections.c:3662 #, c-format msgid "Error: failed to remove a value from %s.%s: %s." msgstr "" -#: ../clients/cli/connections.c:3609 +#: ../clients/cli/connections.c:3696 #, c-format msgid "Error: '%s' is mandatory." msgstr "" -#: ../clients/cli/connections.c:3636 +#: ../clients/cli/connections.c:3723 #, fuzzy, c-format msgid "Error: invalid slave type; %s." msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:3644 +#: ../clients/cli/connections.c:3733 #, fuzzy, c-format msgid "Error: invalid connection type; %s." msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:3721 +#: ../clients/cli/connections.c:3810 #, fuzzy, c-format msgid "Error: bad connection type: %s" msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:3767 +#: ../clients/cli/connections.c:3856 #, fuzzy, c-format msgid "Error: '%s': %s" msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:3788 +#: ../clients/cli/connections.c:3877 msgid "Error: master is required" msgstr "" -#: ../clients/cli/connections.c:3847 +#: ../clients/cli/connections.c:3936 #, fuzzy, c-format msgid "Error: error adding bond option '%s=%s'." msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:3878 +#: ../clients/cli/connections.c:3967 #, c-format msgid "Error: '%s' is not a valid monitoring mode; use '%s' or '%s'.\n" msgstr "" -#: ../clients/cli/connections.c:3909 +#: ../clients/cli/connections.c:3998 #, c-format -msgid "Error: 'bt-type': '%s' not valid; use [%s, %s, %s (%s), %s]." +msgid "Error: 'bt-type': '%s' not valid; use [%s, %s (%s), %s]." msgstr "" -#: ../clients/cli/connections.c:4158 +#: ../clients/cli/connections.c:4246 #, c-format msgid "Error: value for '%s' is missing." msgstr "" -#: ../clients/cli/connections.c:4204 +#: ../clients/cli/connections.c:4292 msgid "Error: . argument is missing." msgstr "" -#: ../clients/cli/connections.c:4227 +#: ../clients/cli/connections.c:4315 #, c-format msgid "Error: invalid or not allowed setting '%s': %s." msgstr "" -#: ../clients/cli/connections.c:4273 ../clients/cli/connections.c:4289 +#: ../clients/cli/connections.c:4361 ../clients/cli/connections.c:4377 #, c-format msgid "Error: '%s' is ambiguous (%s.%s or %s.%s)." msgstr "" -#: ../clients/cli/connections.c:4307 +#: ../clients/cli/connections.c:4395 #, c-format msgid "Error: invalid . '%s'." msgstr "" -#: ../clients/cli/connections.c:4351 ../clients/cli/connections.c:7992 +#: ../clients/cli/connections.c:4437 ../clients/cli/connections.c:8007 #, fuzzy, c-format msgid "Error: Failed to add '%s' connection: %s" msgstr "خطأ أثناء فتح اتصال VPN '%s'" -#: ../clients/cli/connections.c:4369 -#, c-format -msgid "" -"Warning: There is another connection with the name '%1$s'. Reference the " -"connection by its uuid '%2$s'\n" -msgid_plural "" -"Warning: There are %3$u other connections with the name '%1$s'. Reference " -"the connection by its uuid '%2$s'\n" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: ../clients/cli/connections.c:4378 +#: ../clients/cli/connections.c:4442 #, c-format msgid "Connection '%s' (%s) successfully added.\n" msgstr "" -#: ../clients/cli/connections.c:4516 +#: ../clients/cli/connections.c:4580 #, c-format msgid "" "You can specify this option more than once. Press when you're done.\n" msgstr "" #. Ask for optional arguments. -#: ../clients/cli/connections.c:4615 +#: ../clients/cli/connections.c:4645 #, c-format msgid "There is %d optional setting for %s.\n" msgid_plural "There are %d optional settings for %s.\n" @@ -1026,7 +1387,7 @@ msgstr[1] "" msgstr[2] "" msgstr[3] "" -#: ../clients/cli/connections.c:4618 +#: ../clients/cli/connections.c:4648 #, c-format msgid "Do you want to provide it? %s" msgid_plural "Do you want to provide them? %s" @@ -1035,22 +1396,22 @@ msgstr[1] "" msgstr[2] "" msgstr[3] "" -#: ../clients/cli/connections.c:4754 ../clients/cli/utils.c:303 +#: ../clients/cli/connections.c:4773 ../clients/cli/utils.c:302 #, c-format msgid "Error: value for '%s' argument is required." msgstr "" -#: ../clients/cli/connections.c:4760 +#: ../clients/cli/connections.c:4779 #, c-format msgid "Error: 'save': %s." msgstr "" -#: ../clients/cli/connections.c:4848 ../clients/cli/connections.c:4859 +#: ../clients/cli/connections.c:4867 ../clients/cli/connections.c:4878 #, c-format msgid "Error: '%s' argument is required." msgstr "" -#: ../clients/cli/connections.c:5837 +#: ../clients/cli/connections.c:5852 #, c-format msgid "['%s' setting values]\n" msgstr "" @@ -1058,7 +1419,7 @@ msgstr "" #. TRANSLATORS: do not translate command names and keywords before :: #. * However, you should translate terms enclosed in <>. #. -#: ../clients/cli/connections.c:5916 +#: ../clients/cli/connections.c:5931 #, c-format msgid "" "---[ Main menu ]---\n" @@ -1077,7 +1438,7 @@ msgid "" "quit :: exit nmcli\n" msgstr "" -#: ../clients/cli/connections.c:5943 +#: ../clients/cli/connections.c:5958 #, c-format msgid "" "goto [.] | :: enter setting/property for editing\n" @@ -1089,7 +1450,7 @@ msgid "" " nmcli> goto ipv4.addresses\n" msgstr "" -#: ../clients/cli/connections.c:5950 +#: ../clients/cli/connections.c:5965 #, c-format msgid "" "remove [.] :: remove setting or reset property value\n" @@ -1102,7 +1463,7 @@ msgid "" " nmcli> remove eth.mtu\n" msgstr "" -#: ../clients/cli/connections.c:5957 +#: ../clients/cli/connections.c:5972 #, c-format msgid "" "set [. ] :: set property value\n" @@ -1112,7 +1473,7 @@ msgid "" "Example: nmcli> set con.id My connection\n" msgstr "" -#: ../clients/cli/connections.c:5962 +#: ../clients/cli/connections.c:5977 #, c-format msgid "" "describe [.] :: describe property\n" @@ -1121,7 +1482,7 @@ msgid "" "see all NM settings and properties.\n" msgstr "" -#: ../clients/cli/connections.c:5967 +#: ../clients/cli/connections.c:5982 #, c-format msgid "" "print [all] :: print setting or connection values\n" @@ -1131,7 +1492,7 @@ msgid "" "Example: nmcli ipv4> print all\n" msgstr "" -#: ../clients/cli/connections.c:5972 +#: ../clients/cli/connections.c:5987 #, c-format msgid "" "verify [all | fix] :: verify setting or connection validity\n" @@ -1146,7 +1507,7 @@ msgid "" " nmcli bond> verify\n" msgstr "" -#: ../clients/cli/connections.c:5981 +#: ../clients/cli/connections.c:5996 #, c-format msgid "" "save [persistent|temporary] :: save the connection\n" @@ -1162,7 +1523,7 @@ msgid "" "profile must be deleted.\n" msgstr "" -#: ../clients/cli/connections.c:5992 +#: ../clients/cli/connections.c:6007 #, c-format msgid "" "activate [] [/|] :: activate the connection\n" @@ -1175,21 +1536,21 @@ msgid "" "specified)\n" msgstr "" -#: ../clients/cli/connections.c:5999 ../clients/cli/connections.c:6158 +#: ../clients/cli/connections.c:6014 ../clients/cli/connections.c:6173 #, c-format msgid "" "back :: go to upper menu level\n" "\n" msgstr "" -#: ../clients/cli/connections.c:6002 +#: ../clients/cli/connections.c:6017 #, c-format msgid "" "help/? [] :: help for the nmcli commands\n" "\n" msgstr "" -#: ../clients/cli/connections.c:6005 +#: ../clients/cli/connections.c:6020 #, c-format msgid "" "nmcli [ ] :: nmcli configuration\n" @@ -1205,7 +1566,7 @@ msgid "" " nmcli> nmcli prompt-color 3\n" msgstr "" -#: ../clients/cli/connections.c:6027 ../clients/cli/connections.c:6164 +#: ../clients/cli/connections.c:6042 ../clients/cli/connections.c:6179 #, c-format msgid "" "quit :: exit nmcli\n" @@ -1214,8 +1575,8 @@ msgid "" "user is asked to confirm the action.\n" msgstr "" -#: ../clients/cli/connections.c:6032 ../clients/cli/connections.c:6169 -#: ../clients/cli/connections.c:6605 ../clients/cli/connections.c:7562 +#: ../clients/cli/connections.c:6047 ../clients/cli/connections.c:6184 +#: ../clients/cli/connections.c:6610 ../clients/cli/connections.c:7569 #, c-format msgid "Unknown command: '%s'\n" msgstr "" @@ -1223,7 +1584,7 @@ msgstr "" #. TRANSLATORS: do not translate command names and keywords before :: #. * However, you should translate terms enclosed in <>. #. -#: ../clients/cli/connections.c:6098 +#: ../clients/cli/connections.c:6113 #, c-format msgid "" "---[ Property menu ]---\n" @@ -1239,7 +1600,7 @@ msgid "" "quit :: exit nmcli\n" msgstr "" -#: ../clients/cli/connections.c:6123 +#: ../clients/cli/connections.c:6138 #, c-format msgid "" "set [] :: set new value\n" @@ -1247,7 +1608,7 @@ msgid "" "This command sets provided to this property\n" msgstr "" -#: ../clients/cli/connections.c:6127 +#: ../clients/cli/connections.c:6142 #, c-format msgid "" "add [] :: append new value to the property\n" @@ -1257,7 +1618,7 @@ msgid "" "(same as 'set').\n" msgstr "" -#: ../clients/cli/connections.c:6133 +#: ../clients/cli/connections.c:6148 #, c-format msgid "" "change :: change current value\n" @@ -1265,7 +1626,7 @@ msgid "" "Displays current value and allows editing it.\n" msgstr "" -#: ../clients/cli/connections.c:6137 +#: ../clients/cli/connections.c:6152 #, c-format msgid "" "remove [||