summary refs log tree commit diff
path: root/clients/cli/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'clients/cli/common.c')
-rw-r--r--clients/cli/common.c227
1 files changed, 176 insertions, 51 deletions
diff --git a/clients/cli/common.c b/clients/cli/common.c
index 86f91d58..daacce7c 100644
--- a/clients/cli/common.c
+++ b/clients/cli/common.c
@@ -21,59 +21,58 @@
 
 #include "config.h"
 
-#include <glib.h>
-#include <glib/gi18n.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <termios.h>
+#include <sys/ioctl.h>
 
 #include <readline/readline.h>
 #include <readline/history.h>
 
-#include "nm-glib-compat.h"
-
+#include "nm-default.h"
 #include "nm-vpn-helpers.h"
 #include "common.h"
 #include "utils.h"
 
 /* Available fields for IPv4 group */
 NmcOutputField nmc_fields_ip4_config[] = {
-	{"GROUP",      N_("GROUP"),       15},  /* 0 */
-	{"ADDRESS",    N_("ADDRESS"),     68},  /* 1 */
-	{"GATEWAY",    N_("GATEWAY"),      0},  /* 2 */
-	{"ROUTE",      N_("ROUTE"),       68},  /* 3 */
-	{"DNS",        N_("DNS"),         35},  /* 4 */
-	{"DOMAIN",     N_("DOMAIN"),      35},  /* 5 */
-	{"WINS",       N_("WINS"),        20},  /* 6 */
-	{NULL,         NULL,               0}
+	{"GROUP",      N_("GROUP")},    /* 0 */
+	{"ADDRESS",    N_("ADDRESS")},  /* 1 */
+	{"GATEWAY",    N_("GATEWAY")},  /* 2 */
+	{"ROUTE",      N_("ROUTE")},    /* 3 */
+	{"DNS",        N_("DNS")},      /* 4 */
+	{"DOMAIN",     N_("DOMAIN")},   /* 5 */
+	{"WINS",       N_("WINS")},     /* 6 */
+	{NULL, NULL}
 };
 #define NMC_FIELDS_IP4_CONFIG_ALL     "GROUP,ADDRESS,GATEWAY,ROUTE,DNS,DOMAIN,WINS"
 
 /* Available fields for DHCPv4 group */
 NmcOutputField nmc_fields_dhcp4_config[] = {
-	{"GROUP",      N_("GROUP"),       15},  /* 0 */
-	{"OPTION",     N_("OPTION"),      80},  /* 1 */
-	{NULL,         NULL,               0}
+	{"GROUP",      N_("GROUP")},   /* 0 */
+	{"OPTION",     N_("OPTION")},  /* 1 */
+	{NULL, NULL}
 };
 #define NMC_FIELDS_DHCP4_CONFIG_ALL     "GROUP,OPTION"
 
 /* Available fields for IPv6 group */
 NmcOutputField nmc_fields_ip6_config[] = {
-	{"GROUP",      N_("GROUP"),       15},  /* 0 */
-	{"ADDRESS",    N_("ADDRESS"),     95},  /* 1 */
-	{"GATEWAY",    N_("GATEWAY"),      0},  /* 2 */
-	{"ROUTE",      N_("ROUTE"),       95},  /* 3 */
-	{"DNS",        N_("DNS"),         60},  /* 4 */
-	{"DOMAIN",     N_("DOMAIN"),      35},  /* 5 */
-	{NULL,         NULL,               0}
+	{"GROUP",      N_("GROUP")},    /* 0 */
+	{"ADDRESS",    N_("ADDRESS")},  /* 1 */
+	{"GATEWAY",    N_("GATEWAY")},  /* 2 */
+	{"ROUTE",      N_("ROUTE")},    /* 3 */
+	{"DNS",        N_("DNS")},      /* 4 */
+	{"DOMAIN",     N_("DOMAIN")},   /* 5 */
+	{NULL, NULL}
 };
 #define NMC_FIELDS_IP6_CONFIG_ALL     "GROUP,ADDRESS,GATEWAY,ROUTE,DNS,DOMAIN"
 
 /* Available fields for DHCPv6 group */
 NmcOutputField nmc_fields_dhcp6_config[] = {
-	{"GROUP",      N_("GROUP"),       15},  /* 0 */
-	{"OPTION",     N_("OPTION"),      80},  /* 1 */
-	{NULL,         NULL,               0}
+	{"GROUP",      N_("GROUP")},   /* 0 */
+	{"OPTION",     N_("OPTION")},  /* 1 */
+	{NULL, NULL}
 };
 #define NMC_FIELDS_DHCP6_CONFIG_ALL     "GROUP,OPTION"
 
