diff --git a/Makefile.am b/Makefile.am index 1d5c8bfa06..550ad322ce 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3793,7 +3793,6 @@ check-local-clients-tests-test-client: clients/cli/nmcli clients/tests/test-clie LD_LIBRARY_PATH="$(abs_builddir)/libnm/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}" \ NM_TEST_CLIENT_BUILDDIR="$(abs_builddir)" \ NM_TEST_CLIENT_NMCLI_PATH=clients/cli/nmcli \ - NM_TEST_CLIENT_IN_DBUS_SESSION=0 \ $(srcdir)/clients/tests/test-client.py -v &> "$(builddir)/clients/tests/test-client.log" && r=ok; \ cat "$(builddir)/clients/tests/test-client.log"; \ test "$$r" == ok @@ -3811,6 +3810,12 @@ EXTRA_DIST += \ clients/tests/test-client.check-on-disk/test_001-004.expected \ clients/tests/test-client.check-on-disk/test_001-005.expected \ clients/tests/test-client.check-on-disk/test_001-006.expected \ + clients/tests/test-client.check-on-disk/test_001-007.expected \ + clients/tests/test-client.check-on-disk/test_001-008.expected \ + clients/tests/test-client.check-on-disk/test_001-009.expected \ + clients/tests/test-client.check-on-disk/test_001-010.expected \ + clients/tests/test-client.check-on-disk/test_001-011.expected \ + clients/tests/test-client.check-on-disk/test_001-012.expected \ clients/tests/test-client.check-on-disk/test_002-001.expected \ clients/tests/test-client.check-on-disk/test_002-002.expected \ clients/tests/test-client.check-on-disk/test_002-003.expected \ @@ -3828,6 +3833,25 @@ EXTRA_DIST += \ clients/tests/test-client.check-on-disk/test_002-015.expected \ clients/tests/test-client.check-on-disk/test_002-016.expected \ clients/tests/test-client.check-on-disk/test_002-017.expected \ + clients/tests/test-client.check-on-disk/test_002-018.expected \ + clients/tests/test-client.check-on-disk/test_002-019.expected \ + clients/tests/test-client.check-on-disk/test_002-020.expected \ + clients/tests/test-client.check-on-disk/test_002-021.expected \ + clients/tests/test-client.check-on-disk/test_002-022.expected \ + clients/tests/test-client.check-on-disk/test_002-023.expected \ + clients/tests/test-client.check-on-disk/test_002-024.expected \ + clients/tests/test-client.check-on-disk/test_002-025.expected \ + clients/tests/test-client.check-on-disk/test_002-026.expected \ + clients/tests/test-client.check-on-disk/test_002-027.expected \ + clients/tests/test-client.check-on-disk/test_002-028.expected \ + clients/tests/test-client.check-on-disk/test_002-029.expected \ + clients/tests/test-client.check-on-disk/test_002-030.expected \ + clients/tests/test-client.check-on-disk/test_002-031.expected \ + clients/tests/test-client.check-on-disk/test_002-032.expected \ + clients/tests/test-client.check-on-disk/test_002-033.expected \ + clients/tests/test-client.check-on-disk/test_002-034.expected \ + clients/tests/test-client.check-on-disk/test_002-035.expected \ + clients/tests/test-client.check-on-disk/test_002-036.expected \ clients/tests/test-client.check-on-disk/test_003-001.expected \ clients/tests/test-client.check-on-disk/test_003-002.expected \ clients/tests/test-client.check-on-disk/test_003-003.expected \ @@ -3836,6 +3860,28 @@ EXTRA_DIST += \ clients/tests/test-client.check-on-disk/test_003-006.expected \ clients/tests/test-client.check-on-disk/test_003-007.expected \ clients/tests/test-client.check-on-disk/test_003-008.expected \ + clients/tests/test-client.check-on-disk/test_003-009.expected \ + clients/tests/test-client.check-on-disk/test_003-010.expected \ + clients/tests/test-client.check-on-disk/test_003-011.expected \ + clients/tests/test-client.check-on-disk/test_003-012.expected \ + clients/tests/test-client.check-on-disk/test_003-013.expected \ + clients/tests/test-client.check-on-disk/test_003-014.expected \ + clients/tests/test-client.check-on-disk/test_003-015.expected \ + clients/tests/test-client.check-on-disk/test_003-016.expected \ + clients/tests/test-client.check-on-disk/test_003-017.expected \ + clients/tests/test-client.check-on-disk/test_003-018.expected \ + clients/tests/test-client.check-on-disk/test_003-019.expected \ + clients/tests/test-client.check-on-disk/test_003-020.expected \ + clients/tests/test-client.check-on-disk/test_003-021.expected \ + clients/tests/test-client.check-on-disk/test_003-022.expected \ + clients/tests/test-client.check-on-disk/test_003-023.expected \ + clients/tests/test-client.check-on-disk/test_003-024.expected \ + clients/tests/test-client.check-on-disk/test_003-025.expected \ + clients/tests/test-client.check-on-disk/test_003-026.expected \ + clients/tests/test-client.check-on-disk/test_003-027.expected \ + clients/tests/test-client.check-on-disk/test_003-028.expected \ + clients/tests/test-client.check-on-disk/test_003-029.expected \ + clients/tests/test-client.check-on-disk/test_003-030.expected \ \ $(NULL) diff --git a/clients/cli/common.c b/clients/cli/common.c index 738288b690..e566de47c8 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -100,15 +100,7 @@ _ip_config_get_routes (NMIPConfig *cfg) } static gconstpointer -_metagen_ip4_config_get_fcn (const NMMetaEnvironment *environment, - gpointer environment_user_data, - const NmcMetaGenericInfo *info, - gpointer target, - NMMetaAccessorGetType get_type, - NMMetaAccessorGetFlags get_flags, - NMMetaAccessorGetOutFlags *out_flags, - gboolean *out_is_default, - gpointer *out_to_free) +_metagen_ip4_config_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) { NMIPConfig *cfg4 = target; GPtrArray *ptr_array; @@ -183,15 +175,7 @@ arr_out: } static gconstpointer -_metagen_ip6_config_get_fcn (const NMMetaEnvironment *environment, - gpointer environment_user_data, - const NmcMetaGenericInfo *info, - gpointer target, - NMMetaAccessorGetType get_type, - NMMetaAccessorGetFlags get_flags, - NMMetaAccessorGetOutFlags *out_flags, - gboolean *out_is_default, - gpointer *out_to_free) +_metagen_ip6_config_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) { NMIPConfig *cfg6 = target; GPtrArray *ptr_array; @@ -271,11 +255,6 @@ const NmcMetaGenericInfo *const metagen_ip4_config[_NMC_GENERIC_INFO_TYPE_IP4_CO _METAGEN_IP4_CONFIG (NMC_GENERIC_INFO_TYPE_IP4_CONFIG_WINS, "WINS"), }; -static const NmcMetaGenericInfo *const metagen_ip4_config_group[] = { - NMC_META_GENERIC_WITH_NESTED ("IP4", metagen_ip4_config, .name_header = N_("GROUP")), - NULL, -}; - const NmcMetaGenericInfo *const metagen_ip6_config[_NMC_GENERIC_INFO_TYPE_IP6_CONFIG_NUM + 1] = { #define _METAGEN_IP6_CONFIG(type, name) \ [type] = NMC_META_GENERIC(name, .info_type = type, .get_fcn = _metagen_ip6_config_get_fcn) @@ -286,11 +265,6 @@ const NmcMetaGenericInfo *const metagen_ip6_config[_NMC_GENERIC_INFO_TYPE_IP6_CO _METAGEN_IP6_CONFIG (NMC_GENERIC_INFO_TYPE_IP6_CONFIG_DOMAIN, "DOMAIN"), }; -static const NmcMetaGenericInfo *const metagen_ip6_config_group[] = { - NMC_META_GENERIC_WITH_NESTED ("IP6", metagen_ip6_config, .name_header = N_("GROUP")), - NULL, -}; - /*****************************************************************************/ const NmcMetaGenericInfo *const nmc_fields_dhcp_config[] = { @@ -326,7 +300,7 @@ print_ip4_config (NMIPConfig *cfg4, if (!nmc_print (nmc_config, (gpointer[]) { cfg4, NULL }, NULL, - (const NMMetaAbstractInfo *const*) metagen_ip4_config_group, + NMC_META_GENERIC_GROUP ("IP4", metagen_ip4_config, N_("GROUP")), field_str, &error)) { return FALSE; @@ -352,7 +326,7 @@ print_ip6_config (NMIPConfig *cfg6, if (!nmc_print (nmc_config, (gpointer[]) { cfg6, NULL }, NULL, - (const NMMetaAbstractInfo *const*) metagen_ip6_config_group, + NMC_META_GENERIC_GROUP ("IP6", metagen_ip6_config, N_("GROUP")), field_str, &error)) { return FALSE; @@ -412,8 +386,11 @@ print_dhcp_config (NMDhcpConfig *dhcp, * @connections: array of NMConnections to search in * @filter_type: "id", "uuid", "path" or %NULL * @filter_val: connection to find (connection name, UUID or path) - * @start: where to start in @list. The location is updated so that the function - * can be called multiple times (for connections with the same name). + * @out_result: if not NULL, attach all matching connection to this + * list. If necessary, a new array will be allocated. If the array + * already contains a connection, it will not be added a second time. + * All object are referenced by the array. If the function allocates + * a new array, it will set the free function to g_object_unref. * @complete: print possible completions * * Find a connection in @list according to @filter_val. @filter_type determines @@ -428,64 +405,153 @@ NMConnection * nmc_find_connection (const GPtrArray *connections, const char *filter_type, const char *filter_val, - int *start, + GPtrArray **out_result, gboolean complete) { NMConnection *connection; - NMConnection *found = NULL; - int i; - const char *id; - const char *uuid; - const char *path, *path_num; + NMConnection *best_candidate = NULL; + GPtrArray *result = out_result ? *out_result : NULL; + guint i, j; + + nm_assert (connections); + nm_assert (filter_val); + + for (i = 0; i < connections->len; i++) { + const char *v, *v_num; - for (i = start ? *start : 0; i < connections->len; i++) { connection = NM_CONNECTION (connections->pdata[i]); - id = nm_connection_get_id (connection); - uuid = nm_connection_get_uuid (connection); - path = nm_connection_get_path (connection); - path_num = path ? strrchr (path, '/') + 1 : NULL; - /* When filter_type is NULL, compare connection ID (filter_val) * against all types. Otherwise, only compare against the specific * type. If 'path' filter type is specified, comparison against * numeric index (in addition to the whole path) is allowed. */ - if (!filter_type || strcmp (filter_type, "id") == 0) { + if (NM_IN_STRSET (filter_type, NULL, "id")) { + v = nm_connection_get_id (connection); if (complete) - nmc_complete_strings (filter_val, id, NULL); - if (strcmp (filter_val, id) == 0) + nmc_complete_strings (filter_val, v, NULL); + if (nm_streq0 (filter_val, v)) goto found; } - if (!filter_type || strcmp (filter_type, "uuid") == 0) { + if (NM_IN_STRSET (filter_type, NULL, "uuid")) { + v = nm_connection_get_uuid (connection); if (complete && (filter_type || *filter_val)) - nmc_complete_strings (filter_val, uuid, NULL); - if (strcmp (filter_val, uuid) == 0) + nmc_complete_strings (filter_val, v, NULL); + if (nm_streq0 (filter_val, v)) goto found; } - if (!filter_type || strcmp (filter_type, "path") == 0) { + if (NM_IN_STRSET (filter_type, NULL, "path")) { + v = nm_connection_get_path (connection); + v_num = nm_utils_dbus_path_get_last_component (v); if (complete && (filter_type || *filter_val)) - nmc_complete_strings (filter_val, path, filter_type ? path_num : NULL, NULL); - if (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0)) + nmc_complete_strings (filter_val, v, filter_type ? v_num : NULL, NULL); + if ( nm_streq0 (filter_val, v) + || (filter_type && nm_streq0 (filter_val, v_num))) goto found; } continue; found: - if (!start) + if (!out_result) return connection; - if (found) { - *start = i; - return found; + if (!best_candidate) + best_candidate = connection; + if (!result) + result = g_ptr_array_new_with_free_func (g_object_unref); + for (j = 0; j < result->len; j++) { + if (connection == result->pdata[j]) + break; } - found = connection; + if (j == result->len) + g_ptr_array_add (result, g_object_ref (connection)); } - if (start) - *start = 0; - return found; + NM_SET_OUT (out_result, result); + return best_candidate; +} + +NMActiveConnection * +nmc_find_active_connection (const GPtrArray *active_cons, + const char *filter_type, + const char *filter_val, + GPtrArray **out_result, + gboolean complete) +{ + guint i, j; + NMActiveConnection *best_candidate = NULL; + GPtrArray *result = out_result ? *out_result : NULL; + + nm_assert (filter_val); + + for (i = 0; i < active_cons->len; i++) { + NMRemoteConnection *con; + NMActiveConnection *candidate = g_ptr_array_index (active_cons, i); + const char *v, *v_num; + + con = nm_active_connection_get_connection (candidate); + + /* When filter_type is NULL, compare connection ID (filter_val) + * against all types. Otherwise, only compare against the specific + * type. If 'path' or 'apath' filter types are specified, comparison + * against numeric index (in addition to the whole path) is allowed. + */ + if (NM_IN_STRSET (filter_type, NULL, "id")) { + v = nm_active_connection_get_id (candidate); + if (complete) + nmc_complete_strings (filter_val, v, NULL); + if (nm_streq0 (filter_val, v)) + goto found; + } + + if (NM_IN_STRSET (filter_type, NULL, "uuid")) { + v = nm_active_connection_get_uuid (candidate); + if (complete && (filter_type || *filter_val)) + nmc_complete_strings (filter_val, v, NULL); + if (nm_streq0 (filter_val, v)) + goto found; + } + + if (NM_IN_STRSET (filter_type, NULL, "path")) { + v = con ? nm_connection_get_path (NM_CONNECTION (con)) : NULL; + v_num = nm_utils_dbus_path_get_last_component (v); + if (complete && (filter_type || *filter_val)) + nmc_complete_strings (filter_val, v, filter_type ? v_num : NULL, NULL); + if ( nm_streq0 (filter_val, v) + || (filter_type && nm_streq0 (filter_val, v_num))) + goto found; + } + + if (NM_IN_STRSET (filter_type, NULL, "apath")) { + v = nm_object_get_path (NM_OBJECT (candidate)); + v_num = nm_utils_dbus_path_get_last_component (v); + if (complete && (filter_type || *filter_val)) + nmc_complete_strings (filter_val, v, filter_type ? v_num : NULL, NULL); + if ( nm_streq0 (filter_val, v) + || (filter_type && nm_streq0 (filter_val, v_num))) + goto found; + } + + continue; + +found: + if (!out_result) + return candidate; + if (!best_candidate) + best_candidate = candidate; + if (!result) + result = g_ptr_array_new_with_free_func (g_object_unref); + for (j = 0; j < result->len; j++) { + if (candidate == result->pdata[j]) + break; + } + if (j == result->len) + g_ptr_array_add (result, g_object_ref (candidate)); + } + + NM_SET_OUT (out_result, result); + return best_candidate; } static gboolean diff --git a/clients/cli/common.h b/clients/cli/common.h index 6fce3f0f66..8f4e47c28b 100644 --- a/clients/cli/common.h +++ b/clients/cli/common.h @@ -32,9 +32,15 @@ gboolean print_dhcp_config (NMDhcpConfig *dhcp, const NmcConfig *nmc_config, con NMConnection *nmc_find_connection (const GPtrArray *connections, const char *filter_type, const char *filter_val, - int *start, + GPtrArray **out_result, gboolean complete); +NMActiveConnection *nmc_find_active_connection (const GPtrArray *active_cons, + const char *filter_type, + const char *filter_val, + GPtrArray **out_result, + gboolean complete); + void nmc_secrets_requested (NMSecretAgentSimple *agent, const char *request_id, const char *title, diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 5fb78d467d..a4f129b6a3 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -76,6 +76,82 @@ struct _OptionInfo { /*****************************************************************************/ +NM_UTILS_LOOKUP_STR_DEFINE_STATIC (active_connection_state_to_string, NMActiveConnectionState, + NM_UTILS_LOOKUP_DEFAULT (N_("unknown")), + NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_ACTIVATING, N_("activating")), + NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_ACTIVATED, N_("activated")), + NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, N_("deactivating")), + NM_UTILS_LOOKUP_ITEM (NM_ACTIVE_CONNECTION_STATE_DEACTIVATED, N_("deactivated")), + NM_UTILS_LOOKUP_ITEM_IGNORE (NM_ACTIVE_CONNECTION_STATE_UNKNOWN), +) + +NM_UTILS_LOOKUP_STR_DEFINE_STATIC (vpn_connection_state_to_string, NMVpnConnectionState, + NM_UTILS_LOOKUP_DEFAULT (N_("unknown")), + NM_UTILS_LOOKUP_ITEM (NM_VPN_CONNECTION_STATE_PREPARE, N_("VPN connecting (prepare)")), + NM_UTILS_LOOKUP_ITEM (NM_VPN_CONNECTION_STATE_NEED_AUTH, N_("VPN connecting (need authentication)")), + NM_UTILS_LOOKUP_ITEM (NM_VPN_CONNECTION_STATE_CONNECT, N_("VPN connecting")), + NM_UTILS_LOOKUP_ITEM (NM_VPN_CONNECTION_STATE_IP_CONFIG_GET, N_("VPN connecting (getting IP configuration)")), + NM_UTILS_LOOKUP_ITEM (NM_VPN_CONNECTION_STATE_ACTIVATED, N_("VPN connected")), + NM_UTILS_LOOKUP_ITEM (NM_VPN_CONNECTION_STATE_FAILED, N_("VPN connection failed")), + NM_UTILS_LOOKUP_ITEM (NM_VPN_CONNECTION_STATE_DISCONNECTED, N_("VPN disconnected")), + NM_UTILS_LOOKUP_ITEM_IGNORE (NM_VPN_CONNECTION_STATE_UNKNOWN), +) + +/* Essentially a version of nm_setting_connection_get_connection_type() that + * prefers an alias instead of the settings name when in pretty print mode. + * That is so that we print "wifi" instead of "802-11-wireless" in "nmcli c". */ +static const char * +connection_type_pretty (const char *type, NMCPrintOutput print_output) +{ + const NMMetaSettingInfoEditor *editor; + int i; + + if (print_output == NMC_PRINT_TERSE) + return type; + + for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { + editor = &nm_meta_setting_infos_editor[i]; + if (strcmp (type, editor->general->setting_name) == 0) { + if (editor->alias) + return editor->alias; + break; + } + } + + return type; +} + +/* Caller has to free the returned string */ +static char * +get_ac_device_string (NMActiveConnection *active) +{ + GString *dev_str; + const GPtrArray *devices; + int i; + + if (!active) + return NULL; + + /* Get devices of the active connection */ + dev_str = g_string_new (NULL); + devices = nm_active_connection_get_devices (active); + for (i = 0; i < devices->len; i++) { + NMDevice *device = g_ptr_array_index (devices, i); + const char *dev_iface = nm_device_get_iface (device); + + if (dev_iface) { + g_string_append (dev_str, dev_iface); + g_string_append_c (dev_str, ','); + } + } + if (dev_str->len > 0) + g_string_truncate (dev_str, dev_str->len - 1); /* Cut off last ',' */ + + return g_string_free (dev_str, FALSE); +} + +/*****************************************************************************/ + const NmcMetaGenericInfo *const nmc_fields_con_show[] = { NMC_META_GENERIC ("NAME"), /* 0 */ NMC_META_GENERIC ("UUID"), /* 1 */ @@ -186,7 +262,10 @@ typedef struct { NMSetting *setting; const char *property; } TabCompletionInfo; -static TabCompletionInfo nmc_tab_completion = {NULL, NULL, NULL, NULL}; + +static TabCompletionInfo nmc_tab_completion; + +/*****************************************************************************/ static void usage (void) @@ -516,97 +595,38 @@ construct_header_name (const char *base, const char *spec) return g_strdup_printf ("%s (%s)", base, spec); } -static const char * -active_connection_state_to_string (NMActiveConnectionState state) -{ - switch (state) { - case NM_ACTIVE_CONNECTION_STATE_ACTIVATING: - return _("activating"); - case NM_ACTIVE_CONNECTION_STATE_ACTIVATED: - return _("activated"); - case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING: - return _("deactivating"); - case NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: - return _("deactivated"); - case NM_ACTIVE_CONNECTION_STATE_UNKNOWN: - default: - return _("unknown"); - } -} - -static const char * -vpn_connection_state_to_string (NMVpnConnectionState state) -{ - switch (state) { - case NM_VPN_CONNECTION_STATE_PREPARE: - return _("VPN connecting (prepare)"); - case NM_VPN_CONNECTION_STATE_NEED_AUTH: - return _("VPN connecting (need authentication)"); - case NM_VPN_CONNECTION_STATE_CONNECT: - return _("VPN connecting"); - case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: - return _("VPN connecting (getting IP configuration)"); - case NM_VPN_CONNECTION_STATE_ACTIVATED: - return _("VPN connected"); - case NM_VPN_CONNECTION_STATE_FAILED: - return _("VPN connection failed"); - case NM_VPN_CONNECTION_STATE_DISCONNECTED: - return _("VPN disconnected"); - default: - return _("unknown"); - } -} - -/* Caller has to free the returned string */ -static char * -get_ac_device_string (NMActiveConnection *active) -{ - GString *dev_str; - const GPtrArray *devices; - int i; - - if (!active) - return NULL; - - /* Get devices of the active connection */ - dev_str = g_string_new (NULL); - devices = nm_active_connection_get_devices (active); - for (i = 0; i < devices->len; i++) { - NMDevice *device = g_ptr_array_index (devices, i); - const char *dev_iface = nm_device_get_iface (device); - - if (dev_iface) { - g_string_append (dev_str, dev_iface); - g_string_append_c (dev_str, ','); - } - } - if (dev_str->len > 0) - g_string_truncate (dev_str, dev_str->len - 1); /* Cut off last ',' */ - - return g_string_free (dev_str, FALSE); -} - static NMActiveConnection * -get_ac_for_connection (const GPtrArray *active_cons, NMConnection *connection) +get_ac_for_connection (const GPtrArray *active_cons, NMConnection *connection, GPtrArray **out_result) { const char *con_path, *ac_con_path; - int i; - NMActiveConnection *ac = NULL; + guint i; + NMActiveConnection *best_candidate = NULL; + GPtrArray *result = out_result ? *out_result : NULL; - /* Is the connection active? */ con_path = nm_connection_get_path (connection); for (i = 0; i < active_cons->len; i++) { NMActiveConnection *candidate = g_ptr_array_index (active_cons, i); NMRemoteConnection *con; con = nm_active_connection_get_connection (candidate); - ac_con_path = con ? nm_connection_get_path (NM_CONNECTION (con)) : NULL; - if (!g_strcmp0 (ac_con_path, con_path)) { - ac = candidate; - break; + if (NM_CONNECTION (con) != connection) { + /* also compare the D-Bus paths. Why? I don't know. */ + ac_con_path = con ? nm_connection_get_path (NM_CONNECTION (con)) : NULL; + if (!nm_streq0 (ac_con_path, con_path)) + continue; } + + if (!out_result) + return candidate; + if (!best_candidate) + best_candidate = candidate; + if (!result) + result = g_ptr_array_new_with_free_func (g_object_unref); + g_ptr_array_add (result, g_object_ref (candidate)); } - return ac; + + NM_SET_OUT (out_result, result); + return best_candidate; } typedef struct { @@ -734,83 +754,6 @@ nmc_connection_profile_details (NMConnection *connection, NmCli *nmc) return TRUE; } -static NMActiveConnection * -find_active_connection (const GPtrArray *active_cons, - const GPtrArray *cons, - const char *filter_type, - const char *filter_val, - int *idx, - gboolean complete) -{ - int i; - int start = (idx && *idx > 0) ? *idx : 0; - const char *path, *a_path, *path_num, *a_path_num; - const char *id; - const char *uuid; - NMRemoteConnection *con; - NMActiveConnection *found = NULL; - - for (i = start; i < active_cons->len; i++) { - NMActiveConnection *candidate = g_ptr_array_index (active_cons, i); - - con = nm_active_connection_get_connection (candidate); - - id = nm_active_connection_get_id (candidate); - uuid = nm_active_connection_get_uuid (candidate); - path = con ? nm_connection_get_path (NM_CONNECTION (con)) : NULL; - path_num = path ? strrchr (path, '/') + 1 : NULL; - a_path = nm_object_get_path (NM_OBJECT (candidate)); - a_path_num = a_path ? strrchr (a_path, '/') + 1 : NULL; - - /* When filter_type is NULL, compare connection ID (filter_val) - * against all types. Otherwise, only compare against the specific - * type. If 'path' or 'apath' filter types are specified, comparison - * against numeric index (in addition to the whole path) is allowed. - */ - if (!filter_type || strcmp (filter_type, "id") == 0) { - if (complete) - nmc_complete_strings (filter_val, id, NULL); - if (strcmp (filter_val, id) == 0) - goto found; - } - - if (!filter_type || strcmp (filter_type, "uuid") == 0) { - if (complete && (filter_type || *filter_val)) - nmc_complete_strings (filter_val, uuid, NULL); - if (strcmp (filter_val, uuid) == 0) - goto found; - } - - if (!filter_type || strcmp (filter_type, "path") == 0) { - if (complete && (filter_type || *filter_val)) - nmc_complete_strings (filter_val, path, filter_type ? path_num : NULL, NULL); - if (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0)) - goto found; - } - - if (!filter_type || strcmp (filter_type, "apath") == 0) { - if (complete && (filter_type || *filter_val)) - nmc_complete_strings (filter_val, a_path, filter_type ? a_path_num : NULL, NULL); - if (g_strcmp0 (filter_val, a_path) == 0 || (filter_type && g_strcmp0 (filter_val, a_path_num) == 0)) - goto found; - } - - continue; -found: - if (!idx) - return candidate; - if (found) { - *idx = i; - return found; - } - found = candidate; - } - - if (idx) - *idx = 0; - return found; -} - NMMetaColor nmc_active_connection_state_to_color (NMActiveConnectionState state) { @@ -824,30 +767,6 @@ nmc_active_connection_state_to_color (NMActiveConnectionState state) return NM_META_COLOR_CONNECTION_UNKNOWN; } -/* Essentially a version of nm_setting_connection_get_connection_type() that - * prefers an alias instead of the settings name when in pretty print mode. - * That is so that we print "wifi" instead of "802-11-wireless" in "nmcli c". */ -static const char * -connection_type_pretty (const char *type, NMCPrintOutput print_output) -{ - const NMMetaSettingInfoEditor *editor; - int i; - - if (print_output == NMC_PRINT_TERSE) - return type; - - for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { - editor = &nm_meta_setting_infos_editor[i]; - if (strcmp (type, editor->general->setting_name) == 0) { - if (editor->alias) - return editor->alias; - break; - } - } - - return type; -} - static void fill_output_connection (NMConnection *connection, NMClient *client, NMCPrintOutput print_output, GPtrArray *output_data, gboolean active_only) @@ -869,14 +788,14 @@ fill_output_connection (NMConnection *connection, NMClient *client, NMCPrintOutp s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); - ac = get_ac_for_connection (nm_client_get_active_connections (client), connection); + ac = get_ac_for_connection (nm_client_get_active_connections (client), connection, NULL); if (active_only && !ac) return; if (ac) { ac_path = nm_object_get_path (NM_OBJECT (ac)); ac_state_int = nm_active_connection_get_state (ac); - ac_state = active_connection_state_to_string (ac_state_int); + ac_state = gettext (active_connection_state_to_string (ac_state_int)); ac_dev = get_ac_device_string (ac); } @@ -971,7 +890,7 @@ fill_output_active_connection (NMActiveConnection *active, if (con) { con_path = nm_connection_get_path (NM_CONNECTION (con)); s_con = nm_connection_get_setting_connection (NM_CONNECTION (con)); - g_assert (s_con != NULL); + g_assert (s_con); con_zone = nm_setting_connection_get_zone (s_con); } @@ -1092,7 +1011,9 @@ static const gchar * get_vpn_data_item (NMConnection *connection, enum VpnDataItem vpn_data_item) { const char *key; - char *type = get_vpn_connection_type (connection); + gs_free char *type = NULL; + + type = get_vpn_connection_type (connection); switch (vpn_data_item) { case VPN_DATA_ITEM_GATEWAY: @@ -1105,7 +1026,6 @@ get_vpn_data_item (NMConnection *connection, enum VpnDataItem vpn_data_item) key = ""; break; } - g_free (type); return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (connection), key); } @@ -1241,7 +1161,7 @@ nmc_active_connection_details (NMActiveConnection *acon, NmCli *nmc) con = NM_CONNECTION (nm_active_connection_get_connection (acon)); s_con = nm_connection_get_setting_connection (con); - g_assert (s_con != NULL); + g_assert (s_con); tmpl = (const NMMetaAbstractInfo *const*) nmc_fields_con_active_details_vpn; out_indices = parse_output_fields (group_fld, @@ -1269,7 +1189,9 @@ nmc_active_connection_details (NMActiveConnection *acon, NmCli *nmc) if (banner) banner_str = g_strescape (banner, ""); vpn_state = nm_vpn_connection_get_vpn_state (NM_VPN_CONNECTION (acon)); - vpn_state_str = g_strdup_printf ("%d - %s", vpn_state, vpn_connection_state_to_string (vpn_state)); + vpn_state_str = g_strdup_printf ("%d - %s", + vpn_state, + gettext (vpn_connection_state_to_string (vpn_state))); /* Add values */ arr = nmc_dup_fields_array (tmpl, NMC_OF_FLAG_SECTION_PREFIX); @@ -1430,34 +1352,34 @@ typedef struct { static int compare_connections (gconstpointer a, gconstpointer b, gpointer user_data) { - NMConnection *ca = *(NMConnection **)a; - NMConnection *cb = *(NMConnection **)b; + NMConnection *ca = *(NMConnection **) a; + NMConnection *cb = *(NMConnection **) b; + const NmcSortInfo *info = user_data; NMActiveConnection *aca, *acb; - NmcSortInfo *info = (NmcSortInfo *) user_data; - GArray *default_order = NULL; - const GArray *order; - NmcSortOrder item; - int cmp = 0, i; + const NmcSortOrder *order_arr; + guint i, order_len; const char *tmp1, *tmp2; unsigned long tmp1_int, tmp2_int; - if (info->order ) - order = info->order; - else { - NmcSortOrder def[] = { NMC_SORT_ACTIVE, NMC_SORT_NAME, NMC_SORT_PATH }; - int num = G_N_ELEMENTS (def); - default_order = g_array_sized_new (FALSE, FALSE, sizeof (NmcSortOrder), num); - g_array_append_vals (default_order, def, num); - order = default_order; + if (info->order) { + order_arr = &g_array_index (info->order, NmcSortOrder, 0); + order_len = info->order->len; + } else { + static const NmcSortOrder def[] = { NMC_SORT_ACTIVE, NMC_SORT_NAME, NMC_SORT_PATH }; + + order_arr = def; + order_len = G_N_ELEMENTS (def); } - for (i = 0; i < order->len; i++) { - item = g_array_index (order, NmcSortOrder, i); + for (i = 0; i < order_len; i++) { + NmcSortOrder item = order_arr[i]; + int cmp = 0; + switch (item) { case NMC_SORT_ACTIVE: case NMC_SORT_ACTIVE_INV: - aca = get_ac_for_connection (nm_client_get_active_connections (info->nmc->client), ca); - acb = get_ac_for_connection (nm_client_get_active_connections (info->nmc->client), cb); + aca = get_ac_for_connection (nm_client_get_active_connections (info->nmc->client), ca, NULL); + acb = get_ac_for_connection (nm_client_get_active_connections (info->nmc->client), cb, NULL); cmp = (aca && !acb) ? -1 : (!aca && acb) ? 1 : 0; if (item == NMC_SORT_ACTIVE_INV) cmp = -(cmp); @@ -1493,12 +1415,10 @@ compare_connections (gconstpointer a, gconstpointer b, gpointer user_data) break; } if (cmp != 0) - goto end; + return cmp; } -end: - if (default_order) - g_array_unref (default_order); - return cmp; + + return 0; } static GPtrArray * @@ -1550,7 +1470,7 @@ get_invisible_active_connections (NmCli *nmc) GPtrArray *invisibles; int a, c; - g_return_val_if_fail (nmc != NULL, NULL); + g_return_val_if_fail (nmc, NULL); invisibles = g_ptr_array_new (); acons = nm_client_get_active_connections (nmc->client); @@ -1637,12 +1557,21 @@ parse_preferred_connection_order (const char *order, GError **error) } static NMConnection * -get_connection (NmCli *nmc, int *argc, char ***argv, int *pos, GError **error) +get_connection (NmCli *nmc, + int *argc, + char ***argv, + const char **out_selector, + const char **out_value, + GPtrArray **out_result, + GError **error) { const GPtrArray *connections; NMConnection *connection = NULL; const char *selector = NULL; + NM_SET_OUT (out_selector, NULL); + NM_SET_OUT (out_value, NULL); + if (*argc == 0) { g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("No connection specified")); @@ -1666,32 +1595,32 @@ get_connection (NmCli *nmc, int *argc, char ***argv, int *pos, GError **error) } } + NM_SET_OUT (out_selector, selector); + NM_SET_OUT (out_value, **argv); + connections = nm_client_get_connections (nmc->client); - connection = nmc_find_connection (connections, selector, **argv, pos, + connection = nmc_find_connection (connections, selector, **argv, out_result, *argc == 1 && nmc->complete); if (!connection) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_NOT_FOUND, _("unknown connection '%s'"), **argv); } - /* If the caller wants multiple results (pos is set) and there are any, - * don't switch to next argument. - */ - if (!pos || !*pos) - next_arg (nmc, argc, argv, NULL); - + next_arg (nmc, argc, argv, NULL); return connection; } static NMCResultCode do_connections_show (NmCli *nmc, int argc, char **argv) { - GError *err = NULL; - char *profile_flds = NULL, *active_flds = NULL; + gs_free_error GError *err = NULL; + gs_free char *profile_flds = NULL; + gs_free char *active_flds = NULL; GPtrArray *invisibles, *sorted_cons; gboolean active_only = FALSE; - GArray *order = NULL; - int i, option; + gs_unref_array GArray *order = NULL; + guint i, j; + int option; /* check connection show options [--active] [--order ] */ while ((option = next_arg (nmc, &argc, &argv, "--active", "--order", NULL)) > 0) { @@ -1766,7 +1695,6 @@ do_connections_show (NmCli *nmc, int argc, char **argv) gboolean new_line = FALSE; gboolean without_fields = (nmc->required_fields == NULL); const GPtrArray *active_cons = nm_client_get_active_connections (nmc->client); - int pos = 0; /* multiline mode is default for 'connection show ' */ if (!nmc->mode_specified) @@ -1775,8 +1703,8 @@ do_connections_show (NmCli *nmc, int argc, char **argv) /* Split required fields into the settings and active ones. */ if (!split_required_fields_for_con_show (nmc->required_fields, &profile_flds, &active_flds, &err)) goto finish; - g_free (nmc->required_fields); - nmc->required_fields = NULL; + + nm_clear_g_free (&nmc->required_fields); /* Before printing the connections check if we have a "--show-secret" * option after the connection ids */ @@ -1785,10 +1713,7 @@ do_connections_show (NmCli *nmc, int argc, char **argv) char **argv_cp = argv; do { - if ( nm_streq (*argv_cp, "id") - || nm_streq (*argv_cp, "uuid") - || nm_streq (*argv_cp, "path") - || nm_streq (*argv_cp, "apath")) { + if (NM_IN_STRSET (*argv_cp, "id", "uuid", "path", "apath")) { argc_cp--; argv_cp++; } @@ -1799,16 +1724,16 @@ do_connections_show (NmCli *nmc, int argc, char **argv) const GPtrArray *connections; gboolean res; NMConnection *con; - NMActiveConnection *acon = NULL; + gs_unref_object NMActiveConnection *explicit_acon = NULL; const char *selector = NULL; + gs_unref_ptrarray GPtrArray *found_cons = NULL; + gboolean explicit_acon_handled = FALSE; + guint i_found_cons; if (argc == 1 && nmc->complete) nmc_complete_strings (*argv, "id", "uuid", "path", "apath", NULL); - if ( strcmp (*argv, "id") == 0 - || strcmp (*argv, "uuid") == 0 - || strcmp (*argv, "path") == 0 - || strcmp (*argv, "apath") == 0) { + if (NM_IN_STRSET (*argv, "id", "uuid", "path", "apath")) { selector = *argv; argc--; argv++; @@ -1821,17 +1746,26 @@ do_connections_show (NmCli *nmc, int argc, char **argv) /* Try to find connection by id, uuid or path first */ connections = nm_client_get_connections (nmc->client); - con = nmc_find_connection (connections, selector, *argv, &pos, + con = nmc_find_connection (connections, selector, *argv, &found_cons, argc == 1 && nmc->complete); - if (!con && (!selector || strcmp (selector, "apath") == 0)) { + if ( !con + && NM_IN_STRSET (selector, NULL, "apath")) { /* Try apath too */ - acon = find_active_connection (active_cons, connections, "apath", *argv, NULL, - argc == 1 && nmc->complete); - if (acon) - con = NM_CONNECTION (nm_active_connection_get_connection (acon)); + explicit_acon = nmc_find_active_connection (active_cons, "apath", *argv, NULL, + argc == 1 && nmc->complete); + if (explicit_acon) { + if ( !selector + && !nm_streq0 (*argv, nm_object_get_path (NM_OBJECT (explicit_acon)))) { + /* we matched the apath based on the last component alone (note the full D-Bus path). + * That is how nmc_find_active_connection() works, if you pass in a selector. + * Reject it. */ + explicit_acon = NULL; + } + nm_g_object_ref (explicit_acon); + } } - if (!con && !acon) { + if (!con && !explicit_acon) { g_string_printf (nmc->return_text, _("Error: %s - no such connection profile."), *argv); nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; goto finish; @@ -1843,54 +1777,81 @@ do_connections_show (NmCli *nmc, int argc, char **argv) * may see only the active connection. */ - /* Filter only active connections */ - if (!acon) - acon = get_ac_for_connection (active_cons, con); - if (active_only && !acon) { - next_arg (nmc, &argc, &argv, NULL); - continue; - } - if (nmc->complete) { next_arg (nmc, &argc, &argv, NULL); continue; } - /* Show an empty line between connections */ - if (new_line) - g_print ("\n"); + explicit_acon_handled = FALSE; + i_found_cons = 0; + for (;;) { + gs_unref_ptrarray GPtrArray *found_acons = NULL; - /* Show profile configuration */ - if (without_fields || profile_flds) { - if (con) { - nmc->required_fields = profile_flds; - if (nmc->nmc_config.show_secrets) - update_secrets_in_connection (NM_REMOTE_CONNECTION (con), con); - res = nmc_connection_profile_details (con, nmc); - nmc->required_fields = NULL; - if (!res) - goto finish; + if (explicit_acon) { + if (explicit_acon_handled) + break; + explicit_acon_handled = TRUE; + /* the user referenced an "apath". In this case, we can only have at most one connection + * and one apath. */ + con = NM_CONNECTION (nm_active_connection_get_connection (explicit_acon)); + } else { + if (i_found_cons >= found_cons->len) + break; + con = found_cons->pdata[i_found_cons++]; + get_ac_for_connection (active_cons, con, &found_acons); + } + + if (active_only && !explicit_acon && !found_acons) { + /* this connection is not interesting, we only print active ones. */ + continue; + } + + nm_assert (explicit_acon || con); + + if (new_line) + g_print ("\n"); + new_line = TRUE; + + if (without_fields || profile_flds) { + if (con) { + nmc->required_fields = profile_flds; + if (nmc->nmc_config.show_secrets) + update_secrets_in_connection (NM_REMOTE_CONNECTION (con), con); + res = nmc_connection_profile_details (con, nmc); + nmc->required_fields = NULL; + if (!res) + goto finish; + } + } + + if (without_fields || active_flds) { + guint l = explicit_acon ? 1 : (found_acons ? found_acons->len : 0); + + for (j = 0; j < l; j++) { + NMActiveConnection *acon; + + if (j > 0) { + /* if there are multiple active connections, separate them with newline. + * that is a bit odd, because we already separate connections with newlines, + * and commonly don't separate the connection from the first active connection. */ + g_print ("\n"); + } + + if (explicit_acon) + acon = explicit_acon; + else + acon = found_acons->pdata[j]; + + nmc->required_fields = active_flds; + res = nmc_active_connection_details (acon, nmc); + nmc->required_fields = NULL; + if (!res) + goto finish; + } } } - /* If the profile is active, print also active details */ - if (without_fields || active_flds) { - if (acon) { - nmc->required_fields = active_flds; - res = nmc_active_connection_details (acon, nmc); - nmc->required_fields = NULL; - if (!res) - goto finish; - } - } - new_line = TRUE; - - /* Take next argument. - * But for pos != NULL we have more connections of the same name, - * so process the same argument again. - */ - if (!pos) - next_arg (nmc, &argc, &argv, NULL); + next_arg (nmc, &argc, &argv, NULL); } } @@ -1898,12 +1859,7 @@ finish: if (err) { g_string_printf (nmc->return_text, _("Error: %s."), err->message); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_error_free (err); } - g_free (profile_flds); - g_free (active_flds); - if (order) - g_array_unref (order); return nmc->return_value; } @@ -1916,8 +1872,8 @@ get_default_active_connection (NmCli *nmc, NMDevice **device) const GPtrArray *connections; int i; - g_return_val_if_fail (nmc != NULL, NULL); - g_return_val_if_fail (device != NULL, NULL); + g_return_val_if_fail (nmc, NULL); + g_return_val_if_fail (device, NULL); g_return_val_if_fail (*device == NULL, NULL); connections = nm_client_get_active_connections (nmc->client); @@ -1975,10 +1931,10 @@ find_device_for_connection (NmCli *nmc, const char *con_type; int i, j; - g_return_val_if_fail (nmc != NULL, FALSE); + g_return_val_if_fail (nmc, FALSE); g_return_val_if_fail (iface || ap || nsp, FALSE); - g_return_val_if_fail (device != NULL && *device == NULL, FALSE); - g_return_val_if_fail (spec_object != NULL && *spec_object == NULL, FALSE); + g_return_val_if_fail (device && *device == NULL, FALSE); + g_return_val_if_fail (spec_object && *spec_object == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); s_con = nm_connection_get_setting_connection (connection); @@ -2033,8 +1989,10 @@ find_device_for_connection (NmCli *nmc, } found_device = dev; - if (ap && !strcmp (con_type, NM_SETTING_WIRELESS_SETTING_NAME) && NM_IS_DEVICE_WIFI (dev)) { - char *bssid_up = g_ascii_strup (ap, -1); + if ( ap + && nm_streq (con_type, NM_SETTING_WIRELESS_SETTING_NAME) + && NM_IS_DEVICE_WIFI (dev)) { + gs_free char *bssid_up = g_ascii_strup (ap, -1); const GPtrArray *aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev)); found_device = NULL; /* Mark as not found; set to the device again later, only if AP matches */ @@ -2042,29 +2000,28 @@ find_device_for_connection (NmCli *nmc, NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j); const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap); - if (!strcmp (bssid_up, candidate_bssid)) { + if (nm_streq0 (bssid_up, candidate_bssid)) { found_device = dev; *spec_object = nm_object_get_path (NM_OBJECT (candidate_ap)); break; } } - g_free (bssid_up); } - } - if (found_device) { - *device = found_device; - return TRUE; - } else { - if (iface) + if (!found_device) { + if (iface) { g_set_error (error, NMCLI_ERROR, 0, _("device '%s' not compatible with connection '%s'"), iface, nm_setting_connection_get_id (s_con)); - else + } else { g_set_error (error, NMCLI_ERROR, 0, _("no device found for connection '%s'"), nm_setting_connection_get_id (s_con)); + } return FALSE; } + + *device = found_device; + return TRUE; } } @@ -2365,7 +2322,7 @@ nmc_activate_connection (NmCli *nmc, gboolean device_found; GError *local = NULL; - g_return_val_if_fail (nmc != NULL, FALSE); + g_return_val_if_fail (nmc, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (connection && (ifname || ap || nsp)) { @@ -2465,7 +2422,7 @@ do_connection_up (NmCli *nmc, int argc, char **argv) } if (argc > 0 && strcmp (*argv, "ifname") != 0) { - connection = get_connection (nmc, argc_ptr, argv_ptr, NULL, &error); + connection = get_connection (nmc, argc_ptr, argv_ptr, NULL, NULL, NULL, &error); if (!connection) { g_string_printf (nmc->return_text, _("Error: %s."), error->message); return error->code; @@ -2544,20 +2501,108 @@ do_connection_up (NmCli *nmc, int argc, char **argv) return nmc->return_value; } +/*****************************************************************************/ + typedef struct { NmCli *nmc; - GSList *queue; + /* a list of object that is relevant for the callback. The object + * type differs, and depends on the type of callback. */ + GPtrArray *obj_list; guint timeout_id; GCancellable *cancellable; } ConnectionCbInfo; -static void connection_cb_info_finish (ConnectionCbInfo *info, - gpointer connection); +static void connection_removed_cb (NMClient *client, NMConnection *connection, ConnectionCbInfo *info); + +static void down_active_connection_state_cb (NMActiveConnection *active, + GParamSpec *pspec, + ConnectionCbInfo *info); + +static void +connection_cb_info_obj_list_destroy (ConnectionCbInfo *info, gpointer obj) +{ + nm_assert (info); + nm_assert (info->obj_list); + nm_assert (G_IS_OBJECT (obj)); + + g_signal_handlers_disconnect_by_func (obj, down_active_connection_state_cb, info); + g_object_unref (obj); +} + +static gssize +connection_cb_info_obj_list_idx (ConnectionCbInfo *info, gpointer obj) +{ + guint i; + + nm_assert (info); + nm_assert (info->obj_list); + nm_assert (G_IS_OBJECT (obj)); + + for (i = 0; i < info->obj_list->len; i++) { + if (info->obj_list->pdata[i] == obj) + return i; + } + return -1; +} + +static gpointer +connection_cb_info_obj_list_has (ConnectionCbInfo *info, gpointer obj) +{ + gssize idx; + + idx = connection_cb_info_obj_list_idx (info, obj); + if (idx >= 0) + return info->obj_list->pdata[idx]; + return NULL; +} + +static gpointer +connection_cb_info_obj_list_steal (ConnectionCbInfo *info, gpointer obj) +{ + gssize idx; + + idx = connection_cb_info_obj_list_idx (info, obj); + if (idx >= 0) { + g_ptr_array_remove_index (info->obj_list, idx); + return obj; + } + return NULL; +} + +static void +connection_cb_info_finish (ConnectionCbInfo *info, gpointer obj) +{ + if (obj) { + obj = connection_cb_info_obj_list_steal (info, obj); + if (obj) + connection_cb_info_obj_list_destroy (info, obj); + } else { + while (info->obj_list->len > 0) { + obj = info->obj_list->pdata[info->obj_list->len - 1]; + g_ptr_array_remove_index (info->obj_list, info->obj_list->len); + connection_cb_info_obj_list_destroy (info, obj); + } + } + + if (info->obj_list->len > 0) + return; + + nm_clear_g_source (&info->timeout_id); + nm_clear_g_cancellable (&info->cancellable); + + g_signal_handlers_disconnect_by_func (info->nmc->client, connection_removed_cb, info); + + g_slice_free (ConnectionCbInfo, info); + + quit (); +} + +/*****************************************************************************/ static void connection_removed_cb (NMClient *client, NMConnection *connection, ConnectionCbInfo *info) { - if (!g_slist_find (info->queue, connection)) + if (!connection_cb_info_obj_list_has (info, connection)) return; g_print (_("Connection '%s' (%s) successfully deleted.\n"), nm_connection_get_id (connection), @@ -2594,49 +2639,17 @@ connection_op_timeout_cb (gpointer user_data) return G_SOURCE_REMOVE; } -static void -destroy_queue_element (gpointer data) -{ - g_signal_handlers_disconnect_matched (data, G_SIGNAL_MATCH_FUNC, 0, 0, 0, - down_active_connection_state_cb, NULL); - g_object_unref (data); -} - -static void -connection_cb_info_finish (ConnectionCbInfo *info, gpointer connection) -{ - if (connection) { - info->queue = g_slist_remove (info->queue, connection); - g_object_unref (G_OBJECT (connection)); - } else { - g_slist_free_full (info->queue, destroy_queue_element); - info->queue = NULL; - } - - if (info->queue) - return; - - if (info->timeout_id) - g_source_remove (info->timeout_id); - - nm_clear_g_cancellable (&info->cancellable); - - g_signal_handlers_disconnect_by_func (info->nmc->client, connection_removed_cb, info); - g_slice_free (ConnectionCbInfo, info); - quit (); -} - static NMCResultCode do_connection_down (NmCli *nmc, int argc, char **argv) { NMActiveConnection *active; ConnectionCbInfo *info = NULL; const GPtrArray *active_cons; - GSList *queue = NULL, *iter, *next; - char **arg_arr = NULL; + gs_strfreev char **arg_arr = NULL; char **arg_ptr; int arg_num; - int idx = 0; + guint i; + gs_unref_ptrarray GPtrArray *found_active_cons = NULL; if (nmc->timeout == -1) nmc->timeout = 10; @@ -2657,108 +2670,88 @@ do_connection_down (NmCli *nmc, int argc, char **argv) } if (arg_num == 0) { g_string_printf (nmc->return_text, _("Error: No connection specified.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } } /* Get active connections */ active_cons = nm_client_get_active_connections (nmc->client); while (arg_num > 0) { - const GPtrArray *connections; const char *selector = NULL; if (arg_num == 1 && nmc->complete) nmc_complete_strings (*arg_ptr, "id", "uuid", "path", "apath", NULL); - if ( strcmp (*arg_ptr, "id") == 0 - || strcmp (*arg_ptr, "uuid") == 0 - || strcmp (*arg_ptr, "path") == 0 - || strcmp (*arg_ptr, "apath") == 0) { - + if (NM_IN_STRSET (*arg_ptr, "id", "uuid", "path", "apath")) { selector = *arg_ptr; arg_num--; arg_ptr++; if (!arg_num) { g_string_printf (nmc->return_text, _("Error: %s argument is missing."), selector); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } } - connections = nm_client_get_connections (nmc->client); - active = find_active_connection (active_cons, connections, selector, *arg_ptr, &idx, - arg_num == 1 && nmc->complete); - if (active) { - /* Check if the connection is unique. */ - /* Calling down for the same connection repeatedly would result in - * NM responding for the last D-Bus call only and we would stall. */ - if (!g_slist_find (queue, active)) - queue = g_slist_prepend (queue, g_object_ref (active)); - } else { + active = nmc_find_active_connection (active_cons, + selector, + *arg_ptr, + &found_active_cons, + arg_num == 1 && nmc->complete); + if (!active) { if (!nmc->complete) g_printerr (_("Error: '%s' is not an active connection.\n"), *arg_ptr); g_string_printf (nmc->return_text, _("Error: not all active connections found.")); nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; } - if (idx == 0) - next_arg (nmc->ask ? NULL : nmc, &arg_num, &arg_ptr, NULL); + next_arg (nmc->ask ? NULL : nmc, &arg_num, &arg_ptr, NULL); } - if (!queue) { + if (!found_active_cons) { g_string_printf (nmc->return_text, _("Error: no active connection provided.")); - nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; - goto finish; - } else if (nmc->complete) { - g_slist_free (queue); - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_NOT_FOUND); } - queue = g_slist_reverse (queue); + nm_assert (found_active_cons->len > 0); + + if (nmc->complete) + return nmc->return_value; if (nmc->timeout > 0) { nmc->should_wait++; info = g_slice_new0 (ConnectionCbInfo); info->nmc = nmc; - info->queue = queue; - info->timeout_id = g_timeout_add_seconds (nmc->timeout, connection_op_timeout_cb, info); - } - - iter = queue; - while (iter) { - GError *error = NULL; - - next = g_slist_next (iter); - active = iter->data; - - if (info) { + info->obj_list = g_ptr_array_sized_new (found_active_cons->len); + for (i = 0; i < found_active_cons->len; i++) { + active = found_active_cons->pdata[i]; + g_ptr_array_add (info->obj_list, g_object_ref (active)); g_signal_connect (active, "notify::" NM_ACTIVE_CONNECTION_STATE, G_CALLBACK (down_active_connection_state_cb), info); } + info->timeout_id = g_timeout_add_seconds (nmc->timeout, connection_op_timeout_cb, info); + } + + for (i = 0; i < found_active_cons->len; i++) { + GError *error = NULL; + + active = found_active_cons->pdata[i]; - /* Now deactivate the connection */ if (!nm_client_deactivate_connection (nmc->client, active, NULL, &error)) { g_print (_("Connection '%s' deactivation failed: %s\n"), nm_active_connection_get_id (active), error->message); - g_error_free (error); + g_clear_error (&error); if (info) { g_signal_handlers_disconnect_by_func (active, down_active_connection_state_cb, info); - /* Remove the active connection from @queue */ connection_cb_info_finish (info, active); } } - - iter = next; } -finish: - g_strfreev (arg_arr); return nmc->return_value; } @@ -3578,6 +3571,7 @@ set_property (NMConnection *connection, */ if (value) { unsigned long idx; + if (nmc_string_to_uint (value, TRUE, 0, G_MAXUINT32, &idx)) nmc_setting_remove_property_option (setting, property_name, NULL, idx, &local); else @@ -4440,8 +4434,8 @@ nmcli_con_add_tab_completion (const char *text, int start, int end) NMMetaSettingType s; char **match_array = NULL; rl_compentry_func_t *generator_func = NULL; - gs_free char *no = g_strdup_printf ("[%s]: ", gettext ("no")); - gs_free char *yes = g_strdup_printf ("[%s]: ", gettext ("yes")); + gs_free char *no = g_strdup_printf ("[%s]: ", _("no")); + gs_free char *yes = g_strdup_printf ("[%s]: ", _("yes")); /* Disable readline's default filename completion */ rl_attempted_completion_over = 1; @@ -4724,9 +4718,9 @@ again: static NMCResultCode do_connection_add (NmCli *nmc, int argc, char **argv) { - NMConnection *connection = NULL; + gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; - GError *error = NULL; + gs_free_error GError *error = NULL; AddConnectionInfo *info = NULL; gboolean save_bool = TRUE; gboolean seen_dash_dash = FALSE; @@ -4738,27 +4732,24 @@ do_connection_add (NmCli *nmc, int argc, char **argv) nmc->return_value = NMC_RESULT_SUCCESS; - /* Create a new connection object */ connection = nm_simple_connection_new (); - /* Build up the 'connection' setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); nm_connection_add_setting (connection, NM_SETTING (s_con)); read_properties: + g_clear_error (&error); /* Get the arguments from the command line if any */ if (argc && !nmc_read_connection_properties (nmc, connection, &argc, &argv, &error)) { if (g_strcmp0 (*argv, "--") == 0 && !seen_dash_dash) { /* This is for compatibility with older nmcli that required * options and properties to be separated with "--" */ - g_clear_error (&error); seen_dash_dash = TRUE; next_arg (nmc, &argc, &argv, NULL); goto read_properties; } else if (g_strcmp0 (*argv, "save") == 0) { /* It would be better if "save" was a separate argument and not * mixed with properties, but there's not much we can do about it now. */ - g_clear_error (&error); argc--; argv++; if (!argc) { @@ -4768,11 +4759,11 @@ read_properties: nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; goto finish; } + g_clear_error (&error); if (!nmc_string_to_bool (*argv, &save_bool, &error)) { g_string_printf (nmc->return_text, _("Error: 'save': %s."), error->message); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_clear_error (&error); goto finish; } next_arg (nmc, &argc, &argv, NULL); @@ -4781,7 +4772,6 @@ read_properties: g_string_assign (nmc->return_text, error->message); nmc->return_value = error->code; - g_clear_error (&error); goto finish; } @@ -4891,9 +4881,6 @@ read_properties: finish: reset_options (); - if (connection) - g_object_unref (connection); - return nmc->return_value; } @@ -6261,8 +6248,8 @@ static gboolean progress_activation_editor_cb (gpointer user_data) { MonitorACInfo *info = (MonitorACInfo *) user_data; - NMDevice *device = info->device; - NMActiveConnection *ac = info->ac; + gs_unref_object NMDevice *device = info->device; + gs_unref_object NMActiveConnection *ac = info->ac; NMActiveConnectionState ac_state; NMDeviceState dev_state; @@ -6279,12 +6266,12 @@ progress_activation_editor_cb (gpointer user_data) nmc_terminal_erase_line (); g_print (_("Connection successfully activated (D-Bus active path: %s)\n"), nm_object_get_path (NM_OBJECT (ac))); - goto finish; /* we are done */ + goto finish; } else if ( ac_state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED || dev_state == NM_DEVICE_STATE_FAILED) { nmc_terminal_erase_line (); g_print (_("Error: Connection activation failed.\n")); - goto finish; /* we are done */ + goto finish; } if (info->nmc->secret_agent) { @@ -6299,10 +6286,6 @@ progress_activation_editor_cb (gpointer user_data) finish: info->monitor_id = 0; - if (device) - g_object_unref (device); - if (ac) - g_object_unref (ac); return FALSE; } @@ -6407,7 +6390,7 @@ refresh_remote_connection (GWeakRef *weak, NMRemoteConnection **remote) { gboolean previous; - g_return_val_if_fail (remote != NULL, FALSE); + g_return_val_if_fail (remote, FALSE); previous = (*remote != NULL); if (*remote) @@ -6456,16 +6439,10 @@ property_edit_submenu (NmCli *nmc, const char *prop_name) { NmcEditorSubCmd cmdsub; - gboolean cmd_property_loop = TRUE; - gboolean should_quit = FALSE; - char *prop_val_user; gboolean set_result; GError *tmp_err = NULL; - char *prompt; - gboolean dirty; - GValue prop_g_value = G_VALUE_INIT; + gs_free char *prompt = NULL; gboolean temp_changes; - gboolean removed; /* Set global variable for use in TAB completion */ nmc_tab_completion.property = prop_name; @@ -6473,15 +6450,20 @@ property_edit_submenu (NmCli *nmc, prompt = nmc_colorize (&nmc->nmc_config, NM_META_COLOR_PROMPT, "nmcli %s.%s> ", nm_setting_get_name (curr_setting), prop_name); - while (cmd_property_loop) { - char *cmd_property_user; - char *cmd_property_arg; + for (;;) { + gs_free char *cmd_property_user = NULL; + gs_free char *cmd_property_arg = NULL; + gs_free char *prop_val_user = NULL; + nm_auto_unset_gvalue GValue prop_g_value = G_VALUE_INIT; + gboolean removed; + gboolean dirty; /* Get the remote connection again, it may have disapeared */ removed = refresh_remote_connection (rem_con_weak, rem_con); - if (removed) + if (removed) { g_print (_("The connection profile has been removed from another client. " "You may type 'save' in the main menu to restore it.\n")); + } /* Connection is dirty? (not saved or differs from the saved) */ dirty = is_connection_dirty (connection, *rem_con); @@ -6490,7 +6472,7 @@ property_edit_submenu (NmCli *nmc, editor_show_status_line (connection, dirty, temp_changes); cmd_property_user = nmc_readline ("%s", prompt); - if (!cmd_property_user || *cmd_property_user == '\0') + if (!cmd_property_user || !*cmd_property_user) continue; cmdsub = parse_editor_sub_cmd (g_strstrip (cmd_property_user), &cmd_property_arg); @@ -6526,7 +6508,6 @@ property_edit_submenu (NmCli *nmc, } set_result = nmc_setting_set_property (curr_setting, prop_name, prop_val_user, &tmp_err); - g_free (prop_val_user); if (!set_result) { g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message); g_clear_error (&tmp_err); @@ -6537,8 +6518,6 @@ property_edit_submenu (NmCli *nmc, g_signal_handlers_unblock_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL); } } - if (G_IS_VALUE (&prop_g_value)) - g_value_unset (&prop_g_value); break; case NMC_EDITOR_SUB_CMD_CHANGE: @@ -6556,9 +6535,6 @@ property_edit_submenu (NmCli *nmc, nmc_property_set_gvalue (curr_setting, prop_name, &prop_g_value); g_signal_handlers_unblock_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL); } - g_free (prop_val_user); - if (G_IS_VALUE (&prop_g_value)) - g_value_unset (&prop_g_value); break; case NMC_EDITOR_SUB_CMD_REMOVE: @@ -6611,8 +6587,7 @@ property_edit_submenu (NmCli *nmc, case NMC_EDITOR_SUB_CMD_BACK: /* Set global variable for use in TAB completion */ nmc_tab_completion.property = NULL; - cmd_property_loop = FALSE; - break; + return TRUE; case NMC_EDITOR_SUB_CMD_HELP: editor_sub_usage (cmd_property_arg); @@ -6620,14 +6595,10 @@ property_edit_submenu (NmCli *nmc, case NMC_EDITOR_SUB_CMD_QUIT: if (is_connection_dirty (connection, *rem_con)) { - if (confirm_quit ()) { - cmd_property_loop = FALSE; - should_quit = TRUE; /* we will quit nmcli */ - } - } else { - cmd_property_loop = FALSE; - should_quit = TRUE; /* we will quit nmcli */ - } + if (confirm_quit ()) + return FALSE; + } else + return FALSE; break; case NMC_EDITOR_SUB_CMD_UNKNOWN: @@ -6635,12 +6606,7 @@ property_edit_submenu (NmCli *nmc, g_print (_("Unknown command: '%s'\n"), cmd_property_user); break; } - g_free (cmd_property_user); - g_free (cmd_property_arg); } - g_free (prompt); - - return !should_quit; } /* @@ -6845,7 +6811,6 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t gs_free char *valid_settings_str = NULL; const char *s_type = NULL; AddConnectionInfo *info = NULL; - gboolean dirty; gboolean temp_changes; GError *err1 = NULL; NmcEditorMenuContext menu_ctx = { 0 }; @@ -6874,6 +6839,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t gs_free char *cmd_arg_s = NULL; gs_free char *cmd_arg_p = NULL; gs_free char *cmd_arg_v = NULL; + gboolean dirty; /* Connection is dirty? (not saved or differs from the saved) */ dirty = is_connection_dirty (connection, rem_con); @@ -6881,17 +6847,18 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t if (nmc->editor_status_line) editor_show_status_line (connection, dirty, temp_changes); - /* Read user input */ cmd_user = nmc_readline ("%s", menu_ctx.main_prompt); /* Get the remote connection again, it may have disapeared */ removed = refresh_remote_connection (&weak, &rem_con); - if (removed) + if (removed) { g_print (_("The connection profile has been removed from another client. " "You may type 'save' to restore it.\n")); + } - if (!cmd_user || *cmd_user == '\0') + if (!cmd_user || !*cmd_user) continue; + cmd = parse_editor_main_cmd (g_strstrip (cmd_user), &cmd_arg); split_editor_main_cmd_args (cmd_arg, &cmd_arg_s, &cmd_arg_p, &cmd_arg_v); @@ -7241,7 +7208,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t case NMC_EDITOR_MAIN_CMD_PRINT: /* Print current connection settings/properties */ if (cmd_arg) { - if (strcmp (cmd_arg, "all") == 0) + if (nm_streq (cmd_arg, "all")) editor_show_connection (connection, nmc); else { NMSetting *ss = NULL; @@ -7705,28 +7672,24 @@ static NMCResultCode do_connection_edit (NmCli *nmc, int argc, char **argv) { const GPtrArray *connections; - NMConnection *connection = NULL; + gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; const char *connection_type; - char *uuid; - char *default_name = NULL; const char *type = NULL; - char *type_ask = NULL; const char *con_name = NULL; const char *con = NULL; const char *con_id = NULL; const char *con_uuid = NULL; const char *con_path = NULL; const char *selector = NULL; - char *tmp_str; - GError *error = NULL; + gs_free_error GError *error = NULL; GError *err1 = NULL; - nmc_arg_t exp_args[] = { {"type", TRUE, &type, FALSE}, - {"con-name", TRUE, &con_name, FALSE}, - {"id", TRUE, &con_id, FALSE}, - {"uuid", TRUE, &con_uuid, FALSE}, - {"path", TRUE, &con_path, FALSE}, - {NULL} }; + nmc_arg_t exp_args[] = { { "type", TRUE, &type, FALSE }, + { "con-name", TRUE, &con_name, FALSE }, + { "id", TRUE, &con_id, FALSE }, + { "uuid", TRUE, &con_uuid, FALSE }, + { "path", TRUE, &con_path, FALSE }, + { NULL } }; next_arg (nmc, &argc, &argv, NULL); if (argc == 1 && nmc->complete) @@ -7739,9 +7702,7 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) else { if (!nmc_parse_args (exp_args, TRUE, &argc, &argv, &error)) { g_string_assign (nmc->return_text, error->message); - nmc->return_value = error->code; - g_clear_error (&error); - goto error; + NMC_RETURN (nmc, error->code); } } @@ -7768,8 +7729,7 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) } else { g_string_printf (nmc->return_text, _("Error: only one of 'id', uuid, or 'path' can be provided.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } } @@ -7779,12 +7739,11 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) found_con = nmc_find_connection (connections, selector, con, NULL, nmc->complete); if (nmc->complete) - goto error; + return nmc->return_value; if (!found_con) { g_string_printf (nmc->return_text, _("Error: Unknown connection '%s'."), con); - nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; - goto error; + NMC_RETURN (nmc, NMC_RESULT_ERROR_NOT_FOUND); } /* Duplicate the connection and use that so that we need not @@ -7796,7 +7755,6 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) update_secrets_in_connection (NM_REMOTE_CONNECTION (found_con), connection); s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); connection_type = nm_setting_connection_get_connection_type (s_con); if (type) @@ -7812,18 +7770,23 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) editor_init_existing_connection (connection); } else { const char *slave_type = NULL; + gs_free char *uuid = NULL; + gs_free char *default_name = NULL; + gs_free char *tmp_str = NULL; /* New connection */ if (nmc->complete) { if (type && argc == 0) nmc_complete_connection_type (type); - goto error; + return nmc->return_value; } connection_type = check_valid_name_toplevel (type, &slave_type, &err1); tmp_str = get_valid_options_string_toplevel (); while (!connection_type) { + gs_free char *type_ask = NULL; + if (!type) g_print (_("Valid connection types: %s\n"), tmp_str); else @@ -7833,14 +7796,11 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) type_ask = nmc_readline (EDITOR_PROMPT_CON_TYPE); type = type_ask = type_ask ? g_strstrip (type_ask) : NULL; connection_type = check_valid_name_toplevel (type_ask, &slave_type, &err1); - g_free (type_ask); } - g_free (tmp_str); + nm_clear_g_free (&tmp_str); - /* Create a new connection object */ connection = nm_simple_connection_new (); - /* Build up the 'connection' setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); uuid = nm_utils_uuid_generate (); if (con_name) @@ -7855,8 +7815,6 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_TYPE, connection_type, NULL); - g_free (uuid); - g_free (default_name); nm_connection_add_setting (connection, NM_SETTING (s_con)); /* Initialize the new connection so that it is valid from the start */ @@ -7879,7 +7837,6 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) g_print (_("Type 'describe [.]' for detailed property description.")); g_print ("\n\n"); - /* Set global variables for use in TAB completion */ nmc_tab_completion.nmc = nmc; nmc_tab_completion.con_type = g_strdup (connection_type); nmc_tab_completion.connection = connection; @@ -7887,15 +7844,9 @@ do_connection_edit (NmCli *nmc, int argc, char **argv) /* Run menu loop */ editor_menu_main (nmc, connection, connection_type); - if (connection) - g_object_unref (connection); - g_free (nmc_tab_completion.con_type); - - return nmc->return_value; - -error: - g_assert (!connection); - g_free (type_ask); + nmc_tab_completion.nmc = NULL; + nm_clear_g_free (&nmc_tab_completion.con_type); + nmc_tab_completion.connection = NULL; return nmc->return_value; } @@ -7905,8 +7856,8 @@ modify_connection_cb (GObject *connection, GAsyncResult *result, gpointer user_data) { - NmCli *nmc = (NmCli *) user_data; - GError *error = NULL; + NmCli *nmc = user_data; + gs_free_error GError *error = NULL; if (!nm_remote_connection_commit_changes_finish (NM_REMOTE_CONNECTION (connection), result, &error)) { @@ -7914,13 +7865,13 @@ modify_connection_cb (GObject *connection, _("Error: Failed to modify connection '%s': %s"), nm_connection_get_id (NM_CONNECTION (connection)), error->message); - g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; } else { - if (nmc->nmc_config.print_output == NMC_PRINT_PRETTY) + if (nmc->nmc_config.print_output == NMC_PRINT_PRETTY) { g_print (_("Connection '%s' (%s) successfully modified.\n"), nm_connection_get_id (NM_CONNECTION (connection)), nm_connection_get_uuid (NM_CONNECTION (connection))); + } } quit (); } @@ -7932,20 +7883,18 @@ do_connection_modify (NmCli *nmc, { NMConnection *connection = NULL; NMRemoteConnection *rc = NULL; - GError *error = NULL; + gs_free_error GError *error = NULL; gboolean temporary = FALSE; - /* Check --temporary */ if (next_arg (nmc, &argc, &argv, "--temporary", NULL) > 0) { temporary = TRUE; next_arg (nmc, &argc, &argv, NULL); } - connection = get_connection (nmc, &argc, &argv, NULL, &error); + connection = get_connection (nmc, &argc, &argv, NULL, NULL, NULL, &error); if (!connection) { g_string_printf (nmc->return_text, _("Error: %s."), error->message); - nmc->return_value = error->code; - goto finish; + NMC_RETURN (nmc, error->code); } rc = nm_client_get_connection_by_uuid (nmc->client, @@ -7953,24 +7902,20 @@ do_connection_modify (NmCli *nmc, if (!rc) { g_string_printf (nmc->return_text, _("Error: Unknown connection '%s'."), nm_connection_get_uuid (connection)); - nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_NOT_FOUND); } if (!nmc_read_connection_properties (nmc, NM_CONNECTION (rc), &argc, &argv, &error)) { g_string_assign (nmc->return_text, error->message); - nmc->return_value = error->code; - g_clear_error (&error); - goto finish; + NMC_RETURN (nmc, error->code); } if (nmc->complete) - goto finish; + return nmc->return_value; update_connection (!temporary, rc, modify_connection_cb, nmc); nmc->should_wait++; -finish: return nmc->return_value; } @@ -8018,11 +7963,11 @@ static NMCResultCode do_connection_clone (NmCli *nmc, int argc, char **argv) { NMConnection *connection = NULL; - NMConnection *new_connection = NULL; + gs_unref_object NMConnection *new_connection = NULL; NMSettingConnection *s_con; CloneConnectionInfo *info; const char *new_name; - char *new_name_ask = NULL; + gs_free char *new_name_ask = NULL; char *uuid; gboolean temporary = FALSE; char **arg_arr = NULL; @@ -8052,15 +7997,14 @@ do_connection_clone (NmCli *nmc, int argc, char **argv) argc_ptr = &arg_num; } - connection = get_connection (nmc, argc_ptr, argv_ptr, NULL, &error); + connection = get_connection (nmc, argc_ptr, argv_ptr, NULL, NULL, NULL, &error); if (!connection) { g_string_printf (nmc->return_text, _("Error: %s."), error->message); - nmc->return_value = error->code; - goto finish; + NMC_RETURN (nmc, error->code); } if (nmc->complete) - goto finish; + return nmc->return_value; if (argv[0]) new_name = *argv; @@ -8068,14 +8012,12 @@ do_connection_clone (NmCli *nmc, int argc, char **argv) new_name = new_name_ask = nmc_readline (_("New connection name: ")); else { g_string_printf (nmc->return_text, _("Error: argument is missing.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } if (next_arg (nmc->ask ? NULL : nmc, argc_ptr, argv_ptr, NULL) == 0) { g_string_printf (nmc->return_text, _("Error: unknown extra argument: '%s'."), *argv); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } /* Copy the connection */ @@ -8107,11 +8049,6 @@ do_connection_clone (NmCli *nmc, int argc, char **argv) info); nmc->should_wait++; -finish: - if (new_connection) - g_object_unref (new_connection); - g_free (new_name_ask); - return nmc->return_value; } @@ -8141,12 +8078,12 @@ do_connection_delete (NmCli *nmc, int argc, char **argv) { NMConnection *connection; ConnectionCbInfo *info = NULL; - GSList *queue = NULL, *iter; - char **arg_arr = NULL, *old_arg; + gs_strfreev char **arg_arr = NULL; char **arg_ptr; + guint i; int arg_num; - GString *invalid_cons = NULL; - int pos = 0; + nm_auto_free_gstring GString *invalid_cons = NULL; + gs_unref_ptrarray GPtrArray *found_cons = NULL; GError *error = NULL; if (nmc->timeout == -1) @@ -8176,15 +8113,10 @@ do_connection_delete (NmCli *nmc, int argc, char **argv) } while (arg_num > 0) { - old_arg = *arg_ptr; - connection = get_connection (nmc, &arg_num, &arg_ptr, &pos, &error); - if (connection) { - /* Check if the connection is unique. */ - /* Calling delete for the same connection repeatedly would result in - * NM responding for the last D-Bus call only and we would stall. */ - if (!g_slist_find (queue, connection)) - queue = g_slist_prepend (queue, g_object_ref (connection)); - } else { + const char *cur_selector, *cur_value; + + connection = get_connection (nmc, &arg_num, &arg_ptr, &cur_selector, &cur_value, &found_cons, &error); + if (!connection) { if (!nmc->complete) g_printerr (_("Error: %s.\n"), error->message); g_string_printf (nmc->return_text, _("Error: not all connections found.")); @@ -8196,23 +8128,31 @@ do_connection_delete (NmCli *nmc, int argc, char **argv) if (!invalid_cons) invalid_cons = g_string_new (NULL); - g_string_append_printf (invalid_cons, "'%s', ", old_arg); + if (cur_selector) + g_string_append_printf (invalid_cons, "%s '%s', ", cur_selector, cur_value); + else + g_string_append_printf (invalid_cons, "'%s', ", cur_value); } } - if (!queue) { - g_string_printf (nmc->return_text, _("Error: No connection specified.")); - nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; - goto finish; - } else if (nmc->complete) { - g_slist_free (queue); + if (!found_cons) { + if (!invalid_cons) { + g_string_printf (nmc->return_text, _("Error: No connection specified.")); + nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; + } goto finish; } - queue = g_slist_reverse (queue); + + if (nmc->complete) + goto finish; info = g_slice_new0 (ConnectionCbInfo); info->nmc = nmc; - info->queue = queue; + info->obj_list = g_ptr_array_sized_new (found_cons->len); + for (i = 0; i < found_cons->len; i++) { + connection = found_cons->pdata[i]; + g_ptr_array_add (info->obj_list, g_object_ref (connection)); + } info->timeout_id = g_timeout_add_seconds (nmc->timeout, connection_op_timeout_cb, info); info->cancellable = g_cancellable_new (); @@ -8222,10 +8162,10 @@ do_connection_delete (NmCli *nmc, int argc, char **argv) g_signal_connect (nmc->client, NM_CLIENT_CONNECTION_REMOVED, G_CALLBACK (connection_removed_cb), info); - /* Now delete the connections */ - for (iter = queue; iter; iter = g_slist_next (iter)) - nm_remote_connection_delete_async (NM_REMOTE_CONNECTION (iter->data), + for (i = 0; i < found_cons->len; i++) { + nm_remote_connection_delete_async (NM_REMOTE_CONNECTION (found_cons->pdata[i]), info->cancellable, delete_cb, info); + } finish: if (invalid_cons) { @@ -8233,9 +8173,7 @@ finish: g_string_printf (nmc->return_text, _("Error: cannot delete unknown connection(s): %s."), invalid_cons->str); nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; - g_string_free (invalid_cons, TRUE); } - g_strfreev (arg_arr); return nmc->return_value; } @@ -8285,31 +8223,21 @@ static NMCResultCode do_connection_monitor (NmCli *nmc, int argc, char **argv) { GError *error = NULL; + guint i; + gs_unref_ptrarray GPtrArray *found_cons = NULL; + const GPtrArray *connections = NULL; next_arg (nmc, &argc, &argv, NULL); if (argc == 0) { /* No connections specified. Monitor all. */ - const GPtrArray *connections; - int i; /* nmc_do_cmd() should not call this with argc=0. */ g_assert (!nmc->complete); connections = nm_client_get_connections (nmc->client); - for (i = 0; i < connections->len; i++) - connection_watch (nmc, g_ptr_array_index (connections, i)); - - /* We'll watch the connection additions too, never exit. */ - nmc->should_wait++; - g_signal_connect (nmc->client, NM_CLIENT_CONNECTION_ADDED, G_CALLBACK (connection_added), nmc); } else { - /* Look up the specified connections and watch them. */ - NMConnection *connection; - int pos = 0; - - do { - connection = get_connection (nmc, &argc, &argv, &pos, &error); - if (!connection) { + while (argc > 0) { + if (!get_connection (nmc, &argc, &argv, NULL, NULL, &found_cons, &error)) { if (!nmc->complete) g_printerr (_("Error: %s.\n"), error->message); g_string_printf (nmc->return_text, _("Error: not all connections found.")); @@ -8319,8 +8247,17 @@ do_connection_monitor (NmCli *nmc, int argc, char **argv) if (nmc->complete) continue; - connection_watch (nmc, connection); - } while (argc > 0); + connections = found_cons; + } + } + + for (i = 0; i < connections->len; i++) + connection_watch (nmc, connections->pdata[i]); + + if (argc == 0) { + /* We'll watch the connection additions too, never exit. */ + nmc->should_wait++; + g_signal_connect (nmc->client, NM_CLIENT_CONNECTION_ADDED, G_CALLBACK (connection_added), nmc); } if (nmc->complete) @@ -8393,11 +8330,12 @@ do_connection_load (NmCli *nmc, int argc, char **argv) static NMCResultCode do_connection_import (NmCli *nmc, int argc, char **argv) { - GError *error = NULL; + gs_free_error GError *error = NULL; const char *type = NULL, *filename = NULL; - char *type_ask = NULL, *filename_ask = NULL; + gs_free char *type_ask = NULL; + gs_free char *filename_ask = NULL; AddConnectionInfo *info; - NMConnection *connection = NULL; + gs_unref_object NMConnection *connection = NULL; NMVpnEditorPlugin *plugin; gs_free char *service_type = NULL; gboolean temporary = FALSE; @@ -8419,8 +8357,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv) filename = filename_ask = filename_ask ? g_strstrip (filename_ask) : NULL; } else { g_string_printf (nmc->return_text, _("Error: No arguments provided.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } } @@ -8433,8 +8370,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv) argv++; if (!argc) { g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } if (argc == 1 && nmc->complete) @@ -8450,8 +8386,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv) argv++; if (!argc) { g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } if (argc == 1 && nmc->complete) nmc->return_value = NMC_RESULT_COMPLETE_FILE; @@ -8461,32 +8396,28 @@ do_connection_import (NmCli *nmc, int argc, char **argv) g_printerr (_("Warning: 'file' already specified, ignoring extra one.\n")); } else { g_string_printf (nmc->return_text, _("Unknown parameter: %s"), *argv); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } next_arg (nmc, &argc, &argv, NULL); } if (nmc->complete) - goto finish; + return nmc->return_value; if (!type) { g_string_printf (nmc->return_text, _("Error: 'type' argument is required.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } if (!filename) { g_string_printf (nmc->return_text, _("Error: 'file' argument is required.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT); } service_type = nm_vpn_plugin_info_list_find_service_type (nm_vpn_get_plugin_infos (), type); if (!service_type) { g_string_printf (nmc->return_text, _("Error: failed to find VPN plugin for %s."), type); - nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_UNKNOWN); } /* Import VPN configuration */ @@ -8494,16 +8425,14 @@ do_connection_import (NmCli *nmc, int argc, char **argv) if (!plugin) { g_string_printf (nmc->return_text, _("Error: failed to load VPN plugin: %s."), error->message); - nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_UNKNOWN); } connection = nm_vpn_editor_plugin_import (plugin, filename, &error); if (!connection) { g_string_printf (nmc->return_text, _("Error: failed to import '%s': %s."), filename, error->message); - nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; - goto finish; + NMC_RETURN (nmc, NMC_RESULT_ERROR_UNKNOWN); } info = g_malloc0 (sizeof (AddConnectionInfo)); @@ -8518,12 +8447,6 @@ do_connection_import (NmCli *nmc, int argc, char **argv) info); nmc->should_wait++; -finish: - if (connection) - g_object_unref (connection); - g_clear_error (&error); - g_free (type_ask); - g_free (filename_ask); return nmc->return_value; } @@ -8532,12 +8455,11 @@ do_connection_export (NmCli *nmc, int argc, char **argv) { NMConnection *connection = NULL; const char *out_name = NULL; - char *name_ask = NULL; - char *out_name_ask = NULL; + gs_free char *out_name_ask = NULL; const char *path = NULL; const char *type = NULL; NMVpnEditorPlugin *plugin; - GError *error = NULL; + gs_free_error GError *error = NULL; char tmpfile[] = "/tmp/nmcli-export-temp-XXXXXX"; char **arg_arr = NULL; int arg_num; @@ -8561,7 +8483,7 @@ do_connection_export (NmCli *nmc, int argc, char **argv) argc_ptr = &arg_num; } - connection = get_connection (nmc, argc_ptr, argv_ptr, NULL, &error); + connection = get_connection (nmc, argc_ptr, argv_ptr, NULL, NULL, NULL, &error); if (!connection) { g_string_printf (nmc->return_text, _("Error: %s."), error->message); nmc->return_value = error->code; @@ -8602,14 +8524,14 @@ do_connection_export (NmCli *nmc, int argc, char **argv) if (out_name) path = out_name; else { - int fd; + nm_auto_close int fd = -1; + fd = g_mkstemp (tmpfile); if (fd == -1) { g_string_printf (nmc->return_text, _("Error: failed to create temporary file %s."), tmpfile); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto finish; } - nm_close (fd); path = tmpfile; } @@ -8622,8 +8544,9 @@ do_connection_export (NmCli *nmc, int argc, char **argv) /* No output file -> copy data to stdout */ if (!out_name) { - char *contents = NULL; + gs_free char *contents = NULL; gsize len = 0; + if (!g_file_get_contents (path, &contents, &len, &error)) { g_string_printf (nmc->return_text, _("Error: failed to read temporary file '%s': %s."), path, error->message); @@ -8631,15 +8554,11 @@ do_connection_export (NmCli *nmc, int argc, char **argv) goto finish; } g_print ("%s", contents); - g_free (contents); } finish: if (!out_name && path) unlink (path); - g_clear_error (&error); - g_free (name_ask); - g_free (out_name_ask); return nmc->return_value; } diff --git a/clients/cli/general.c b/clients/cli/general.c index f1a350c77d..841df8bdec 100644 --- a/clients/cli/general.c +++ b/clients/cli/general.c @@ -172,15 +172,7 @@ _NM_UTILS_LOOKUP_DEFINE (static, permission_result_to_color, NMClientPermissionR static const NmcMetaGenericInfo *const metagen_general_status[]; static gconstpointer -_metagen_general_status_get_fcn (const NMMetaEnvironment *environment, - gpointer environment_user_data, - const NmcMetaGenericInfo *info, - gpointer target, - NMMetaAccessorGetType get_type, - NMMetaAccessorGetFlags get_flags, - NMMetaAccessorGetOutFlags *out_flags, - gboolean *out_is_default, - gpointer *out_to_free) +_metagen_general_status_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) { NmCli *nmc = target; const char *value; @@ -280,15 +272,7 @@ static const NmcMetaGenericInfo *const metagen_general_status[_NMC_GENERIC_INFO_ /*****************************************************************************/ static gconstpointer -_metagen_general_permissions_get_fcn (const NMMetaEnvironment *environment, - gpointer environment_user_data, - const NmcMetaGenericInfo *info, - gpointer target, - NMMetaAccessorGetType get_type, - NMMetaAccessorGetFlags get_flags, - NMMetaAccessorGetOutFlags *out_flags, - gboolean *out_is_default, - gpointer *out_to_free) +_metagen_general_permissions_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) { NMClientPermission perm = GPOINTER_TO_UINT (target); NmCli *nmc = environment_user_data; @@ -329,15 +313,7 @@ typedef struct { } GetGeneralLoggingData; static gconstpointer -_metagen_general_logging_get_fcn (const NMMetaEnvironment *environment, - gpointer environment_user_data, - const NmcMetaGenericInfo *info, - gpointer target, - NMMetaAccessorGetType get_type, - NMMetaAccessorGetFlags get_flags, - NMMetaAccessorGetOutFlags *out_flags, - gboolean *out_is_default, - gpointer *out_to_free) +_metagen_general_logging_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) { NmCli *nmc = environment_user_data; GetGeneralLoggingData *d = target; diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index 1b176a66a9..61bf86dec5 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -141,6 +141,11 @@ typedef struct _NmCli { char *palette_buffer; /* Buffer with sequences for terminal-colors.d(5)-based coloring. */ } NmCli; +#define NMC_RETURN(nmc, rvalue) \ + G_STMT_START { \ + return ((nmc)->return_value = (rvalue)); \ + } G_STMT_END + extern NmCli nm_cli; /* Error quark for GError domain */ diff --git a/clients/cli/utils.c b/clients/cli/utils.c index 2c0e3b57d7..958da08100 100644 --- a/clients/cli/utils.c +++ b/clients/cli/utils.c @@ -93,7 +93,8 @@ _meta_type_nmc_generic_info_get_fcn (const NMMetaAbstractInfo *abstract_info, nm_assert (out_to_free || NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_COLOR)); if (info->get_fcn) { - return info->get_fcn (environment, environment_user_data, + return info->get_fcn (environment, + environment_user_data, info, target, get_type, get_flags, diff --git a/clients/cli/utils.h b/clients/cli/utils.h index 883e73188c..dc0ce08391 100644 --- a/clients/cli/utils.h +++ b/clients/cli/utils.h @@ -138,15 +138,19 @@ struct _NmcMetaGenericInfo { const char *name; const char *name_header; const NmcMetaGenericInfo *const*nested; - gconstpointer (*get_fcn) (const NMMetaEnvironment *environment, - gpointer environment_user_data, - const NmcMetaGenericInfo *info, - gpointer target, - NMMetaAccessorGetType get_type, - NMMetaAccessorGetFlags get_flags, - NMMetaAccessorGetOutFlags *out_flags, - gboolean *out_is_default, - gpointer *out_to_free); + +#define NMC_META_GENERIC_INFO_GET_FCN_ARGS \ + const NMMetaEnvironment *environment, \ + gpointer environment_user_data, \ + const NmcMetaGenericInfo *info, \ + gpointer target, \ + NMMetaAccessorGetType get_type, \ + NMMetaAccessorGetFlags get_flags, \ + NMMetaAccessorGetOutFlags *out_flags, \ + gboolean *out_is_default, \ + gpointer *out_to_free + + gconstpointer (*get_fcn) (NMC_META_GENERIC_INFO_GET_FCN_ARGS); }; #define NMC_META_GENERIC(n, ...) \ @@ -159,6 +163,52 @@ struct _NmcMetaGenericInfo { #define NMC_META_GENERIC_WITH_NESTED(n, nest, ...) \ NMC_META_GENERIC (n, .nested = (nest), __VA_ARGS__) +#define NMC_META_GENERIC_GROUP(_group_name, _nested, _name_header) \ + ((const NMMetaAbstractInfo *const*) ((const NmcMetaGenericInfo *const[]) { \ + NMC_META_GENERIC_WITH_NESTED (_group_name,_nested, .name_header = _name_header), \ + NULL, \ + })) + +static inline const char * +nmc_meta_generic_get_str_i18n (const char *s, NMMetaAccessorGetType get_type) +{ + if (!NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_PRETTY, + NM_META_ACCESSOR_GET_TYPE_PARSABLE)) + g_return_val_if_reached (NULL); + + if (!s) + return NULL; + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return gettext (s); + return s; +} + +static inline const char * +nmc_meta_generic_get_bool (gboolean val, NMMetaAccessorGetType get_type) +{ + return nmc_meta_generic_get_str_i18n (val ? N_("yes") : N_("no"), get_type); +} + +static inline char * +nmc_meta_generic_get_enum_with_detail (gint64 enum_val, const char *str_val, NMMetaAccessorGetType get_type) +{ + if (!NM_IN_SET (get_type, NM_META_ACCESSOR_GET_TYPE_PRETTY, + NM_META_ACCESSOR_GET_TYPE_PARSABLE)) + g_return_val_if_reached (NULL); + + if (!str_val) { + /* Pass %NULL for only printing the numeric value. */ + return g_strdup_printf ("%lld", (long long) enum_val); + } + + /* note that this function will always print "$NUM ($NICK)", also in PARSABLE + * mode. That might not be desired, but it's done for certain properties to preserve + * previous behavior. */ + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + return g_strdup_printf (_("%lld (%s)"), (long long) enum_val, gettext (str_val)); + return g_strdup_printf ("%lld (%s)", (long long) enum_val, str_val); +} + /*****************************************************************************/ gboolean nmc_print (const NmcConfig *nmc_config, diff --git a/clients/common/nm-client-utils.c b/clients/common/nm-client-utils.c index b4b4c1b9c4..f683c7ce81 100644 --- a/clients/common/nm-client-utils.c +++ b/clients/common/nm-client-utils.c @@ -26,6 +26,47 @@ #include "nm-device-bridge.h" #include "nm-device-team.h" +/*****************************************************************************/ + +static int +_nmc_objects_sort_by_path_cmp (gconstpointer pa, gconstpointer pb, gpointer user_data) +{ + NMObject *a = *((NMObject **) pa); + NMObject *b = *((NMObject **) pb); + + NM_CMP_SELF (a, b); + NM_CMP_RETURN (nm_utils_dbus_path_cmp (nm_object_get_path (a), + nm_object_get_path (b))); + return 0; +} + +const NMObject ** +nmc_objects_sort_by_path (const NMObject *const* objs, gssize len) +{ + const NMObject **arr; + gsize i, l; + + if (len < 0) + l = NM_PTRARRAY_LEN (objs); + else + l = len; + + arr = g_new (const NMObject *, l + 1); + for (i = 0; i < l; i++) + arr[i] = objs[i]; + arr[l] = NULL; + + if (l > 1) { + g_qsort_with_data (arr, + l, + sizeof (gpointer), + _nmc_objects_sort_by_path_cmp, + NULL); + } + return arr; +} + +/*****************************************************************************/ /* * Convert string to unsigned integer. * If required, the resulting number is checked to be in the range. diff --git a/clients/common/nm-client-utils.h b/clients/common/nm-client-utils.h index cd66276565..cc0b7330ac 100644 --- a/clients/common/nm-client-utils.h +++ b/clients/common/nm-client-utils.h @@ -30,6 +30,8 @@ typedef enum { NMC_TRI_STATE_UNKNOWN, } NMCTriStateValue; +const NMObject **nmc_objects_sort_by_path (const NMObject *const*objs, gssize len); + const char *nmc_string_is_valid (const char *input, const char **allowed, GError **error); gboolean nmc_string_to_uint (const char *str, diff --git a/clients/tests/test-client.check-on-disk/test_001-001.expected b/clients/tests/test-client.check-on-disk/test_001-001.expected index f3e8cf37ab..a6490d2e6a 100644 --- a/clients/tests/test-client.check-on-disk/test_001-001.expected +++ b/clients/tests/test-client.check-on-disk/test_001-001.expected @@ -1,4 +1,4 @@ -location: clients/tests/test-client.py:489:test_001()/1 +location: clients/tests/test-client.py:543:test_001()/1 cmd: $NMCLI lang: C returncode: 0 diff --git a/clients/tests/test-client.check-on-disk/test_001-002.expected b/clients/tests/test-client.check-on-disk/test_001-002.expected index 357cf3911b..03107ea54e 100644 --- a/clients/tests/test-client.check-on-disk/test_001-002.expected +++ b/clients/tests/test-client.check-on-disk/test_001-002.expected @@ -1,4 +1,4 @@ -location: clients/tests/test-client.py:490:test_001()/2 +location: clients/tests/test-client.py:543:test_001()/2 cmd: $NMCLI lang: pl_PL.UTF-8 returncode: 0 diff --git a/clients/tests/test-client.check-on-disk/test_001-003.expected b/clients/tests/test-client.check-on-disk/test_001-003.expected index ea06b8d0bb..5bbd500b4e 100644 --- a/clients/tests/test-client.check-on-disk/test_001-003.expected +++ b/clients/tests/test-client.check-on-disk/test_001-003.expected @@ -1,13 +1,20 @@ -location: clients/tests/test-client.py:492:test_001()/3 -cmd: $NMCLI -f AP -mode multiline -p d show wlan0 -lang: C -returncode: 10 -stdout: 0 bytes +location: clients/tests/test-client.py:543:test_001()/3 +cmd: $NMCLI +lang: de_DE.utf8 +returncode: 0 +stdout: 322 bytes +>>> +DNS configuration: + servers: 1.2.3.4 5.6.7.8 + +Rufen Sie »nmcli device show« auf, um vollständige Informationen über bekannte Geräte abzurufen +und »nmcli connection show« für eine Übersicht über aktive Verbindungsprofile. + + +Die Hilfeseiten nmcli(1) und nmcli-examples(5) geben vollständige Aufrufbeschreibungen. + +<<< +stderr: 0 bytes >>> <<< -stderr: 33 bytes ->>> -Error: Device 'wlan0' not found. - -<<< diff --git a/clients/tests/test-client.check-on-disk/test_001-004.expected b/clients/tests/test-client.check-on-disk/test_001-004.expected index 8e58d1493a..83f32d5a8f 100644 --- a/clients/tests/test-client.check-on-disk/test_001-004.expected +++ b/clients/tests/test-client.check-on-disk/test_001-004.expected @@ -1,13 +1,13 @@ -location: clients/tests/test-client.py:493:test_001()/4 +location: clients/tests/test-client.py:545:test_001()/4 cmd: $NMCLI -f AP -mode multiline -p d show wlan0 -lang: de_DE.utf8 +lang: C returncode: 10 stdout: 0 bytes >>> <<< -stderr: 47 bytes +stderr: 33 bytes >>> -Fehler: Gerät »wlan0« wurde nicht gefunden. +Error: Device 'wlan0' not found. <<< diff --git a/clients/tests/test-client.check-on-disk/test_001-005.expected b/clients/tests/test-client.check-on-disk/test_001-005.expected index c24b6cd32f..b27c224d16 100644 --- a/clients/tests/test-client.check-on-disk/test_001-005.expected +++ b/clients/tests/test-client.check-on-disk/test_001-005.expected @@ -1,13 +1,13 @@ -location: clients/tests/test-client.py:495:test_001()/5 -cmd: $NMCLI c s -lang: C -returncode: 0 -stdout: 26 bytes ->>> -NAME UUID TYPE DEVICE - -<<< -stderr: 0 bytes +location: clients/tests/test-client.py:545:test_001()/5 +cmd: $NMCLI -f AP -mode multiline -p d show wlan0 +lang: pl_PL.UTF-8 +returncode: 10 +stdout: 0 bytes >>> <<< +stderr: 49 bytes +>>> +Błąd: Nie odnaleziono urządzenia „wlan0”. + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_001-006.expected b/clients/tests/test-client.check-on-disk/test_001-006.expected index 66c0e9917d..724e80e1f5 100644 --- a/clients/tests/test-client.check-on-disk/test_001-006.expected +++ b/clients/tests/test-client.check-on-disk/test_001-006.expected @@ -1,13 +1,13 @@ -location: clients/tests/test-client.py:497:test_001()/6 -cmd: $NMCLI bogus s -lang: C -returncode: 2 +location: clients/tests/test-client.py:545:test_001()/6 +cmd: $NMCLI -f AP -mode multiline -p d show wlan0 +lang: de_DE.utf8 +returncode: 10 stdout: 0 bytes >>> <<< -stderr: 68 bytes +stderr: 47 bytes >>> -Error: argument 'bogus' not understood. Try passing --help instead. +Fehler: Gerät »wlan0« wurde nicht gefunden. <<< diff --git a/clients/tests/test-client.check-on-disk/test_001-007.expected b/clients/tests/test-client.check-on-disk/test_001-007.expected new file mode 100644 index 0000000000..56dc92a366 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_001-007.expected @@ -0,0 +1,13 @@ +location: clients/tests/test-client.py:547:test_001()/7 +cmd: $NMCLI c s +lang: C +returncode: 0 +stdout: 26 bytes +>>> +NAME UUID TYPE DEVICE + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_001-008.expected b/clients/tests/test-client.check-on-disk/test_001-008.expected new file mode 100644 index 0000000000..e2da59bd10 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_001-008.expected @@ -0,0 +1,13 @@ +location: clients/tests/test-client.py:547:test_001()/8 +cmd: $NMCLI c s +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 26 bytes +>>> +NAME UUID TYPE DEVICE + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_001-009.expected b/clients/tests/test-client.check-on-disk/test_001-009.expected new file mode 100644 index 0000000000..967df95b2a --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_001-009.expected @@ -0,0 +1,13 @@ +location: clients/tests/test-client.py:547:test_001()/9 +cmd: $NMCLI c s +lang: de_DE.utf8 +returncode: 0 +stdout: 26 bytes +>>> +NAME UUID TYPE DEVICE + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_001-010.expected b/clients/tests/test-client.check-on-disk/test_001-010.expected new file mode 100644 index 0000000000..876f8c52c3 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_001-010.expected @@ -0,0 +1,13 @@ +location: clients/tests/test-client.py:549:test_001()/10 +cmd: $NMCLI bogus s +lang: C +returncode: 2 +stdout: 0 bytes +>>> + +<<< +stderr: 68 bytes +>>> +Error: argument 'bogus' not understood. Try passing --help instead. + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_001-011.expected b/clients/tests/test-client.check-on-disk/test_001-011.expected new file mode 100644 index 0000000000..95101af11d --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_001-011.expected @@ -0,0 +1,13 @@ +location: clients/tests/test-client.py:549:test_001()/11 +cmd: $NMCLI bogus s +lang: pl_PL.UTF-8 +returncode: 2 +stdout: 0 bytes +>>> + +<<< +stderr: 87 bytes +>>> +Błąd: nie zrozumiano parametru „bogus”. Można użyć „--help” zamiast tego. + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_001-012.expected b/clients/tests/test-client.check-on-disk/test_001-012.expected new file mode 100644 index 0000000000..f2acfca91d --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_001-012.expected @@ -0,0 +1,13 @@ +location: clients/tests/test-client.py:549:test_001()/12 +cmd: $NMCLI bogus s +lang: de_DE.utf8 +returncode: 2 +stdout: 0 bytes +>>> + +<<< +stderr: 88 bytes +>>> +Fehler: Argument »bogus« wird nicht verstanden. Versuchen Sie stattdessen »--help«. + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-001.expected b/clients/tests/test-client.check-on-disk/test_002-001.expected index bc0d4f5dd9..c1f8737afa 100644 --- a/clients/tests/test-client.check-on-disk/test_002-001.expected +++ b/clients/tests/test-client.check-on-disk/test_002-001.expected @@ -1,4 +1,4 @@ -location: clients/tests/test-client.py:502:test_002()/1 +location: clients/tests/test-client.py:554:test_002()/1 cmd: $NMCLI d lang: C returncode: 0 diff --git a/clients/tests/test-client.check-on-disk/test_002-002.expected b/clients/tests/test-client.check-on-disk/test_002-002.expected index d516e2f849..a05f585c72 100644 --- a/clients/tests/test-client.check-on-disk/test_002-002.expected +++ b/clients/tests/test-client.check-on-disk/test_002-002.expected @@ -1,14 +1,14 @@ -location: clients/tests/test-client.py:504:test_002()/2 -cmd: $NMCLI -f all d -lang: C +location: clients/tests/test-client.py:554:test_002()/2 +cmd: $NMCLI d +lang: pl_PL.UTF-8 returncode: 0 -stdout: 530 bytes +stdout: 219 bytes >>> -DEVICE TYPE STATE DBUS-PATH CONNECTION CON-UUID CON-PATH -eth0 ethernet unavailable /org/freedesktop/NetworkManager/Devices/1 -- -- -- -wlan0 wifi unavailable /org/freedesktop/NetworkManager/Devices/2 -- -- -- -wlan1 wifi unavailable /org/freedesktop/NetworkManager/Devices/3 -- -- -- -wlan1 wifi unavailable /org/freedesktop/NetworkManager/Devices/4 -- -- -- +DEVICE TYPE STATE CONNECTION +eth0 ethernet niedostępne -- +wlan0 wifi niedostępne -- +wlan1 wifi niedostępne -- +wlan1 wifi niedostępne -- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-003.expected b/clients/tests/test-client.check-on-disk/test_002-003.expected index ff88393cc6..bea81cdb74 100644 --- a/clients/tests/test-client.check-on-disk/test_002-003.expected +++ b/clients/tests/test-client.check-on-disk/test_002-003.expected @@ -1,32 +1,14 @@ -location: clients/tests/test-client.py:506:test_002()/3 -cmd: $NMCLI -lang: C +location: clients/tests/test-client.py:554:test_002()/3 +cmd: $NMCLI d +lang: de_DE.utf8 returncode: 0 -stdout: 551 bytes +stdout: 239 bytes >>> -eth0: unavailable - "eth0" - ethernet (virtual), 72:41:AB:90:41:5D, hw - -wlan0: unavailable - "wlan0" - wifi (virtual), 5A:88:5E:B6:90:40, hw - -wlan1: unavailable - "wlan1" - wifi (virtual), 7C:D4:69:31:67:0B, hw - -wlan1: unavailable - "wlan1" - wifi (virtual), 41:21:6B:F3:C9:4A, hw - -DNS configuration: - servers: 1.2.3.4 5.6.7.8 - -Use "nmcli device show" to get complete information about known devices and -"nmcli connection show" to get an overview on active connection profiles. - -Consult nmcli(1) and nmcli-examples(5) manual pages for complete usage details. +DEVICE TYPE STATE CONNECTION +eth0 ethernet nicht verfügbar -- +wlan0 wifi nicht verfügbar -- +wlan1 wifi nicht verfügbar -- +wlan1 wifi nicht verfügbar -- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-004.expected b/clients/tests/test-client.check-on-disk/test_002-004.expected index 2e29897654..381bff9996 100644 --- a/clients/tests/test-client.check-on-disk/test_002-004.expected +++ b/clients/tests/test-client.check-on-disk/test_002-004.expected @@ -1,33 +1,14 @@ -location: clients/tests/test-client.py:508:test_002()/4 -cmd: $NMCLI -f AP -mode multiline d show wlan0 +location: clients/tests/test-client.py:556:test_002()/4 +cmd: $NMCLI -f all d lang: C returncode: 0 -stdout: 1107 bytes +stdout: 530 bytes >>> -AP[1].IN-USE: -AP[1].SSID: wlan0-ap-3 -AP[1].MODE: Infra -AP[1].CHAN: 1 -AP[1].RATE: 54 Mbit/s -AP[1].SIGNAL: 61 -AP[1].BARS: *** -AP[1].SECURITY: WPA1 WPA2 -AP[2].IN-USE: -AP[2].SSID: wlan0-ap-1 -AP[2].MODE: Infra -AP[2].CHAN: 1 -AP[2].RATE: 54 Mbit/s -AP[2].SIGNAL: 34 -AP[2].BARS: ** -AP[2].SECURITY: WPA1 WPA2 -AP[3].IN-USE: -AP[3].SSID: wlan0-ap-2 -AP[3].MODE: Infra -AP[3].CHAN: 1 -AP[3].RATE: 54 Mbit/s -AP[3].SIGNAL: 29 -AP[3].BARS: * -AP[3].SECURITY: WPA1 WPA2 +DEVICE TYPE STATE DBUS-PATH CONNECTION CON-UUID CON-PATH +eth0 ethernet unavailable /org/freedesktop/NetworkManager/Devices/1 -- -- -- +wlan0 wifi unavailable /org/freedesktop/NetworkManager/Devices/2 -- -- -- +wlan1 wifi unavailable /org/freedesktop/NetworkManager/Devices/3 -- -- -- +wlan1 wifi unavailable /org/freedesktop/NetworkManager/Devices/4 -- -- -- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-005.expected b/clients/tests/test-client.check-on-disk/test_002-005.expected index f70e30a4b3..9bc51b99b4 100644 --- a/clients/tests/test-client.check-on-disk/test_002-005.expected +++ b/clients/tests/test-client.check-on-disk/test_002-005.expected @@ -1,39 +1,14 @@ -location: clients/tests/test-client.py:509:test_002()/5 -cmd: $NMCLI -f AP -mode multiline -p d show wlan0 -lang: C +location: clients/tests/test-client.py:556:test_002()/5 +cmd: $NMCLI -f all d +lang: pl_PL.UTF-8 returncode: 0 -stdout: 1558 bytes +stdout: 534 bytes >>> -=============================================================================== - Device details (wlan0) -=============================================================================== -AP[1].IN-USE: -AP[1].SSID: wlan0-ap-3 -AP[1].MODE: Infra -AP[1].CHAN: 1 -AP[1].RATE: 54 Mbit/s -AP[1].SIGNAL: 61 -AP[1].BARS: *** -AP[1].SECURITY: WPA1 WPA2 -------------------------------------------------------------------------------- -AP[2].IN-USE: -AP[2].SSID: wlan0-ap-1 -AP[2].MODE: Infra -AP[2].CHAN: 1 -AP[2].RATE: 54 Mbit/s -AP[2].SIGNAL: 34 -AP[2].BARS: ** -AP[2].SECURITY: WPA1 WPA2 -------------------------------------------------------------------------------- -AP[3].IN-USE: -AP[3].SSID: wlan0-ap-2 -AP[3].MODE: Infra -AP[3].CHAN: 1 -AP[3].RATE: 54 Mbit/s -AP[3].SIGNAL: 29 -AP[3].BARS: * -AP[3].SECURITY: WPA1 WPA2 -------------------------------------------------------------------------------- +DEVICE TYPE STATE DBUS-PATH CONNECTION CON-UUID CON-PATH +eth0 ethernet niedostępne /org/freedesktop/NetworkManager/Devices/1 -- -- -- +wlan0 wifi niedostępne /org/freedesktop/NetworkManager/Devices/2 -- -- -- +wlan1 wifi niedostępne /org/freedesktop/NetworkManager/Devices/3 -- -- -- +wlan1 wifi niedostępne /org/freedesktop/NetworkManager/Devices/4 -- -- -- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-006.expected b/clients/tests/test-client.check-on-disk/test_002-006.expected index e87dc1d11b..f97b23a2a3 100644 --- a/clients/tests/test-client.check-on-disk/test_002-006.expected +++ b/clients/tests/test-client.check-on-disk/test_002-006.expected @@ -1,33 +1,14 @@ -location: clients/tests/test-client.py:510:test_002()/6 -cmd: $NMCLI -f AP -mode multiline -t d show wlan0 -lang: C +location: clients/tests/test-client.py:556:test_002()/6 +cmd: $NMCLI -f all d +lang: de_DE.utf8 returncode: 0 -stdout: 435 bytes +stdout: 554 bytes >>> -AP[1].IN-USE: -AP[1].SSID:wlan0-ap-3 -AP[1].MODE:Infra -AP[1].CHAN:1 -AP[1].RATE:54 Mbit/s -AP[1].SIGNAL:61 -AP[1].BARS:*** -AP[1].SECURITY:WPA1 WPA2 -AP[2].IN-USE: -AP[2].SSID:wlan0-ap-1 -AP[2].MODE:Infra -AP[2].CHAN:1 -AP[2].RATE:54 Mbit/s -AP[2].SIGNAL:34 -AP[2].BARS:** -AP[2].SECURITY:WPA1 WPA2 -AP[3].IN-USE: -AP[3].SSID:wlan0-ap-2 -AP[3].MODE:Infra -AP[3].CHAN:1 -AP[3].RATE:54 Mbit/s -AP[3].SIGNAL:29 -AP[3].BARS:* -AP[3].SECURITY:WPA1 WPA2 +DEVICE TYPE STATE DBUS-PATH CONNECTION CON-UUID CON-PATH +eth0 ethernet nicht verfügbar /org/freedesktop/NetworkManager/Devices/1 -- -- -- +wlan0 wifi nicht verfügbar /org/freedesktop/NetworkManager/Devices/2 -- -- -- +wlan1 wifi nicht verfügbar /org/freedesktop/NetworkManager/Devices/3 -- -- -- +wlan1 wifi nicht verfügbar /org/freedesktop/NetworkManager/Devices/4 -- -- -- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-007.expected b/clients/tests/test-client.check-on-disk/test_002-007.expected index 78f7bf66cd..5b0e5d81e2 100644 --- a/clients/tests/test-client.check-on-disk/test_002-007.expected +++ b/clients/tests/test-client.check-on-disk/test_002-007.expected @@ -1,13 +1,32 @@ -location: clients/tests/test-client.py:511:test_002()/7 -cmd: $NMCLI -f AP -mode tabular d show wlan0 +location: clients/tests/test-client.py:558:test_002()/7 +cmd: $NMCLI lang: C returncode: 0 -stdout: 304 bytes +stdout: 551 bytes >>> -NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY -AP[1] wlan0-ap-3 Infra 1 54 Mbit/s 61 *** WPA1 WPA2 -AP[2] wlan0-ap-1 Infra 1 54 Mbit/s 34 ** WPA1 WPA2 -AP[3] wlan0-ap-2 Infra 1 54 Mbit/s 29 * WPA1 WPA2 +eth0: unavailable + "eth0" + ethernet (virtual), 72:41:AB:90:41:5D, hw + +wlan0: unavailable + "wlan0" + wifi (virtual), 5A:88:5E:B6:90:40, hw + +wlan1: unavailable + "wlan1" + wifi (virtual), 7C:D4:69:31:67:0B, hw + +wlan1: unavailable + "wlan1" + wifi (virtual), 41:21:6B:F3:C9:4A, hw + +DNS configuration: + servers: 1.2.3.4 5.6.7.8 + +Use "nmcli device show" to get complete information about known devices and +"nmcli connection show" to get an overview on active connection profiles. + +Consult nmcli(1) and nmcli-examples(5) manual pages for complete usage details. <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-008.expected b/clients/tests/test-client.check-on-disk/test_002-008.expected index 951ad9ce0d..8c8e0d8266 100644 --- a/clients/tests/test-client.check-on-disk/test_002-008.expected +++ b/clients/tests/test-client.check-on-disk/test_002-008.expected @@ -1,17 +1,34 @@ -location: clients/tests/test-client.py:512:test_002()/8 -cmd: $NMCLI -f AP -mode tabular -p d show wlan0 -lang: C +location: clients/tests/test-client.py:558:test_002()/8 +cmd: $NMCLI +lang: pl_PL.UTF-8 returncode: 0 -stdout: 460 bytes +stdout: 608 bytes >>> -========================== - Device details (wlan0) -========================== -NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY ----------------------------------------------------------------------------- -AP[1] wlan0-ap-3 Infra 1 54 Mbit/s 61 *** WPA1 WPA2 -AP[2] wlan0-ap-1 Infra 1 54 Mbit/s 34 ** WPA1 WPA2 -AP[3] wlan0-ap-2 Infra 1 54 Mbit/s 29 * WPA1 WPA2 +eth0: niedostępne + "eth0" + ethernet (virtual), 72:41:AB:90:41:5D, sprzęt + +wlan0: niedostępne + "wlan0" + wifi (virtual), 5A:88:5E:B6:90:40, sprzęt + +wlan1: niedostępne + "wlan1" + wifi (virtual), 7C:D4:69:31:67:0B, sprzęt + +wlan1: niedostępne + "wlan1" + wifi (virtual), 41:21:6B:F3:C9:4A, sprzęt + +DNS configuration: + servers: 1.2.3.4 5.6.7.8 + +Polecenie „nmcli device show” wyświetli pełne informacje o znanych +urządzeniach, a „nmcli connection show” wyświetli przegląd aktywnych +profili połączeń. + +Strony podręcznika nmcli(1) i nmcli-examples(5) zawierają pełne informacje +o użyciu. <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-009.expected b/clients/tests/test-client.check-on-disk/test_002-009.expected index ce7172e346..c505b76b59 100644 --- a/clients/tests/test-client.check-on-disk/test_002-009.expected +++ b/clients/tests/test-client.check-on-disk/test_002-009.expected @@ -1,12 +1,33 @@ -location: clients/tests/test-client.py:513:test_002()/9 -cmd: $NMCLI -f AP -mode tabular -t d show wlan0 -lang: C +location: clients/tests/test-client.py:558:test_002()/9 +cmd: $NMCLI +lang: de_DE.utf8 returncode: 0 -stdout: 165 bytes +stdout: 616 bytes >>> -AP[1]: :wlan0-ap-3:Infra:1:54 Mbit/s:61:*** :WPA1 WPA2 -AP[2]: :wlan0-ap-1:Infra:1:54 Mbit/s:34:** :WPA1 WPA2 -AP[3]: :wlan0-ap-2:Infra:1:54 Mbit/s:29:* :WPA1 WPA2 +eth0: nicht verfügbar + "eth0" + ethernet (virtual), 72:41:AB:90:41:5D, hw + +wlan0: nicht verfügbar + "wlan0" + wifi (virtual), 5A:88:5E:B6:90:40, hw + +wlan1: nicht verfügbar + "wlan1" + wifi (virtual), 7C:D4:69:31:67:0B, hw + +wlan1: nicht verfügbar + "wlan1" + wifi (virtual), 41:21:6B:F3:C9:4A, hw + +DNS configuration: + servers: 1.2.3.4 5.6.7.8 + +Rufen Sie »nmcli device show« auf, um vollständige Informationen über bekannte Geräte abzurufen +und »nmcli connection show« für eine Übersicht über aktive Verbindungsprofile. + + +Die Hilfeseiten nmcli(1) und nmcli-examples(5) geben vollständige Aufrufbeschreibungen. <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-010.expected b/clients/tests/test-client.check-on-disk/test_002-010.expected index 85b9337157..8167d6bc1f 100644 --- a/clients/tests/test-client.check-on-disk/test_002-010.expected +++ b/clients/tests/test-client.check-on-disk/test_002-010.expected @@ -1,30 +1,30 @@ -location: clients/tests/test-client.py:515:test_002()/10 +location: clients/tests/test-client.py:560:test_002()/10 cmd: $NMCLI -f AP -mode multiline d show wlan0 -lang: pl_PL.UTF-8 +lang: C returncode: 0 -stdout: 1134 bytes +stdout: 1107 bytes >>> AP[1].IN-USE: AP[1].SSID: wlan0-ap-3 -AP[1].MODE: Infrastruktura +AP[1].MODE: Infra AP[1].CHAN: 1 -AP[1].RATE: 54 Mb/s -AP[1].SIGNAL: 61 -AP[1].BARS: *** +AP[1].RATE: 54 Mbit/s +AP[1].SIGNAL: 88 +AP[1].BARS: **** AP[1].SECURITY: WPA1 WPA2 AP[2].IN-USE: -AP[2].SSID: wlan0-ap-1 -AP[2].MODE: Infrastruktura +AP[2].SSID: wlan0-ap-2 +AP[2].MODE: Infra AP[2].CHAN: 1 -AP[2].RATE: 54 Mb/s -AP[2].SIGNAL: 34 -AP[2].BARS: ** +AP[2].RATE: 54 Mbit/s +AP[2].SIGNAL: 61 +AP[2].BARS: *** AP[2].SECURITY: WPA1 WPA2 AP[3].IN-USE: -AP[3].SSID: wlan0-ap-2 -AP[3].MODE: Infrastruktura +AP[3].SSID: wlan0-ap-1 +AP[3].MODE: Infra AP[3].CHAN: 1 -AP[3].RATE: 54 Mb/s +AP[3].RATE: 54 Mbit/s AP[3].SIGNAL: 29 AP[3].BARS: * AP[3].SECURITY: WPA1 WPA2 diff --git a/clients/tests/test-client.check-on-disk/test_002-011.expected b/clients/tests/test-client.check-on-disk/test_002-011.expected index e48611f59f..6e705a9097 100644 --- a/clients/tests/test-client.check-on-disk/test_002-011.expected +++ b/clients/tests/test-client.check-on-disk/test_002-011.expected @@ -1,39 +1,33 @@ -location: clients/tests/test-client.py:516:test_002()/11 -cmd: $NMCLI -f AP -mode multiline -p d show wlan0 +location: clients/tests/test-client.py:560:test_002()/11 +cmd: $NMCLI -f AP -mode multiline d show wlan0 lang: pl_PL.UTF-8 returncode: 0 -stdout: 1592 bytes +stdout: 1134 bytes >>> -=============================================================================== - Informacje o urządzeniu (wlan0) -=============================================================================== AP[1].IN-USE: AP[1].SSID: wlan0-ap-3 AP[1].MODE: Infrastruktura AP[1].CHAN: 1 AP[1].RATE: 54 Mb/s -AP[1].SIGNAL: 61 -AP[1].BARS: *** +AP[1].SIGNAL: 88 +AP[1].BARS: **** AP[1].SECURITY: WPA1 WPA2 -------------------------------------------------------------------------------- AP[2].IN-USE: -AP[2].SSID: wlan0-ap-1 +AP[2].SSID: wlan0-ap-2 AP[2].MODE: Infrastruktura AP[2].CHAN: 1 AP[2].RATE: 54 Mb/s -AP[2].SIGNAL: 34 -AP[2].BARS: ** +AP[2].SIGNAL: 61 +AP[2].BARS: *** AP[2].SECURITY: WPA1 WPA2 -------------------------------------------------------------------------------- AP[3].IN-USE: -AP[3].SSID: wlan0-ap-2 +AP[3].SSID: wlan0-ap-1 AP[3].MODE: Infrastruktura AP[3].CHAN: 1 AP[3].RATE: 54 Mb/s AP[3].SIGNAL: 29 AP[3].BARS: * AP[3].SECURITY: WPA1 WPA2 -------------------------------------------------------------------------------- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-012.expected b/clients/tests/test-client.check-on-disk/test_002-012.expected index 542261c38d..836310387d 100644 --- a/clients/tests/test-client.check-on-disk/test_002-012.expected +++ b/clients/tests/test-client.check-on-disk/test_002-012.expected @@ -1,33 +1,33 @@ -location: clients/tests/test-client.py:517:test_002()/12 -cmd: $NMCLI -f AP -mode multiline -t d show wlan0 -lang: pl_PL.UTF-8 +location: clients/tests/test-client.py:560:test_002()/12 +cmd: $NMCLI -f AP -mode multiline d show wlan0 +lang: de_DE.utf8 returncode: 0 -stdout: 462 bytes +stdout: 1107 bytes >>> -AP[1].IN-USE: -AP[1].SSID:wlan0-ap-3 -AP[1].MODE:Infrastruktura -AP[1].CHAN:1 -AP[1].RATE:54 Mb/s -AP[1].SIGNAL:61 -AP[1].BARS:*** -AP[1].SECURITY:WPA1 WPA2 -AP[2].IN-USE: -AP[2].SSID:wlan0-ap-1 -AP[2].MODE:Infrastruktura -AP[2].CHAN:1 -AP[2].RATE:54 Mb/s -AP[2].SIGNAL:34 -AP[2].BARS:** -AP[2].SECURITY:WPA1 WPA2 -AP[3].IN-USE: -AP[3].SSID:wlan0-ap-2 -AP[3].MODE:Infrastruktura -AP[3].CHAN:1 -AP[3].RATE:54 Mb/s -AP[3].SIGNAL:29 -AP[3].BARS:* -AP[3].SECURITY:WPA1 WPA2 +AP[1].IN-USE: +AP[1].SSID: wlan0-ap-3 +AP[1].MODE: Infra +AP[1].CHAN: 1 +AP[1].RATE: 54 Mbit/s +AP[1].SIGNAL: 88 +AP[1].BARS: **** +AP[1].SECURITY: WPA1 WPA2 +AP[2].IN-USE: +AP[2].SSID: wlan0-ap-2 +AP[2].MODE: Infra +AP[2].CHAN: 1 +AP[2].RATE: 54 Mbit/s +AP[2].SIGNAL: 61 +AP[2].BARS: *** +AP[2].SECURITY: WPA1 WPA2 +AP[3].IN-USE: +AP[3].SSID: wlan0-ap-1 +AP[3].MODE: Infra +AP[3].CHAN: 1 +AP[3].RATE: 54 Mbit/s +AP[3].SIGNAL: 29 +AP[3].BARS: * +AP[3].SECURITY: WPA1 WPA2 <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-013.expected b/clients/tests/test-client.check-on-disk/test_002-013.expected index 54ddb50a32..dc134b9929 100644 --- a/clients/tests/test-client.check-on-disk/test_002-013.expected +++ b/clients/tests/test-client.check-on-disk/test_002-013.expected @@ -1,13 +1,39 @@ -location: clients/tests/test-client.py:518:test_002()/13 -cmd: $NMCLI -f AP -mode tabular d show wlan0 -lang: pl_PL.UTF-8 +location: clients/tests/test-client.py:561:test_002()/13 +cmd: $NMCLI -f AP -mode multiline -p d show wlan0 +lang: C returncode: 0 -stdout: 338 bytes +stdout: 1558 bytes >>> -NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY -AP[1] wlan0-ap-3 Infrastruktura 1 54 Mb/s 61 *** WPA1 WPA2 -AP[2] wlan0-ap-1 Infrastruktura 1 54 Mb/s 34 ** WPA1 WPA2 -AP[3] wlan0-ap-2 Infrastruktura 1 54 Mb/s 29 * WPA1 WPA2 +=============================================================================== + Device details (wlan0) +=============================================================================== +AP[1].IN-USE: +AP[1].SSID: wlan0-ap-3 +AP[1].MODE: Infra +AP[1].CHAN: 1 +AP[1].RATE: 54 Mbit/s +AP[1].SIGNAL: 88 +AP[1].BARS: **** +AP[1].SECURITY: WPA1 WPA2 +------------------------------------------------------------------------------- +AP[2].IN-USE: +AP[2].SSID: wlan0-ap-2 +AP[2].MODE: Infra +AP[2].CHAN: 1 +AP[2].RATE: 54 Mbit/s +AP[2].SIGNAL: 61 +AP[2].BARS: *** +AP[2].SECURITY: WPA1 WPA2 +------------------------------------------------------------------------------- +AP[3].IN-USE: +AP[3].SSID: wlan0-ap-1 +AP[3].MODE: Infra +AP[3].CHAN: 1 +AP[3].RATE: 54 Mbit/s +AP[3].SIGNAL: 29 +AP[3].BARS: * +AP[3].SECURITY: WPA1 WPA2 +------------------------------------------------------------------------------- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-014.expected b/clients/tests/test-client.check-on-disk/test_002-014.expected index ea42ce9a43..2ce1dd5b5e 100644 --- a/clients/tests/test-client.check-on-disk/test_002-014.expected +++ b/clients/tests/test-client.check-on-disk/test_002-014.expected @@ -1,17 +1,39 @@ -location: clients/tests/test-client.py:519:test_002()/14 -cmd: $NMCLI -f AP -mode tabular -p d show wlan0 +location: clients/tests/test-client.py:561:test_002()/14 +cmd: $NMCLI -f AP -mode multiline -p d show wlan0 lang: pl_PL.UTF-8 returncode: 0 -stdout: 530 bytes +stdout: 1592 bytes >>> -=================================== - Informacje o urządzeniu (wlan0) -=================================== -NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY ------------------------------------------------------------------------------------ -AP[1] wlan0-ap-3 Infrastruktura 1 54 Mb/s 61 *** WPA1 WPA2 -AP[2] wlan0-ap-1 Infrastruktura 1 54 Mb/s 34 ** WPA1 WPA2 -AP[3] wlan0-ap-2 Infrastruktura 1 54 Mb/s 29 * WPA1 WPA2 +=============================================================================== + Informacje o urządzeniu (wlan0) +=============================================================================== +AP[1].IN-USE: +AP[1].SSID: wlan0-ap-3 +AP[1].MODE: Infrastruktura +AP[1].CHAN: 1 +AP[1].RATE: 54 Mb/s +AP[1].SIGNAL: 88 +AP[1].BARS: **** +AP[1].SECURITY: WPA1 WPA2 +------------------------------------------------------------------------------- +AP[2].IN-USE: +AP[2].SSID: wlan0-ap-2 +AP[2].MODE: Infrastruktura +AP[2].CHAN: 1 +AP[2].RATE: 54 Mb/s +AP[2].SIGNAL: 61 +AP[2].BARS: *** +AP[2].SECURITY: WPA1 WPA2 +------------------------------------------------------------------------------- +AP[3].IN-USE: +AP[3].SSID: wlan0-ap-1 +AP[3].MODE: Infrastruktura +AP[3].CHAN: 1 +AP[3].RATE: 54 Mb/s +AP[3].SIGNAL: 29 +AP[3].BARS: * +AP[3].SECURITY: WPA1 WPA2 +------------------------------------------------------------------------------- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-015.expected b/clients/tests/test-client.check-on-disk/test_002-015.expected index 3854822bb3..31774e7711 100644 --- a/clients/tests/test-client.check-on-disk/test_002-015.expected +++ b/clients/tests/test-client.check-on-disk/test_002-015.expected @@ -1,12 +1,39 @@ -location: clients/tests/test-client.py:520:test_002()/15 -cmd: $NMCLI -f AP -mode tabular -t d show wlan0 -lang: pl_PL.UTF-8 +location: clients/tests/test-client.py:561:test_002()/15 +cmd: $NMCLI -f AP -mode multiline -p d show wlan0 +lang: de_DE.utf8 returncode: 0 -stdout: 192 bytes +stdout: 1562 bytes >>> -AP[1]: :wlan0-ap-3:Infrastruktura:1:54 Mb/s:61:*** :WPA1 WPA2 -AP[2]: :wlan0-ap-1:Infrastruktura:1:54 Mb/s:34:** :WPA1 WPA2 -AP[3]: :wlan0-ap-2:Infrastruktura:1:54 Mb/s:29:* :WPA1 WPA2 +=============================================================================== + Geräteinformationen (wlan0) +=============================================================================== +AP[1].IN-USE: +AP[1].SSID: wlan0-ap-3 +AP[1].MODE: Infra +AP[1].CHAN: 1 +AP[1].RATE: 54 Mbit/s +AP[1].SIGNAL: 88 +AP[1].BARS: **** +AP[1].SECURITY: WPA1 WPA2 +------------------------------------------------------------------------------- +AP[2].IN-USE: +AP[2].SSID: wlan0-ap-2 +AP[2].MODE: Infra +AP[2].CHAN: 1 +AP[2].RATE: 54 Mbit/s +AP[2].SIGNAL: 61 +AP[2].BARS: *** +AP[2].SECURITY: WPA1 WPA2 +------------------------------------------------------------------------------- +AP[3].IN-USE: +AP[3].SSID: wlan0-ap-1 +AP[3].MODE: Infra +AP[3].CHAN: 1 +AP[3].RATE: 54 Mbit/s +AP[3].SIGNAL: 29 +AP[3].BARS: * +AP[3].SECURITY: WPA1 WPA2 +------------------------------------------------------------------------------- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-016.expected b/clients/tests/test-client.check-on-disk/test_002-016.expected index 452db9a444..74e46abfaf 100644 --- a/clients/tests/test-client.check-on-disk/test_002-016.expected +++ b/clients/tests/test-client.check-on-disk/test_002-016.expected @@ -1,11 +1,33 @@ -location: clients/tests/test-client.py:522:test_002()/16 -cmd: $NMCLI c +location: clients/tests/test-client.py:562:test_002()/16 +cmd: $NMCLI -f AP -mode multiline -t d show wlan0 lang: C returncode: 0 -stdout: 126 bytes +stdout: 435 bytes >>> -NAME UUID TYPE DEVICE -con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- +AP[1].IN-USE: +AP[1].SSID:wlan0-ap-3 +AP[1].MODE:Infra +AP[1].CHAN:1 +AP[1].RATE:54 Mbit/s +AP[1].SIGNAL:88 +AP[1].BARS:**** +AP[1].SECURITY:WPA1 WPA2 +AP[2].IN-USE: +AP[2].SSID:wlan0-ap-2 +AP[2].MODE:Infra +AP[2].CHAN:1 +AP[2].RATE:54 Mbit/s +AP[2].SIGNAL:61 +AP[2].BARS:*** +AP[2].SECURITY:WPA1 WPA2 +AP[3].IN-USE: +AP[3].SSID:wlan0-ap-1 +AP[3].MODE:Infra +AP[3].CHAN:1 +AP[3].RATE:54 Mbit/s +AP[3].SIGNAL:29 +AP[3].BARS:* +AP[3].SECURITY:WPA1 WPA2 <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-017.expected b/clients/tests/test-client.check-on-disk/test_002-017.expected index 88ac43f02f..abe9fab09f 100644 --- a/clients/tests/test-client.check-on-disk/test_002-017.expected +++ b/clients/tests/test-client.check-on-disk/test_002-017.expected @@ -1,30 +1,33 @@ -location: clients/tests/test-client.py:524:test_002()/17 -cmd: $NMCLI c s con-1 -lang: C +location: clients/tests/test-client.py:562:test_002()/17 +cmd: $NMCLI -f AP -mode multiline -t d show wlan0 +lang: pl_PL.UTF-8 returncode: 0 -stdout: 990 bytes +stdout: 462 bytes >>> -connection.id: con-1 -connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d -connection.stable-id: -- -connection.type: 802-3-ethernet -connection.interface-name: -- -connection.autoconnect: yes -connection.autoconnect-priority: 0 -connection.autoconnect-retries: -1 (default) -connection.auth-retries: -1 -connection.timestamp: 0 -connection.read-only: no -connection.permissions: -- -connection.zone: -- -connection.master: -- -connection.slave-type: -- -connection.autoconnect-slaves: -1 (default) -connection.secondaries: -- -connection.gateway-ping-timeout: 0 -connection.metered: unknown -connection.lldp: default -connection.mdns: -1 (default) +AP[1].IN-USE: +AP[1].SSID:wlan0-ap-3 +AP[1].MODE:Infrastruktura +AP[1].CHAN:1 +AP[1].RATE:54 Mb/s +AP[1].SIGNAL:88 +AP[1].BARS:**** +AP[1].SECURITY:WPA1 WPA2 +AP[2].IN-USE: +AP[2].SSID:wlan0-ap-2 +AP[2].MODE:Infrastruktura +AP[2].CHAN:1 +AP[2].RATE:54 Mb/s +AP[2].SIGNAL:61 +AP[2].BARS:*** +AP[2].SECURITY:WPA1 WPA2 +AP[3].IN-USE: +AP[3].SSID:wlan0-ap-1 +AP[3].MODE:Infrastruktura +AP[3].CHAN:1 +AP[3].RATE:54 Mb/s +AP[3].SIGNAL:29 +AP[3].BARS:* +AP[3].SECURITY:WPA1 WPA2 <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_002-018.expected b/clients/tests/test-client.check-on-disk/test_002-018.expected new file mode 100644 index 0000000000..15972d961d --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-018.expected @@ -0,0 +1,36 @@ +location: clients/tests/test-client.py:562:test_002()/18 +cmd: $NMCLI -f AP -mode multiline -t d show wlan0 +lang: de_DE.utf8 +returncode: 0 +stdout: 435 bytes +>>> +AP[1].IN-USE: +AP[1].SSID:wlan0-ap-3 +AP[1].MODE:Infra +AP[1].CHAN:1 +AP[1].RATE:54 Mbit/s +AP[1].SIGNAL:88 +AP[1].BARS:**** +AP[1].SECURITY:WPA1 WPA2 +AP[2].IN-USE: +AP[2].SSID:wlan0-ap-2 +AP[2].MODE:Infra +AP[2].CHAN:1 +AP[2].RATE:54 Mbit/s +AP[2].SIGNAL:61 +AP[2].BARS:*** +AP[2].SECURITY:WPA1 WPA2 +AP[3].IN-USE: +AP[3].SSID:wlan0-ap-1 +AP[3].MODE:Infra +AP[3].CHAN:1 +AP[3].RATE:54 Mbit/s +AP[3].SIGNAL:29 +AP[3].BARS:* +AP[3].SECURITY:WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-019.expected b/clients/tests/test-client.check-on-disk/test_002-019.expected new file mode 100644 index 0000000000..4a495e21fe --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-019.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:563:test_002()/19 +cmd: $NMCLI -f AP -mode tabular d show wlan0 +lang: C +returncode: 0 +stdout: 304 bytes +>>> +NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY +AP[1] wlan0-ap-3 Infra 1 54 Mbit/s 88 **** WPA1 WPA2 +AP[2] wlan0-ap-2 Infra 1 54 Mbit/s 61 *** WPA1 WPA2 +AP[3] wlan0-ap-1 Infra 1 54 Mbit/s 29 * WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-020.expected b/clients/tests/test-client.check-on-disk/test_002-020.expected new file mode 100644 index 0000000000..4a9a528dc7 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-020.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:563:test_002()/20 +cmd: $NMCLI -f AP -mode tabular d show wlan0 +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 338 bytes +>>> +NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY +AP[1] wlan0-ap-3 Infrastruktura 1 54 Mb/s 88 **** WPA1 WPA2 +AP[2] wlan0-ap-2 Infrastruktura 1 54 Mb/s 61 *** WPA1 WPA2 +AP[3] wlan0-ap-1 Infrastruktura 1 54 Mb/s 29 * WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-021.expected b/clients/tests/test-client.check-on-disk/test_002-021.expected new file mode 100644 index 0000000000..6a9ce747e4 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-021.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:563:test_002()/21 +cmd: $NMCLI -f AP -mode tabular d show wlan0 +lang: de_DE.utf8 +returncode: 0 +stdout: 304 bytes +>>> +NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY +AP[1] wlan0-ap-3 Infra 1 54 Mbit/s 88 **** WPA1 WPA2 +AP[2] wlan0-ap-2 Infra 1 54 Mbit/s 61 *** WPA1 WPA2 +AP[3] wlan0-ap-1 Infra 1 54 Mbit/s 29 * WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-022.expected b/clients/tests/test-client.check-on-disk/test_002-022.expected new file mode 100644 index 0000000000..244225addb --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-022.expected @@ -0,0 +1,20 @@ +location: clients/tests/test-client.py:564:test_002()/22 +cmd: $NMCLI -f AP -mode tabular -p d show wlan0 +lang: C +returncode: 0 +stdout: 460 bytes +>>> +========================== + Device details (wlan0) +========================== +NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY +---------------------------------------------------------------------------- +AP[1] wlan0-ap-3 Infra 1 54 Mbit/s 88 **** WPA1 WPA2 +AP[2] wlan0-ap-2 Infra 1 54 Mbit/s 61 *** WPA1 WPA2 +AP[3] wlan0-ap-1 Infra 1 54 Mbit/s 29 * WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-023.expected b/clients/tests/test-client.check-on-disk/test_002-023.expected new file mode 100644 index 0000000000..8d04359192 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-023.expected @@ -0,0 +1,20 @@ +location: clients/tests/test-client.py:564:test_002()/23 +cmd: $NMCLI -f AP -mode tabular -p d show wlan0 +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 530 bytes +>>> +=================================== + Informacje o urządzeniu (wlan0) +=================================== +NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY +----------------------------------------------------------------------------------- +AP[1] wlan0-ap-3 Infrastruktura 1 54 Mb/s 88 **** WPA1 WPA2 +AP[2] wlan0-ap-2 Infrastruktura 1 54 Mb/s 61 *** WPA1 WPA2 +AP[3] wlan0-ap-1 Infrastruktura 1 54 Mb/s 29 * WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-024.expected b/clients/tests/test-client.check-on-disk/test_002-024.expected new file mode 100644 index 0000000000..63648ea829 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-024.expected @@ -0,0 +1,20 @@ +location: clients/tests/test-client.py:564:test_002()/24 +cmd: $NMCLI -f AP -mode tabular -p d show wlan0 +lang: de_DE.utf8 +returncode: 0 +stdout: 476 bytes +>>> +=============================== + Geräteinformationen (wlan0) +=============================== +NAME IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY +---------------------------------------------------------------------------- +AP[1] wlan0-ap-3 Infra 1 54 Mbit/s 88 **** WPA1 WPA2 +AP[2] wlan0-ap-2 Infra 1 54 Mbit/s 61 *** WPA1 WPA2 +AP[3] wlan0-ap-1 Infra 1 54 Mbit/s 29 * WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-025.expected b/clients/tests/test-client.check-on-disk/test_002-025.expected new file mode 100644 index 0000000000..34bc44eed2 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-025.expected @@ -0,0 +1,15 @@ +location: clients/tests/test-client.py:565:test_002()/25 +cmd: $NMCLI -f AP -mode tabular -t d show wlan0 +lang: C +returncode: 0 +stdout: 165 bytes +>>> +AP[1]: :wlan0-ap-3:Infra:1:54 Mbit/s:88:****:WPA1 WPA2 +AP[2]: :wlan0-ap-2:Infra:1:54 Mbit/s:61:*** :WPA1 WPA2 +AP[3]: :wlan0-ap-1:Infra:1:54 Mbit/s:29:* :WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-026.expected b/clients/tests/test-client.check-on-disk/test_002-026.expected new file mode 100644 index 0000000000..21b3ae9993 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-026.expected @@ -0,0 +1,15 @@ +location: clients/tests/test-client.py:565:test_002()/26 +cmd: $NMCLI -f AP -mode tabular -t d show wlan0 +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 192 bytes +>>> +AP[1]: :wlan0-ap-3:Infrastruktura:1:54 Mb/s:88:****:WPA1 WPA2 +AP[2]: :wlan0-ap-2:Infrastruktura:1:54 Mb/s:61:*** :WPA1 WPA2 +AP[3]: :wlan0-ap-1:Infrastruktura:1:54 Mb/s:29:* :WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-027.expected b/clients/tests/test-client.check-on-disk/test_002-027.expected new file mode 100644 index 0000000000..19f7899f29 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-027.expected @@ -0,0 +1,15 @@ +location: clients/tests/test-client.py:565:test_002()/27 +cmd: $NMCLI -f AP -mode tabular -t d show wlan0 +lang: de_DE.utf8 +returncode: 0 +stdout: 165 bytes +>>> +AP[1]: :wlan0-ap-3:Infra:1:54 Mbit/s:88:****:WPA1 WPA2 +AP[2]: :wlan0-ap-2:Infra:1:54 Mbit/s:61:*** :WPA1 WPA2 +AP[3]: :wlan0-ap-1:Infra:1:54 Mbit/s:29:* :WPA1 WPA2 + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-028.expected b/clients/tests/test-client.check-on-disk/test_002-028.expected new file mode 100644 index 0000000000..9ec2112173 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-028.expected @@ -0,0 +1,21 @@ +location: clients/tests/test-client.py:567:test_002()/28 +cmd: $NMCLI -f ALL d wifi +lang: C +returncode: 0 +stdout: 1840 bytes +>>> +NAME SSID SSID-HEX BSSID MODE CHAN FREQ RATE SIGNAL BARS SECURITY WPA-FLAGS RSN-FLAGS DEVICE ACTIVE IN-USE DBUS-PATH +AP[1] wlan0-ap-3 776C616E302D61702D33 53:8C:FC:BD:7D:2B Infra 1 2412 MHz 54 Mbit/s 88 **** WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan0 no /org/freedesktop/NetworkManager/AccessPoint/3 +AP[2] wlan0-ap-2 776C616E302D61702D32 A1:A2:78:A7:C5:D5 Infra 1 2412 MHz 54 Mbit/s 61 *** WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan0 no /org/freedesktop/NetworkManager/AccessPoint/2 +AP[3] wlan0-ap-1 776C616E302D61702D31 81:28:C5:C2:E5:15 Infra 1 2412 MHz 54 Mbit/s 29 * WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan0 no /org/freedesktop/NetworkManager/AccessPoint/1 + +NAME SSID SSID-HEX BSSID MODE CHAN FREQ RATE SIGNAL BARS SECURITY WPA-FLAGS RSN-FLAGS DEVICE ACTIVE IN-USE DBUS-PATH +AP[1] wlan1-ap-4 776C616E312D61702D34 EA:62:1C:BD:C0:8F Infra 1 2412 MHz 54 Mbit/s 34 ** WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan1 no /org/freedesktop/NetworkManager/AccessPoint/4 + +NAME SSID SSID-HEX BSSID MODE CHAN FREQ RATE SIGNAL BARS SECURITY WPA-FLAGS RSN-FLAGS DEVICE ACTIVE IN-USE DBUS-PATH + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-029.expected b/clients/tests/test-client.check-on-disk/test_002-029.expected new file mode 100644 index 0000000000..a3f09fce81 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-029.expected @@ -0,0 +1,21 @@ +location: clients/tests/test-client.py:567:test_002()/29 +cmd: $NMCLI -f ALL d wifi +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 1898 bytes +>>> +NAME SSID SSID-HEX BSSID MODE CHAN FREQ RATE SIGNAL BARS SECURITY WPA-FLAGS RSN-FLAGS DEVICE ACTIVE IN-USE DBUS-PATH +AP[1] wlan0-ap-3 776C616E302D61702D33 53:8C:FC:BD:7D:2B Infrastruktura 1 2412 MHz 54 Mb/s 88 **** WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan0 nie /org/freedesktop/NetworkManager/AccessPoint/3 +AP[2] wlan0-ap-2 776C616E302D61702D32 A1:A2:78:A7:C5:D5 Infrastruktura 1 2412 MHz 54 Mb/s 61 *** WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan0 nie /org/freedesktop/NetworkManager/AccessPoint/2 +AP[3] wlan0-ap-1 776C616E302D61702D31 81:28:C5:C2:E5:15 Infrastruktura 1 2412 MHz 54 Mb/s 29 * WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan0 nie /org/freedesktop/NetworkManager/AccessPoint/1 + +NAME SSID SSID-HEX BSSID MODE CHAN FREQ RATE SIGNAL BARS SECURITY WPA-FLAGS RSN-FLAGS DEVICE ACTIVE IN-USE DBUS-PATH +AP[1] wlan1-ap-4 776C616E312D61702D34 EA:62:1C:BD:C0:8F Infrastruktura 1 2412 MHz 54 Mb/s 34 ** WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan1 nie /org/freedesktop/NetworkManager/AccessPoint/4 + +NAME SSID SSID-HEX BSSID MODE CHAN FREQ RATE SIGNAL BARS SECURITY WPA-FLAGS RSN-FLAGS DEVICE ACTIVE IN-USE DBUS-PATH + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-030.expected b/clients/tests/test-client.check-on-disk/test_002-030.expected new file mode 100644 index 0000000000..41e1435c84 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-030.expected @@ -0,0 +1,21 @@ +location: clients/tests/test-client.py:567:test_002()/30 +cmd: $NMCLI -f ALL d wifi +lang: de_DE.utf8 +returncode: 0 +stdout: 1840 bytes +>>> +NAME SSID SSID-HEX BSSID MODE CHAN FREQ RATE SIGNAL BARS SECURITY WPA-FLAGS RSN-FLAGS DEVICE ACTIVE IN-USE DBUS-PATH +AP[1] wlan0-ap-3 776C616E302D61702D33 53:8C:FC:BD:7D:2B Infra 1 2412 MHz 54 Mbit/s 88 **** WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan0 nein /org/freedesktop/NetworkManager/AccessPoint/3 +AP[2] wlan0-ap-2 776C616E302D61702D32 A1:A2:78:A7:C5:D5 Infra 1 2412 MHz 54 Mbit/s 61 *** WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan0 nein /org/freedesktop/NetworkManager/AccessPoint/2 +AP[3] wlan0-ap-1 776C616E302D61702D31 81:28:C5:C2:E5:15 Infra 1 2412 MHz 54 Mbit/s 29 * WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan0 nein /org/freedesktop/NetworkManager/AccessPoint/1 + +NAME SSID SSID-HEX BSSID MODE CHAN FREQ RATE SIGNAL BARS SECURITY WPA-FLAGS RSN-FLAGS DEVICE ACTIVE IN-USE DBUS-PATH +AP[1] wlan1-ap-4 776C616E312D61702D34 EA:62:1C:BD:C0:8F Infra 1 2412 MHz 54 Mbit/s 34 ** WPA1 WPA2 pair_tkip pair_ccmp group_tkip group_ccmp psk pair_tkip pair_ccmp group_tkip group_ccmp psk wlan1 nein /org/freedesktop/NetworkManager/AccessPoint/4 + +NAME SSID SSID-HEX BSSID MODE CHAN FREQ RATE SIGNAL BARS SECURITY WPA-FLAGS RSN-FLAGS DEVICE ACTIVE IN-USE DBUS-PATH + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-031.expected b/clients/tests/test-client.check-on-disk/test_002-031.expected new file mode 100644 index 0000000000..2dd4201c8e --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-031.expected @@ -0,0 +1,14 @@ +location: clients/tests/test-client.py:569:test_002()/31 +cmd: $NMCLI c +lang: C +returncode: 0 +stdout: 126 bytes +>>> +NAME UUID TYPE DEVICE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-032.expected b/clients/tests/test-client.check-on-disk/test_002-032.expected new file mode 100644 index 0000000000..d6dfedab7e --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-032.expected @@ -0,0 +1,14 @@ +location: clients/tests/test-client.py:569:test_002()/32 +cmd: $NMCLI c +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 126 bytes +>>> +NAME UUID TYPE DEVICE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-033.expected b/clients/tests/test-client.check-on-disk/test_002-033.expected new file mode 100644 index 0000000000..9a9c109cda --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-033.expected @@ -0,0 +1,14 @@ +location: clients/tests/test-client.py:569:test_002()/33 +cmd: $NMCLI c +lang: de_DE.utf8 +returncode: 0 +stdout: 126 bytes +>>> +NAME UUID TYPE DEVICE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-034.expected b/clients/tests/test-client.check-on-disk/test_002-034.expected new file mode 100644 index 0000000000..59fc086675 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-034.expected @@ -0,0 +1,33 @@ +location: clients/tests/test-client.py:571:test_002()/34 +cmd: $NMCLI c s con-1 +lang: C +returncode: 0 +stdout: 990 bytes +>>> +connection.id: con-1 +connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d +connection.stable-id: -- +connection.type: 802-3-ethernet +connection.interface-name: -- +connection.autoconnect: yes +connection.autoconnect-priority: 0 +connection.autoconnect-retries: -1 (default) +connection.auth-retries: -1 +connection.timestamp: 0 +connection.read-only: no +connection.permissions: -- +connection.zone: -- +connection.master: -- +connection.slave-type: -- +connection.autoconnect-slaves: -1 (default) +connection.secondaries: -- +connection.gateway-ping-timeout: 0 +connection.metered: unknown +connection.lldp: default +connection.mdns: -1 (default) + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-035.expected b/clients/tests/test-client.check-on-disk/test_002-035.expected new file mode 100644 index 0000000000..ec3bad7634 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-035.expected @@ -0,0 +1,33 @@ +location: clients/tests/test-client.py:571:test_002()/35 +cmd: $NMCLI c s con-1 +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 992 bytes +>>> +connection.id: con-1 +connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d +connection.stable-id: -- +connection.type: 802-3-ethernet +connection.interface-name: -- +connection.autoconnect: tak +connection.autoconnect-priority: 0 +connection.autoconnect-retries: -1 (default) +connection.auth-retries: -1 +connection.timestamp: 0 +connection.read-only: nie +connection.permissions: -- +connection.zone: -- +connection.master: -- +connection.slave-type: -- +connection.autoconnect-slaves: -1 (default) +connection.secondaries: -- +connection.gateway-ping-timeout: 0 +connection.metered: nieznane +connection.lldp: default +connection.mdns: -1 (default) + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_002-036.expected b/clients/tests/test-client.check-on-disk/test_002-036.expected new file mode 100644 index 0000000000..244facd05b --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_002-036.expected @@ -0,0 +1,33 @@ +location: clients/tests/test-client.py:571:test_002()/36 +cmd: $NMCLI c s con-1 +lang: de_DE.utf8 +returncode: 0 +stdout: 993 bytes +>>> +connection.id: con-1 +connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d +connection.stable-id: -- +connection.type: 802-3-ethernet +connection.interface-name: -- +connection.autoconnect: ja +connection.autoconnect-priority: 0 +connection.autoconnect-retries: -1 (default) +connection.auth-retries: -1 +connection.timestamp: 0 +connection.read-only: nein +connection.permissions: -- +connection.zone: -- +connection.master: -- +connection.slave-type: -- +connection.autoconnect-slaves: -1 (default) +connection.secondaries: -- +connection.gateway-ping-timeout: 0 +connection.metered: unbekannt +connection.lldp: default +connection.mdns: -1 (default) + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-001.expected b/clients/tests/test-client.check-on-disk/test_003-001.expected index 9e37cf9f7a..a4e739c764 100644 --- a/clients/tests/test-client.check-on-disk/test_003-001.expected +++ b/clients/tests/test-client.check-on-disk/test_003-001.expected @@ -1,4 +1,4 @@ -location: clients/tests/test-client.py:534:test_003()/1 +location: clients/tests/test-client.py:581:test_003()/1 cmd: $NMCLI c add type ethernet ifname '*' con-name con-xx1 lang: C returncode: 0 diff --git a/clients/tests/test-client.check-on-disk/test_003-002.expected b/clients/tests/test-client.check-on-disk/test_003-002.expected index 3447e60919..21c1a23205 100644 --- a/clients/tests/test-client.check-on-disk/test_003-002.expected +++ b/clients/tests/test-client.check-on-disk/test_003-002.expected @@ -1,4 +1,4 @@ -location: clients/tests/test-client.py:537:test_003()/2 +location: clients/tests/test-client.py:584:test_003()/2 cmd: $NMCLI c s lang: C returncode: 0 diff --git a/clients/tests/test-client.check-on-disk/test_003-003.expected b/clients/tests/test-client.check-on-disk/test_003-003.expected index c241bc5bcb..86acb7c455 100644 --- a/clients/tests/test-client.check-on-disk/test_003-003.expected +++ b/clients/tests/test-client.check-on-disk/test_003-003.expected @@ -1,10 +1,12 @@ -location: clients/tests/test-client.py:542:test_003()/3 -cmd: $NMCLI c add type ethernet ifname '*' -lang: C +location: clients/tests/test-client.py:584:test_003()/3 +cmd: $NMCLI c s +lang: pl_PL.UTF-8 returncode: 0 -stdout: 81 bytes +stdout: 195 bytes >>> -Connection 'ethernet' (UUID-ethernet-REPLACED-REPLACED-REPL) successfully added. +NAME UUID TYPE DEVICE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_003-004.expected b/clients/tests/test-client.check-on-disk/test_003-004.expected index 2c921be2f4..576708df2e 100644 --- a/clients/tests/test-client.check-on-disk/test_003-004.expected +++ b/clients/tests/test-client.check-on-disk/test_003-004.expected @@ -1,13 +1,12 @@ -location: clients/tests/test-client.py:545:test_003()/4 +location: clients/tests/test-client.py:584:test_003()/4 cmd: $NMCLI c s -lang: C +lang: de_DE.utf8 returncode: 0 -stdout: 264 bytes +stdout: 195 bytes >>> -NAME UUID TYPE DEVICE -con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- -con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- -ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet -- +NAME UUID TYPE DEVICE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_003-005.expected b/clients/tests/test-client.check-on-disk/test_003-005.expected index 2ec86c01a1..ca71469c7f 100644 --- a/clients/tests/test-client.check-on-disk/test_003-005.expected +++ b/clients/tests/test-client.check-on-disk/test_003-005.expected @@ -1,13 +1,10 @@ -location: clients/tests/test-client.py:547:test_003()/5 -cmd: $NMCLI c s -lang: pl_PL.UTF-8 +location: clients/tests/test-client.py:589:test_003()/5 +cmd: $NMCLI c add type ethernet ifname '*' +lang: C returncode: 0 -stdout: 264 bytes +stdout: 81 bytes >>> -NAME UUID TYPE DEVICE -con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- -con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- -ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet -- +Connection 'ethernet' (UUID-ethernet-REPLACED-REPLACED-REPL) successfully added. <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_003-006.expected b/clients/tests/test-client.check-on-disk/test_003-006.expected index 1e8a29973a..80df78cb6e 100644 --- a/clients/tests/test-client.check-on-disk/test_003-006.expected +++ b/clients/tests/test-client.check-on-disk/test_003-006.expected @@ -1,13 +1,13 @@ -location: clients/tests/test-client.py:550:test_003()/6 -cmd: $NMCLI -f ALL c s +location: clients/tests/test-client.py:592:test_003()/6 +cmd: $NMCLI c s lang: C returncode: 0 -stdout: 912 bytes +stdout: 264 bytes >>> -NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT AUTOCONNECT-PRIORITY READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH SLAVE -con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/1 no -- -- -- -- -con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/2 no -- -- -- -- -ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/3 no -- -- -- -- +NAME UUID TYPE DEVICE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet -- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_003-007.expected b/clients/tests/test-client.check-on-disk/test_003-007.expected index e566f474f7..e27a081f0a 100644 --- a/clients/tests/test-client.check-on-disk/test_003-007.expected +++ b/clients/tests/test-client.check-on-disk/test_003-007.expected @@ -1,13 +1,13 @@ -location: clients/tests/test-client.py:552:test_003()/7 -cmd: $NMCLI -f ALL c s +location: clients/tests/test-client.py:592:test_003()/7 +cmd: $NMCLI c s lang: pl_PL.UTF-8 returncode: 0 -stdout: 912 bytes +stdout: 264 bytes >>> -NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT AUTOCONNECT-PRIORITY READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH SLAVE -con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet 0 nigdy tak 0 nie /org/freedesktop/NetworkManager/Settings/Connection/1 nie -- -- -- -- -con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet 0 nigdy tak 0 nie /org/freedesktop/NetworkManager/Settings/Connection/2 nie -- -- -- -- -ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet 0 nigdy tak 0 nie /org/freedesktop/NetworkManager/Settings/Connection/3 nie -- -- -- -- +NAME UUID TYPE DEVICE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet -- <<< stderr: 0 bytes diff --git a/clients/tests/test-client.check-on-disk/test_003-008.expected b/clients/tests/test-client.check-on-disk/test_003-008.expected index 44be3e054e..5892986b52 100644 --- a/clients/tests/test-client.check-on-disk/test_003-008.expected +++ b/clients/tests/test-client.check-on-disk/test_003-008.expected @@ -1,20 +1,14 @@ -location: clients/tests/test-client.py:556:test_003()/8 -cmd: $NMCLI --complete-args -f ALL c s '' -lang: pl_PL.UTF-8 +location: clients/tests/test-client.py:592:test_003()/8 +cmd: $NMCLI c s +lang: de_DE.utf8 returncode: 0 -stdout: 64 bytes +stdout: 264 bytes >>> +NAME UUID TYPE DEVICE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet -- ---active ---order -apath -con-1 -con-xx1 -ethernet -help -id -path -uuid <<< stderr: 0 bytes >>> diff --git a/clients/tests/test-client.check-on-disk/test_003-009.expected b/clients/tests/test-client.check-on-disk/test_003-009.expected new file mode 100644 index 0000000000..85a102a392 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-009.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:595:test_003()/9 +cmd: $NMCLI -f ALL c s +lang: C +returncode: 0 +stdout: 912 bytes +>>> +NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT AUTOCONNECT-PRIORITY READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH SLAVE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/1 no -- -- -- -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/2 no -- -- -- -- +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/3 no -- -- -- -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-010.expected b/clients/tests/test-client.check-on-disk/test_003-010.expected new file mode 100644 index 0000000000..4d1b93e718 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-010.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:595:test_003()/10 +cmd: $NMCLI -f ALL c s +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 912 bytes +>>> +NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT AUTOCONNECT-PRIORITY READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH SLAVE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet 0 nigdy tak 0 nie /org/freedesktop/NetworkManager/Settings/Connection/1 nie -- -- -- -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet 0 nigdy tak 0 nie /org/freedesktop/NetworkManager/Settings/Connection/2 nie -- -- -- -- +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet 0 nigdy tak 0 nie /org/freedesktop/NetworkManager/Settings/Connection/3 nie -- -- -- -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-011.expected b/clients/tests/test-client.check-on-disk/test_003-011.expected new file mode 100644 index 0000000000..9611a18263 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-011.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:595:test_003()/11 +cmd: $NMCLI -f ALL c s +lang: de_DE.utf8 +returncode: 0 +stdout: 912 bytes +>>> +NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT AUTOCONNECT-PRIORITY READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH SLAVE +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet 0 nie ja 0 nein /org/freedesktop/NetworkManager/Settings/Connection/1 nein -- -- -- -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet 0 nie ja 0 nein /org/freedesktop/NetworkManager/Settings/Connection/2 nein -- -- -- -- +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet 0 nie ja 0 nein /org/freedesktop/NetworkManager/Settings/Connection/3 nein -- -- -- -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-012.expected b/clients/tests/test-client.check-on-disk/test_003-012.expected new file mode 100644 index 0000000000..1a56267735 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-012.expected @@ -0,0 +1,22 @@ +location: clients/tests/test-client.py:599:test_003()/12 +cmd: $NMCLI --complete-args -f ALL c s '' +lang: C +returncode: 0 +stdout: 64 bytes +>>> + +--active +--order +apath +con-1 +con-xx1 +ethernet +help +id +path +uuid +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-013.expected b/clients/tests/test-client.check-on-disk/test_003-013.expected new file mode 100644 index 0000000000..3fa8126ea1 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-013.expected @@ -0,0 +1,22 @@ +location: clients/tests/test-client.py:599:test_003()/13 +cmd: $NMCLI --complete-args -f ALL c s '' +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 64 bytes +>>> + +--active +--order +apath +con-1 +con-xx1 +ethernet +help +id +path +uuid +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-014.expected b/clients/tests/test-client.check-on-disk/test_003-014.expected new file mode 100644 index 0000000000..247e785f53 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-014.expected @@ -0,0 +1,22 @@ +location: clients/tests/test-client.py:599:test_003()/14 +cmd: $NMCLI --complete-args -f ALL c s '' +lang: de_DE.utf8 +returncode: 0 +stdout: 64 bytes +>>> + +--active +--order +apath +con-1 +con-xx1 +ethernet +help +id +path +uuid +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-015.expected b/clients/tests/test-client.check-on-disk/test_003-015.expected new file mode 100644 index 0000000000..5937f5241d --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-015.expected @@ -0,0 +1,13 @@ +location: clients/tests/test-client.py:601:test_003()/15 +cmd: $NMCLI con up ethernet ifname eth0 +lang: C +returncode: 0 +stdout: 106 bytes +>>> +Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/1) + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-016.expected b/clients/tests/test-client.check-on-disk/test_003-016.expected new file mode 100644 index 0000000000..57bbcd7247 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-016.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:604:test_003()/16 +cmd: $NMCLI con +lang: C +returncode: 0 +stdout: 264 bytes +>>> +NAME UUID TYPE DEVICE +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet eth0 +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-017.expected b/clients/tests/test-client.check-on-disk/test_003-017.expected new file mode 100644 index 0000000000..11aad7c5b9 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-017.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:604:test_003()/17 +cmd: $NMCLI con +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 264 bytes +>>> +NAME UUID TYPE DEVICE +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet eth0 +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-018.expected b/clients/tests/test-client.check-on-disk/test_003-018.expected new file mode 100644 index 0000000000..7c5070b5b4 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-018.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:604:test_003()/18 +cmd: $NMCLI con +lang: de_DE.utf8 +returncode: 0 +stdout: 264 bytes +>>> +NAME UUID TYPE DEVICE +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet eth0 +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-019.expected b/clients/tests/test-client.check-on-disk/test_003-019.expected new file mode 100644 index 0000000000..d95f3ea073 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-019.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:607:test_003()/19 +cmd: $NMCLI -f ALL con +lang: C +returncode: 0 +stdout: 1084 bytes +>>> +NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT AUTOCONNECT-PRIORITY READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH SLAVE +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/3 yes eth0 activated /org/freedesktop/NetworkManager/ActiveConnection/1 -- +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/1 no -- -- -- -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/2 no -- -- -- -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-020.expected b/clients/tests/test-client.check-on-disk/test_003-020.expected new file mode 100644 index 0000000000..be0e3109d1 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-020.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:607:test_003()/20 +cmd: $NMCLI -f ALL con +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 1088 bytes +>>> +NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT AUTOCONNECT-PRIORITY READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH SLAVE +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet 0 nigdy tak 0 nie /org/freedesktop/NetworkManager/Settings/Connection/3 tak eth0 aktywowano /org/freedesktop/NetworkManager/ActiveConnection/1 -- +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet 0 nigdy tak 0 nie /org/freedesktop/NetworkManager/Settings/Connection/1 nie -- -- -- -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet 0 nigdy tak 0 nie /org/freedesktop/NetworkManager/Settings/Connection/2 nie -- -- -- -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-021.expected b/clients/tests/test-client.check-on-disk/test_003-021.expected new file mode 100644 index 0000000000..a5fe70a1e6 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-021.expected @@ -0,0 +1,16 @@ +location: clients/tests/test-client.py:607:test_003()/21 +cmd: $NMCLI -f ALL con +lang: de_DE.utf8 +returncode: 0 +stdout: 1084 bytes +>>> +NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT AUTOCONNECT-PRIORITY READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH SLAVE +ethernet UUID-ethernet-REPLACED-REPLACED-REPL ethernet 0 nie ja 0 nein /org/freedesktop/NetworkManager/Settings/Connection/3 ja eth0 aktiviert /org/freedesktop/NetworkManager/ActiveConnection/1 -- +con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet 0 nie ja 0 nein /org/freedesktop/NetworkManager/Settings/Connection/1 nein -- -- -- -- +con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet 0 nie ja 0 nein /org/freedesktop/NetworkManager/Settings/Connection/2 nein -- -- -- -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-022.expected b/clients/tests/test-client.check-on-disk/test_003-022.expected new file mode 100644 index 0000000000..b74865ed3f --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-022.expected @@ -0,0 +1,90 @@ +location: clients/tests/test-client.py:610:test_003()/22 +cmd: $NMCLI -f ALL con s ethernet +lang: C +returncode: 0 +stdout: 3516 bytes +>>> +connection.id: ethernet +connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL +connection.stable-id: -- +connection.type: 802-3-ethernet +connection.interface-name: -- +connection.autoconnect: yes +connection.autoconnect-priority: 0 +connection.autoconnect-retries: -1 (default) +connection.auth-retries: -1 +connection.timestamp: 0 +connection.read-only: no +connection.permissions: -- +connection.zone: -- +connection.master: -- +connection.slave-type: -- +connection.autoconnect-slaves: -1 (default) +connection.secondaries: -- +connection.gateway-ping-timeout: 0 +connection.metered: unknown +connection.lldp: default +connection.mdns: -1 (default) +802-3-ethernet.port: -- +802-3-ethernet.speed: 0 +802-3-ethernet.duplex: -- +802-3-ethernet.auto-negotiate: no +802-3-ethernet.mac-address: -- +802-3-ethernet.cloned-mac-address: -- +802-3-ethernet.generate-mac-address-mask:-- +802-3-ethernet.mac-address-blacklist: -- +802-3-ethernet.mtu: auto +802-3-ethernet.s390-subchannels: -- +802-3-ethernet.s390-nettype: -- +802-3-ethernet.s390-options: -- +802-3-ethernet.wake-on-lan: default +802-3-ethernet.wake-on-lan-password: -- +ipv4.method: auto +ipv4.dns: -- +ipv4.dns-search: -- +ipv4.dns-options: "" +ipv4.dns-priority: 0 +ipv4.addresses: -- +ipv4.gateway: -- +ipv4.routes: -- +ipv4.route-metric: -1 +ipv4.route-table: 0 (unspec) +ipv4.ignore-auto-routes: no +ipv4.ignore-auto-dns: no +ipv4.dhcp-client-id: -- +ipv4.dhcp-timeout: 0 (default) +ipv4.dhcp-send-hostname: yes +ipv4.dhcp-hostname: -- +ipv4.dhcp-fqdn: -- +ipv4.never-default: no +ipv4.may-fail: yes +ipv4.dad-timeout: -1 (default) +ipv6.method: auto +ipv6.dns: -- +ipv6.dns-search: -- +ipv6.dns-options: "" +ipv6.dns-priority: 0 +ipv6.addresses: -- +ipv6.gateway: -- +ipv6.routes: -- +ipv6.route-metric: -1 +ipv6.route-table: 0 (unspec) +ipv6.ignore-auto-routes: no +ipv6.ignore-auto-dns: no +ipv6.never-default: no +ipv6.may-fail: yes +ipv6.ip6-privacy: -1 (unknown) +ipv6.addr-gen-mode: stable-privacy +ipv6.dhcp-send-hostname: yes +ipv6.dhcp-hostname: -- +ipv6.token: -- +proxy.method: none +proxy.browser-only: no +proxy.pac-url: -- +proxy.pac-script: -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-023.expected b/clients/tests/test-client.check-on-disk/test_003-023.expected new file mode 100644 index 0000000000..a2e91df1c1 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-023.expected @@ -0,0 +1,90 @@ +location: clients/tests/test-client.py:610:test_003()/23 +cmd: $NMCLI -f ALL con s ethernet +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 3534 bytes +>>> +connection.id: ethernet +connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL +connection.stable-id: -- +connection.type: 802-3-ethernet +connection.interface-name: -- +connection.autoconnect: tak +connection.autoconnect-priority: 0 +connection.autoconnect-retries: -1 (default) +connection.auth-retries: -1 +connection.timestamp: 0 +connection.read-only: nie +connection.permissions: -- +connection.zone: -- +connection.master: -- +connection.slave-type: -- +connection.autoconnect-slaves: -1 (default) +connection.secondaries: -- +connection.gateway-ping-timeout: 0 +connection.metered: nieznane +connection.lldp: default +connection.mdns: -1 (default) +802-3-ethernet.port: -- +802-3-ethernet.speed: 0 +802-3-ethernet.duplex: -- +802-3-ethernet.auto-negotiate: nie +802-3-ethernet.mac-address: -- +802-3-ethernet.cloned-mac-address: -- +802-3-ethernet.generate-mac-address-mask:-- +802-3-ethernet.mac-address-blacklist: -- +802-3-ethernet.mtu: automatyczne +802-3-ethernet.s390-subchannels: -- +802-3-ethernet.s390-nettype: -- +802-3-ethernet.s390-options: -- +802-3-ethernet.wake-on-lan: default +802-3-ethernet.wake-on-lan-password: -- +ipv4.method: auto +ipv4.dns: -- +ipv4.dns-search: -- +ipv4.dns-options: "" +ipv4.dns-priority: 0 +ipv4.addresses: -- +ipv4.gateway: -- +ipv4.routes: -- +ipv4.route-metric: -1 +ipv4.route-table: 0 (unspec) +ipv4.ignore-auto-routes: nie +ipv4.ignore-auto-dns: nie +ipv4.dhcp-client-id: -- +ipv4.dhcp-timeout: 0 (default) +ipv4.dhcp-send-hostname: tak +ipv4.dhcp-hostname: -- +ipv4.dhcp-fqdn: -- +ipv4.never-default: nie +ipv4.may-fail: tak +ipv4.dad-timeout: -1 (default) +ipv6.method: auto +ipv6.dns: -- +ipv6.dns-search: -- +ipv6.dns-options: "" +ipv6.dns-priority: 0 +ipv6.addresses: -- +ipv6.gateway: -- +ipv6.routes: -- +ipv6.route-metric: -1 +ipv6.route-table: 0 (unspec) +ipv6.ignore-auto-routes: nie +ipv6.ignore-auto-dns: nie +ipv6.never-default: nie +ipv6.may-fail: tak +ipv6.ip6-privacy: -1 (unknown) +ipv6.addr-gen-mode: stable-privacy +ipv6.dhcp-send-hostname: tak +ipv6.dhcp-hostname: -- +ipv6.token: -- +proxy.method: none +proxy.browser-only: nie +proxy.pac-url: -- +proxy.pac-script: -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-024.expected b/clients/tests/test-client.check-on-disk/test_003-024.expected new file mode 100644 index 0000000000..0ae321ebad --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-024.expected @@ -0,0 +1,90 @@ +location: clients/tests/test-client.py:610:test_003()/24 +cmd: $NMCLI -f ALL con s ethernet +lang: de_DE.utf8 +returncode: 0 +stdout: 3531 bytes +>>> +connection.id: ethernet +connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL +connection.stable-id: -- +connection.type: 802-3-ethernet +connection.interface-name: -- +connection.autoconnect: ja +connection.autoconnect-priority: 0 +connection.autoconnect-retries: -1 (default) +connection.auth-retries: -1 +connection.timestamp: 0 +connection.read-only: nein +connection.permissions: -- +connection.zone: -- +connection.master: -- +connection.slave-type: -- +connection.autoconnect-slaves: -1 (default) +connection.secondaries: -- +connection.gateway-ping-timeout: 0 +connection.metered: unbekannt +connection.lldp: default +connection.mdns: -1 (default) +802-3-ethernet.port: -- +802-3-ethernet.speed: 0 +802-3-ethernet.duplex: -- +802-3-ethernet.auto-negotiate: nein +802-3-ethernet.mac-address: -- +802-3-ethernet.cloned-mac-address: -- +802-3-ethernet.generate-mac-address-mask:-- +802-3-ethernet.mac-address-blacklist: -- +802-3-ethernet.mtu: auto +802-3-ethernet.s390-subchannels: -- +802-3-ethernet.s390-nettype: -- +802-3-ethernet.s390-options: -- +802-3-ethernet.wake-on-lan: default +802-3-ethernet.wake-on-lan-password: -- +ipv4.method: auto +ipv4.dns: -- +ipv4.dns-search: -- +ipv4.dns-options: "" +ipv4.dns-priority: 0 +ipv4.addresses: -- +ipv4.gateway: -- +ipv4.routes: -- +ipv4.route-metric: -1 +ipv4.route-table: 0 (unspec) +ipv4.ignore-auto-routes: nein +ipv4.ignore-auto-dns: nein +ipv4.dhcp-client-id: -- +ipv4.dhcp-timeout: 0 (default) +ipv4.dhcp-send-hostname: ja +ipv4.dhcp-hostname: -- +ipv4.dhcp-fqdn: -- +ipv4.never-default: nein +ipv4.may-fail: ja +ipv4.dad-timeout: -1 (default) +ipv6.method: auto +ipv6.dns: -- +ipv6.dns-search: -- +ipv6.dns-options: "" +ipv6.dns-priority: 0 +ipv6.addresses: -- +ipv6.gateway: -- +ipv6.routes: -- +ipv6.route-metric: -1 +ipv6.route-table: 0 (unspec) +ipv6.ignore-auto-routes: nein +ipv6.ignore-auto-dns: nein +ipv6.never-default: nein +ipv6.may-fail: ja +ipv6.ip6-privacy: -1 (unknown) +ipv6.addr-gen-mode: stable-privacy +ipv6.dhcp-send-hostname: ja +ipv6.dhcp-hostname: -- +ipv6.token: -- +proxy.method: none +proxy.browser-only: nein +proxy.pac-url: -- +proxy.pac-script: -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-025.expected b/clients/tests/test-client.check-on-disk/test_003-025.expected new file mode 100644 index 0000000000..1cc8f5a609 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-025.expected @@ -0,0 +1,18 @@ +location: clients/tests/test-client.py:613:test_003()/25 +cmd: $NMCLI -f ALL dev s eth0 +lang: C +returncode: 0 +stdout: 880 bytes +>>> +DEVICE TYPE STATE DBUS-PATH CONNECTION CON-UUID CON-PATH +wlan0 wifi unavailable /org/freedesktop/NetworkManager/Devices/2 -- -- -- +wlan1 wifi unavailable /org/freedesktop/NetworkManager/Devices/3 -- -- -- +wlan1 wifi unavailable /org/freedesktop/NetworkManager/Devices/4 -- -- -- +eth0 ethernet unavailable /org/freedesktop/NetworkManager/Devices/1 ethernet UUID-ethernet-REPLACED-REPLACED-REPL /org/freedesktop/NetworkManager/ActiveConnection/1 + +<<< +stderr: 24 bytes +>>> +Unknown parameter: eth0 + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-026.expected b/clients/tests/test-client.check-on-disk/test_003-026.expected new file mode 100644 index 0000000000..92161b21af --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-026.expected @@ -0,0 +1,18 @@ +location: clients/tests/test-client.py:613:test_003()/26 +cmd: $NMCLI -f ALL dev s eth0 +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 884 bytes +>>> +DEVICE TYPE STATE DBUS-PATH CONNECTION CON-UUID CON-PATH +wlan0 wifi niedostępne /org/freedesktop/NetworkManager/Devices/2 -- -- -- +wlan1 wifi niedostępne /org/freedesktop/NetworkManager/Devices/3 -- -- -- +wlan1 wifi niedostępne /org/freedesktop/NetworkManager/Devices/4 -- -- -- +eth0 ethernet niedostępne /org/freedesktop/NetworkManager/Devices/1 ethernet UUID-ethernet-REPLACED-REPLACED-REPL /org/freedesktop/NetworkManager/ActiveConnection/1 + +<<< +stderr: 24 bytes +>>> +Nieznany parametr: eth0 + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-027.expected b/clients/tests/test-client.check-on-disk/test_003-027.expected new file mode 100644 index 0000000000..45ecba75cf --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-027.expected @@ -0,0 +1,18 @@ +location: clients/tests/test-client.py:613:test_003()/27 +cmd: $NMCLI -f ALL dev s eth0 +lang: de_DE.utf8 +returncode: 0 +stdout: 904 bytes +>>> +DEVICE TYPE STATE DBUS-PATH CONNECTION CON-UUID CON-PATH +wlan0 wifi nicht verfügbar /org/freedesktop/NetworkManager/Devices/2 -- -- -- +wlan1 wifi nicht verfügbar /org/freedesktop/NetworkManager/Devices/3 -- -- -- +wlan1 wifi nicht verfügbar /org/freedesktop/NetworkManager/Devices/4 -- -- -- +eth0 ethernet nicht verfügbar /org/freedesktop/NetworkManager/Devices/1 ethernet UUID-ethernet-REPLACED-REPLACED-REPL /org/freedesktop/NetworkManager/ActiveConnection/1 + +<<< +stderr: 28 bytes +>>> +Unbekannter Parameter: eth0 + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-028.expected b/clients/tests/test-client.check-on-disk/test_003-028.expected new file mode 100644 index 0000000000..b3563bbe4b --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-028.expected @@ -0,0 +1,42 @@ +location: clients/tests/test-client.py:616:test_003()/28 +cmd: $NMCLI -f ALL dev show eth0 +lang: C +returncode: 0 +stdout: 1487 bytes +>>> +GENERAL.DEVICE: eth0 +GENERAL.TYPE: ethernet +GENERAL.NM-TYPE: NMDeviceEthernet +GENERAL.VENDOR: -- +GENERAL.PRODUCT: -- +GENERAL.DRIVER: virtual +GENERAL.DRIVER-VERSION: -- +GENERAL.FIRMWARE-VERSION: -- +GENERAL.HWADDR: 72:41:AB:90:41:5D +GENERAL.MTU: 0 +GENERAL.STATE: 20 (unavailable) +GENERAL.REASON: 0 (No reason given) +GENERAL.UDI: /sys/devices/virtual/eth0 +GENERAL.IP-IFACE: -- +GENERAL.IS-SOFTWARE: no +GENERAL.NM-MANAGED: yes +GENERAL.AUTOCONNECT: yes +GENERAL.FIRMWARE-MISSING: no +GENERAL.NM-PLUGIN-MISSING: no +GENERAL.PHYS-PORT-ID: -- +GENERAL.CONNECTION: ethernet +GENERAL.CON-UUID: UUID-ethernet-REPLACED-REPLACED-REPL +GENERAL.CON-PATH: /org/freedesktop/NetworkManager/ActiveConnection/1 +GENERAL.METERED: unknown +CAPABILITIES.CARRIER-DETECT: no +CAPABILITIES.SPEED: 100 Mb/s +CAPABILITIES.IS-SOFTWARE: no +CAPABILITIES.SRIOV: no +WIRED-PROPERTIES.CARRIER: off +CONNECTIONS.AVAILABLE-CONNECTION-PATHS: -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-029.expected b/clients/tests/test-client.check-on-disk/test_003-029.expected new file mode 100644 index 0000000000..ae4af0107e --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-029.expected @@ -0,0 +1,42 @@ +location: clients/tests/test-client.py:616:test_003()/29 +cmd: $NMCLI -f ALL dev show eth0 +lang: pl_PL.UTF-8 +returncode: 0 +stdout: 1510 bytes +>>> +GENERAL.DEVICE: eth0 +GENERAL.TYPE: ethernet +GENERAL.NM-TYPE: NMDeviceEthernet +GENERAL.VENDOR: -- +GENERAL.PRODUCT: -- +GENERAL.DRIVER: virtual +GENERAL.DRIVER-VERSION: -- +GENERAL.FIRMWARE-VERSION: -- +GENERAL.HWADDR: 72:41:AB:90:41:5D +GENERAL.MTU: 0 +GENERAL.STATE: 20 (niedostępne) +GENERAL.REASON: 0 (Nie podano przyczyny) +GENERAL.UDI: /sys/devices/virtual/eth0 +GENERAL.IP-IFACE: -- +GENERAL.IS-SOFTWARE: nie +GENERAL.NM-MANAGED: tak +GENERAL.AUTOCONNECT: tak +GENERAL.FIRMWARE-MISSING: nie +GENERAL.NM-PLUGIN-MISSING: nie +GENERAL.PHYS-PORT-ID: -- +GENERAL.CONNECTION: ethernet +GENERAL.CON-UUID: UUID-ethernet-REPLACED-REPLACED-REPL +GENERAL.CON-PATH: /org/freedesktop/NetworkManager/ActiveConnection/1 +GENERAL.METERED: nieznane +CAPABILITIES.CARRIER-DETECT: nie +CAPABILITIES.SPEED: 100 Mb/s +CAPABILITIES.IS-SOFTWARE: nie +CAPABILITIES.SRIOV: nie +WIRED-PROPERTIES.CARRIER: wyłączone +CONNECTIONS.AVAILABLE-CONNECTION-PATHS: -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.check-on-disk/test_003-030.expected b/clients/tests/test-client.check-on-disk/test_003-030.expected new file mode 100644 index 0000000000..9a4106a3a3 --- /dev/null +++ b/clients/tests/test-client.check-on-disk/test_003-030.expected @@ -0,0 +1,42 @@ +location: clients/tests/test-client.py:616:test_003()/30 +cmd: $NMCLI -f ALL dev show eth0 +lang: de_DE.utf8 +returncode: 0 +stdout: 1509 bytes +>>> +GENERAL.DEVICE: eth0 +GENERAL.TYPE: ethernet +GENERAL.NM-TYPE: NMDeviceEthernet +GENERAL.VENDOR: -- +GENERAL.PRODUCT: -- +GENERAL.DRIVER: virtual +GENERAL.DRIVER-VERSION: -- +GENERAL.FIRMWARE-VERSION: -- +GENERAL.HWADDR: 72:41:AB:90:41:5D +GENERAL.MTU: 0 +GENERAL.STATE: 20 (nicht verfügbar) +GENERAL.REASON: 0 (Kein Grund angegeben) +GENERAL.UDI: /sys/devices/virtual/eth0 +GENERAL.IP-IFACE: -- +GENERAL.IS-SOFTWARE: nein +GENERAL.NM-MANAGED: ja +GENERAL.AUTOCONNECT: ja +GENERAL.FIRMWARE-MISSING: nein +GENERAL.NM-PLUGIN-MISSING: nein +GENERAL.PHYS-PORT-ID: -- +GENERAL.CONNECTION: ethernet +GENERAL.CON-UUID: UUID-ethernet-REPLACED-REPLACED-REPL +GENERAL.CON-PATH: /org/freedesktop/NetworkManager/ActiveConnection/1 +GENERAL.METERED: unbekannt +CAPABILITIES.CARRIER-DETECT: nein +CAPABILITIES.SPEED: 100 Mb/s +CAPABILITIES.IS-SOFTWARE: nein +CAPABILITIES.SRIOV: nein +WIRED-PROPERTIES.CARRIER: aus +CONNECTIONS.AVAILABLE-CONNECTION-PATHS: -- + +<<< +stderr: 0 bytes +>>> + +<<< diff --git a/clients/tests/test-client.py b/clients/tests/test-client.py index 8afd22c167..84863d7526 100755 --- a/clients/tests/test-client.py +++ b/clients/tests/test-client.py @@ -279,8 +279,32 @@ class TestNmcli(NmTestBase): text = text2 return b''.join([(t[0] if isinstance(t, tuple) else t) for t in text]) + def call_nmcli_l(self, + args, + check_on_disk = _DEFAULT_ARG, + expected_returncode = _DEFAULT_ARG, + expected_stdout = _DEFAULT_ARG, + expected_stderr = _DEFAULT_ARG, + replace_stdout = None, + replace_stderr = None, + sort_lines_stdout = False): + frame = sys._getframe(1) + for lang in [ 'C', 'pl', 'de' ]: + self._call_nmcli(args, + lang, + check_on_disk, + expected_returncode, + expected_stdout, + expected_stderr, + replace_stdout, + replace_stderr, + sort_lines_stdout, + frame) + + def call_nmcli(self, args, + langs = None, lang = None, check_on_disk = _DEFAULT_ARG, expected_returncode = _DEFAULT_ARG, @@ -292,8 +316,38 @@ class TestNmcli(NmTestBase): frame = sys._getframe(1) - calling_fcn = frame.f_code.co_name + if langs is not None: + assert lang is None + else: + if lang is None: + lang = 'C' + langs = [lang] + for lang in langs: + self._call_nmcli(args, + lang, + check_on_disk, + expected_returncode, + expected_stdout, + expected_stderr, + replace_stdout, + replace_stderr, + sort_lines_stdout, + frame) + + def _call_nmcli(self, + args, + lang, + check_on_disk, + expected_returncode, + expected_stdout, + expected_stderr, + replace_stdout, + replace_stderr, + sort_lines_stdout, + frame): + + calling_fcn = frame.f_code.co_name calling_num = self._calling_num.get(calling_fcn, 0) + 1 self._calling_num[calling_fcn] = calling_num @@ -486,42 +540,35 @@ class TestNmcli(NmTestBase): def test_001(self): - self.call_nmcli([]) - self.call_nmcli([], lang = 'pl') + self.call_nmcli_l([]) - self.call_nmcli(['-f', 'AP', '-mode', 'multiline', '-p', 'd', 'show', 'wlan0']) - self.call_nmcli(['-f', 'AP', '-mode', 'multiline', '-p', 'd', 'show', 'wlan0'], lang = 'de') + self.call_nmcli_l(['-f', 'AP', '-mode', 'multiline', '-p', 'd', 'show', 'wlan0']) - self.call_nmcli(['c', 's']) + self.call_nmcli_l(['c', 's']) - self.call_nmcli(['bogus', 's']) + self.call_nmcli_l(['bogus', 's']) def test_002(self): self.init_001() - self.call_nmcli(['d']) + self.call_nmcli_l(['d']) - self.call_nmcli(['-f', 'all', 'd']) + self.call_nmcli_l(['-f', 'all', 'd']) - self.call_nmcli([]) + self.call_nmcli_l([]) - self.call_nmcli(['-f', 'AP', '-mode', 'multiline', 'd', 'show', 'wlan0']) - self.call_nmcli(['-f', 'AP', '-mode', 'multiline', '-p', 'd', 'show', 'wlan0']) - self.call_nmcli(['-f', 'AP', '-mode', 'multiline', '-t', 'd', 'show', 'wlan0']) - self.call_nmcli(['-f', 'AP', '-mode', 'tabular', 'd', 'show', 'wlan0']) - self.call_nmcli(['-f', 'AP', '-mode', 'tabular', '-p', 'd', 'show', 'wlan0']) - self.call_nmcli(['-f', 'AP', '-mode', 'tabular', '-t', 'd', 'show', 'wlan0']) + self.call_nmcli_l(['-f', 'AP', '-mode', 'multiline', 'd', 'show', 'wlan0']) + self.call_nmcli_l(['-f', 'AP', '-mode', 'multiline', '-p', 'd', 'show', 'wlan0']) + self.call_nmcli_l(['-f', 'AP', '-mode', 'multiline', '-t', 'd', 'show', 'wlan0']) + self.call_nmcli_l(['-f', 'AP', '-mode', 'tabular', 'd', 'show', 'wlan0']) + self.call_nmcli_l(['-f', 'AP', '-mode', 'tabular', '-p', 'd', 'show', 'wlan0']) + self.call_nmcli_l(['-f', 'AP', '-mode', 'tabular', '-t', 'd', 'show', 'wlan0']) - self.call_nmcli(['-f', 'AP', '-mode', 'multiline', 'd', 'show', 'wlan0'], lang = 'pl') - self.call_nmcli(['-f', 'AP', '-mode', 'multiline', '-p', 'd', 'show', 'wlan0'], lang = 'pl') - self.call_nmcli(['-f', 'AP', '-mode', 'multiline', '-t', 'd', 'show', 'wlan0'], lang = 'pl') - self.call_nmcli(['-f', 'AP', '-mode', 'tabular', 'd', 'show', 'wlan0'], lang = 'pl') - self.call_nmcli(['-f', 'AP', '-mode', 'tabular', '-p', 'd', 'show', 'wlan0'], lang = 'pl') - self.call_nmcli(['-f', 'AP', '-mode', 'tabular', '-t', 'd', 'show', 'wlan0'], lang = 'pl') + self.call_nmcli_l(['-f', 'ALL', 'd', 'wifi']) - self.call_nmcli(['c']) + self.call_nmcli_l(['c']) - self.call_nmcli(['c', 's', 'con-1']) + self.call_nmcli_l(['c', 's', 'con-1']) def test_003(self): self.init_001() @@ -533,27 +580,40 @@ class TestNmcli(NmTestBase): self.call_nmcli(['c', 'add', 'type', 'ethernet', 'ifname', '*', 'con-name', 'con-xx1'], replace_stdout = replace_stdout) - self.call_nmcli(['c', 's'], - replace_stdout = replace_stdout) + self.call_nmcli_l(['c', 's'], + replace_stdout = replace_stdout) replace_stdout.append((lambda: self.srv.findConnectionUuid('ethernet'), 'UUID-ethernet-REPLACED-REPLACED-REPL')) self.call_nmcli(['c', 'add', 'type', 'ethernet', 'ifname', '*'], replace_stdout = replace_stdout) - self.call_nmcli(['c', 's'], - replace_stdout = replace_stdout) - self.call_nmcli(['c', 's'], lang = 'pl', - replace_stdout = replace_stdout) + self.call_nmcli_l(['c', 's'], + replace_stdout = replace_stdout) - self.call_nmcli(['-f', 'ALL', 'c', 's'], - replace_stdout = replace_stdout) - self.call_nmcli(['-f', 'ALL', 'c', 's'], lang = 'pl', - replace_stdout = replace_stdout) + self.call_nmcli_l(['-f', 'ALL', 'c', 's'], + replace_stdout = replace_stdout) - self.call_nmcli(['--complete-args', '-f', 'ALL', 'c', 's', ''], lang = 'pl', - replace_stdout = replace_stdout, - sort_lines_stdout = True) + self.call_nmcli_l(['--complete-args', '-f', 'ALL', 'c', 's', ''], + replace_stdout = replace_stdout, + sort_lines_stdout = True) + + self.call_nmcli(['con', 'up', 'ethernet', 'ifname', 'eth0']) + + self.call_nmcli_l(['con'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['-f', 'ALL', 'con'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['-f', 'ALL', 'con', 's', 'ethernet'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['-f', 'ALL', 'dev', 's', 'eth0'], + replace_stdout = replace_stdout) + + self.call_nmcli_l(['-f', 'ALL', 'dev', 'show', 'eth0'], + replace_stdout = replace_stdout) ############################################################################### diff --git a/po/POTFILES.in b/po/POTFILES.in index ed492ba11e..941250418b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -10,6 +10,7 @@ clients/cli/nmcli.c clients/cli/polkit-agent.c clients/cli/settings.c clients/cli/utils.c +clients/cli/utils.h clients/common/nm-client-utils.c clients/common/nm-meta-setting-access.c clients/common/nm-meta-setting-desc.c diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index aad1b3ddda..96e5da350b 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -549,6 +549,108 @@ nm_cmp_int2ptr_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_ /*****************************************************************************/ +const char * +nm_utils_dbus_path_get_last_component (const char *dbus_path) +{ + if (dbus_path) { + dbus_path = strrchr (dbus_path, '/'); + if (dbus_path) + return dbus_path + 1; + } + return NULL; +} + +static gint64 +_dbus_path_component_as_num (const char *p) +{ + gint64 n; + + /* no odd stuff. No leading zeros, only a non-negative, decimal integer. + * + * Otherwise, there would be multiple ways to encode the same number "10" + * and "010". That is just confusing. A number has no leading zeros, + * if it has, it's not a number (as far as we are concerned here). */ + if (p[0] == '0') { + if (p[1] != '\0') + return -1; + else + return 0; + } + if (!(p[0] >= '1' && p[0] <= '9')) + return -1; + if (!NM_STRCHAR_ALL (&p[1], ch, (ch >= '0' && ch <= '9'))) + return -1; + n = _nm_utils_ascii_str_to_int64 (p, 10, 0, G_MAXINT64, -1); + nm_assert (n == -1 || nm_streq0 (p, nm_sprintf_bufa (100, "%"G_GINT64_FORMAT, n))); + return n; +} + +int +nm_utils_dbus_path_cmp (const char *dbus_path_a, const char *dbus_path_b) +{ + const char *l_a, *l_b; + gsize plen; + gint64 n_a, n_b; + + /* compare function for two D-Bus paths. It behaves like + * strcmp(), except, if both paths have the same prefix, + * and both end in a (positive) number, then the paths + * will be sorted by number. */ + + NM_CMP_SELF (dbus_path_a, dbus_path_b); + + /* if one or both paths have no slash (and no last component) + * compare the full paths directly. */ + if ( !(l_a = nm_utils_dbus_path_get_last_component (dbus_path_a)) + || !(l_b = nm_utils_dbus_path_get_last_component (dbus_path_b))) + goto comp_full; + + /* check if both paths have the same prefix (up to the last-component). */ + plen = l_a - dbus_path_a; + if (plen != (l_b - dbus_path_b)) + goto comp_full; + NM_CMP_RETURN (strncmp (dbus_path_a, dbus_path_b, plen)); + + n_a = _dbus_path_component_as_num (l_a); + n_b = _dbus_path_component_as_num (l_b); + if (n_a == -1 && n_b == -1) + goto comp_l; + + /* both components must be convertiable to a number. If they are not, + * (and only one of them is), then we must always strictly sort numeric parts + * after non-numeric components. If we wouldn't, we wouldn't have + * a total order. + * + * An example of a not total ordering would be: + * "8" < "010" (numeric) + * "0x" < "8" (lexical) + * "0x" > "010" (lexical) + * We avoid this, by forcing that a non-numeric entry "0x" always sorts + * before numeric entries. + * + * Additionally, _dbus_path_component_as_num() would also reject "010" as + * not a valid number. + */ + if (n_a == -1) + return -1; + if (n_b == -1) + return 1; + + NM_CMP_DIRECT (n_a, n_b); + nm_assert (nm_streq (dbus_path_a, dbus_path_b)); + return 0; + +comp_full: + NM_CMP_DIRECT_STRCMP0 (dbus_path_a, dbus_path_b); + return 0; +comp_l: + NM_CMP_DIRECT_STRCMP0 (l_a, l_b); + nm_assert (nm_streq (dbus_path_a, dbus_path_b)); + return 0; +} + +/*****************************************************************************/ + /** * nm_utils_strsplit_set: * @str: the string to split. diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index ddb77a429b..4b081630cf 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -113,6 +113,9 @@ nm_ip_addr_set (int addr_family, gpointer dst, const NMIPAddr *src) #define NM_CMP_DIRECT_MEMCMP(a, b, size) \ NM_CMP_RETURN (memcmp ((a), (b), (size))) +#define NM_CMP_DIRECT_STRCMP0(a, b) \ + NM_CMP_RETURN (g_strcmp0 ((a), (b))) + #define NM_CMP_DIRECT_IN6ADDR(a, b) \ G_STMT_START { \ const struct in6_addr *const _a = (a); \ @@ -199,6 +202,12 @@ nm_utils_is_separator (const char c) /*****************************************************************************/ +const char *nm_utils_dbus_path_get_last_component (const char *dbus_path); + +int nm_utils_dbus_path_cmp (const char *dbus_path_a, const char *dbus_path_b); + +/*****************************************************************************/ + const char **nm_utils_strsplit_set (const char *str, const char *delimiters); gssize nm_utils_strv_find_first (char **list, gssize len, const char *needle); @@ -446,6 +455,16 @@ nm_g_variant_unref_floating (GVariant *var) /*****************************************************************************/ +static inline int +nm_utf8_collate0 (const char *a, const char *b) +{ + if (!a) + return !b ? 0 : -1; + if (!b) + return 1; + return g_utf8_collate (a, b); +} + int nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data); int nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data); int nm_cmp_int2ptr_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data); diff --git a/tools/test-networkmanager-service.py b/tools/test-networkmanager-service.py index e4246d31be..2121bb2b27 100755 --- a/tools/test-networkmanager-service.py +++ b/tools/test-networkmanager-service.py @@ -23,94 +23,25 @@ import collections import uuid import hashlib +############################################################################### + _DEFAULT_ARG = object() -######################################################### +############################################################################### + +class Global: + pass + +gl = None + +############################################################################### class TestError(AssertionError): def __init__(self, message = 'Unspecified error', errors = None): AssertionError.__init__(self, message) self.errors = errors -def pseudorandom_stream(seed, length = None): - seed = str(seed) - v = None - i = 0 - while length is None or length > 0: - if not v: - s = seed + str(i) - s = s.encode('utf8') - v = hashlib.sha256(s).hexdigest() - i += 1 - yield int(v[0:2], 16) - v = v[2:] - if length is not None: - length -= 1 - -def pseudorandom_num(seed, v_end, v_start = 0): - n = 0 - span = v_end - v_start - for r in pseudorandom_stream(seed): - n = n * 256 + r - if n > span: - break - return v_start + (n % span) - -######################################################### - -mainloop = GLib.MainLoop() - -# NM State -NM_STATE_UNKNOWN = 0 -NM_STATE_ASLEEP = 10 -NM_STATE_DISCONNECTED = 20 -NM_STATE_DISCONNECTING = 30 -NM_STATE_CONNECTING = 40 -NM_STATE_CONNECTED_LOCAL = 50 -NM_STATE_CONNECTED_SITE = 60 -NM_STATE_CONNECTED_GLOBAL = 70 - -# Device state -NM_DEVICE_STATE_UNKNOWN = 0 -NM_DEVICE_STATE_UNMANAGED = 10 -NM_DEVICE_STATE_UNAVAILABLE = 20 -NM_DEVICE_STATE_DISCONNECTED = 30 -NM_DEVICE_STATE_PREPARE = 40 -NM_DEVICE_STATE_CONFIG = 50 -NM_DEVICE_STATE_NEED_AUTH = 60 -NM_DEVICE_STATE_IP_CONFIG = 70 -NM_DEVICE_STATE_IP_CHECK = 80 -NM_DEVICE_STATE_SECONDARIES = 90 -NM_DEVICE_STATE_ACTIVATED = 100 -NM_DEVICE_STATE_DEACTIVATING = 110 -NM_DEVICE_STATE_FAILED = 120 - -# Device type -NM_DEVICE_TYPE_UNKNOWN = 0 -NM_DEVICE_TYPE_ETHERNET = 1 -NM_DEVICE_TYPE_WIFI = 2 -NM_DEVICE_TYPE_UNUSED1 = 3 -NM_DEVICE_TYPE_UNUSED2 = 4 -NM_DEVICE_TYPE_BT = 5 -NM_DEVICE_TYPE_OLPC_MESH = 6 -NM_DEVICE_TYPE_WIMAX = 7 -NM_DEVICE_TYPE_MODEM = 8 -NM_DEVICE_TYPE_INFINIBAND = 9 -NM_DEVICE_TYPE_BOND = 10 -NM_DEVICE_TYPE_VLAN = 11 -NM_DEVICE_TYPE_ADSL = 12 -NM_DEVICE_TYPE_BRIDGE = 13 -NM_DEVICE_TYPE_GENERIC = 14 -NM_DEVICE_TYPE_TEAM = 15 - -# AC state -NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0 -NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1 -NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2 -NM_ACTIVE_CONNECTION_STATE_DEACTIVATING = 3 -NM_ACTIVE_CONNECTION_STATE_DEACTIVATED = 4 - -######################################################### +############################################################################### IFACE_DBUS = 'org.freedesktop.DBus' @@ -120,24 +51,75 @@ class UnknownInterfaceException(dbus.DBusException): class UnknownPropertyException(dbus.DBusException): _dbus_error_name = IFACE_DBUS + '.UnknownProperty' -def to_path_array(src): - array = dbus.Array([], signature=dbus.Signature('o')) - for o in src: - array.append(to_path(o)) - return array +class Util: -def to_path(src): - if src: - return dbus.ObjectPath(src.path) - return dbus.ObjectPath("/") + @staticmethod + def pseudorandom_stream(seed, length = None): + seed = str(seed) + v = None + i = 0 + while length is None or length > 0: + if not v: + s = seed + str(i) + s = s.encode('utf8') + v = hashlib.sha256(s).hexdigest() + i += 1 + yield int(v[0:2], 16) + v = v[2:] + if length is not None: + length -= 1 + + @staticmethod + def pseudorandom_num(seed, v_end, v_start = 0): + n = 0 + span = v_end - v_start + for r in Util.pseudorandom_stream(seed): + n = n * 256 + r + if n > span: + break + return v_start + (n % span) + + @staticmethod + def random_mac(seed = None): + if seed is None: + r = tuple([random.randint(0, 255) for x in range(6)]) + else: + r = tuple(Util.pseudorandom_stream(seed, 6)) + return '%02X:%02X:%02X:%02X:%02X:%02X' % r + +############################################################################### class ExportedObj(dbus.service.Object): - DBusInterface = collections.namedtuple('DBusInterface', ['dbus_iface', 'get_props_func', 'prop_changed_func']) + DBusInterface = collections.namedtuple('DBusInterface', ['dbus_iface', 'props', 'legacy_prop_changed_func']) - def __init__(self, bus, object_path, ident = None): - dbus.service.Object.__init__(self, bus, object_path) - self._bus = bus + @staticmethod + def create_path(klass, path_prefix = None): + if path_prefix is None: + path_prefix = klass.path_prefix + path = path_prefix + str(klass.path_counter_next) + klass.path_counter_next += 1 + return path + + @staticmethod + def to_path_array(src): + array = dbus.Array([], signature=dbus.Signature('o')) + if src is not None: + for o in src: + array.append(ExportedObj.to_path(o)) + return array + + @staticmethod + def to_path(src): + if src: + return dbus.ObjectPath(src.path) + return dbus.ObjectPath("/") + + def __init__(self, object_path, ident = None): + dbus.service.Object.__init__(self) + + self._dbus_ifaces = {} + self.path = object_path # ident is an optional (unique) identifier for the instance. # The test driver may set it to reference to the object by @@ -150,35 +132,56 @@ class ExportedObj(dbus.service.Object): ident = object_path self.ident = ident - self.path = object_path - self.__ensure_dbus_ifaces() - object_manager.add_object(self) + def export(self): + self.add_to_connection(gl.bus, self.path) + gl.object_manager.add_object(self) - def __ensure_dbus_ifaces(self): - if not hasattr(self, '_ExportedObj__dbus_ifaces'): - self.__dbus_ifaces = {} + def unexport(self): + gl.object_manager.remove_object(self) + self.remove_from_connection() - def add_dbus_interface(self, dbus_iface, get_props_func, prop_changed_func): - self.__ensure_dbus_ifaces() - self.__dbus_ifaces[dbus_iface] = ExportedObj.DBusInterface(dbus_iface, get_props_func, prop_changed_func) + def dbus_interface_add(self, dbus_iface, props, legacy_prop_changed_func = None): + self._dbus_ifaces[dbus_iface] = ExportedObj.DBusInterface(dbus_iface, props, legacy_prop_changed_func) - def __dbus_interface_get(self, dbus_iface): - if dbus_iface not in self.__dbus_ifaces: + def _dbus_interface_get(self, dbus_iface): + if dbus_iface not in self._dbus_ifaces: raise UnknownInterfaceException() - return self.__dbus_ifaces[dbus_iface] + return self._dbus_ifaces[dbus_iface] - def _dbus_property_get(self, dbus_iface, propname = None): - props = self.__dbus_interface_get(dbus_iface).get_props_func() + def _dbus_interface_get_property(self, dbus_interface, propname = None): + props = dbus_interface.props if propname is None: return props if propname not in props: raise UnknownPropertyException() return props[propname] + def _dbus_property_get(self, dbus_iface, propname = None): + return self._dbus_interface_get_property(self._dbus_interface_get(dbus_iface), + propname) + + def _dbus_property_set(self, dbus_iface, propname, value): + dbus_interface = self._dbus_interface_get(dbus_iface) + prop = self._dbus_interface_get_property(dbus_interface) + assert propname in prop + prop[propname] = value + self._dbus_property_notify(dbus_iface, propname) + def _dbus_property_notify(self, dbus_iface, propname): - prop = self._dbus_property_get(dbus_iface, propname) - self.__dbus_interface_get(dbus_iface).prop_changed_func(self, { propname: prop }) - ExportedObj.PropertiesChanged(self, dbus_iface, { propname: prop }, []) + dbus_interface = self._dbus_interface_get(dbus_iface) + prop = self._dbus_interface_get_property(dbus_interface, propname) + if propname is not None: + prop = { propname: prop } + ExportedObj.PropertiesChanged(self, dbus_iface, prop, []) + + # the legacy_prop_changed_func signal is a legacy signal that got obsoleted by the standard + # PropertiesChanged signal. NetworkManager (and this stub) still emit it for backward + # compatibility reasons. Note that this stub server implementation gets this wrong, + # for example, it emits PropertiesChanged signal on org.freedesktop.NetworkManager.Device, + # which NetworkManager never did. + # See https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/src/nm-dbus-manager.c?id=db80d5f62a1edf39c5970887ef7b9ec62dd4163f#n1274 + if dbus_interface.legacy_prop_changed_func is not None: + dbus_interface.legacy_prop_changed_func(self, prop) @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as') def PropertiesChanged(self, iface, changed, invalidated): @@ -194,78 +197,61 @@ class ExportedObj(dbus.service.Object): def get_managed_ifaces(self): my_ifaces = {} - for iface in self.__dbus_ifaces: - my_ifaces[iface] = self.__dbus_ifaces[iface].get_props_func() + for iface in self._dbus_ifaces: + my_ifaces[iface] = self._dbus_ifaces[iface].props return self.path, my_ifaces - def remove_from_connection(self): - object_manager.remove_object(self) - dbus.service.Object.remove_from_connection(self) +############################################################################### -################################################################### IFACE_DEVICE = 'org.freedesktop.NetworkManager.Device' class NotSoftwareException(dbus.DBusException): _dbus_error_name = IFACE_DEVICE + '.NotSoftware' -PD_UDI = "Udi" -PD_IFACE = "Interface" -PD_DRIVER = "Driver" -PD_STATE = "State" -PD_ACTIVE_CONNECTION = "ActiveConnection" -PD_IP4_CONFIG = "Ip4Config" -PD_IP6_CONFIG = "Ip6Config" -PD_DHCP4_CONFIG = "Dhcp4Config" -PD_DHCP6_CONFIG = "Dhcp6Config" -PD_MANAGED = "Managed" -PD_AUTOCONNECT = "Autoconnect" -PD_DEVICE_TYPE = "DeviceType" -PD_AVAILABLE_CONNECTIONS = "AvailableConnections" +PRP_DEVICE_UDI = "Udi" +PRP_DEVICE_IFACE = "Interface" +PRP_DEVICE_DRIVER = "Driver" +PRP_DEVICE_STATE = "State" +PRP_DEVICE_ACTIVE_CONNECTION = "ActiveConnection" +PRP_DEVICE_IP4_CONFIG = "Ip4Config" +PRP_DEVICE_IP6_CONFIG = "Ip6Config" +PRP_DEVICE_DHCP4_CONFIG = "Dhcp4Config" +PRP_DEVICE_DHCP6_CONFIG = "Dhcp6Config" +PRP_DEVICE_MANAGED = "Managed" +PRP_DEVICE_AUTOCONNECT = "Autoconnect" +PRP_DEVICE_DEVICE_TYPE = "DeviceType" +PRP_DEVICE_AVAILABLE_CONNECTIONS = "AvailableConnections" class Device(ExportedObj): - counter = 1 - def __init__(self, bus, iface, devtype, ident = None): + path_counter_next = 1 + path_prefix = "/org/freedesktop/NetworkManager/Devices/" + + def __init__(self, iface, devtype, ident = None): if ident is None: ident = iface - object_path = "/org/freedesktop/NetworkManager/Devices/%d" % Device.counter - Device.counter = Device.counter + 1 + ExportedObj.__init__(self, ExportedObj.create_path(Device), ident) - self.iface = iface - self.udi = "/sys/devices/virtual/%s" % iface - self.devtype = devtype - self.active_connection = None - self.state = NM_DEVICE_STATE_UNAVAILABLE - self.ip4_config = None - self.ip6_config = None - self.dhcp4_config = None - self.dhcp6_config = None - self.available_connections = [] + props = { + PRP_DEVICE_UDI: "/sys/devices/virtual/%s" % (iface), + PRP_DEVICE_IFACE: iface, + PRP_DEVICE_DRIVER: "virtual", + PRP_DEVICE_STATE: dbus.UInt32(NM.DeviceState.UNAVAILABLE), + PRP_DEVICE_ACTIVE_CONNECTION: ExportedObj.to_path(None), + PRP_DEVICE_IP4_CONFIG: ExportedObj.to_path(None), + PRP_DEVICE_IP6_CONFIG: ExportedObj.to_path(None), + PRP_DEVICE_DHCP4_CONFIG: ExportedObj.to_path(None), + PRP_DEVICE_DHCP6_CONFIG: ExportedObj.to_path(None), + PRP_DEVICE_MANAGED: True, + PRP_DEVICE_AUTOCONNECT: True, + PRP_DEVICE_DEVICE_TYPE: dbus.UInt32(devtype), + PRP_DEVICE_AVAILABLE_CONNECTIONS: ExportedObj.to_path_array([]), + } - self.add_dbus_interface(IFACE_DEVICE, self.__get_props, Device.PropertiesChanged) - ExportedObj.__init__(self, bus, object_path, ident) + self.dbus_interface_add(IFACE_DEVICE, props, Device.PropertiesChanged) - # Properties interface - def __get_props(self): - props = {} - props[PD_UDI] = self.udi - props[PD_IFACE] = self.iface - props[PD_DRIVER] = "virtual" - props[PD_STATE] = dbus.UInt32(self.state) - props[PD_ACTIVE_CONNECTION] = to_path(self.active_connection) - props[PD_IP4_CONFIG] = to_path(self.ip4_config) - props[PD_IP6_CONFIG] = to_path(self.ip6_config) - props[PD_DHCP4_CONFIG] = to_path(self.dhcp4_config) - props[PD_DHCP6_CONFIG] = to_path(self.dhcp6_config) - props[PD_MANAGED] = True - props[PD_AUTOCONNECT] = True - props[PD_DEVICE_TYPE] = dbus.UInt32(self.devtype) - props[PD_AVAILABLE_CONNECTIONS] = to_path_array(self.available_connections) - return props - - # methods @dbus.service.method(dbus_interface=IFACE_DEVICE, in_signature='', out_signature='') def Disconnect(self): pass @@ -276,112 +262,92 @@ class Device(ExportedObj): raise NotSoftwareException() pass - def __notify(self, propname): - self._dbus_property_notify(IFACE_DEVICE, propname) - @dbus.service.signal(IFACE_DEVICE, signature='a{sv}') def PropertiesChanged(self, changed): pass def set_active_connection(self, ac): - self.active_connection = ac - self.__notify(PD_ACTIVE_CONNECTION) + self._dbus_property_set(IFACE_DEVICE, PRP_DEVICE_ACTIVE_CONNECTION, ac) -################################################################### +############################################################################### -def random_mac(seed = None): - if seed is None: - r = tuple([random.randint(0, 255) for x in range(6)]) - else: - r = tuple(pseudorandom_stream(seed, 6)) - return '%02X:%02X:%02X:%02X:%02X:%02X' % r - -################################################################### IFACE_WIRED = 'org.freedesktop.NetworkManager.Device.Wired' -PE_HW_ADDRESS = "HwAddress" -PE_PERM_HW_ADDRESS = "PermHwAddress" -PE_SPEED = "Speed" -PE_CARRIER = "Carrier" -PE_S390_SUBCHANNELS = "S390Subchannels" +PRP_WIRED_HW_ADDRESS = "HwAddress" +PRP_WIRED_PERM_HW_ADDRESS = "PermHwAddress" +PRP_WIRED_SPEED = "Speed" +PRP_WIRED_CARRIER = "Carrier" +PRP_WIRED_S390_SUBCHANNELS = "S390Subchannels" class WiredDevice(Device): - def __init__(self, bus, iface, mac = None, subchannels = None, ident = None): + def __init__(self, iface, mac = None, subchannels = None, ident = None): + Device.__init__(self, iface, NM.DeviceType.ETHERNET, ident) + if mac is None: - mac = random_mac(iface if ident is None else ident) + mac = Util.random_mac(self.ident) if subchannels is None: subchannels = dbus.Array(signature = 's') - self.mac = mac - self.carrier = False - self.s390_subchannels = subchannels - self.add_dbus_interface(IFACE_WIRED, self.__get_props, WiredDevice.PropertiesChanged) - Device.__init__(self, bus, iface, NM_DEVICE_TYPE_ETHERNET, ident) + props = { + PRP_WIRED_HW_ADDRESS: mac, + PRP_WIRED_PERM_HW_ADDRESS: mac, + PRP_WIRED_SPEED: dbus.UInt32(100), + PRP_WIRED_CARRIER: False, + PRP_WIRED_S390_SUBCHANNELS: subchannels, + } - # Properties interface - def __get_props(self): - props = {} - props[PE_HW_ADDRESS] = self.mac - props[PE_PERM_HW_ADDRESS] = self.mac - props[PE_SPEED] = dbus.UInt32(100) - props[PE_CARRIER] = self.carrier - props[PE_S390_SUBCHANNELS] = self.s390_subchannels - return props - - def __notify(self, propname): - self._dbus_property_notify(IFACE_WIRED, propname) + self.dbus_interface_add(IFACE_WIRED, props, WiredDevice.PropertiesChanged) @dbus.service.signal(IFACE_WIRED, signature='a{sv}') def PropertiesChanged(self, changed): pass -################################################################### +############################################################################### + IFACE_VLAN = 'org.freedesktop.NetworkManager.Device.Vlan' -PV_HW_ADDRESS = "HwAddress" -PV_CARRIER = "Carrier" -PV_VLAN_ID = "VlanId" +PRP_VLAN_HW_ADDRESS = "HwAddress" +PRP_VLAN_CARRIER = "Carrier" +PRP_VLAN_VLAN_ID = "VlanId" class VlanDevice(Device): - def __init__(self, bus, iface, ident = None): - self.mac = random_mac(iface if ident is None else ident) - self.carrier = False - self.vlan_id = 1 + def __init__(self, iface, ident = None): + Device.__init__(self, iface, NM.DeviceType.VLAN, ident) - self.add_dbus_interface(IFACE_VLAN, self.__get_props, VlanDevice.PropertiesChanged) - Device.__init__(self, bus, iface, NM_DEVICE_TYPE_VLAN, ident) + props = { + PRP_VLAN_HW_ADDRESS: Util.random_mac(self.ident), + PRP_VLAN_CARRIER: False, + PRP_VLAN_VLAN_ID: dbus.UInt32(1), + } - # Properties interface - def __get_props(self): - props = {} - props[PV_HW_ADDRESS] = self.mac - props[PV_CARRIER] = self.carrier - props[PV_VLAN_ID] = dbus.UInt32(self.vlan_id) - return props + self.dbus_interface_add(IFACE_VLAN, props, VlanDevice.PropertiesChanged) @dbus.service.signal(IFACE_VLAN, signature='a{sv}') def PropertiesChanged(self, changed): pass -################################################################### +############################################################################### + IFACE_WIFI_AP = 'org.freedesktop.NetworkManager.AccessPoint' -PP_FLAGS = "Flags" -PP_WPA_FLAGS = "WpaFlags" -PP_RSN_FLAGS = "RsnFlags" -PP_SSID = "Ssid" -PP_FREQUENCY = "Frequency" -PP_HW_ADDRESS = "HwAddress" -PP_MODE = "Mode" -PP_MAX_BITRATE = "MaxBitrate" -PP_STRENGTH = "Strength" +PRP_WIFI_AP_FLAGS = "Flags" +PRP_WIFI_AP_WPA_FLAGS = "WpaFlags" +PRP_WIFI_AP_RSN_FLAGS = "RsnFlags" +PRP_WIFI_AP_SSID = "Ssid" +PRP_WIFI_AP_FREQUENCY = "Frequency" +PRP_WIFI_AP_HW_ADDRESS = "HwAddress" +PRP_WIFI_AP_MODE = "Mode" +PRP_WIFI_AP_MAX_BITRATE = "MaxBitrate" +PRP_WIFI_AP_STRENGTH = "Strength" class WifiAp(ExportedObj): - counter = 0 - def __init__(self, bus, ssid, bssid = None, flags = None, wpaf = None, rsnf = None, freq = None, strength = None, ident = None): - path = "/org/freedesktop/NetworkManager/AccessPoint/%d" % WifiAp.counter - WifiAp.counter = WifiAp.counter + 1 + path_counter_next = 1 + path_prefix = "/org/freedesktop/NetworkManager/AccessPoint/" + + def __init__(self, ssid, bssid = None, flags = None, wpaf = None, rsnf = None, freq = None, strength = None, ident = None): + + ExportedObj.__init__(self, ExportedObj.create_path(WifiAp), ident) if flags is None: flags = 0x1 @@ -392,22 +358,27 @@ class WifiAp(ExportedObj): if freq is None: freq = 2412 if bssid is None: - bssid = random_mac(path) + bssid = Util.random_mac(self.path) if strength is None: - strength = pseudorandom_num(path, 100) + strength = Util.pseudorandom_num(self.path, 100) self.ssid = ssid - self.bssid = bssid - self.flags = flags - self.wpaf = wpaf - self.rsnf = rsnf - self.freq = freq - self.strength = strength self.strength_counter = 0 self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None) - self.add_dbus_interface(IFACE_WIFI_AP, self.__get_props, WifiAp.PropertiesChanged) - ExportedObj.__init__(self, bus, path, ident) + props = { + PRP_WIFI_AP_FLAGS: dbus.UInt32(flags), + PRP_WIFI_AP_WPA_FLAGS: dbus.UInt32(wpaf), + PRP_WIFI_AP_RSN_FLAGS: dbus.UInt32(rsnf), + PRP_WIFI_AP_SSID: dbus.ByteArray(self.ssid.encode('utf-8')), + PRP_WIFI_AP_FREQUENCY: dbus.UInt32(freq), + PRP_WIFI_AP_HW_ADDRESS: bssid, + PRP_WIFI_AP_MODE: dbus.UInt32(getattr(NM,'80211Mode').INFRA), + PRP_WIFI_AP_MAX_BITRATE: dbus.UInt32(54000), + PRP_WIFI_AP_STRENGTH: dbus.Byte(strength), + } + + self.dbus_interface_add(IFACE_WIFI_AP, props, WifiAp.PropertiesChanged) def __del__(self): if self.strength_id > 0: @@ -416,66 +387,59 @@ class WifiAp(ExportedObj): def strength_cb(self, ignored): self.strength_counter += 1 - self.strength = pseudorandom_num(self.path + str(self.strength_counter), 100) - self.__notify(PP_STRENGTH) + strength = Util.pseudorandom_num(self.path + str(self.strength_counter), 100) + self._dbus_property_set(IFACE_WIFI_AP, PRP_WIFI_AP_STRENGTH, strength) return True - # Properties interface - def __get_props(self): - props = {} - props[PP_FLAGS] = dbus.UInt32(self.flags) - props[PP_WPA_FLAGS] = dbus.UInt32(self.wpaf) - props[PP_RSN_FLAGS] = dbus.UInt32(self.rsnf) - props[PP_SSID] = dbus.ByteArray(self.ssid.encode('utf-8')) - props[PP_FREQUENCY] = dbus.UInt32(self.freq) - props[PP_HW_ADDRESS] = self.bssid - props[PP_MODE] = dbus.UInt32(2) # NM_802_11_MODE_INFRA - props[PP_MAX_BITRATE] = dbus.UInt32(54000) - props[PP_STRENGTH] = dbus.Byte(self.strength) - return props - - def __notify(self, propname): - self._dbus_property_notify(IFACE_WIFI_AP, propname) - @dbus.service.signal(IFACE_WIFI_AP, signature='a{sv}') def PropertiesChanged(self, changed): pass -################################################################### +############################################################################### + IFACE_WIFI = 'org.freedesktop.NetworkManager.Device.Wireless' class ApNotFoundException(dbus.DBusException): _dbus_error_name = IFACE_WIFI + '.AccessPointNotFound' -PW_HW_ADDRESS = "HwAddress" -PW_PERM_HW_ADDRESS = "PermHwAddress" -PW_MODE = "Mode" -PW_BITRATE = "Bitrate" -PW_ACCESS_POINTS = "AccessPoints" -PW_ACTIVE_ACCESS_POINT = "ActiveAccessPoint" -PW_WIRELESS_CAPABILITIES = "WirelessCapabilities" +PRP_WIFI_HW_ADDRESS = "HwAddress" +PRP_WIFI_PERM_HW_ADDRESS = "PermHwAddress" +PRP_WIFI_MODE = "Mode" +PRP_WIFI_BITRATE = "Bitrate" +PRP_WIFI_ACCESS_POINTS = "AccessPoints" +PRP_WIFI_ACTIVE_ACCESS_POINT = "ActiveAccessPoint" +PRP_WIFI_WIRELESS_CAPABILITIES = "WirelessCapabilities" class WifiDevice(Device): - def __init__(self, bus, iface, mac = None, ident = None): + def __init__(self, iface, mac = None, ident = None): + Device.__init__(self, iface, NM.DeviceType.WIFI, ident) + if mac is None: - mac = random_mac(iface if ident is None else ident) - self.mac = mac + mac = Util.random_mac(self.ident) + self.aps = [] - self.active_ap = None - self.add_dbus_interface(IFACE_WIFI, self.__get_props, WifiDevice.PropertiesChanged) - Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIFI, ident) + props = { + PRP_WIFI_HW_ADDRESS: mac, + PRP_WIFI_PERM_HW_ADDRESS: mac, + PRP_WIFI_MODE: dbus.UInt32(getattr(NM,'80211Mode').INFRA), + PRP_WIFI_BITRATE: dbus.UInt32(21000), + PRP_WIFI_WIRELESS_CAPABILITIES: dbus.UInt32(0xFF), + PRP_WIFI_ACCESS_POINTS: ExportedObj.to_path_array(self.aps), + PRP_WIFI_ACTIVE_ACCESS_POINT: ExportedObj.to_path(None), + } + + self.dbus_interface_add(IFACE_WIFI, props, WifiDevice.PropertiesChanged) - # methods @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao') def GetAccessPoints(self): # only include non-hidden APs - return to_path_array([a for a in self.aps if a.ssid]) + return ExportedObj.to_path_array([a for a in self.aps if a.ssid]) @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao') def GetAllAccessPoints(self): # include all APs including hidden ones - return to_path_array(self.aps) + return ExportedObj.to_path_array(self.aps) @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='a{sv}', out_signature='') def RequestScan(self, props): @@ -486,35 +450,22 @@ class WifiDevice(Device): pass def add_ap(self, ap): + ap.export() self.aps.append(ap) - self.__notify(PW_ACCESS_POINTS) - self.AccessPointAdded(to_path(ap)) + self._dbus_property_set(IFACE_WIFI, PRP_WIFI_ACCESS_POINTS, ExportedObj.to_path_array(self.aps)) + self.AccessPointAdded(ExportedObj.to_path(ap)) return ap + def remove_ap(self, ap): + self.aps.remove(ap) + self._dbus_property_set(IFACE_WIFI, PRP_WIFI_ACCESS_POINTS, ExportedObj.to_path_array(self.aps)) + self.AccessPointRemoved(ExportedObj.to_path(ap)) + ap.unexport() + @dbus.service.signal(IFACE_WIFI, signature='o') def AccessPointRemoved(self, ap_path): pass - def remove_ap(self, ap): - self.aps.remove(ap) - self.__notify(PW_ACCESS_POINTS) - self.AccessPointRemoved(to_path(ap)) - - # Properties interface - def __get_props(self): - props = {} - props[PW_HW_ADDRESS] = self.mac - props[PW_PERM_HW_ADDRESS] = self.mac - props[PW_MODE] = dbus.UInt32(3) # NM_802_11_MODE_INFRA - props[PW_BITRATE] = dbus.UInt32(21000) - props[PW_WIRELESS_CAPABILITIES] = dbus.UInt32(0xFF) - props[PW_ACCESS_POINTS] = to_path_array(self.aps) - props[PW_ACTIVE_ACCESS_POINT] = to_path(self.active_ap) - return props - - def __notify(self, propname): - self._dbus_property_notify(IFACE_WIFI, propname) - @dbus.service.signal(IFACE_WIFI, signature='a{sv}') def PropertiesChanged(self, changed): pass @@ -527,26 +478,32 @@ class WifiDevice(Device): raise ApNotFoundException("AP %s not found" % path) -################################################################### +############################################################################### + IFACE_WIMAX_NSP = 'org.freedesktop.NetworkManager.WiMax.Nsp' -PN_NAME = "Name" -PN_SIGNAL_QUALITY = "SignalQuality" -PN_NETWORK_TYPE = "NetworkType" +PRP_WIMAX_NSP_NAME = "Name" +PRP_WIMAX_NSP_SIGNAL_QUALITY = "SignalQuality" +PRP_WIMAX_NSP_NETWORK_TYPE = "NetworkType" class WimaxNsp(ExportedObj): - counter = 0 - def __init__(self, bus, name): - path = "/org/freedesktop/NetworkManager/Nsp/%d" % WimaxNsp.counter - WimaxNsp.counter = WimaxNsp.counter + 1 + path_counter_next = 1 + path_prefix = "/org/freedesktop/NetworkManager/Nsp/" + + def __init__(self, name): + + ExportedObj.__init__(self, ExportedObj.create_path(WimaxNsp)) - self.name = name - self.strength = random.randint(0, 100) self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None) - self.add_dbus_interface(IFACE_WIMAX_NSP, self.__get_props, WimaxNsp.PropertiesChanged) - ExportedObj.__init__(self, bus, path) + props = { + PRP_WIMAX_NSP_NAME: name, + PRP_WIMAX_NSP_SIGNAL_QUALITY: dbus.UInt32(random.randint(0, 100)), + PRP_WIMAX_NSP_NETWORK_TYPE: dbus.UInt32(NM.WimaxNspNetworkType.HOME), + } + + self.dbus_interface_add(IFACE_WIMAX_NSP, props, WimaxNsp.PropertiesChanged) def __del__(self): if self.strength_id > 0: @@ -554,97 +511,81 @@ class WimaxNsp(ExportedObj): self.strength_id = 0 def strength_cb(self, ignored): - self.strength = random.randint(0, 100) - self.__notify(PN_SIGNAL_QUALITY) + self._dbus_property_set(IFACE_WIMAX_NSP, PRP_WIMAX_NSP_SIGNAL_QUALITY, dbus.UInt32(random.randint(0, 100))) return True - # Properties interface - def __get_props(self): - props = {} - props[PN_NAME] = self.name - props[PN_SIGNAL_QUALITY] = dbus.UInt32(self.strength) - props[PN_NETWORK_TYPE] = dbus.UInt32(0x1) # NM_WIMAX_NSP_NETWORK_TYPE_HOME - return props - - def __notify(self, propname): - self._dbus_property_notify(IFACE_WIMAX_NSP, propname) - @dbus.service.signal(IFACE_WIMAX_NSP, signature='a{sv}') def PropertiesChanged(self, changed): pass -################################################################### +############################################################################### + IFACE_WIMAX = 'org.freedesktop.NetworkManager.Device.WiMax' class NspNotFoundException(dbus.DBusException): _dbus_error_name = IFACE_WIMAX + '.NspNotFound' -PX_NSPS = "Nsps" -PX_HW_ADDRESS = "HwAddress" -PX_CENTER_FREQUENCY = "CenterFrequency" -PX_RSSI = "Rssi" -PX_CINR = "Cinr" -PX_TX_POWER = "TxPower" -PX_BSID = "Bsid" -PX_ACTIVE_NSP = "ActiveNsp" +PRP_WIMAX_NSPS = "Nsps" +PRP_WIMAX_HW_ADDRESS = "HwAddress" +PRP_WIMAX_CENTER_FREQUENCY = "CenterFrequency" +PRP_WIMAX_RSSI = "Rssi" +PRP_WIMAX_CINR = "Cinr" +PRP_WIMAX_TX_POWER = "TxPower" +PRP_WIMAX_BSID = "Bsid" +PRP_WIMAX_ACTIVE_NSP = "ActiveNsp" class WimaxDevice(Device): - def __init__(self, bus, iface, ident = None): - self.mac = random_mac(iface if ident is None else ident) - self.bsid = random_mac(iface if ident is None else ident) + def __init__(self, iface, ident = None): + Device.__init__(self, iface, NM.DeviceType.WIMAX, ident) + + mac = Util.random_mac(self.ident) + bsid = Util.random_mac(self.ident + '.bsid') + self.nsps = [] - self.active_nsp = None - self.add_dbus_interface(IFACE_WIMAX, self.__get_props, WimaxDevice.PropertiesChanged) - Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIMAX, ident) + props = { + PRP_WIMAX_HW_ADDRESS: mac, + PRP_WIMAX_CENTER_FREQUENCY: dbus.UInt32(2525), + PRP_WIMAX_RSSI: dbus.Int32(-48), + PRP_WIMAX_CINR: dbus.Int32(24), + PRP_WIMAX_TX_POWER: dbus.Int32(9), + PRP_WIMAX_BSID: bsid, + PRP_WIMAX_NSPS: ExportedObj.to_path_array(self.nsps), + PRP_WIMAX_ACTIVE_NSP: ExportedObj.to_path(None), + } + + self.dbus_interface_add(IFACE_WIMAX, props, WimaxDevice.PropertiesChanged) - # methods @dbus.service.method(dbus_interface=IFACE_WIMAX, in_signature='', out_signature='ao') def GetNspList(self): - # include all APs including hidden ones - return to_path_array(self.nsps) + return ExportedObj.to_path_array(self.nsps) @dbus.service.signal(IFACE_WIMAX, signature='o') def NspAdded(self, nsp_path): pass def add_nsp(self, nsp): + nsp.export() self.nsps.append(nsp) - self.__notify(PX_NSPS) - self.NspAdded(to_path(nsp)) + self._dbus_property_set(IFACE_WIMAX, PRP_WIMAX_NSPS, ExportedObj.to_path_array(self.nsps)) + self.NspAdded(ExportedObj.to_path(nsp)) + + def remove_nsp(self, nsp): + self.nsps.remove(nsp) + self._dbus_property_set(IFACE_WIMAX, PRP_WIMAX_NSPS, ExportedObj.to_path_array(self.nsps)) + self.NspRemoved(ExportedObj.to_path(nsp)) + nsp.unexport() @dbus.service.signal(IFACE_WIMAX, signature='o') def NspRemoved(self, nsp_path): pass - def remove_nsp(self, nsp): - self.nsps.remove(nsp) - self.__notify(PX_NSPS) - self.NspRemoved(to_path(nsp)) - - # Properties interface - def __get_props(self): - props = {} - props[PX_HW_ADDRESS] = self.mac - props[PX_CENTER_FREQUENCY] = dbus.UInt32(2525) - props[PX_RSSI] = dbus.Int32(-48) - props[PX_CINR] = dbus.Int32(24) - props[PX_TX_POWER] = dbus.Int32(9) - props[PX_BSID] = self.bsid - props[PX_NSPS] = to_path_array(self.nsps) - props[PX_ACTIVE_NSP] = to_path(self.active_nsp) - return props - - def __notify(self, propname): - self._dbus_property_notify(IFACE_WIMAX, propname) - @dbus.service.signal(IFACE_WIMAX, signature='a{sv}') def PropertiesChanged(self, changed): pass - # test functions def add_test_nsp(self, name): - nsp = WimaxNsp(self._bus, name) + nsp = WimaxNsp(name) self.add_nsp(nsp) return nsp @@ -655,75 +596,102 @@ class WimaxDevice(Device): return raise NspNotFoundException("NSP %s not found" % path) -################################################################### +############################################################################### + IFACE_ACTIVE_CONNECTION = 'org.freedesktop.NetworkManager.Connection.Active' -PAC_CONNECTION = "Connection" -PAC_SPECIFIC_OBJECT = "SpecificObject" -PAC_ID = "Id" -PAC_UUID = "Uuid" -PAC_TYPE = "Type" -PAC_DEVICES = "Devices" -PAC_STATE = "State" -PAC_DEFAULT = "Default" -PAC_IP4CONFIG = "Ip4Config" -PAC_DHCP4CONFIG = "Dhcp4Config" -PAC_DEFAULT6 = "Default6" -PAC_IP6CONFIG = "Ip6Config" -PAC_DHCP6CONFIG = "Dhcp6Config" -PAC_VPN = "Vpn" -PAC_MASTER = "Master" +PRP_ACTIVE_CONNECTION_CONNECTION = "Connection" +PRP_ACTIVE_CONNECTION_SPECIFIC_OBJECT = "SpecificObject" +PRP_ACTIVE_CONNECTION_ID = "Id" +PRP_ACTIVE_CONNECTION_UUID = "Uuid" +PRP_ACTIVE_CONNECTION_TYPE = "Type" +PRP_ACTIVE_CONNECTION_DEVICES = "Devices" +PRP_ACTIVE_CONNECTION_STATE = "State" +PRP_ACTIVE_CONNECTION_DEFAULT = "Default" +PRP_ACTIVE_CONNECTION_IP4CONFIG = "Ip4Config" +PRP_ACTIVE_CONNECTION_DHCP4CONFIG = "Dhcp4Config" +PRP_ACTIVE_CONNECTION_DEFAULT6 = "Default6" +PRP_ACTIVE_CONNECTION_IP6CONFIG = "Ip6Config" +PRP_ACTIVE_CONNECTION_DHCP6CONFIG = "Dhcp6Config" +PRP_ACTIVE_CONNECTION_VPN = "Vpn" +PRP_ACTIVE_CONNECTION_MASTER = "Master" class ActiveConnection(ExportedObj): - counter = 1 - def __init__(self, bus, device, connection, specific_object): - object_path = "/org/freedesktop/NetworkManager/ActiveConnection/%d" % ActiveConnection.counter - ActiveConnection.counter = ActiveConnection.counter + 1 + path_counter_next = 1 + path_prefix = "/org/freedesktop/NetworkManager/ActiveConnection/" + + def __init__(self, device, connection, specific_object): + + ExportedObj.__init__(self, ExportedObj.create_path(ActiveConnection)) self.device = device self.conn = connection - self.specific_object = specific_object - self.state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN - self.default = False - self.ip4config = None - self.dhcp4config = None - self.default6 = False - self.ip6config = None - self.dhcp6config = None - self.vpn = False - self.master = None - self.add_dbus_interface(IFACE_ACTIVE_CONNECTION, self.__get_props, ActiveConnection.PropertiesChanged) - ExportedObj.__init__(self, bus, object_path) + self._activation_id = None - # Properties interface - def __get_props(self): - props = {} - props[PAC_CONNECTION] = to_path(self.conn) - props[PAC_SPECIFIC_OBJECT] = to_path(self.specific_object) conn_settings = self.conn.GetSettings() s_con = conn_settings['connection'] - props[PAC_ID] = s_con['id'] - props[PAC_UUID] = s_con['uuid'] - props[PAC_TYPE] = s_con['type'] - props[PAC_DEVICES] = to_path_array([self.device]) - props[PAC_STATE] = dbus.UInt32(self.state) - props[PAC_DEFAULT] = self.default - props[PAC_IP4CONFIG] = to_path(self.ip4config) - props[PAC_DHCP4CONFIG] = to_path(self.dhcp4config) - props[PAC_DEFAULT6] = self.default6 - props[PAC_IP6CONFIG] = to_path(self.ip6config) - props[PAC_DHCP6CONFIG] = to_path(self.dhcp6config) - props[PAC_VPN] = self.vpn - props[PAC_MASTER] = to_path(self.master) - return props + + props = { + PRP_ACTIVE_CONNECTION_CONNECTION: ExportedObj.to_path(self.conn), + PRP_ACTIVE_CONNECTION_SPECIFIC_OBJECT: ExportedObj.to_path(specific_object), + PRP_ACTIVE_CONNECTION_ID: s_con['id'], + PRP_ACTIVE_CONNECTION_UUID: s_con['uuid'], + PRP_ACTIVE_CONNECTION_TYPE: s_con['type'], + PRP_ACTIVE_CONNECTION_DEVICES: ExportedObj.to_path_array([self.device]), + PRP_ACTIVE_CONNECTION_STATE: dbus.UInt32(NM.ActiveConnectionState.UNKNOWN), + PRP_ACTIVE_CONNECTION_DEFAULT: False, + PRP_ACTIVE_CONNECTION_IP4CONFIG: ExportedObj.to_path(None), + PRP_ACTIVE_CONNECTION_DHCP4CONFIG: ExportedObj.to_path(None), + PRP_ACTIVE_CONNECTION_DEFAULT6: False, + PRP_ACTIVE_CONNECTION_IP6CONFIG: ExportedObj.to_path(None), + PRP_ACTIVE_CONNECTION_DHCP6CONFIG: ExportedObj.to_path(None), + PRP_ACTIVE_CONNECTION_VPN: False, + PRP_ACTIVE_CONNECTION_MASTER: ExportedObj.to_path(None), + } + + self.dbus_interface_add(IFACE_ACTIVE_CONNECTION, props, ActiveConnection.PropertiesChanged) + + def _set_state(self, state, reason): + state = dbus.UInt32(state) + self._dbus_property_set(IFACE_ACTIVE_CONNECTION, PRP_ACTIVE_CONNECTION_STATE, state) + self.StateChanged(state, dbus.UInt32(reason)) + + def activation_cancel(self): + if self._activation_id is None: + return False + GLib.source_remove(self._activation_id) + self._activation_id = None + return True + + def _activation_step2(self): + assert self._activation_id is not None + self._activation_id = None + self._set_state(NM.ActiveConnectionState.ACTIVATED, NM.ActiveConnectionStateReason.UNKNOWN) + return False + + def _activation_step1(self): + assert self._activation_id is not None + self._activation_id = GLib.timeout_add(50, self._activation_step2) + self.device.set_active_connection(self) + self._set_state(NM.ActiveConnectionState.ACTIVATING, NM.ActiveConnectionStateReason.UNKNOWN) + return False + + def start_activation(self): + assert self._activation_id is None + self._activation_id = GLib.timeout_add(50, self._activation_step1) @dbus.service.signal(IFACE_ACTIVE_CONNECTION, signature='a{sv}') def PropertiesChanged(self, changed): pass -################################################################### + @dbus.service.signal(IFACE_ACTIVE_CONNECTION, signature='uu') + def StateChanged(self, state, reason): + pass + +############################################################################### + IFACE_TEST = 'org.freedesktop.NetworkManager.LibnmGlibTest' IFACE_NM = 'org.freedesktop.NetworkManager' @@ -736,65 +704,76 @@ class UnknownDeviceException(dbus.DBusException): class UnknownConnectionException(dbus.DBusException): _dbus_error_name = IFACE_NM + '.UnknownConnection' -PM_DEVICES = 'Devices' -PM_ALL_DEVICES = 'AllDevices' -PM_NETWORKING_ENABLED = 'NetworkingEnabled' -PM_WWAN_ENABLED = 'WwanEnabled' -PM_WWAN_HARDWARE_ENABLED = 'WwanHardwareEnabled' -PM_WIRELESS_ENABLED = 'WirelessEnabled' -PM_WIRELESS_HARDWARE_ENABLED = 'WirelessHardwareEnabled' -PM_WIMAX_ENABLED = 'WimaxEnabled' -PM_WIMAX_HARDWARE_ENABLED = 'WimaxHardwareEnabled' -PM_ACTIVE_CONNECTIONS = 'ActiveConnections' -PM_PRIMARY_CONNECTION = 'PrimaryConnection' -PM_ACTIVATING_CONNECTION = 'ActivatingConnection' -PM_STARTUP = 'Startup' -PM_STATE = 'State' -PM_VERSION = 'Version' -PM_CONNECTIVITY = 'Connectivity' - -def set_device_ac_cb(device, ac): - device.set_active_connection(ac) +PRP_NM_DEVICES = 'Devices' +PRP_NM_ALL_DEVICES = 'AllDevices' +PRP_NM_NETWORKING_ENABLED = 'NetworkingEnabled' +PRP_NM_WWAN_ENABLED = 'WwanEnabled' +PRP_NM_WWAN_HARDWARE_ENABLED = 'WwanHardwareEnabled' +PRP_NM_WIRELESS_ENABLED = 'WirelessEnabled' +PRP_NM_WIRELESS_HARDWARE_ENABLED = 'WirelessHardwareEnabled' +PRP_NM_WIMAX_ENABLED = 'WimaxEnabled' +PRP_NM_WIMAX_HARDWARE_ENABLED = 'WimaxHardwareEnabled' +PRP_NM_ACTIVE_CONNECTIONS = 'ActiveConnections' +PRP_NM_PRIMARY_CONNECTION = 'PrimaryConnection' +PRP_NM_ACTIVATING_CONNECTION = 'ActivatingConnection' +PRP_NM_STARTUP = 'Startup' +PRP_NM_STATE = 'State' +PRP_NM_VERSION = 'Version' +PRP_NM_CONNECTIVITY = 'Connectivity' class NetworkManager(ExportedObj): - def __init__(self, bus, object_path): - self._bus = bus; + def __init__(self): + ExportedObj.__init__(self, "/org/freedesktop/NetworkManager") self.devices = [] self.active_connections = [] - self.primary_connection = None - self.activating_connection = None - self.state = NM_STATE_DISCONNECTED - self.connectivity = 1 - self.add_dbus_interface(IFACE_NM, self.__get_props, NetworkManager.PropertiesChanged) - ExportedObj.__init__(self, bus, object_path) + props = { + PRP_NM_DEVICES: ExportedObj.to_path_array(self.devices), + PRP_NM_ALL_DEVICES: ExportedObj.to_path_array(self.devices), + PRP_NM_NETWORKING_ENABLED: True, + PRP_NM_WWAN_ENABLED: True, + PRP_NM_WWAN_HARDWARE_ENABLED: True, + PRP_NM_WIRELESS_ENABLED: True, + PRP_NM_WIRELESS_HARDWARE_ENABLED: True, + PRP_NM_WIMAX_ENABLED: True, + PRP_NM_WIMAX_HARDWARE_ENABLED: True, + PRP_NM_ACTIVE_CONNECTIONS: ExportedObj.to_path_array(self.active_connections), + PRP_NM_PRIMARY_CONNECTION: ExportedObj.to_path(None), + PRP_NM_ACTIVATING_CONNECTION: ExportedObj.to_path(None), + PRP_NM_STARTUP: False, + PRP_NM_STATE: dbus.UInt32(NM.State.DISCONNECTED), + PRP_NM_VERSION: "0.9.9.0", + PRP_NM_CONNECTIVITY: dbus.UInt32(NM.ConnectivityState.NONE), + } + + self.dbus_interface_add(IFACE_NM, props, NetworkManager.PropertiesChanged) + self.export() @dbus.service.signal(IFACE_NM, signature='u') def StateChanged(self, new_state): pass def set_state(self, new_state): - self.state = new_state - self.__notify(PM_STATE) + self._dbus_property_set(IFACE_NM, PRP_NM_STATE, state) self.StateChanged(dbus.UInt32(self.state)) @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ao') def GetDevices(self): - return to_path_array(self.devices) + return ExportedObj.to_path_array(self.devices) @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ao') def GetAllDevices(self): - return to_path_array(self.devices) + return ExportedObj.to_path_array(self.devices) @dbus.service.method(dbus_interface=IFACE_NM, in_signature='s', out_signature='o') def GetDeviceByIpIface(self, ip_iface): d = self.find_device_first(ip_iface = ip_iface, require = UnknownDeviceException) - return to_path(d) + return ExportedObj.to_path(d) @dbus.service.method(dbus_interface=IFACE_NM, in_signature='ooo', out_signature='o') def ActivateConnection(self, conpath, devpath, specific_object): try: - connection = settings.get_connection(conpath) + connection = gl.settings.get_connection(conpath) except Exception as e: raise UnknownConnectionException("Connection not found") @@ -804,7 +783,7 @@ class NetworkManager(ExportedObj): device = self.find_device_first(path = devpath) if not device and s_con['type'] == 'vlan': ifname = s_con['interface-name'] - device = VlanDevice(self._bus, ifname) + device = VlanDevice(ifname) self.add_device(device) if not device: raise UnknownDeviceException("No device found for the requested iface.") @@ -813,7 +792,7 @@ class NetworkManager(ExportedObj): if '802-11-wireless-security' in hash: s_wsec = hash['802-11-wireless-security'] if (s_wsec['key-mgmt'] == 'wpa-psk' and 'psk' not in s_wsec): - secrets = agent_manager.get_secrets(hash, conpath, '802-11-wireless-security') + secrets = gl.agent_manager.get_secrets(hash, conpath, '802-11-wireless-security') if secrets is None: raise NoSecretsException("No secret agent available") if '802-11-wireless-security' not in secrets: @@ -822,23 +801,34 @@ class NetworkManager(ExportedObj): if 'psk' not in s_wsec: raise NoSecretsException("No secrets provided") - ac = ActiveConnection(self._bus, device, connection, None) - self.active_connections.append(ac) - self.__notify(PM_ACTIVE_CONNECTIONS) + ac = ActiveConnection(device, connection, None) + self.active_connection_add(ac) if s_con['id'] == 'object-creation-failed-test': - self.active_connections.remove(ac) - self.__notify(PM_ACTIVE_CONNECTIONS) - ac.remove_from_connection() - else: - GLib.timeout_add(50, set_device_ac_cb, device, ac) + # FIXME: this is not the right test, to delete the active-connection + # before returning it. It's the wrong order of what NetworkManager + # would do. + self.active_connection_remove(ac) + return ExportedObj.to_path(ac) - return to_path(ac) + return ExportedObj.to_path(ac) + + def active_connection_add(self, ac): + ac.export() + self.active_connections.append(ac) + self._dbus_property_set(IFACE_NM, PRP_NM_ACTIVE_CONNECTIONS, ExportedObj.to_path_array(self.active_connections)) + ac.start_activation() + + def active_connection_remove(self, ac): + ac.activation_cancel() + self.active_connections.remove(ac) + self._dbus_property_set(IFACE_NM, PRP_NM_ACTIVE_CONNECTIONS, ExportedObj.to_path_array(self.active_connections)) + ac.unexport() @dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}oo', out_signature='oo') def AddAndActivateConnection(self, connection, devpath, specific_object): device = self.find_device_first(path = devpath, require = UnknownDeviceException) - conpath = settings.AddConnection(connection) + conpath = gl.settings.AddConnection(connection) return (conpath, self.ActivateConnection(conpath, devpath, specific_object)) @dbus.service.method(dbus_interface=IFACE_NM, in_signature='o', out_signature='') @@ -848,10 +838,10 @@ class NetworkManager(ExportedObj): @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='') def Sleep(self, do_sleep): if do_sleep: - self.state = NM_STATE_ASLEEP + state = NM.State.ASLEEP else: - self.state = NM_STATE_DISCONNECTED - self.__notify(PM_STATE) + state = NM.State.DISCONNECTED + self.set_state(state) @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='') def Enable(self, do_enable): @@ -922,90 +912,67 @@ class NetworkManager(ExportedObj): def add_device(self, device): if self.find_device_first(ident = device.ident, path = device.path) is not None: raise TestError("Duplicate device ident=%s / path=%s" % (device.ident, device.path)) + device.export() self.devices.append(device) - self.__notify(PM_DEVICES) - self.__notify(PM_ALL_DEVICES) - self.DeviceAdded(to_path(device)) + self._dbus_property_set(IFACE_NM, PRP_NM_DEVICES, ExportedObj.to_path_array(self.devices)) + self._dbus_property_set(IFACE_NM, PRP_NM_ALL_DEVICES, ExportedObj.to_path_array(self.devices)) + self.DeviceAdded(ExportedObj.to_path(device)) return device + def remove_device(self, device): + self.devices.remove(device) + self._dbus_property_set(IFACE_NM, PRP_NM_DEVICES, ExportedObj.to_path_array(self.devices)) + self._dbus_property_set(IFACE_NM, PRP_NM_ALL_DEVICES, ExportedObj.to_path_array(self.devices)) + self.DeviceRemoved(ExportedObj.to_path(device)) + device.unexport() + @dbus.service.signal(IFACE_NM, signature='o') def DeviceRemoved(self, devpath): pass - def remove_device(self, device): - self.devices.remove(device) - self.__notify(PM_DEVICES) - self.__notify(PM_ALL_DEVICES) - self.DeviceRemoved(to_path(device)) - - ################# D-Bus Properties interface - def __get_props(self): - props = {} - props[PM_DEVICES] = to_path_array(self.devices) - props[PM_ALL_DEVICES] = to_path_array(self.devices) - props[PM_NETWORKING_ENABLED] = True - props[PM_WWAN_ENABLED] = True - props[PM_WWAN_HARDWARE_ENABLED] = True - props[PM_WIRELESS_ENABLED] = True - props[PM_WIRELESS_HARDWARE_ENABLED] = True - props[PM_WIMAX_ENABLED] = True - props[PM_WIMAX_HARDWARE_ENABLED] = True - props[PM_ACTIVE_CONNECTIONS] = to_path_array(self.active_connections) - props[PM_PRIMARY_CONNECTION] = to_path(self.primary_connection) - props[PM_ACTIVATING_CONNECTION] = to_path(self.activating_connection) - props[PM_STARTUP] = False - props[PM_STATE] = dbus.UInt32(self.state) - props[PM_VERSION] = "0.9.9.0" - props[PM_CONNECTIVITY] = dbus.UInt32(self.connectivity) - return props - - def __notify(self, propname): - self._dbus_property_notify(IFACE_NM, propname) - @dbus.service.signal(IFACE_NM, signature='a{sv}') def PropertiesChanged(self, changed): pass - ################# Testing methods @dbus.service.method(IFACE_TEST, in_signature='', out_signature='') def Quit(self): - mainloop.quit() + gl.mainloop.quit() @dbus.service.method(IFACE_TEST, in_signature='a{ss}', out_signature='a(sss)') def FindConnections(self, args): - return [(c.path, c.get_uuid(), c.get_id()) for c in settings.find_connections(**args)] + return [(c.path, c.get_uuid(), c.get_id()) for c in gl.settings.find_connections(**args)] @dbus.service.method(IFACE_TEST, in_signature='sa{sv}', out_signature='o') def AddObj(self, class_name, args): if class_name in ['WiredDevice', 'WifiDevice']: py_class = globals()[class_name] - d = py_class(self._bus, **args) - return to_path(self.add_device(d)) + d = py_class(**args) + return ExportedObj.to_path(self.add_device(d)) elif class_name in ['WifiAp']: if 'device' not in args: raise TestError('missing "device" paramter') d = self.find_device_first(ident = args['device'], require = TestError) del args['device'] if 'ssid' not in args: - args['ssid'] = d.ident + '-ap-' + str(WifiAp.counter + 1) - ap = WifiAp(self._bus, **args) - return to_path(d.add_ap(ap)) + args['ssid'] = d.ident + '-ap-' + str(WifiAp.path_counter_next) + ap = WifiAp(**args) + return ExportedObj.to_path(d.add_ap(ap)) raise TestError("Invalid python type \"%s\"" % (class_name)) @dbus.service.method(IFACE_TEST, in_signature='ssas', out_signature='o') def AddWiredDevice(self, ifname, mac, subchannels): - dev = WiredDevice(self._bus, ifname, mac, subchannels) - return to_path(self.add_device(dev)) + dev = WiredDevice(ifname, mac, subchannels) + return ExportedObj.to_path(self.add_device(dev)) @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') def AddWifiDevice(self, ifname): - dev = WifiDevice(self._bus, ifname) - return to_path(self.add_device(dev)) + dev = WifiDevice(ifname) + return ExportedObj.to_path(self.add_device(dev)) @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') def AddWimaxDevice(self, ifname): - dev = WimaxDevice(self._bus, ifname) - return to_path(self.add_device(dev)) + dev = WimaxDevice(ifname) + return ExportedObj.to_path(self.add_device(dev)) @dbus.service.method(IFACE_TEST, in_signature='o', out_signature='') def RemoveDevice(self, path): @@ -1015,8 +982,8 @@ class NetworkManager(ExportedObj): @dbus.service.method(IFACE_TEST, in_signature='sss', out_signature='o') def AddWifiAp(self, ident, ssid, bssid): d = self.find_device_first(ident = ident, require = TestError) - ap = WifiAp(self._bus, ssid, bssid) - return to_path(d.add_ap(ap)) + ap = WifiAp(ssid, bssid) + return ExportedObj.to_path(d.add_ap(ap)) @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='') def RemoveWifiAp(self, ident, ap_path): @@ -1026,7 +993,7 @@ class NetworkManager(ExportedObj): @dbus.service.method(IFACE_TEST, in_signature='ss', out_signature='o') def AddWimaxNsp(self, ident, name): d = self.find_device_first(ident = ident, require = TestError) - return to_path(d.add_test_nsp(name)) + return ExportedObj.to_path(d.add_test_nsp(name)) @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='') def RemoveWimaxNsp(self, ident, nsp_path): @@ -1035,23 +1002,24 @@ class NetworkManager(ExportedObj): @dbus.service.method(IFACE_TEST, in_signature='', out_signature='') def AutoRemoveNextConnection(self): - settings.auto_remove_next_connection() + gl.settings.auto_remove_next_connection() @dbus.service.method(dbus_interface=IFACE_TEST, in_signature='a{sa{sv}}b', out_signature='o') def AddConnection(self, connection, verify_connection): - return settings.add_connection(connection, verify_connection) + return gl.settings.add_connection(connection, verify_connection) @dbus.service.method(dbus_interface=IFACE_TEST, in_signature='sa{sa{sv}}b', out_signature='') def UpdateConnection(self, path, connection, verify_connection): - return settings.update_connection(connection, path, verify_connection) + return gl.settings.update_connection(connection, path, verify_connection) @dbus.service.method(dbus_interface=IFACE_TEST, in_signature='', out_signature='') def Restart(self): - bus.release_name("org.freedesktop.NetworkManager") - bus.request_name("org.freedesktop.NetworkManager") + gl.bus.release_name("org.freedesktop.NetworkManager") + gl.bus.request_name("org.freedesktop.NetworkManager") -################################################################### +############################################################################### + IFACE_CONNECTION = 'org.freedesktop.NetworkManager.Settings.Connection' class InvalidPropertyException(dbus.DBusException): @@ -1066,11 +1034,15 @@ class InvalidSettingException(dbus.DBusException): class MissingSettingException(dbus.DBusException): _dbus_error_name = IFACE_CONNECTION + '.MissingSetting' +PRP_CONNECTION_UNSAVED = 'Unsaved' + class Connection(ExportedObj): - def __init__(self, bus, path_counter, settings, remove_func, verify_connection=True): + def __init__(self, path_counter, settings, verify_connection=True): path = "/org/freedesktop/NetworkManager/Settings/Connection/%s" % (path_counter) + ExportedObj.__init__(self, path) + if 'connection' not in settings: settings['connection'] = { } if self.get_id(settings) is None: @@ -1081,13 +1053,13 @@ class Connection(ExportedObj): self.path = path self.settings = settings - self.remove_func = remove_func self.visible = True - self.props = {} - self.props['Unsaved'] = False - self.add_dbus_interface(IFACE_CONNECTION, self.__get_props, None) - ExportedObj.__init__(self, bus, path) + props = { + PRP_CONNECTION_UNSAVED: False, + } + + self.dbus_interface_add(IFACE_CONNECTION, props) def get_id(self, settings=None): if settings is None: @@ -1137,13 +1109,6 @@ class Connection(ExportedObj): self.settings = settings; self.Updated() - def __get_props(self): - return self.props - - def __notify(self, propname): - self._dbus_property_notify(IFACE_CONNECTION, propname) - - # Connection methods @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}') def GetSettings(self): if not self.visible: @@ -1157,9 +1122,7 @@ class Connection(ExportedObj): @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='') def Delete(self): - self.remove_func(self) - self.Removed() - self.remove_from_connection() + gl.settings.delete_connection(self) @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='a{sa{sv}}', out_signature='') def Update(self, settings): @@ -1173,25 +1136,33 @@ class Connection(ExportedObj): def Updated(self): pass -################################################################### +############################################################################### + IFACE_SETTINGS = 'org.freedesktop.NetworkManager.Settings' class InvalidHostnameException(dbus.DBusException): _dbus_error_name = IFACE_SETTINGS + '.InvalidHostname' -class Settings(ExportedObj): - def __init__(self, bus, object_path): - self.connections = {} - self.bus = bus - self.counter = 0 - self.remove_next_connection = False - self.props = {} - self.props['Hostname'] = "foobar.baz" - self.props['CanModify'] = True - self.props['Connections'] = dbus.Array([], 'o') +PRP_SETTINGS_HOSTNAME = 'Hostname' +PRP_SETTINGS_CAN_MODIFY = 'CanModify' +PRP_SETTINGS_CONNECTIONS = 'Connections' - self.add_dbus_interface(IFACE_SETTINGS, self.__get_props, Settings.PropertiesChanged) - ExportedObj.__init__(self, bus, object_path) +class Settings(ExportedObj): + def __init__(self): + ExportedObj.__init__(self, "/org/freedesktop/NetworkManager/Settings") + + self.connections = {} + self.c_counter = 0 + self.remove_next_connection = False + + props = { + PRP_SETTINGS_HOSTNAME: "foobar.baz", + PRP_SETTINGS_CAN_MODIFY: True, + PRP_SETTINGS_CONNECTIONS: dbus.Array([], 'o'), + } + + self.dbus_interface_add(IFACE_SETTINGS, props, Settings.PropertiesChanged) + self.export() def auto_remove_next_connection(self): self.remove_next_connection = True; @@ -1221,21 +1192,21 @@ class Settings(ExportedObj): return self.add_connection(settings) def add_connection(self, settings, verify_connection=True): - self.counter += 1 - con = Connection(self.bus, self.counter, settings, self.delete_connection, verify_connection) + self.c_counter += 1 + con = Connection(self.c_counter, settings, verify_connection) uuid = con.get_uuid() if uuid in [c.get_uuid() for c in self.connections.values()]: raise InvalidSettingException('cannot add duplicate connection with uuid %s' % (uuid)) + con.export() self.connections[con.path] = con - self.props['Connections'] = dbus.Array(self.connections.keys(), 'o') self.NewConnection(con.path) - self.__notify('Connections') + self._dbus_property_set(IFACE_SETTINGS, PRP_SETTINGS_CONNECTIONS, dbus.Array(self.connections.keys(), 'o')) if self.remove_next_connection: self.remove_next_connection = False - self.connections[con.path].Delete() + self.delete_connection(con) return con.path @@ -1249,22 +1220,16 @@ class Settings(ExportedObj): def delete_connection(self, connection): del self.connections[connection.path] - self.props['Connections'] = dbus.Array(self.connections.keys(), 'o') - self.__notify('Connections') + self._dbus_property_set(IFACE_SETTINGS, PRP_SETTINGS_CONNECTIONS, dbus.Array(self.connections.keys(), 'o')) + connection.Removed() + connection.unexport() @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='s', out_signature='') def SaveHostname(self, hostname): # Arbitrary requirement to test error handling if hostname.find('.') == -1: raise InvalidHostnameException() - self.props['Hostname'] = hostname - self.__notify('Hostname') - - def __get_props(self): - return self.props - - def __notify(self, propname): - self._dbus_property_notify(IFACE_SETTINGS, propname) + self._dbus_property_set(IFACE_SETTINGS, PRP_SETTINGS_HOSTNAME, hostname) @dbus.service.signal(IFACE_SETTINGS, signature='o') def NewConnection(self, path): @@ -1276,9 +1241,40 @@ class Settings(ExportedObj): @dbus.service.method(IFACE_SETTINGS, in_signature='', out_signature='') def Quit(self): - mainloop.quit() + gl.mainloop.quit() + +############################################################################### + +IFACE_DNS_MANAGER = 'org.freedesktop.NetworkManager.DnsManager' + +PRP_DNS_MANAGER_MODE = 'Mode' +PRP_DNS_MANAGER_RC_MANAGER = 'RcManager' +PRP_DNS_MANAGER_CONFIGURATION = 'Configuration' + +class DnsManager(ExportedObj): + def __init__(self): + ExportedObj.__init__(self, "/org/freedesktop/NetworkManager/DnsManager") + + props = { + PRP_DNS_MANAGER_MODE: "dnsmasq", + PRP_DNS_MANAGER_RC_MANAGER: "symlink", + PRP_DNS_MANAGER_CONFIGURATION: dbus.Array( + [ + dbus.Dictionary( + { + 'nameservers' : dbus.Array(['1.2.3.4', '5.6.7.8'], 's'), + 'priority' : dbus.Int32(100), + }, + 'sv') + ], + 'a{sv}'), + } + + self.dbus_interface_add(IFACE_DNS_MANAGER, props) + self.export() + +############################################################################### -################################################################### IFACE_AGENT_MANAGER = 'org.freedesktop.NetworkManager.AgentManager' IFACE_AGENT = 'org.freedesktop.NetworkManager.SecretAgent' @@ -1295,10 +1291,9 @@ class UserCanceledException(dbus.DBusException): _dbus_error_name = IFACE_AGENT_MANAGER + '.UserCanceled' class AgentManager(dbus.service.Object): - def __init__(self, bus, object_path): - dbus.service.Object.__init__(self, bus, object_path) + def __init__(self): + dbus.service.Object.__init__(self, gl.bus, "/org/freedesktop/NetworkManager/AgentManager") self.agents = {} - self.bus = bus @dbus.service.method(dbus_interface=IFACE_AGENT_MANAGER, in_signature='s', out_signature='', @@ -1310,7 +1305,7 @@ class AgentManager(dbus.service.Object): in_signature='su', out_signature='', sender_keyword='sender') def RegisterWithCapabilities(self, name, caps, sender=None): - self.agents[sender] = self.bus.get_object(sender, PATH_SECRET_AGENT) + self.agents[sender] = gl.bus.get_object(sender, PATH_SECRET_AGENT) @dbus.service.method(dbus_interface=IFACE_AGENT_MANAGER, in_signature='', out_signature='', @@ -1337,16 +1332,32 @@ class AgentManager(dbus.service.Object): continue return secrets -################################################################### +############################################################################### + IFACE_OBJECT_MANAGER = 'org.freedesktop.DBus.ObjectManager' -PATH_OBJECT_MANAGER = '/org/freedesktop' - class ObjectManager(dbus.service.Object): - def __init__(self, bus, object_path): - dbus.service.Object.__init__(self, bus, object_path) + def __init__(self, object_path): + dbus.service.Object.__init__(self, gl.bus, object_path) self.objs = [] - self.bus = bus + + def add_object(self, obj): + name, ifaces = obj.get_managed_ifaces() + self.objs.append(obj) + self.InterfacesAdded(name, ifaces) + + def remove_object(self, obj): + name, ifaces = obj.get_managed_ifaces() + self.objs.remove(obj) + self.InterfacesRemoved(name, ifaces.keys()) + + @dbus.service.signal(IFACE_OBJECT_MANAGER, signature='oa{sa{sv}}') + def InterfacesAdded(self, name, ifaces): + pass + + @dbus.service.signal(IFACE_OBJECT_MANAGER, signature='oas') + def InterfacesRemoved(self, name, ifaces): + pass @dbus.service.method(dbus_interface=IFACE_OBJECT_MANAGER, in_signature='', out_signature='a{oa{sa{sv}}}', @@ -1358,97 +1369,49 @@ class ObjectManager(dbus.service.Object): managed_objects[name] = ifaces return managed_objects - def add_object(self, obj): - self.objs.append(obj) - name, ifaces = obj.get_managed_ifaces() - self.InterfacesAdded(name, ifaces) - - def remove_object(self, obj): - self.objs.remove(obj) - name, ifaces = obj.get_managed_ifaces() - self.InterfacesRemoved(name, ifaces.keys()) - - @dbus.service.signal(IFACE_OBJECT_MANAGER, signature='oa{sa{sv}}') - def InterfacesAdded(self, name, ifaces): - pass - - @dbus.service.signal(IFACE_OBJECT_MANAGER, signature='oas') - def InterfacesRemoved(self, name, ifaces): - pass - -################################################################### -IFACE_DNS_MANAGER = 'org.freedesktop.NetworkManager.DnsManager' - -class DnsManager(ExportedObj): - def __init__(self, bus, object_path): - self.props = {} - self.props['Mode'] = "dnsmasq" - self.props['RcManager'] = "symlink" - self.props['Configuration'] = dbus.Array([ - dbus.Dictionary( - { 'nameservers' : dbus.Array(['1.2.3.4', '5.6.7.8'], 's'), - 'priority' : dbus.Int32(100) }, - 'sv') ], - 'a{sv}') - - self.add_dbus_interface(IFACE_DNS_MANAGER, self.__get_props, None) - ExportedObj.__init__(self, bus, object_path) - - @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') - def GetAll(self, iface): - if iface != IFACE_DNS_MANAGER: - raise UnknownInterfaceException() - return self.props - - @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') - def Get(self, iface, name): - if iface != IFACE_DNS_MANAGER: - raise UnknownInterfaceException() - if not name in self.props.keys(): - raise UnknownPropertyException() - return self.props[name] - - def __get_props(self): - return self.props - -################################################################### -def stdin_cb(io, condition): - mainloop.quit() - -def quit_cb(user_data): - mainloop.quit() +############################################################################### def main(): dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) random.seed() - global manager, settings, agent_manager, dns_manager, object_manager, bus + global gl + gl = Global() - bus = dbus.SessionBus() - object_manager = ObjectManager(bus, "/org/freedesktop") - manager = NetworkManager(bus, "/org/freedesktop/NetworkManager") - settings = Settings(bus, "/org/freedesktop/NetworkManager/Settings") - agent_manager = AgentManager(bus, "/org/freedesktop/NetworkManager/AgentManager") - dns_manager = DnsManager(bus, "/org/freedesktop/NetworkManager/DnsManager") + gl.mainloop = GLib.MainLoop() + gl.bus = dbus.SessionBus() - if not bus.request_name("org.freedesktop.NetworkManager"): - sys.exit(1) + gl.object_manager = ObjectManager('/org/freedesktop') + gl.manager = NetworkManager() + gl.settings = Settings() + gl.dns_manager = DnsManager() + gl.agent_manager = AgentManager() + + if not gl.bus.request_name("org.freedesktop.NetworkManager"): + raise AssertionError("Failure to request D-Bus name org.freedesktop.NetworkManager") # Watch stdin; if it closes, assume our parent has crashed, and exit io = GLib.IOChannel(0) - io.add_watch(GLib.IOCondition.HUP, stdin_cb) + id1 = io.add_watch(GLib.IOCondition.HUP, + lambda io, condition: gl.mainloop.quit()) # also quit after inactivity to ensure we don't stick around if the above fails somehow - GLib.timeout_add_seconds(20, quit_cb, None) + id2 = GLib.timeout_add_seconds(20, + lambda: gl.mainloop.quit()) - try: - mainloop.run() - except Exception as e: - pass + gl.mainloop.run() + + GLib.source_remove(id1) + GLib.source_remove(id2) + + gl.agent_manager.remove_from_connection() + gl.dns_manager.unexport() + gl.settings.unexport() + gl.manager.unexport() + gl.object_manager.remove_from_connection() sys.exit(0) if __name__ == '__main__': main() -