diff options
Diffstat (limited to 'clients/cli/connections.c')
| -rw-r--r-- | clients/cli/connections.c | 316 |
1 files changed, 123 insertions, 193 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 0e4a95e6..44e34d56 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -490,9 +490,7 @@ _metagen_con_show_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) const char *s; char *s_mut; - NMC_HANDLE_COLOR ( ac - ? nmc_active_connection_state_to_color (nm_active_connection_get_state (ac)) - : NM_META_COLOR_CONNECTION_UNKNOWN); + NMC_HANDLE_COLOR (nmc_active_connection_state_to_color (ac)); if (c) s_con = nm_connection_get_setting_connection (c); @@ -541,6 +539,8 @@ _metagen_con_show_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) if (info->info_type == NMC_GENERIC_INFO_TYPE_CON_SHOW_TIMESTAMP) return (*out_to_free = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp)); else { + struct tm localtime_result; + if (!timestamp) { if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) return _("never"); @@ -548,7 +548,7 @@ _metagen_con_show_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS) } timestamp_real = timestamp; s_mut = g_malloc0 (128); - strftime (s_mut, 64, "%c", localtime (×tamp_real)); + strftime (s_mut, 127, "%c", localtime_r (×tamp_real, &localtime_result)); return (*out_to_free = s_mut); } } @@ -1425,8 +1425,18 @@ nmc_connection_profile_details (NMConnection *connection, NmCli *nmc) } NMMetaColor -nmc_active_connection_state_to_color (NMActiveConnectionState state) +nmc_active_connection_state_to_color (NMActiveConnection *ac) { + NMActiveConnectionState state; + + if (!ac) + return NM_META_COLOR_CONNECTION_UNKNOWN; + + if (NM_FLAGS_HAS (nm_active_connection_get_state_flags (ac), NM_ACTIVATION_STATE_FLAG_EXTERNAL)) + return NM_META_COLOR_CONNECTION_EXTERNAL; + + state = nm_active_connection_get_state (ac); + if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING) return NM_META_COLOR_CONNECTION_ACTIVATING; else if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) @@ -1449,7 +1459,9 @@ nmc_active_connection_details (NMActiveConnection *acon, NmCli *nmc) gboolean was_output = FALSE; if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) { + /* pass */ } else if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; @@ -2074,6 +2086,7 @@ do_connections_show (const NMCCommand *cmd, NmCli *nmc, int argc, const char *co if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "common") == 0) fields_str = NMC_FIELDS_CON_SHOW_COMMON; else if (!nmc->required_fields || g_ascii_strcasecmp (nmc->required_fields, "all") == 0) { + /* pass */ } else fields_str = nmc->required_fields; @@ -2600,7 +2613,7 @@ progress_active_connection_cb (gpointer user_data) } str = device - ? gettext (nmc_device_state_to_string (nm_device_get_state (device))) + ? gettext (nmc_device_state_to_string_with_external (device)) : active_connection_state_to_string (ac_state); nmc_terminal_show_progress (str); @@ -2689,91 +2702,6 @@ activate_connection_cb (GObject *client, GAsyncResult *result, gpointer user_dat } } -/** - * parse_passwords: - * @passwd_file: file with passwords to parse - * @error: location to store error, or %NULL - * - * Parse passwords given in @passwd_file and insert them into a hash table. - * Example of @passwd_file contents: - * wifi.psk:tajne heslo - * 802-1x.password:krakonos - * 802-11-wireless-security:leap-password:my leap password - * - * Returns: hash table with parsed passwords, or %NULL on an error - */ -static GHashTable * -parse_passwords (const char *passwd_file, GError **error) -{ - gs_unref_hashtable GHashTable *pwds_hash = NULL; - gs_free char *contents = NULL; - gsize len = 0; - GError *local_err = NULL; - gs_free const char **strv = NULL; - const char *const*iter; - char *pwd_spec, *pwd, *prop; - const char *setting; - - pwds_hash = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); - - if (!passwd_file) - return g_steal_pointer (&pwds_hash); - - if (!g_file_get_contents (passwd_file, &contents, &len, &local_err)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("failed to read passwd-file '%s': %s"), - passwd_file, local_err->message); - g_error_free (local_err); - return NULL; - } - - strv = nm_utils_strsplit_set (contents, "\r\n"); - for (iter = strv; strv && *iter; iter++) { - gs_free char *iter_s = g_strdup (*iter); - - pwd = strchr (iter_s, ':'); - if (!pwd) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("missing colon in 'password' entry '%s'"), *iter); - return NULL; - } - *(pwd++) = '\0'; - - prop = strchr (iter_s, '.'); - if (!prop) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("missing dot in 'password' entry '%s'"), *iter); - return NULL; - } - *(prop++) = '\0'; - - setting = iter_s; - while (g_ascii_isspace (*setting)) - setting++; - /* Accept wifi-sec or wifi instead of cumbersome '802-11-wireless-security' */ - if (!strcmp (setting, "wifi-sec") || !strcmp (setting, "wifi")) - setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; - if (nm_setting_lookup_type (setting) == G_TYPE_INVALID) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid setting name in 'password' entry '%s'"), setting); - return NULL; - } - - if ( nm_streq (setting, "vpn") - && g_str_has_prefix (prop, "secret.")) { - /* in 1.12.0, we wrongly required the VPN secrets to be named - * "vpn.secret". It should be "vpn.secrets". Work around it - * (rh#1628833). */ - pwd_spec = g_strdup_printf ("vpn.secrets.%s", &prop[NM_STRLEN ("secret.")]); - } else - pwd_spec = g_strdup_printf ("%s.%s", setting, prop); - - g_hash_table_insert (pwds_hash, pwd_spec, g_strdup (pwd)); - } - - return g_steal_pointer (&pwds_hash); -} - static gboolean nmc_activate_connection (NmCli *nmc, NMConnection *connection, @@ -2822,9 +2750,27 @@ nmc_activate_connection (NmCli *nmc, } /* Parse passwords given in passwords file */ - pwds_hash = parse_passwords (pwds, error); - if (!pwds_hash) - return FALSE; + { + gs_free_error GError *local = NULL; + gssize error_line; + + pwds_hash = nmc_utils_read_passwd_file (pwds, &error_line, &local); + if (!pwds_hash) { + if (error_line >= 0) { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("invalid passwd-file '%s' at line %zd: %s"), + pwds, + error_line, + local->message); + } else { + g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, + _("invalid passwd-file '%s': %s"), + pwds, + local->message); + } + return FALSE; + } + } if (nmc->pwds_hash) g_hash_table_destroy (nmc->pwds_hash); @@ -3506,10 +3452,10 @@ static const char * check_valid_name_toplevel (const char *val, const char **slave_type, GError **error) { gs_unref_ptrarray GPtrArray *tmp_arr = NULL; + const NMMetaSettingInfoEditor *setting_info; + gs_free_error GError *tmp_err = NULL; const char *str; - GError *tmp_err = NULL; int i; - const NMMetaSettingInfoEditor *setting_info; NM_SET_OUT (slave_type, NULL); @@ -3530,14 +3476,13 @@ check_valid_name_toplevel (const char *val, const char **slave_type, GError **er str = nmc_string_is_valid (val, (const char **) tmp_arr->pdata, &tmp_err); if (!str) { if (tmp_err->code == 1) - g_propagate_error (error, tmp_err); + g_propagate_error (error, g_steal_pointer (&tmp_err)); else { /* We want to handle aliases, so construct own error message */ - char *err_str = get_valid_options_string_toplevel (); + gs_free char *err_str = NULL; + err_str = get_valid_options_string_toplevel (); g_set_error (error, 1, 0, _("'%s' not among [%s]"), val, err_str); - g_free (err_str); - g_clear_error (&tmp_err); } return NULL; } @@ -3731,15 +3676,12 @@ is_setting_valid (NMConnection *connection, const NMMetaSettingValidPartItem *co static char * is_property_valid (NMSetting *setting, const char *property, GError **error) { - char **valid_props = NULL; + gs_strfreev char **valid_props = NULL; const char *prop_name; - char *ret; valid_props = nmc_setting_get_valid_properties (setting); prop_name = nmc_string_is_valid (property, (const char **) valid_props, error); - ret = g_strdup (prop_name); - g_strfreev (valid_props); - return ret; + return g_strdup (prop_name); } static char * @@ -6034,19 +5976,23 @@ extract_setting_and_property (const char *prompt, const char *line, } static void -get_setting_and_property (const char *prompt, const char *line, - NMSetting **setting_out, char**property_out) +get_setting_and_property (const char *prompt, + const char *line, + NMSetting **setting_out, + char **property_out) { const NMMetaSettingValidPartItem *const*valid_settings_main; const NMMetaSettingValidPartItem *const*valid_settings_slave; - const char *setting_name; - NMSetting *setting = NULL; - char *property = NULL; - char *sett = NULL, *prop = NULL; + gs_unref_object NMSetting *setting = NULL; + gs_free char *property = NULL; NMSettingConnection *s_con; + gs_free char *sett = NULL; + gs_free char *prop = NULL; const char *s_type = NULL; + const char *setting_name; extract_setting_and_property (prompt, line, &sett, &prop); + if (sett) { /* Is this too much (and useless?) effort for an unlikely case? */ s_con = nm_connection_get_setting_connection (nmc_tab_completion.connection); @@ -6056,23 +6002,22 @@ get_setting_and_property (const char *prompt, const char *line, valid_settings_main = get_valid_settings_array (nmc_tab_completion.con_type); valid_settings_slave = nm_meta_setting_info_valid_parts_for_slave_type (s_type, NULL); - setting_name = check_valid_name (sett, valid_settings_main, - valid_settings_slave, NULL); + setting_name = check_valid_name (sett, + valid_settings_main, + valid_settings_slave, + NULL); setting = nm_meta_setting_info_editor_new_setting (nm_meta_setting_info_editor_find_by_name (setting_name, FALSE), NM_META_ACCESSOR_SETTING_INIT_TYPE_DEFAULT); } else - setting = nmc_tab_completion.setting ? g_object_ref (nmc_tab_completion.setting) : NULL; + setting = nm_g_object_ref (nmc_tab_completion.setting); if (setting && prop) property = is_property_valid (setting, prop, NULL); else property = g_strdup (nmc_tab_completion.property); - *setting_out = setting; - *property_out = property; - - g_free (sett); - g_free (prop); + *setting_out = g_steal_pointer (&setting); + *property_out = g_steal_pointer (&property); } static gboolean @@ -6082,7 +6027,7 @@ _get_and_check_property (const char *prompt, const char **array_multi, gboolean *multi) { - char *prop; + gs_free char *prop = NULL; gboolean found = FALSE; extract_setting_and_property (prompt, line, NULL, &prop); @@ -6091,7 +6036,6 @@ _get_and_check_property (const char *prompt, found = !!nmc_string_is_valid (prop, array, NULL); if (array_multi && multi) *multi = !!nmc_string_is_valid (prop, array_multi, NULL); - g_free (prop); } return found; } @@ -6169,33 +6113,26 @@ should_complete_property_values (const char *prompt, const char *line, gboolean static gboolean _setting_property_is_boolean (NMSetting *setting, const char *property_name) { - GParamSpec *pspec; + const GParamSpec *pspec; - g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); - g_return_val_if_fail (property_name, FALSE); + nm_assert (NM_IS_SETTING (setting)); + nm_assert (property_name); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name); - if (pspec && pspec->value_type == G_TYPE_BOOLEAN) - return TRUE; - return FALSE; + return pspec + && pspec->value_type == G_TYPE_BOOLEAN; } static gboolean should_complete_boolean (const char *prompt, const char *line) { - NMSetting *setting; - char *property; - gboolean is_boolean = FALSE; + gs_unref_object NMSetting *setting = NULL; + gs_free char *property = NULL; get_setting_and_property (prompt, line, &setting, &property); - if (setting && property) - is_boolean = _setting_property_is_boolean (setting, property); - - if (setting) - g_object_unref (setting); - g_free (property); - - return is_boolean; + return setting + && property + && _setting_property_is_boolean (setting, property); } static char * @@ -6222,11 +6159,11 @@ extern int rl_complete_with_tilde_expansion; static char ** nmcli_editor_tab_completion (const char *text, int start, int end) { - char **match_array = NULL; - const char *line = rl_line_buffer; rl_compentry_func_t *generator_func = NULL; - char *prompt_tmp; - char *word = NULL; + const char *line = rl_line_buffer; + gs_free char *prompt_tmp = NULL; + gs_free char *word = NULL; + char **match_array = NULL; size_t n1; int num; @@ -6280,7 +6217,7 @@ nmcli_editor_tab_completion (const char *text, int start, int end) rl_completion_append_character = '.'; } else generator_func = gen_property_names; - } else if (num >= 3) { + } else { if (num == 3 && should_complete_files (NULL, line)) rl_attempted_completion_over = 0; else if (should_complete_vpn_uuids (NULL, line)) { @@ -6350,8 +6287,6 @@ nmcli_editor_tab_completion (const char *text, int start, int end) if (generator_func) match_array = rl_completion_matches (text, generator_func); - g_free (prompt_tmp); - g_free (word); return match_array; } @@ -6391,49 +6326,44 @@ load_history_cmds (const char *uuid) static void save_history_cmds (const char *uuid) { - HIST_ENTRY **hist = NULL; - GKeyFile *kf; - char *filename; - size_t i; - char *key; - char *data; - gsize len = 0; - GError *err = NULL; + gs_unref_keyfile GKeyFile *kf = NULL; + gs_free_error GError *error = NULL; + gs_free char *filename = NULL; + gs_free char *data = NULL; + HIST_ENTRY **hist; + gsize len; + gsize i; hist = history_list (); - if (hist) { - filename = g_build_filename (g_get_home_dir (), NMCLI_EDITOR_HISTORY, NULL); - kf = g_key_file_new (); - if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_KEEP_COMMENTS, &err)) { - if ( !g_error_matches (err, G_FILE_ERROR, G_FILE_ERROR_NOENT) - && !g_error_matches (err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { - g_print ("Warning: %s parse error: %s\n", filename, err->message); - g_key_file_free (kf); - g_free (filename); - g_clear_error (&err); - return; - } - g_clear_error (&err); - } + if (!hist) + return; - /* Remove previous history group and save new history entries */ - g_key_file_remove_group (kf, uuid, NULL); - for (i = 0; hist[i]; i++) - { - key = g_strdup_printf ("%zd", i); - g_key_file_set_string (kf, uuid, key, hist[i]->line); - g_free (key); - } + filename = g_build_filename (g_get_home_dir (), NMCLI_EDITOR_HISTORY, NULL); + + kf = g_key_file_new (); - /* Write history to file */ - data = g_key_file_to_data (kf, &len, NULL); - if (data) { - g_file_set_contents (filename, data, len, NULL); - g_free (data); + if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_KEEP_COMMENTS, &error)) { + if ( !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) + && !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { + g_print ("Warning: %s parse error: %s\n", filename, error->message); + return; } - g_key_file_free (kf); - g_free (filename); + g_clear_error (&error); + } + + /* Remove previous history group and save new history entries */ + g_key_file_remove_group (kf, uuid, NULL); + for (i = 0; hist[i]; i++) { + char key[100]; + + nm_sprintf_buf (key, "%zd", i); + g_key_file_set_string (kf, uuid, key, hist[i]->line); } + + /* Write history to file */ + data = g_key_file_to_data (kf, &len, NULL); + if (data) + g_file_set_contents (filename, data, len, NULL); } /*****************************************************************************/ @@ -6890,7 +6820,7 @@ progress_activation_editor_cb (gpointer user_data) ac_state = nm_active_connection_get_state (ac); dev_state = nm_device_get_state (device); - nmc_terminal_show_progress (gettext (nmc_device_state_to_string (dev_state))); + nmc_terminal_show_progress (gettext (nmc_device_state_to_string_with_external (device))); if ( ac_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED || dev_state == NM_DEVICE_STATE_ACTIVATED) { @@ -7181,9 +7111,10 @@ property_edit_submenu (NmCli *nmc, else g_print (_("Unknown command argument: '%s'\n"), cmd_property_arg); } else { - char *prop_val = nmc_setting_get_property (curr_setting, prop_name, NULL); + gs_free char *prop_val = NULL; + + prop_val = nmc_setting_get_property (curr_setting, prop_name, NULL); g_print ("%s: %s\n", prop_name, prop_val); - g_free (prop_val); } break; @@ -7265,7 +7196,7 @@ ask_check_setting (const NmcConfig *nmc_config, const NMMetaSettingValidPartItem *const*valid_settings_slave, const char *valid_settings_str) { - char *setting_name_user; + gs_free char *setting_name_user = NULL; const char *setting_name; GError *err = NULL; @@ -7285,7 +7216,6 @@ ask_check_setting (const NmcConfig *nmc_config, g_print (_("Error: invalid setting name; %s\n"), err->message); g_clear_error (&err); } - g_free (setting_name_user); return setting_name; } @@ -7295,9 +7225,9 @@ ask_check_property (const NmcConfig *nmc_config, const char **valid_props, const char *valid_props_str) { - char *prop_name_user; + gs_free_error GError *tmp_err = NULL; + gs_free char *prop_name_user = NULL; const char *prop_name; - GError *tmp_err = NULL; if (!arg) { g_print (_("Available properties: %s\n"), valid_props_str); @@ -7307,11 +7237,10 @@ ask_check_property (const NmcConfig *nmc_config, } else prop_name_user = g_strdup (arg); - if (!(prop_name = nmc_string_is_valid (prop_name_user, valid_props, &tmp_err))) { + prop_name = nmc_string_is_valid (prop_name_user, valid_props, &tmp_err); + if (!prop_name) g_print (_("Error: property %s\n"), tmp_err->message); - g_clear_error (&tmp_err); - } - g_free (prop_name_user); + return prop_name; } @@ -7325,6 +7254,7 @@ update_connection_timestamp (NMConnection *src, NMConnection *dst) s_con_dst = nm_connection_get_setting_connection (dst); if (s_con_src && s_con_dst) { guint64 timestamp = nm_setting_connection_get_timestamp (s_con_src); + g_object_set (s_con_dst, NM_SETTING_CONNECTION_TIMESTAMP, timestamp, NULL); } } |