@@ -1009,6 +1008,7 @@ get_secrets_from_user (const char *request_id,
                        const char *msg,
                        NMConnection *connection,
                        gboolean ask,
+                       gboolean echo_on,
                        GHashTable *pwds_hash,
                        GPtrArray *secrets)
 {
@@ -1039,7 +1039,7 @@ get_secrets_from_user (const char *request_id,
 					}
 				}
 				g_print ("%s\n", msg);
-				pwd = nmc_readline ("%s (%s): ", secret->name, secret->prop_name);
+				pwd = nmc_readline_echo (echo_on, "%s (%s): ", secret->name, secret->prop_name);
 				if (!pwd)
 					pwd = g_strdup ("");
 			} else {
@@ -1099,7 +1099,7 @@ nmc_secrets_requested (NMSecretAgentSimple *agent,
 	}
 
 	success = get_secrets_from_user (request_id, title, msg, connection, nmc->in_editor || nmc->ask,
-	                                 nmc->pwds_hash, secrets);
+	                                 nmc->show_secrets, nmc->pwds_hash, secrets);
 	if (success)
 		nm_secret_agent_simple_response (agent, request_id, secrets);
 	else {
@@ -1109,9 +1109,32 @@ nmc_secrets_requested (NMSecretAgentSimple *agent,
 			nm_secret_agent_old_unregister (nmc->secret_agent, NULL, NULL);
 			g_clear_object (&nmc->secret_agent);
 		}
-        }
+	}
 }
 
+char *
+nmc_unique_connection_name (const GPtrArray *connections, const char *try_name)
+{
+	NMConnection *connection;
+	const char *name;
+	char *new_name;
+	unsigned int num = 1;
+	int i = 0;
+
+	new_name = g_strdup (try_name);
+	while (i < connections->len) {
+		connection = NM_CONNECTION (connections->pdata[i]);
+
+		name = nm_connection_get_id (connection);
+		if (g_strcmp0 (new_name, name) == 0) {
+			g_free (new_name);
+			new_name = g_strdup_printf ("%s-%d", try_name, num++);
+			i = 0;
+		} else
+			i++;
+	}
+	return new_name;
+}
 
 /**
  * nmc_cleanup_readline:
@@ -1152,29 +1175,12 @@ nmc_set_in_readline (gboolean in_readline)
 /* Global variable defined in nmcli.c */
 extern NmCli nm_cli;
 
-/**
- * nmc_readline:
- * @prompt_fmt: prompt to print (telling user what to enter). It is standard
- *   printf() format string
- * @...: a list of arguments according to the @prompt_fmt format string
- *
- * Wrapper around libreadline's readline() function.
- * If user pressed Ctrl-C, readline() is called again (if not in editor and
- * line is empty, nmcli will quit).
- * If user pressed Ctrl-D on empty line, nmcli will quit.
- *
- * Returns: the user provided string. In case the user entered empty string,
- * this function returns NULL.
- */
-char *
-nmc_readline (const char *prompt_fmt, ...)
-{
-	va_list args;
-	char *prompt, *str;
 
-	va_start (args, prompt_fmt);
-	prompt = g_strdup_vprintf (prompt_fmt, args);
-	va_end (args);
+static char *
+nmc_readline_helper (const char *prompt)
+{
+	char *str;
+	int b;
 
 readline_mark:
 	/* We are in readline -> Ctrl-C should not quit nmcli */
@@ -1183,6 +1189,13 @@ readline_mark:
 	/* We are outside readline -> Ctrl-C should quit nmcli */
 	nmc_set_in_readline (FALSE);
 
+	/* Check for an I/O error by attempting to peek into the input buffer.
+	 * Readline just inserts newlines when errors occur so we need to check ourselves. */
+	if (ioctl (0, FIONREAD, &b) == -1) {
+		g_free (str);
+		str = NULL;
+	}
+
 	/* Add string to the history */
 	if (str && *str)
 		add_history (str);
@@ -1215,7 +1228,6 @@ readline_mark:
 				sleep (3);
 		}
 	}
