diff options
| author | Michael Biebl <biebl@debian.org> | 2018-06-17 14:54:10 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2018-06-17 14:54:10 +0200 |
| commit | 069cb5c3a525ebcc19cc2927964258acaca87b13 (patch) | |
| tree | 66ac6b21a44d630c0fc281c0df327239d491226a /clients/cli/devices.c | |
| parent | 04bc9e1cd3544445d883ad29ea108c1645c8e7b7 (diff) | |
New upstream version 1.11.90 upstream/1.11.90
Diffstat (limited to 'clients/cli/devices.c')
| -rw-r--r-- | clients/cli/devices.c | 437 |
1 files changed, 266 insertions, 171 deletions
diff --git a/clients/cli/devices.c b/clients/cli/devices.c index b99e606a..58102ed3 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -1725,7 +1725,7 @@ add_and_activate_cb (GObject *client, if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { if (nmc->nmc_config.print_output == NMC_PRINT_PRETTY) nmc_terminal_erase_line (); - if (info->hotspot) + if (!info->hotspot) g_print (_("Connection with UUID '%s' created and activated on device '%s'\n"), nm_active_connection_get_uuid (active), nm_device_get_iface (device)); else @@ -2488,41 +2488,6 @@ do_devices_monitor (NmCli *nmc, int argc, char **argv) return nmc->return_value; } -static void -show_access_point_info (NMDevice *device, NmCli *nmc, NmcOutputData *out) -{ - NMAccessPoint *active_ap = NULL; - const char *active_bssid = NULL; - GPtrArray *aps; - NmcOutputField *arr; - - if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { - active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device)); - active_bssid = active_ap ? nm_access_point_get_bssid (active_ap) : NULL; - } - - arr = nmc_dup_fields_array ((const NMMetaAbstractInfo *const*) nmc_fields_dev_wifi_list, - NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (out->output_data, arr); - - { - APInfo info = { - .nmc = nmc, - .index = 1, - .output_flags = 0, - .active_bssid = active_bssid, - .device = nm_device_get_iface (device), - .output_data = out->output_data, - }; - - aps = sort_access_points (nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device))); - g_ptr_array_foreach (aps, fill_output_access_point, &info); - g_ptr_array_free (aps, FALSE); - } - - print_data_prepare_width (out->output_data); -} - /* * Find a Wi-Fi device with 'iface' in 'devices' array. If 'iface' is NULL, * the first Wi-Fi device is returned. 'idx' parameter is updated to the point @@ -2616,6 +2581,217 @@ find_ap_on_device (NMDevice *device, const char *bssid, const char *ssid, gboole } static void +show_access_point_info (NMDeviceWifi *wifi, NmCli *nmc, NmcOutputData *out) +{ + NMAccessPoint *active_ap = NULL; + const char *active_bssid = NULL; + GPtrArray *aps; + NmcOutputField *arr; + + if (nm_device_get_state (NM_DEVICE (wifi)) == NM_DEVICE_STATE_ACTIVATED) { + active_ap = nm_device_wifi_get_active_access_point (wifi); + active_bssid = active_ap ? nm_access_point_get_bssid (active_ap) : NULL; + } + + arr = nmc_dup_fields_array ((const NMMetaAbstractInfo *const*) nmc_fields_dev_wifi_list, + NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); + g_ptr_array_add (out->output_data, arr); + + { + APInfo info = { + .nmc = nmc, + .index = 1, + .output_flags = 0, + .active_bssid = active_bssid, + .device = nm_device_get_iface (NM_DEVICE (wifi)), + .output_data = out->output_data, + }; + + aps = sort_access_points (nm_device_wifi_get_access_points (wifi)); + g_ptr_array_foreach (aps, fill_output_access_point, &info); + g_ptr_array_free (aps, FALSE); + } + + print_data_prepare_width (out->output_data); +} + +static void +wifi_print_aps (NMDeviceWifi *wifi, + NmCli *nmc, + GArray *_out_indices, + const NMMetaAbstractInfo *const*tmpl, + const char *bssid_user) +{ + NMAccessPoint *ap = NULL; + const GPtrArray *aps; + APInfo *info; + guint i; + NmcOutputField *arr; + const char *base_hdr = _("Wi-Fi scan list"); + NMC_OUTPUT_DATA_DEFINE_SCOPED (out); + gs_free char *header_name = NULL; + static gboolean empty_line = FALSE; + + if (empty_line) + g_print ("\n"); /* Empty line between devices' APs */ + + /* Main header name */ + header_name = construct_header_name (base_hdr, nm_device_get_iface (NM_DEVICE (wifi))); + + out_indices = g_array_ref (_out_indices); + + if (bssid_user) { + /* Specific AP requested - list only that */ + aps = nm_device_wifi_get_access_points (wifi); + for (i = 0; i < aps->len; i++) { + char *bssid_up; + NMAccessPoint *candidate_ap = g_ptr_array_index (aps, i); + const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap); + + bssid_up = g_ascii_strup (bssid_user, -1); + if (!strcmp (bssid_up, candidate_bssid)) + ap = candidate_ap; + g_free (bssid_up); + } + if (ap) { + /* Add headers (field names) */ + arr = nmc_dup_fields_array (tmpl, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); + g_ptr_array_add (out.output_data, arr); + + info = g_malloc0 (sizeof (APInfo)); + info->nmc = nmc; + info->index = 1; + info->output_flags = 0; + info->active_bssid = NULL; + info->device = nm_device_get_iface (NM_DEVICE (wifi)); + info->output_data = out.output_data; + + fill_output_access_point (ap, info); + + print_data_prepare_width (out.output_data); + print_data (&nmc->nmc_config, out_indices, header_name, 0, &out); + g_free (info); + + nmc->return_value = NMC_RESULT_SUCCESS; + empty_line = TRUE; + } + } else { + show_access_point_info (wifi, nmc, &out); + print_data (&nmc->nmc_config, out_indices, header_name, 0, &out); + empty_line = TRUE; + } +} + +typedef struct { + NmCli *nmc; + NMDeviceWifi *wifi; + const NMMetaAbstractInfo *const*tmpl; + + const char *bssid_user; + gulong last_scan_id; + guint timeout_id; + GCancellable *scan_cancellable; + GArray *out_indices; +} WifiListData; + +static void +wifi_list_finish (WifiListData *data) +{ + NmCli *nmc = data->nmc; + + wifi_print_aps (data->wifi, data->nmc, data->out_indices, + data->tmpl, data->bssid_user); + + if (--nmc->should_wait == 0) { + if (nmc->return_value == NMC_RESULT_ERROR_NOT_FOUND) { + g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), + data->bssid_user); + } + g_main_loop_quit (loop); + } + + g_signal_handler_disconnect (data->wifi, data->last_scan_id); + nm_clear_g_source (&data->timeout_id); + nm_clear_g_cancellable (&data->scan_cancellable); + g_array_unref (data->out_indices); + g_object_unref (data->wifi); + g_slice_free (WifiListData, data); +} + +static void +wifi_last_scan_updated (GObject *gobject, GParamSpec *pspec, gpointer user_data) +{ + WifiListData *data = user_data; + + wifi_list_finish (data); +} + +static void +wifi_list_rescan_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + NMDeviceWifi *wifi = NM_DEVICE_WIFI (source_object); + WifiListData *data = user_data; + gs_free_error GError *error = NULL; + + if (!nm_device_wifi_request_scan_finish (wifi, res, &error)) { + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + if (g_error_matches (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ALLOWED)) { + /* This likely means that scanning is already in progress. There's + * a good chance we'll get updated results soon; wait for them. */ + return; + } + + /* Scanning could not be initiated for unknown reason, + * no point in waiting for results. */ + wifi_list_finish (data); + } +} + +static gboolean +wifi_list_scan_timeout (gpointer user_data) +{ + WifiListData *data = user_data; + + wifi_list_finish (data); + + return G_SOURCE_REMOVE; +} + +static void +wifi_list_aps (NMDeviceWifi *wifi, + NmCli *nmc, + GArray *out_indices, + const NMMetaAbstractInfo *const*tmpl, + const char *bssid_user, + gint64 rescan_cutoff) +{ + gboolean needs_rescan; + WifiListData *data; + + needs_rescan = rescan_cutoff < 0 || (rescan_cutoff > 0 && nm_device_wifi_get_last_scan (wifi) < rescan_cutoff); + + if (needs_rescan) { + data = g_slice_new0 (WifiListData); + data->nmc = nmc; + data->wifi = g_object_ref (wifi); + data->tmpl = tmpl; + data->out_indices = g_array_ref (out_indices);; + data->bssid_user = bssid_user; + data->last_scan_id = g_signal_connect (wifi, "notify::" NM_DEVICE_WIFI_LAST_SCAN, + G_CALLBACK (wifi_last_scan_updated), data); + data->scan_cancellable = g_cancellable_new (); + data->timeout_id = g_timeout_add_seconds (15, wifi_list_scan_timeout, data); + nm_device_wifi_request_scan_async (wifi, data->scan_cancellable, wifi_list_rescan_cb, data); + + nmc->should_wait++; + } else { + wifi_print_aps (wifi, nmc, out_indices, tmpl, bssid_user); + } +} + +static void complete_aps (NMDevice **devices, const char *ifname, const char *bssid_prefix, const char *ssid_prefix) { @@ -2640,28 +2816,22 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) { GError *error = NULL; NMDevice *device = NULL; - NMAccessPoint *ap = NULL; const char *ifname = NULL; const char *bssid_user = NULL; + const char *rescan = NULL; gs_free NMDevice **devices = NULL; - const GPtrArray *aps; - APInfo *info; - int i, j; + guint i; const char *fields_str = NULL; const NMMetaAbstractInfo *const*tmpl; - NmcOutputField *arr; - const char *base_hdr = _("Wi-Fi scan list"); - NMC_OUTPUT_DATA_DEFINE_SCOPED (out); - gs_free char *header_name = NULL; + gs_unref_array GArray *out_indices = NULL; + int option; + guint64 rescan_cutoff; devices = nmc_get_devices_sorted (nmc->client); - next_arg (nmc, &argc, &argv, NULL); - while (argc > 0) { - if (argc == 1 && nmc->complete) - nmc_complete_strings (*argv, "ifname", "bssid", NULL); - - if (strcmp (*argv, "ifname") == 0) { + while ((option = next_arg (nmc, &argc, &argv, "ifname", "hwaddr", "bssid", "--rescan", NULL)) > 0) { + switch (option) { + case 1: /* ifname */ argc--; argv++; if (!argc) { @@ -2671,8 +2841,9 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) ifname = *argv; if (argc == 1 && nmc->complete) complete_device (devices, ifname, TRUE); - } else if (strcmp (*argv, "bssid") == 0 || strcmp (*argv, "hwaddr") == 0) { - /* hwaddr is deprecated and will be removed later */ + break; + case 2: /* hwaddr is deprecated and will be removed later */ + case 3: /* bssid */ argc--; argv++; if (!argc) { @@ -2682,11 +2853,24 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) bssid_user = *argv; if (argc == 1 && nmc->complete) complete_aps (devices, NULL, bssid_user, NULL); - } else if (!nmc->complete) { - g_printerr (_("Unknown parameter: %s\n"), *argv); + /* We'll switch this to NMC_RESULT_SUCCESS if we find an access point. */ + nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; + break; + case 4: /* --rescan */ + argc--; + argv++; + if (!argc) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); + return NMC_RESULT_ERROR_USER_INPUT; + } + rescan = *argv; + if (argc == 1 && nmc->complete) + nmc_complete_strings (rescan, "auto", "no", "yes", NULL); + break; + default: + g_assert_not_reached(); + break; } - - next_arg (nmc, &argc, &argv, NULL); } if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) @@ -2707,55 +2891,29 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) if (nmc->complete) return nmc->return_value; - if (ifname) { + if (argc) + g_printerr (_("Unknown parameter: %s\n"), *argv); + + if (rescan == NULL || strcmp (rescan, "auto") == 0) { + rescan_cutoff = NM_MAX (nm_utils_get_timestamp_msec () - 30 * NM_UTILS_MSEC_PER_SECOND, 0); + } else if (strcmp (rescan, "no") == 0) { + rescan_cutoff = 0; + } else if (strcmp (rescan, "yes") == 0) { + rescan_cutoff = -1; + } else { + g_string_printf (nmc->return_text, _("Error: invalid rescan argument: '%s' not among [auto, no, yes]"), rescan); + return NMC_RESULT_ERROR_USER_INPUT; + } + if (ifname) { device = find_wifi_device_by_iface (devices, ifname, NULL); if (!device) { g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), ifname); return NMC_RESULT_ERROR_NOT_FOUND; } - /* Main header name */ - header_name = construct_header_name (base_hdr, ifname); if (NM_IS_DEVICE_WIFI (device)) { - if (bssid_user) { - /* Specific AP requested - list only that */ - aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device)); - for (j = 0; j < aps->len; j++) { - char *bssid_up; - NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j); - const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap); - - bssid_up = g_ascii_strup (bssid_user, -1); - if (!strcmp (bssid_up, candidate_bssid)) - ap = candidate_ap; - g_free (bssid_up); - } - if (!ap) { - g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), - bssid_user); - return NMC_RESULT_ERROR_NOT_FOUND; - } - /* Add headers (field names) */ - arr = nmc_dup_fields_array (tmpl, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (out.output_data, arr); - - info = g_malloc0 (sizeof (APInfo)); - info->nmc = nmc; - info->index = 1; - info->output_flags = 0; - info->active_bssid = NULL; - info->device = nm_device_get_iface (device); - - fill_output_access_point (ap, info); - - print_data_prepare_width (out.output_data); - print_data (&nmc->nmc_config, out_indices, header_name, 0, &out); - g_free (info); - } else { - show_access_point_info (device, nmc, &out); - print_data (&nmc->nmc_config, out_indices, NULL, 0, &out); - } + wifi_list_aps (NM_DEVICE_WIFI (device), nmc, out_indices, tmpl, bssid_user, rescan_cutoff); } else { if ( nm_device_get_device_type (device) == NM_DEVICE_TYPE_GENERIC && g_strcmp0 (nm_device_get_type_description (device), "wifi") == 0) { @@ -2770,76 +2928,11 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) return NMC_RESULT_ERROR_UNKNOWN; } } else { - gboolean empty_line = FALSE; - - /* List APs for all devices */ - if (bssid_user) { - /* Specific AP requested - list only that */ - for (i = 0; devices[i]; i++) { - NMDevice *dev = devices[i]; - NMC_OUTPUT_DATA_DEFINE_SCOPED (out2); - gs_free char *header_name2 = NULL; - - if (!NM_IS_DEVICE_WIFI (dev)) - continue; - - /* Main header name */ - header_name2 = construct_header_name (base_hdr, nm_device_get_iface (dev)); - out2_indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, NULL); - - arr = nmc_dup_fields_array (tmpl, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (out2.output_data, arr); - - aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev)); - for (j = 0; j < aps->len; j++) { - char *bssid_up; - NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j); - const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap); - - bssid_up = g_ascii_strup (bssid_user, -1); - if (!strcmp (bssid_up, candidate_bssid)) { - ap = candidate_ap; - - info = g_malloc0 (sizeof (APInfo)); - info->nmc = nmc; - info->index = 1; - info->output_flags = 0; - info->active_bssid = NULL; - info->device = nm_device_get_iface (dev); - fill_output_access_point (ap, info); - g_free (info); - } - g_free (bssid_up); - } - if (empty_line) - g_print ("\n"); /* Empty line between devices' APs */ - print_data_prepare_width (out2.output_data); - print_data (&nmc->nmc_config, out2_indices, header_name2, 0, &out2); - empty_line = TRUE; - } - if (!ap) { - g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), - bssid_user); - return NMC_RESULT_ERROR_NOT_FOUND; - } - } else { - for (i = 0; devices[i]; i++) { - NMDevice *dev = devices[i]; - NMC_OUTPUT_DATA_DEFINE_SCOPED (out2); - gs_free char *header_name2 = NULL; - - /* Main header name */ - header_name2 = construct_header_name (base_hdr, - nm_device_get_iface (dev)); - out2_indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, NULL); - - if (NM_IS_DEVICE_WIFI (dev)) { - if (empty_line) - g_print ("\n"); /* Empty line between devices' APs */ - show_access_point_info (dev, nmc, &out2); - print_data (&nmc->nmc_config, out2_indices, header_name2, 0, &out2); - empty_line = TRUE; - } + for (i = 0; devices[i]; i++) { + NMDevice *dev = devices[i]; + + if (NM_IS_DEVICE_WIFI (dev)) { + wifi_list_aps (NM_DEVICE_WIFI (dev), nmc, out_indices, tmpl, bssid_user, rescan_cutoff); } } } @@ -2852,9 +2945,9 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv) { NMDevice *device = NULL; NMAccessPoint *ap = NULL; - NM80211ApFlags ap_flags = NM_802_11_AP_FLAGS_NONE; - NM80211ApSecurityFlags ap_wpa_flags = NM_802_11_AP_SEC_NONE; - NM80211ApSecurityFlags ap_rsn_flags = NM_802_11_AP_SEC_NONE; + NM80211ApFlags ap_flags; + NM80211ApSecurityFlags ap_wpa_flags; + NM80211ApSecurityFlags ap_rsn_flags; NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingWireless *s_wifi; @@ -3151,7 +3244,9 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv) ap_rsn_flags = nm_access_point_get_rsn_flags (ap); /* Set password for WEP or WPA-PSK. */ - if (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) { + if ( (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) + || ap_wpa_flags != NM_802_11_AP_SEC_NONE + || ap_rsn_flags != NM_802_11_AP_SEC_NONE) { /* Ask for missing password when one is expected and '--ask' is used */ if (!password && nmc->ask) password = passwd_ask = nmc_readline_echo (nmc->nmc_config.show_secrets, _("Password: ")); |