summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clients/cli/connections.c115
-rw-r--r--man/nmcli.1.in14
2 files changed, 127 insertions, 2 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c
index 08c2ea8eea..e35e7dae1e 100644
--- a/clients/cli/connections.c
+++ b/clients/cli/connections.c
@@ -261,7 +261,7 @@ static void
usage (void)
{
g_printerr (_("Usage: nmcli connection { COMMAND | help }\n\n"
- "COMMAND := { show | up | down | add | modify | edit | delete | reload | load }\n\n"
+ "COMMAND := { show | up | down | add | modify | edit | delete | monitor | reload | load }\n\n"
" show [--active] [--order <order spec>]\n"
" show [--active] [--show-secrets] [id | uuid | path | apath] <ID> ...\n\n"
" up [[id | uuid | path] <ID>] [ifname <ifname>] [ap <BSSID>] [passwd-file <file with passwords>]\n\n"
@@ -272,6 +272,7 @@ usage (void)
" edit [id | uuid | path] <ID>\n"
" edit [type <new_con_type>] [con-name <new_con_name>]\n\n"
" delete [id | uuid | path] <ID>\n\n"
+ " monitor [id | uuid | path] <ID> ...\n\n"
" reload\n\n"
" load <filename> [ <filename>... ]\n\n"));
}
@@ -490,6 +491,18 @@ usage_connection_delete (void)
}
static void
+usage_connection_monitor (void)
+{
+ g_printerr (_("Usage: nmcli connection monitor { ARGUMENTS | help }\n"
+ "\n"
+ "ARGUMENTS := [id | uuid | path] <ID> ...\n"
+ "\n"
+ "Monitor connection profile activity.\n"
+ "This command prints a line whenever the specified connection changes.\n"
+ "Monitors all connection profiles in case none is specified.\n\n"));
+}
+
+static void
usage_connection_reload (void)
{
g_printerr (_("Usage: nmcli connection reload { help }\n"
@@ -530,6 +543,8 @@ usage_connection_second_level (const char *cmd)
usage_connection_edit ();
else if (matches (cmd, "delete") == 0)
usage_connection_delete ();
+ else if (matches (cmd, "monitor") == 0)
+ usage_connection_monitor ();
else if (matches (cmd, "reload") == 0)
usage_connection_reload ();
else if (matches (cmd, "load") == 0)
@@ -9801,6 +9816,102 @@ finish:
return nmc->return_value;
}
+static void
+connection_changed (NMConnection *connection, NmCli *nmc)
+{
+ g_print (_("%s: connection profile changed\n"), nm_connection_get_id (connection));
+}
+
+static void
+connection_watch (NmCli *nmc, NMConnection *connection)
+{
+ nmc->should_wait++;
+ g_signal_connect (connection, NM_CONNECTION_CHANGED, G_CALLBACK (connection_changed), nmc);
+}
+
+static void
+connection_unwatch (NmCli *nmc, NMConnection *connection)
+{
+ if (g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_changed), nmc))
+ nmc->should_wait--;
+
+ /* Terminate if all the watched connections disappeared. */
+ if (!nmc->should_wait)
+ quit ();
+}
+
+static void
+connection_added (NMClient *client, NMRemoteConnection *con, NmCli *nmc)
+{
+ NMConnection *connection = NM_CONNECTION (con);
+
+ g_print (_("%s: connection profile created\n"), nm_connection_get_id (connection));
+ connection_watch (nmc, connection);
+}
+
+static void
+connection_removed (NMClient *client, NMRemoteConnection *con, NmCli *nmc)
+{
+ NMConnection *connection = NM_CONNECTION (con);
+
+ g_print (_("%s: connection profile removed\n"), nm_connection_get_id (connection));
+ connection_unwatch (nmc, connection);
+}
+
+static NMCResultCode
+do_connection_monitor (NmCli *nmc, int argc, char **argv)
+{
+ if (argc == 0) {
+ /* No connections specified. Monitor all. */
+ int i;
+
+ nmc->connections = nm_client_get_connections (nmc->client);
+ for (i = 0; i < nmc->connections->len; i++)
+ connection_watch (nmc, g_ptr_array_index (nmc->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;
+ char **arg_ptr = argv;
+ int arg_num = argc;
+ int pos = 0;
+
+ do {
+ const char *selector = NULL;
+
+ if ( strcmp (*arg_ptr, "id") == 0
+ || strcmp (*arg_ptr, "uuid") == 0
+ || strcmp (*arg_ptr, "path") == 0) {
+ selector = *arg_ptr;
+ if (next_arg (&arg_num, &arg_ptr) != 0) {
+ g_string_printf (nmc->return_text, _("Error: %s argument is missing."), selector);
+ return NMC_RESULT_ERROR_USER_INPUT;
+ }
+ }
+
+ connection = nmc_find_connection (nmc->connections, selector, *arg_ptr, &pos);
+ if (connection) {
+ connection_watch (nmc, connection);
+ } else {
+ g_printerr (_("Error: unknown connection '%s'\n"), *arg_ptr);
+ g_string_printf (nmc->return_text, _("Error: not all connections found."));
+ return NMC_RESULT_ERROR_NOT_FOUND;
+ }
+
+ /* Take next argument (if there's no other connection of the same name) */
+ if (!pos)
+ next_arg (&arg_num, &arg_ptr);
+ } while (arg_num > 0);
+ }
+
+ g_signal_connect (nmc->client, NM_CLIENT_CONNECTION_REMOVED, G_CALLBACK (connection_removed), nmc);
+
+ return NMC_RESULT_SUCCESS;
+}
+
static NMCResultCode
do_connection_reload (NmCli *nmc, int argc, char **argv)
{
@@ -10115,6 +10226,8 @@ do_connections (NmCli *nmc, int argc, char **argv)
g_thread_unref (editor_thread);
} else if (matches(*argv, "delete") == 0) {
nmc->return_value = do_connection_delete (nmc, argc-1, argv+1);
+ } else if (matches(*argv, "monitor") == 0) {
+ nmc->return_value = do_connection_monitor (nmc, argc-1, argv+1);
} else if (matches(*argv, "reload") == 0) {
nmc->return_value = do_connection_reload (nmc, argc-1, argv+1);
} else if (matches(*argv, "load") == 0) {
diff --git a/man/nmcli.1.in b/man/nmcli.1.in
index fef275d23f..d24a1cb159 100644
--- a/man/nmcli.1.in
+++ b/man/nmcli.1.in
@@ -278,7 +278,7 @@ be saved as two connections which both apply to eth0, one for DHCP (called
connected to the DHCP-enabled network the user would run "nmcli con up default"
, and when connected to the static network the user would run "nmcli con up testing".
.TP
-.SS \fICOMMAND\fP := { show | up | down | add | edit | modify | delete | reload | load }
+.SS \fICOMMAND\fP := { show | up | down | add | edit | modify | delete | monitor | reload | load }
.sp
.RS
.TP
@@ -779,6 +779,18 @@ See \fBconnection show\fP above for the description of the <ID>-specifying keywo
.br
If '--wait' option is not specified, the default timeout will be 10 seconds.
.TP
+.B monitor [ id | uuid | path ] <ID> ...
+.br
+Monitor connection profile activity. This command prints a line whenever the
+specified connection changes. The connection to be monitored is identified by
+its name, UUID or D-Bus path. If <ID> is ambiguous, a keyword \fIid\fP,
+\fIuuid\fP or \fIpath\fP can be used.
+.br
+See \fBconnection show\fP above for the description of the <ID>-specifying keywords.
+.br
+Monitors all connection profiles in case none is specified. The command terminates
+when all monitored connections disappear.
+.TP
.B reload
.br
Reload all connection files from disk. \fINetworkManager\fP does not monitor