-	g_free (prompt);
 
 	/* Return NULL, not empty string */
 	if (str && *str == '\0') {
@@ -1226,6 +1238,76 @@ readline_mark:
 }
 
 /**
+ * nmc_readline:
+ * @prompt_fmt: prompt to print (telling user what to enter). It is standard
+ *   printf() format string
+ * @...: a list of arguments according to the @prompt_fmt format string
+ *
+ * Wrapper around libreadline's readline() function.
+ * If user pressed Ctrl-C, readline() is called again (if not in editor and
+ * line is empty, nmcli will quit).
+ * If user pressed Ctrl-D on empty line, nmcli will quit.
+ *
+ * Returns: the user provided string. In case the user entered empty string,
+ * this function returns NULL.
+ */
+char *
+nmc_readline (const char *prompt_fmt, ...)
+{
+	va_list args;
+	char *prompt, *str;
+
+	va_start (args, prompt_fmt);
+	prompt = g_strdup_vprintf (prompt_fmt, args);
+	va_end (args);
+
+	str = nmc_readline_helper (prompt);
+
+	g_free (prompt);
+
+	return str;
+}
+
+/**
+ * nmc_readline_echo:
+ *
+ * The same as nmc_readline() except it can disable echoing of input characters if @echo_on is %FALSE.
+ * nmc_readline(TRUE, ...) == nmc_readline(...)
+ */
+char *
+nmc_readline_echo (gboolean echo_on, const char *prompt_fmt, ...)
+{
+	va_list args;
+	char *prompt, *str;
+	struct termios termios_orig, termios_new;
+
+	va_start (args, prompt_fmt);
+	prompt = g_strdup_vprintf (prompt_fmt, args);
+	va_end (args);
+
+	/* Disable echoing characters */
+	if (!echo_on) {
+		tcgetattr (STDIN_FILENO, &termios_orig);
+		termios_new = termios_orig;
+		termios_new.c_lflag &= ~(ECHO);
+		tcsetattr (STDIN_FILENO, TCSADRAIN, &termios_new);
+	}
+
+	str = nmc_readline_helper (prompt);
+
+	g_free (prompt);
+
+	/* Restore original terminal settings */
+	if (!echo_on) {
+		tcsetattr (STDIN_FILENO, TCSADRAIN, &termios_orig);
+		/* New line - setting ECHONL | ICANON did not help */
+		fprintf (stdout, "\n");
+	}
+
+	return str;
+}
+
+/**
  * nmc_rl_gen_func_basic:
  * @text: text to complete
  * @state: readline state; says whether start from scratch (state == 0)
@@ -1270,3 +1352,46 @@ nmc_rl_set_deftext (void)
 	return 0;
 }
 
+/**
+ * nmc_parse_lldp_capabilities:
+ * @value: the capabilities value
+ *
+ * Parses LLDP capabilities flags
+ *
+ * Returns: a newly allocated string containing capabilities names separated by commas.
+ */
+char *
+nmc_parse_lldp_capabilities (guint value)
+{
+	/* IEEE Std 802.1AB-2009 - Table 8.4 */
+	const char *names[] = { "other", "repeater", "mac-bridge", "wlan-access-point",
+	                        "router", "telephone", "docsis-cable-device", "station-only",
+	                        "c-vlan-component", "s-vlan-component", "tpmr" };
+	gboolean first = TRUE;
+	GString *str;
+	int i;
+
+	if (!value)
+		return g_strdup ("none");
+
+	str = g_string_new ("");
+
+	for (i = 0; i < G_N_ELEMENTS (names); i++) {
+		if (value & (1 << i)) {
+			if (!first)
+				g_string_append_c (str, ',');
+
+			first = FALSE;
+			value &= ~(1 << i);
+			g_string_append (str, names[i]);
+		}
+	}
+
+	if (value) {
+		if (!first)
+			g_string_append_c (str, ',');
+		g_string_append (str, "reserved");
+	}
+
+	return g_string_free (str, FALSE);
+}