Commit c2ec07f1 authored by Jirka Klimes's avatar Jirka Klimes Committed by Dan Williams

cli: add initial pieces of nmcli

parent bace73c5
......@@ -72,3 +72,4 @@ m4/lt*.m4
policy/org.freedesktop.network-manager-settings.system.policy
cli/src/nmcli
......@@ -7,6 +7,7 @@ SUBDIRS = \
introspection \
callouts \
system-settings \
cli \
tools \
policy \
initscript \
......
SUBDIRS = src
bin_PROGRAMS = \
nmcli
INCLUDES = \
-I${top_srcdir} \
-I${top_srcdir}/include \
-I${top_builddir}/marshallers \
-I${top_srcdir}/libnm-util \
-I${top_srcdir}/libnm-glib
nmcli_SOURCES = \
connections.c \
connections.h \
devices.c \
devices.h \
network-manager.c \
network-manager.h \
nmcli.c \
nmcli.h \
utils.c \
utils.h
nmcli_CPPFLAGS = \
$(DBUS_CFLAGS) \
$(GLIB_CFLAGS) \
-DNMCLI_LOCALEDIR=\"$(datadir)/locale\" \
-DG_DISABLE_DEPRECATED
nmcli_LDADD = \
$(DBUS_LIBS) \
$(GLIB_LIBS) \
$(top_builddir)/marshallers/libmarshallers.la \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/libnm-glib/libnm-glib.la
This diff is collapsed.
/* nmcli - command-line tool to control NetworkManager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2010 Red Hat, Inc.
*/
#ifndef NMC_CONNECTIONS_H
#define NMC_CONNECTIONS_H
#include "nmcli.h"
NMCResultCode do_connections (NmCli *nmc, int argc, char **argv);
#endif /* NMC_CONNECTIONS_H */
This diff is collapsed.
/* nmcli - command-line tool to control NetworkManager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2010 Red Hat, Inc.
*/
#ifndef NMC_DEVICES_H
#define NMC_DEVICES_H
#include "nmcli.h"
NMCResultCode do_devices (NmCli *nmc, int argc, char **argv);
#endif /* NMC_DEVICES_H */
/* nmcli - command-line tool to control NetworkManager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2010 Red Hat, Inc.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <nm-client.h>
#include <nm-setting-connection.h>
#include "utils.h"
#include "network-manager.h"
extern GMainLoop *loop;
/* static function prototypes */
static void usage (void);
static void quit (void);
static const char *nm_state_to_string (NMState state);
static NMCResultCode show_nm_status (NmCli *nmc);
static void
usage (void)
{
fprintf (stderr,
_("Usage: nmcli nm { COMMAND | help }\n\n"
" COMMAND := { status | sleep | wakeup | wifi | wwan }\n\n"
" status\n"
" sleep\n"
" wakeup\n"
" wifi [on|off]\n"
" wwan [on|off]\n\n"));
}
/* quit main loop */
static void
quit (void)
{
g_main_loop_quit (loop); /* quit main loop */
}
static const char *
nm_state_to_string (NMState state)
{
switch (state) {
case NM_STATE_ASLEEP:
return _("asleep");
case NM_STATE_CONNECTING:
return _("connecting");
case NM_STATE_CONNECTED:
return _("connected");
case NM_STATE_DISCONNECTED:
return _("disconnected");
case NM_STATE_UNKNOWN:
default:
return _("unknown");
}
}
static NMCResultCode
show_nm_status (NmCli *nmc)
{
gboolean nm_running;
NMState state;
const char *wireless_hw_enabled_str, *wireless_enabled_str;
const char *wwan_hw_enabled_str, *wwan_enabled_str;
g_return_val_if_fail (nmc->client != NULL, NMC_RESULT_ERROR_UNKNOWN);
nm_running = nm_client_get_manager_running (nmc->client);
state = nm_client_get_state (nmc->client);
if (nm_running) {
wireless_hw_enabled_str = nm_client_wireless_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled");
wireless_enabled_str = nm_client_wireless_get_enabled (nmc->client) ? _("enabled") : _("disabled");
wwan_hw_enabled_str = nm_client_wwan_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled");
wwan_enabled_str = nm_client_wwan_get_enabled (nmc->client) ? _("enabled") : _("disabled");
} else {
wireless_hw_enabled_str = wireless_enabled_str = wwan_hw_enabled_str = wwan_enabled_str = _("unknown");
}
if (nmc->print_output == NMC_PRINT_PRETTY)
print_table_header (_("NetworkManager status"), NULL);
print_table_line (0, _("NM running:"), 25, nm_running ? _("running") : _("not running"), 0, NULL);
print_table_line (0, _("NM state:"), 25, nm_state_to_string (state), 0, NULL);
print_table_line (0, _("NM wireless hardware:"), 25, wireless_hw_enabled_str, 0, NULL);
print_table_line (0, _("NM wireless:"), 25, wireless_enabled_str, 0, NULL);
print_table_line (0, _("NM WWAN hardware:"), 25, wwan_hw_enabled_str, 0, NULL);
print_table_line (0, _("NM WWAN:"), 25, wwan_enabled_str, 0, NULL);
return NMC_RESULT_SUCCESS;
}
/* entry point function for global network manager related commands 'nmcli nm' */
NMCResultCode
do_network_manager (NmCli *nmc, int argc, char **argv)
{
gboolean enable_wifi;
gboolean enable_wwan;
/* create NMClient */
if (!nmc->get_client (nmc))
goto end;
if (argc == 0) {
nmc->return_value = show_nm_status (nmc);
}
if (argc > 0) {
if (matches (*argv, "status") == 0) {
nmc->return_value = show_nm_status (nmc);
}
else if (matches (*argv, "sleep") == 0) {
nm_client_sleep (nmc->client, TRUE);
}
else if (matches (*argv, "wakeup") == 0) {
nm_client_sleep (nmc->client, FALSE);
}
else if (matches (*argv, "wifi") == 0) {
if (next_arg (&argc, &argv) != 0) {
/* no argument, show current state */
print_table_line (0, _("NM wireless:"), 25, nm_client_wireless_get_enabled (nmc->client) ? _("enabled") : _("disabled"), 0, NULL);
} else {
if (!strcmp (*argv, "on"))
enable_wifi = TRUE;
else if (!strcmp (*argv, "off"))
enable_wifi = FALSE;
else {
g_string_printf (nmc->return_text, _("Error: invalid 'wifi' parameter: '%s'."), *argv);
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
goto end;
}
nm_client_wireless_set_enabled (nmc->client, enable_wifi);
}
}
else if (matches (*argv, "wwan") == 0) {
if (next_arg (&argc, &argv) != 0) {
/* no argument, show current state */
print_table_line (0, _("NM WWAN:"), 25, nm_client_wwan_get_enabled (nmc->client) ? _("enabled") : _("disabled"), 0, NULL);
} else {
if (!strcmp (*argv, "on"))
enable_wwan = TRUE;
else if (!strcmp (*argv, "off"))
enable_wwan = FALSE;
else {
g_string_printf (nmc->return_text, _("Error: invalid 'wwan' parameter: '%s'."), *argv);
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
goto end;
}
nm_client_wwan_set_enabled (nmc->client, enable_wwan);
}
}
else if (strcmp (*argv, "help") == 0) {
usage ();
}
else {
g_string_printf (nmc->return_text, _("Error: 'nm' command '%s' is not valid."), *argv);
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
}
}
end:
quit ();
return nmc->return_value;
}
/* nmcli - command-line tool to control NetworkManager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2010 Red Hat, Inc.
*/
#ifndef NMC_NETWORK_MANAGER_H
#define NMC_NETWORK_MANAGER_H
#include "nmcli.h"
NMCResultCode do_network_manager (NmCli *nmc, int argc, char **argv);
#endif /* NMC_NETWORK_MANAGER_H */
/* nmcli - command-line tool to control NetworkManager
*
* Jiri Klimes <jklimes@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2010 Red Hat, Inc.
*/
/* Generated configuration file */
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <locale.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <nm-client.h>
#include <nm-setting-connection.h>
#include <nm-remote-settings.h>
#include <nm-remote-settings-system.h>
#include <nm-settings-interface.h>
#include <nm-settings-connection-interface.h>
#include "nmcli.h"
#include "utils.h"
#include "connections.h"
#include "devices.h"
#include "network-manager.h"
#define NMCLI_VERSION "0.1"
typedef struct {
NmCli *nmc;
int argc;
char **argv;
} ArgsInfo;
/* --- Global variables --- */
GMainLoop *loop = NULL;
static void
usage (const char *prog_name)
{
fprintf (stderr,
_("Usage: %s [OPTIONS] OBJECT { COMMAND | help }\n\n"
"OPTIONS\n"
" -t[erse] terse output\n"
" -p[retty] pretty output\n"
" -v[ersion] show program version\n"
" -h[elp] print this help\n\n"
"OBJECT\n"
" nm NetworkManager status\n"
" con NetworkManager connections\n"
" dev devices managed by NetworkManager\n\n"),
prog_name);
}
static NMCResultCode
do_help (NmCli *nmc, int argc, char **argv)
{
usage ("nmcli");
return NMC_RESULT_SUCCESS;
}
static const struct cmd {
const char *cmd;
NMCResultCode (*func) (NmCli *nmc, int argc, char **argv);
} nmcli_cmds[] = {
{ "nm", do_network_manager },
{ "con", do_connections },
{ "dev", do_devices },
{ "help", do_help },
{ 0 }
};
static NMCResultCode
do_cmd (NmCli *nmc, const char *argv0, int argc, char **argv)
{
const struct cmd *c;
for (c = nmcli_cmds; c->cmd; ++c) {
if (matches (argv0, c->cmd) == 0)
return c->func (nmc, argc-1, argv+1);
}
g_string_printf (nmc->return_text, _("Object '%s' is unknown, try 'nmcli help'."), argv0);
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
static NMCResultCode
parse_command_line (NmCli *nmc, int argc, char **argv)
{
char *base;
base = strrchr (argv[0], '/');
if (base == NULL)
base = argv[0];
else
base++;
/* parse options */
while (argc > 1) {
char *opt = argv[1];
/* '--' ends options */
if (strcmp (opt, "--") == 0) {
argc--; argv++;
break;
}
if (opt[0] != '-')
break;
if (opt[1] == '-')
opt++;
if (matches (opt, "-terse") == 0) {
nmc->print_output = NMC_PRINT_TERSE;
} else if (matches (opt, "-pretty") == 0) {
nmc->print_output = NMC_PRINT_PRETTY;
} else if (matches (opt, "-version") == 0) {
printf (_("nmcli tool, version %s\n"), NMCLI_VERSION);
return NMC_RESULT_SUCCESS;
} else if (matches (opt, "-help") == 0) {
usage (base);
return NMC_RESULT_SUCCESS;
} else {
g_string_printf (nmc->return_text, _("Option '%s' is unknown, try 'nmcli -help'."), opt);
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
return nmc->return_value;
}
argc--;
argv++;
}
if (argc > 1)
return do_cmd (nmc, argv[1], argc-1, argv+1);
usage (base);
return nmc->return_value;
}
static void
signal_handler (int signo)
{
if (signo == SIGINT || signo == SIGTERM) {
g_message (_("Caught signal %d, shutting down..."), signo);
g_main_loop_quit (loop);
}
}
static void
setup_signals (void)
{
struct sigaction action;
sigset_t mask;
sigemptyset (&mask);
action.sa_handler = signal_handler;
action.sa_mask = mask;
action.sa_flags = 0;
sigaction (SIGTERM, &action, NULL);
sigaction (SIGINT, &action, NULL);
}
static NMClient *
nmc_get_client (NmCli *nmc)
{
if (!nmc->client) {
nmc->client = nm_client_new ();
if (!nmc->client) {
g_string_printf (nmc->return_text, _("Error: Could not connect to NetworkManager."));
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
}
}
return nmc->client;
}
/* Initialize NmCli structure - set default values */
static void
nmc_init (NmCli *nmc)
{
nmc->client = NULL;
nmc->get_client = &nmc_get_client;
nmc->return_value = NMC_RESULT_SUCCESS;
nmc->return_text = g_string_new (_("Success"));
nmc->timeout = 10;
nmc->system_settings = NULL;
nmc->user_settings = NULL;
nmc->system_settings_running = FALSE;
nmc->user_settings_running = FALSE;
nmc->system_connections = NULL;
nmc->user_connections = NULL;
nmc->should_wait = FALSE;
nmc->print_output = NMC_PRINT_NORMAL;
}
static void
nmc_cleanup (NmCli *nmc)
{
if (nmc->client) g_object_unref (nmc->client);
g_string_free (nmc->return_text, TRUE);
if (nmc->system_settings) g_object_unref (nmc->system_settings);
if (nmc->user_settings) g_object_unref (nmc->user_settings);
g_slist_free (nmc->system_connections);
g_slist_free (nmc->user_connections);
}
static gboolean
start (gpointer data)
{
ArgsInfo *info = (ArgsInfo *) data;
info->nmc->return_value = parse_command_line (info->nmc, info->argc, info->argv);
if (!info->nmc->should_wait)
g_main_loop_quit (loop);
return FALSE;
}
int
main (int argc, char *argv[])
{
NmCli nmc;
ArgsInfo args_info = { &nmc, argc, argv };
/* Set locale to use environment variables */
setlocale (LC_ALL, "");
#ifdef GETTEXT_PACKAGE
/* Set i18n stuff */
bindtextdomain (GETTEXT_PACKAGE, NMCLI_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#endif
g_type_init ();
nmc_init (&nmc);
g_idle_add (start, &args_info);
loop = g_main_loop_new (NULL, FALSE); /* create main loop */
setup_signals (); /* setup UNIX signals */
g_main_loop_run (loop); /* run main loop */
/* Print result descripting text */
if (nmc.return_value != NMC_RESULT_SUCCESS) {
fprintf (stderr, "%s\n", nmc.return_text->str);
}
g_main_loop_unref (loop);
nmc_cleanup (&nmc);
return nmc.return_value;
}
/* nmcli - command-line tool to control NetworkManager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2010 Red Hat, Inc.
*/
#ifndef NMC_NMCLI_H
#define NMC_NMCLI_H
#include <nm-remote-settings.h>
#include <nm-remote-settings-system.h>
/* nmcli exit codes */
typedef enum {
/* Indicates successful execution */
NMC_RESULT_SUCCESS = 0,
/* Unknown / unspecified error */
NMC_RESULT_ERROR_UNKNOWN,
/* A timeout expired */
NMC_RESULT_ERROR_TIMEOUT_EXPIRED,
/* Error in connection activation */
NMC_RESULT_ERROR_CON_ACTIVATION,
/* Error in connection deactivation */
NMC_RESULT_ERROR_CON_DEACTIVATION,
/* Error in device disconnect */
NMC_RESULT_ERROR_DEV_DISCONNECT
} NMCResultCode;
typedef enum {
NMC_PRINT_TERSE = 0,
NMC_PRINT_NORMAL,
NMC_PRINT_PRETTY
} NMCPrintOutput;
/* NmCli - main structure */
typedef struct _NmCli {
NMClient *client;
NMClient *(*get_client) (struct _NmCli *nmc);
NMCResultCode return_value;
GString *return_text;
int timeout;
NMRemoteSettingsSystem *system_settings;
NMRemoteSettings *user_settings;
gboolean system_settings_running;
gboolean user_settings_running;
GSList *system_connections;
GSList *user_connections;
gboolean should_wait;
NMCPrintOutput print_output;
} NmCli;
#endif /* NMC_NMCLI_H */
/* nmcli - command-line tool to control NetworkManager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2010 Red Hat, Inc.
*/
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include "utils.h"
int
matches (const char *cmd, const char *pattern)
{
int len = strlen (cmd);
if (len > strlen (pattern))
return -1;
return memcmp (pattern, cmd, len);
}
int
next_arg (int *argc, char ***argv)
{
if (*argc <= 1) {
return -1;
}
else {
(*argc)--;
(*argv)++;
}
return 0;
}
void
print_table_header (const char *name, ...)
{
va_list ap;
GString *str;
char *col, *line = NULL;
int col_width, width1, width2, table_width = 0;
str = g_string_new (NULL);
va_start (ap, name);
while ((col = va_arg (ap, char *)) != NULL) {