2010-02-25 09:52:30 -08:00
|
|
|
/* 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 <glib.h>
|
|
|
|
|
#include <glib/gi18n.h>
|
|
|
|
|
#include <dbus/dbus.h>
|
|
|
|
|
#include <dbus/dbus-glib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
2010-07-29 16:16:20 +02:00
|
|
|
#include <unistd.h>
|
2010-02-25 09:52:30 -08:00
|
|
|
#include <errno.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <netinet/ether.h>
|
|
|
|
|
|
|
|
|
|
#include <nm-client.h>
|
|
|
|
|
#include <nm-setting-connection.h>
|
|
|
|
|
#include <nm-setting-wired.h>
|
|
|
|
|
#include <nm-setting-pppoe.h>
|
|
|
|
|
#include <nm-setting-wireless.h>
|
|
|
|
|
#include <nm-setting-gsm.h>
|
|
|
|
|
#include <nm-setting-cdma.h>
|
|
|
|
|
#include <nm-setting-bluetooth.h>
|
|
|
|
|
#include <nm-setting-olpc-mesh.h>
|
|
|
|
|
#include <nm-device-ethernet.h>
|
|
|
|
|
#include <nm-device-wifi.h>
|
|
|
|
|
#include <nm-gsm-device.h>
|
|
|
|
|
#include <nm-cdma-device.h>
|
|
|
|
|
#include <nm-device-bt.h>
|
|
|
|
|
//#include <nm-device-olpc-mesh.h>
|
|
|
|
|
#include <nm-remote-settings.h>
|
|
|
|
|
#include <nm-remote-settings-system.h>
|
|
|
|
|
#include <nm-settings-interface.h>
|
|
|
|
|
#include <nm-settings-connection-interface.h>
|
|
|
|
|
#include <nm-vpn-connection.h>
|
|
|
|
|
|
|
|
|
|
#include "utils.h"
|
2010-03-31 17:14:35 +02:00
|
|
|
#include "settings.h"
|
2010-02-25 09:52:30 -08:00
|
|
|
#include "connections.h"
|
|
|
|
|
|
|
|
|
|
|
2010-03-31 17:14:35 +02:00
|
|
|
/* Available fields for 'con status' */
|
2010-03-18 15:39:15 +01:00
|
|
|
static NmcOutputField nmc_fields_con_status[] = {
|
|
|
|
|
{"NAME", N_("NAME"), 25, NULL, 0}, /* 0 */
|
|
|
|
|
{"UUID", N_("UUID"), 38, NULL, 0}, /* 1 */
|
|
|
|
|
{"DEVICES", N_("DEVICES"), 10, NULL, 0}, /* 2 */
|
|
|
|
|
{"SCOPE", N_("SCOPE"), 8, NULL, 0}, /* 3 */
|
|
|
|
|
{"DEFAULT", N_("DEFAULT"), 8, NULL, 0}, /* 4 */
|
|
|
|
|
{"DBUS-SERVICE", N_("DBUS-SERVICE"), 45, NULL, 0}, /* 5 */
|
|
|
|
|
{"SPEC-OBJECT", N_("SPEC-OBJECT"), 10, NULL, 0}, /* 6 */
|
|
|
|
|
{"VPN", N_("VPN"), 5, NULL, 0}, /* 7 */
|
2010-09-22 12:26:44 +02:00
|
|
|
{"DBUS-PATH", N_("DBUS-PATH"), 51, NULL, 0}, /* 8 */
|
2010-03-18 15:39:15 +01:00
|
|
|
{NULL, NULL, 0, NULL, 0}
|
|
|
|
|
};
|
2010-09-22 12:26:44 +02:00
|
|
|
#define NMC_FIELDS_CON_STATUS_ALL "NAME,UUID,DEVICES,SCOPE,DEFAULT,VPN,DBUS-SERVICE,DBUS-PATH,SPEC-OBJECT"
|
2010-03-18 15:39:15 +01:00
|
|
|
#define NMC_FIELDS_CON_STATUS_COMMON "NAME,UUID,DEVICES,SCOPE,DEFAULT,VPN"
|
|
|
|
|
|
2010-03-31 17:14:35 +02:00
|
|
|
/* Available fields for 'con list' */
|
2010-03-18 15:39:15 +01:00
|
|
|
static NmcOutputField nmc_fields_con_list[] = {
|
|
|
|
|
{"NAME", N_("NAME"), 25, NULL, 0}, /* 0 */
|
|
|
|
|
{"UUID", N_("UUID"), 38, NULL, 0}, /* 1 */
|
|
|
|
|
{"TYPE", N_("TYPE"), 17, NULL, 0}, /* 2 */
|
|
|
|
|
{"SCOPE", N_("SCOPE"), 8, NULL, 0}, /* 3 */
|
|
|
|
|
{"TIMESTAMP", N_("TIMESTAMP"), 12, NULL, 0}, /* 4 */
|
|
|
|
|
{"TIMESTAMP-REAL", N_("TIMESTAMP-REAL"), 34, NULL, 0}, /* 5 */
|
|
|
|
|
{"AUTOCONNECT", N_("AUTOCONNECT"), 13, NULL, 0}, /* 6 */
|
|
|
|
|
{"READONLY", N_("READONLY"), 10, NULL, 0}, /* 7 */
|
2010-09-20 15:05:47 +02:00
|
|
|
{"DBUS-PATH", N_("DBUS-PATH"), 42, NULL, 0}, /* 8 */
|
2010-03-18 15:39:15 +01:00
|
|
|
{NULL, NULL, 0, NULL, 0}
|
|
|
|
|
};
|
2010-09-20 15:05:47 +02:00
|
|
|
#define NMC_FIELDS_CON_LIST_ALL "NAME,UUID,TYPE,SCOPE,TIMESTAMP,TIMESTAMP-REAL,AUTOCONNECT,READONLY,DBUS-PATH"
|
2010-03-18 15:39:15 +01:00
|
|
|
#define NMC_FIELDS_CON_LIST_COMMON "NAME,UUID,TYPE,SCOPE,TIMESTAMP-REAL"
|
|
|
|
|
|
|
|
|
|
|
2010-03-31 17:14:35 +02:00
|
|
|
/* Helper macro to define fields */
|
|
|
|
|
#define SETTING_FIELD(setting, width) { setting, N_(setting), width, NULL, 0 }
|
|
|
|
|
|
|
|
|
|
/* Available settings for 'con list id/uuid <con>' */
|
|
|
|
|
static NmcOutputField nmc_fields_settings_names[] = {
|
|
|
|
|
SETTING_FIELD (NM_SETTING_CONNECTION_SETTING_NAME, 0), /* 0 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_WIRED_SETTING_NAME, 0), /* 1 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_802_1X_SETTING_NAME, 0), /* 2 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_WIRELESS_SETTING_NAME, 0), /* 3 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, 0), /* 4 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_IP4_CONFIG_SETTING_NAME, 0), /* 5 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_IP6_CONFIG_SETTING_NAME, 0), /* 6 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_SERIAL_SETTING_NAME, 0), /* 7 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_PPP_SETTING_NAME, 0), /* 8 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_PPPOE_SETTING_NAME, 0), /* 9 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_GSM_SETTING_NAME, 0), /* 10 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_CDMA_SETTING_NAME, 0), /* 11 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_BLUETOOTH_SETTING_NAME, 0), /* 12 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_OLPC_MESH_SETTING_NAME, 0), /* 13 */
|
|
|
|
|
SETTING_FIELD (NM_SETTING_VPN_SETTING_NAME, 0), /* 14 */
|
|
|
|
|
{NULL, NULL, 0, NULL, 0}
|
|
|
|
|
};
|
|
|
|
|
#define NMC_FIELDS_SETTINGS_NAMES_ALL NM_SETTING_CONNECTION_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_802_1X_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_WIRELESS_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_WIRELESS_SECURITY_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_IP4_CONFIG_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_IP6_CONFIG_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_SERIAL_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_PPP_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_PPPOE_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_GSM_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_CDMA_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_BLUETOOTH_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_OLPC_MESH_SETTING_NAME","\
|
|
|
|
|
NM_SETTING_VPN_SETTING_NAME
|
|
|
|
|
|
|
|
|
|
|
2010-02-25 09:52:30 -08:00
|
|
|
typedef struct {
|
|
|
|
|
NmCli *nmc;
|
|
|
|
|
int argc;
|
|
|
|
|
char **argv;
|
|
|
|
|
} ArgsInfo;
|
|
|
|
|
|
|
|
|
|
extern GMainLoop *loop; /* glib main loop variable */
|
|
|
|
|
|
|
|
|
|
static ArgsInfo args_info;
|
|
|
|
|
|
|
|
|
|
/* static function prototypes */
|
|
|
|
|
static void usage (void);
|
|
|
|
|
static void quit (void);
|
|
|
|
|
static void show_connection (NMConnection *data, gpointer user_data);
|
|
|
|
|
static NMConnection *find_connection (GSList *list, const char *filter_type, const char *filter_val);
|
|
|
|
|
static gboolean find_device_for_connection (NmCli *nmc, NMConnection *connection, const char *iface, const char *ap,
|
|
|
|
|
NMDevice **device, const char **spec_object, GError **error);
|
|
|
|
|
static const char *active_connection_state_to_string (NMActiveConnectionState state);
|
|
|
|
|
static void active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data);
|
|
|
|
|
static void activate_connection_cb (gpointer user_data, const char *path, GError *error);
|
|
|
|
|
static void get_connections_cb (NMSettingsInterface *settings, gpointer user_data);
|
|
|
|
|
static NMCResultCode do_connections_list (NmCli *nmc, int argc, char **argv);
|
|
|
|
|
static NMCResultCode do_connections_status (NmCli *nmc, int argc, char **argv);
|
|
|
|
|
static NMCResultCode do_connection_up (NmCli *nmc, int argc, char **argv);
|
|
|
|
|
static NMCResultCode do_connection_down (NmCli *nmc, int argc, char **argv);
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
usage (void)
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr,
|
|
|
|
|
_("Usage: nmcli con { COMMAND | help }\n"
|
|
|
|
|
" COMMAND := { list | status | up | down }\n\n"
|
|
|
|
|
" list [id <id> | uuid <id> | system | user]\n"
|
|
|
|
|
" status\n"
|
|
|
|
|
" up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [--nowait] [--timeout <timeout>]\n"
|
|
|
|
|
" down id <id> | uuid <id>\n"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* quit main loop */
|
|
|
|
|
static void
|
|
|
|
|
quit (void)
|
|
|
|
|
{
|
|
|
|
|
g_main_loop_quit (loop); /* quit main loop */
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-31 17:14:35 +02:00
|
|
|
static gboolean
|
|
|
|
|
nmc_connection_detail (NMConnection *connection, NmCli *nmc)
|
|
|
|
|
{
|
|
|
|
|
NMSetting *setting;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
GArray *print_settings_array;
|
|
|
|
|
int i;
|
|
|
|
|
char *fields_str;
|
|
|
|
|
char *fields_all = NMC_FIELDS_SETTINGS_NAMES_ALL;
|
|
|
|
|
char *fields_common = NMC_FIELDS_SETTINGS_NAMES_ALL;
|
|
|
|
|
guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
|
|
|
|
|
guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
|
|
|
|
|
guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
|
|
|
|
|
gboolean was_output = FALSE;
|
|
|
|
|
|
|
|
|
|
if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
|
|
|
|
|
fields_str = fields_common;
|
|
|
|
|
else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
|
|
|
|
|
fields_str = fields_all;
|
|
|
|
|
else
|
|
|
|
|
fields_str = nmc->required_fields;
|
|
|
|
|
|
|
|
|
|
print_settings_array = parse_output_fields (fields_str, nmc_fields_settings_names, &error);
|
|
|
|
|
if (error) {
|
|
|
|
|
if (error->code == 0)
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: 'con list': %s"), error->message);
|
|
|
|
|
else
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: 'con list': %s; allowed fields: %s"), error->message, NMC_FIELDS_SETTINGS_NAMES_ALL);
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nmc->allowed_fields = nmc_fields_settings_names;
|
|
|
|
|
nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ONLY;
|
|
|
|
|
nmc->print_fields.header_name = _("Connection details");
|
|
|
|
|
nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTINGS_NAMES_ALL, nmc->allowed_fields, NULL);
|
|
|
|
|
print_fields (nmc->print_fields, nmc->allowed_fields);
|
|
|
|
|
|
|
|
|
|
/* Loop through the required settings and print them. */
|
|
|
|
|
for (i = 0; i < print_settings_array->len; i++) {
|
|
|
|
|
int section_idx = g_array_index (print_settings_array, int, i);
|
|
|
|
|
|
|
|
|
|
if (nmc->print_output != NMC_PRINT_TERSE && !nmc->multiline_output && was_output)
|
|
|
|
|
printf ("\n"); /* Empty line */
|
|
|
|
|
|
|
|
|
|
was_output = FALSE;
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[0].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_connection_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[1].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_wired_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[2].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_802_1X_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[3].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_wireless_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[4].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_wireless_security_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[5].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_ip4_config_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[6].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_ip6_config_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[7].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_serial_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[8].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_ppp_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[9].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_pppoe_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[10].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_gsm_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[11].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_cdma_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[12].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_bluetooth_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[13].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_olpc_mesh_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[14].name)) {
|
|
|
|
|
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
|
|
|
|
|
if (setting) {
|
|
|
|
|
setting_vpn_details (setting, nmc);
|
|
|
|
|
was_output = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (print_settings_array)
|
|
|
|
|
g_array_free (print_settings_array, FALSE);
|
|
|
|
|
|
|
|
|
|
return NMC_RESULT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-25 09:52:30 -08:00
|
|
|
static void
|
|
|
|
|
show_connection (NMConnection *data, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection = (NMConnection *) data;
|
2010-03-18 15:39:15 +01:00
|
|
|
NmCli *nmc = (NmCli *) user_data;
|
2010-02-25 09:52:30 -08:00
|
|
|
NMSettingConnection *s_con;
|
2010-03-18 15:39:15 +01:00
|
|
|
guint64 timestamp;
|
|
|
|
|
char *timestamp_str;
|
|
|
|
|
char timestamp_real_str[64];
|
2010-02-25 09:52:30 -08:00
|
|
|
|
|
|
|
|
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
|
|
|
|
if (s_con) {
|
2010-03-18 15:39:15 +01:00
|
|
|
/* Obtain field values */
|
|
|
|
|
timestamp = nm_setting_connection_get_timestamp (s_con);
|
2010-05-05 04:54:03 -07:00
|
|
|
timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp);
|
2010-03-18 15:39:15 +01:00
|
|
|
strftime (timestamp_real_str, sizeof (timestamp_real_str), "%c", localtime ((time_t *) ×tamp));
|
2010-09-20 15:05:47 +02:00
|
|
|
|
2010-03-18 15:39:15 +01:00
|
|
|
nmc->allowed_fields[0].value = nm_setting_connection_get_id (s_con);
|
|
|
|
|
nmc->allowed_fields[1].value = nm_setting_connection_get_uuid (s_con);
|
|
|
|
|
nmc->allowed_fields[2].value = nm_setting_connection_get_connection_type (s_con);
|
|
|
|
|
nmc->allowed_fields[3].value = nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM ? _("system") : _("user");
|
|
|
|
|
nmc->allowed_fields[4].value = timestamp_str;
|
2010-03-31 17:14:35 +02:00
|
|
|
nmc->allowed_fields[5].value = timestamp ? timestamp_real_str : _("never");
|
2010-03-18 15:39:15 +01:00
|
|
|
nmc->allowed_fields[6].value = nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no");
|
|
|
|
|
nmc->allowed_fields[7].value = nm_setting_connection_get_read_only (s_con) ? _("yes") : _("no");
|
2010-09-20 15:05:47 +02:00
|
|
|
nmc->allowed_fields[8].value = nm_connection_get_path (connection);
|
2010-03-18 15:39:15 +01:00
|
|
|
|
2010-03-24 19:05:35 +01:00
|
|
|
nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */
|
2010-03-18 15:39:15 +01:00
|
|
|
print_fields (nmc->print_fields, nmc->allowed_fields);
|
|
|
|
|
|
|
|
|
|
g_free (timestamp_str);
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMConnection *
|
|
|
|
|
find_connection (GSList *list, const char *filter_type, const char *filter_val)
|
|
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
GSList *iterator;
|
|
|
|
|
const char *id;
|
|
|
|
|
const char *uuid;
|
|
|
|
|
|
|
|
|
|
iterator = list;
|
|
|
|
|
while (iterator) {
|
|
|
|
|
connection = NM_CONNECTION (iterator->data);
|
|
|
|
|
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
|
|
|
|
if (s_con) {
|
|
|
|
|
id = nm_setting_connection_get_id (s_con);
|
|
|
|
|
uuid = nm_setting_connection_get_uuid (s_con);
|
|
|
|
|
if (filter_type) {
|
|
|
|
|
if ((strcmp (filter_type, "id") == 0 && strcmp (filter_val, id) == 0) ||
|
|
|
|
|
(strcmp (filter_type, "uuid") == 0 && strcmp (filter_val, uuid) == 0)) {
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
iterator = g_slist_next (iterator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMCResultCode
|
|
|
|
|
do_connections_list (NmCli *nmc, int argc, char **argv)
|
|
|
|
|
{
|
2010-03-31 17:14:35 +02:00
|
|
|
GError *error1 = NULL;
|
|
|
|
|
GError *error2 = NULL;
|
2010-03-18 15:39:15 +01:00
|
|
|
char *fields_str;
|
|
|
|
|
char *fields_all = NMC_FIELDS_CON_LIST_ALL;
|
|
|
|
|
char *fields_common = NMC_FIELDS_CON_LIST_COMMON;
|
|
|
|
|
guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
|
|
|
|
|
guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
|
|
|
|
|
guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
|
2010-02-25 09:52:30 -08:00
|
|
|
gboolean valid_param_specified = FALSE;
|
|
|
|
|
|
|
|
|
|
nmc->should_wait = FALSE;
|
|
|
|
|
|
2010-03-18 15:39:15 +01:00
|
|
|
if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
|
|
|
|
|
fields_str = fields_common;
|
|
|
|
|
else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
|
|
|
|
|
fields_str = fields_all;
|
2010-03-31 17:14:35 +02:00
|
|
|
else
|
2010-03-18 15:39:15 +01:00
|
|
|
fields_str = nmc->required_fields;
|
|
|
|
|
|
|
|
|
|
nmc->allowed_fields = nmc_fields_con_list;
|
2010-03-31 17:14:35 +02:00
|
|
|
nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error1);
|
|
|
|
|
/* error1 is checked later - it's not valid for connection details */
|
2010-03-18 15:39:15 +01:00
|
|
|
|
2010-02-25 09:52:30 -08:00
|
|
|
if (argc == 0) {
|
2010-03-31 17:14:35 +02:00
|
|
|
if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error2))
|
|
|
|
|
goto error;
|
|
|
|
|
if (error1)
|
|
|
|
|
goto error;
|
2010-02-25 09:52:30 -08:00
|
|
|
valid_param_specified = TRUE;
|
2010-03-18 15:39:15 +01:00
|
|
|
|
2010-03-24 19:05:35 +01:00
|
|
|
nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
|
2010-03-18 15:39:15 +01:00
|
|
|
nmc->print_fields.header_name = _("System connections");
|
|
|
|
|
print_fields (nmc->print_fields, nmc->allowed_fields);
|
|
|
|
|
g_slist_foreach (nmc->system_connections, (GFunc) show_connection, nmc);
|
|
|
|
|
|
2010-03-24 19:05:35 +01:00
|
|
|
nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
|
2010-03-18 15:39:15 +01:00
|
|
|
nmc->print_fields.header_name = _("User connections");
|
|
|
|
|
print_fields (nmc->print_fields, nmc->allowed_fields);
|
|
|
|
|
g_slist_foreach (nmc->user_connections, (GFunc) show_connection, nmc);
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
while (argc > 0) {
|
|
|
|
|
if (strcmp (*argv, "id") == 0 || strcmp (*argv, "uuid") == 0) {
|
|
|
|
|
const char *selector = *argv;
|
|
|
|
|
NMConnection *con1;
|
|
|
|
|
NMConnection *con2;
|
|
|
|
|
|
|
|
|
|
if (next_arg (&argc, &argv) != 0) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-03-31 17:14:35 +02:00
|
|
|
return nmc->return_value;
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
valid_param_specified = TRUE;
|
2010-04-06 16:22:01 +02:00
|
|
|
if (!nmc->mode_specified)
|
|
|
|
|
nmc->multiline_output = TRUE; /* multiline mode is default for 'con list id|uuid' */
|
2010-02-25 09:52:30 -08:00
|
|
|
|
|
|
|
|
con1 = find_connection (nmc->system_connections, selector, *argv);
|
|
|
|
|
con2 = find_connection (nmc->user_connections, selector, *argv);
|
2010-03-31 17:14:35 +02:00
|
|
|
if (con1) nmc_connection_detail (con1, nmc);
|
|
|
|
|
if (con2) nmc_connection_detail (con2, nmc);
|
2010-02-25 09:52:30 -08:00
|
|
|
if (!con1 && !con2) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: %s - no such connection."), *argv);
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
|
|
|
|
}
|
2010-03-18 15:39:15 +01:00
|
|
|
break;
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
else if (strcmp (*argv, "system") == 0) {
|
2010-03-31 17:14:35 +02:00
|
|
|
if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error2))
|
|
|
|
|
goto error;
|
|
|
|
|
if (error1)
|
|
|
|
|
goto error;
|
2010-02-25 09:52:30 -08:00
|
|
|
valid_param_specified = TRUE;
|
|
|
|
|
|
2010-03-24 19:05:35 +01:00
|
|
|
nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
|
2010-03-18 15:39:15 +01:00
|
|
|
nmc->print_fields.header_name = _("System connections");
|
|
|
|
|
print_fields (nmc->print_fields, nmc->allowed_fields);
|
|
|
|
|
g_slist_foreach (nmc->system_connections, (GFunc) show_connection, nmc);
|
|
|
|
|
break;
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
else if (strcmp (*argv, "user") == 0) {
|
2010-03-31 17:14:35 +02:00
|
|
|
if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error2))
|
|
|
|
|
goto error;
|
|
|
|
|
if (error1)
|
|
|
|
|
goto error;
|
2010-02-25 09:52:30 -08:00
|
|
|
valid_param_specified = TRUE;
|
|
|
|
|
|
2010-03-24 19:05:35 +01:00
|
|
|
nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
|
2010-03-18 15:39:15 +01:00
|
|
|
nmc->print_fields.header_name = _("User connections");
|
|
|
|
|
print_fields (nmc->print_fields, nmc->allowed_fields);
|
|
|
|
|
g_slist_foreach (nmc->user_connections, (GFunc) show_connection, nmc);
|
|
|
|
|
break;
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
argc--;
|
|
|
|
|
argv++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!valid_param_specified) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: no valid parameter specified."));
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
2010-03-31 17:14:35 +02:00
|
|
|
return nmc->return_value;
|
2010-02-25 09:52:30 -08:00
|
|
|
|
|
|
|
|
error:
|
2010-03-31 17:14:35 +02:00
|
|
|
if (error1) {
|
|
|
|
|
if (error1->code == 0)
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: 'con list': %s"), error1->message);
|
|
|
|
|
else
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: 'con list': %s; allowed fields: %s"), error1->message, NMC_FIELDS_CON_LIST_ALL);
|
|
|
|
|
g_error_free (error1);
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
|
|
|
|
}
|
|
|
|
|
if (error2) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: %s."), error2->message);
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
|
|
|
|
g_error_free (error2);
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-25 09:52:30 -08:00
|
|
|
return nmc->return_value;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-18 15:39:15 +01:00
|
|
|
typedef struct {
|
|
|
|
|
NmCli *nmc;
|
|
|
|
|
NMConnectionScope scope;
|
|
|
|
|
} StatusInfo;
|
|
|
|
|
|
2010-02-25 09:52:30 -08:00
|
|
|
static void
|
|
|
|
|
show_active_connection (gpointer data, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMActiveConnection *active = NM_ACTIVE_CONNECTION (data);
|
2010-03-18 15:39:15 +01:00
|
|
|
StatusInfo *info = (StatusInfo *) user_data;
|
|
|
|
|
GSList *con_list, *iter;
|
2010-02-25 09:52:30 -08:00
|
|
|
const char *active_path;
|
|
|
|
|
NMConnectionScope active_service_scope;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
const GPtrArray *devices;
|
|
|
|
|
GString *dev_str;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
active_path = nm_active_connection_get_connection (active);
|
|
|
|
|
active_service_scope = nm_active_connection_get_scope (active);
|
|
|
|
|
|
2010-03-18 15:39:15 +01:00
|
|
|
if (active_service_scope != info->scope)
|
|
|
|
|
return;
|
|
|
|
|
|
2010-02-25 09:52:30 -08:00
|
|
|
/* Get devices of the active connection */
|
2010-03-18 15:39:15 +01:00
|
|
|
dev_str = g_string_new (NULL);
|
2010-02-25 09:52:30 -08:00
|
|
|
devices = nm_active_connection_get_devices (active);
|
|
|
|
|
for (i = 0; devices && (i < devices->len); i++) {
|
|
|
|
|
NMDevice *device = g_ptr_array_index (devices, i);
|
|
|
|
|
|
|
|
|
|
g_string_append (dev_str, nm_device_get_iface (device));
|
|
|
|
|
g_string_append_c (dev_str, ',');
|
|
|
|
|
}
|
|
|
|
|
if (dev_str->len > 0)
|
|
|
|
|
g_string_truncate (dev_str, dev_str->len - 1); /* Cut off last ',' */
|
|
|
|
|
|
2010-03-18 15:39:15 +01:00
|
|
|
con_list = (info->scope == NM_CONNECTION_SCOPE_SYSTEM) ? info->nmc->system_connections : info->nmc->user_connections;
|
2010-02-25 09:52:30 -08:00
|
|
|
for (iter = con_list; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMConnection *connection = (NMConnection *) iter->data;
|
|
|
|
|
const char *con_path = nm_connection_get_path (connection);
|
|
|
|
|
|
2010-03-18 15:39:15 +01:00
|
|
|
if (!strcmp (active_path, con_path)) {
|
|
|
|
|
/* This connection is active */
|
2010-02-25 09:52:30 -08:00
|
|
|
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
|
|
|
|
g_assert (s_con != NULL);
|
|
|
|
|
|
2010-03-18 15:39:15 +01:00
|
|
|
/* Obtain field values */
|
|
|
|
|
info->nmc->allowed_fields[0].value = nm_setting_connection_get_id (s_con);
|
|
|
|
|
info->nmc->allowed_fields[1].value = nm_setting_connection_get_uuid (s_con);
|
|
|
|
|
info->nmc->allowed_fields[2].value = dev_str->str;
|
|
|
|
|
info->nmc->allowed_fields[3].value = active_service_scope == NM_CONNECTION_SCOPE_SYSTEM ? _("system") : _("user");
|
|
|
|
|
info->nmc->allowed_fields[4].value = nm_active_connection_get_default (active) ? _("yes") : _("no");
|
|
|
|
|
info->nmc->allowed_fields[5].value = nm_active_connection_get_service_name (active);
|
|
|
|
|
info->nmc->allowed_fields[6].value = nm_active_connection_get_specific_object (active);
|
|
|
|
|
info->nmc->allowed_fields[7].value = NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no");
|
2010-09-22 12:26:44 +02:00
|
|
|
info->nmc->allowed_fields[8].value = nm_object_get_path (NM_OBJECT (active));
|
2010-03-18 15:39:15 +01:00
|
|
|
|
2010-03-24 19:05:35 +01:00
|
|
|
info->nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */
|
2010-03-18 15:39:15 +01:00
|
|
|
print_fields (info->nmc->print_fields, info->nmc->allowed_fields);
|
|
|
|
|
break;
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_string_free (dev_str, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMCResultCode
|
|
|
|
|
do_connections_status (NmCli *nmc, int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
const GPtrArray *active_cons;
|
2010-03-18 15:39:15 +01:00
|
|
|
GError *error = NULL;
|
|
|
|
|
StatusInfo *info;
|
|
|
|
|
char *fields_str;
|
|
|
|
|
char *fields_all = NMC_FIELDS_CON_STATUS_ALL;
|
|
|
|
|
char *fields_common = NMC_FIELDS_CON_STATUS_COMMON;
|
|
|
|
|
guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
|
|
|
|
|
guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
|
|
|
|
|
guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
|
2010-02-25 09:52:30 -08:00
|
|
|
|
|
|
|
|
nmc->should_wait = FALSE;
|
|
|
|
|
|
|
|
|
|
/* create NMClient */
|
|
|
|
|
if (!nmc->get_client (nmc))
|
|
|
|
|
return nmc->return_value;
|
|
|
|
|
|
|
|
|
|
active_cons = nm_client_get_active_connections (nmc->client);
|
|
|
|
|
|
2010-03-18 15:39:15 +01:00
|
|
|
if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
|
|
|
|
|
fields_str = fields_common;
|
|
|
|
|
else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0)
|
|
|
|
|
fields_str = fields_all;
|
2010-03-31 17:14:35 +02:00
|
|
|
else
|
2010-03-18 15:39:15 +01:00
|
|
|
fields_str = nmc->required_fields;
|
|
|
|
|
|
|
|
|
|
nmc->allowed_fields = nmc_fields_con_status;
|
|
|
|
|
nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error);
|
|
|
|
|
|
|
|
|
|
if (error) {
|
2010-03-20 14:08:06 +01:00
|
|
|
if (error->code == 0)
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: 'con status': %s"), error->message);
|
|
|
|
|
else
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: 'con status': %s; allowed fields: %s"), error->message, NMC_FIELDS_CON_STATUS_ALL);
|
2010-03-18 15:39:15 +01:00
|
|
|
g_error_free (error);
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-03-18 15:39:15 +01:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-24 19:05:35 +01:00
|
|
|
nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES;
|
2010-03-18 15:39:15 +01:00
|
|
|
nmc->print_fields.header_name = _("Active connections");
|
|
|
|
|
print_fields (nmc->print_fields, nmc->allowed_fields);
|
2010-02-25 09:52:30 -08:00
|
|
|
|
|
|
|
|
if (active_cons && active_cons->len) {
|
2010-03-18 15:39:15 +01:00
|
|
|
info = g_malloc0 (sizeof (StatusInfo));
|
|
|
|
|
info->nmc = nmc;
|
|
|
|
|
info->scope = NM_CONNECTION_SCOPE_SYSTEM;
|
|
|
|
|
g_ptr_array_foreach ((GPtrArray *) active_cons, show_active_connection, (gpointer) info);
|
|
|
|
|
info->scope = NM_CONNECTION_SCOPE_USER;
|
|
|
|
|
g_ptr_array_foreach ((GPtrArray *) active_cons, show_active_connection, (gpointer) info);
|
|
|
|
|
g_free (info);
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
|
2010-03-18 15:39:15 +01:00
|
|
|
error:
|
|
|
|
|
|
|
|
|
|
return nmc->return_value;
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --------------------
|
|
|
|
|
* These function should be moved to libnm-glib in the end.
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
|
|
|
|
check_ethernet_compatible (NMDeviceEthernet *device, NMConnection *connection, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMSettingWired *s_wired;
|
|
|
|
|
const char *connection_type;
|
|
|
|
|
gboolean is_pppoe = FALSE;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
|
|
|
|
|
connection_type = nm_setting_connection_get_connection_type (s_con);
|
|
|
|
|
if ( strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME)
|
|
|
|
|
&& strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection was not a wired or PPPoE connection.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
|
|
|
|
|
is_pppoe = TRUE;
|
|
|
|
|
|
|
|
|
|
s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
|
|
|
|
|
/* Wired setting is optional for PPPoE */
|
|
|
|
|
if (!is_pppoe && !s_wired) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection was not a valid wired connection.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s_wired) {
|
|
|
|
|
const GByteArray *mac;
|
|
|
|
|
const char *device_mac_str;
|
2010-09-27 16:29:56 -05:00
|
|
|
struct ether_addr *device_mac = NULL;
|
2010-02-25 09:52:30 -08:00
|
|
|
|
2010-06-22 14:21:25 +02:00
|
|
|
device_mac_str = nm_device_ethernet_get_permanent_hw_address (device);
|
2010-09-27 16:29:56 -05:00
|
|
|
if (device_mac_str)
|
|
|
|
|
device_mac = ether_aton (device_mac_str);
|
2010-02-25 09:52:30 -08:00
|
|
|
if (!device_mac) {
|
|
|
|
|
g_set_error (error, 0, 0, "Invalid device MAC address.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mac = nm_setting_wired_get_mac_address (s_wired);
|
|
|
|
|
if (mac && memcmp (mac->data, device_mac->ether_addr_octet, ETH_ALEN)) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection's MAC address did not match this device.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: check bitrate against device capabilities
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
check_wifi_compatible (NMDeviceWifi *device, NMConnection *connection, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMSettingWireless *s_wireless;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
|
|
|
|
|
if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME)) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection was not a WiFi connection.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
|
|
|
|
|
if (!s_wireless) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection was not a valid WiFi connection.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s_wireless) {
|
|
|
|
|
const GByteArray *mac;
|
|
|
|
|
const char *device_mac_str;
|
2010-09-27 16:29:56 -05:00
|
|
|
struct ether_addr *device_mac = NULL;
|
2010-02-25 09:52:30 -08:00
|
|
|
|
2010-06-22 14:21:25 +02:00
|
|
|
device_mac_str = nm_device_wifi_get_permanent_hw_address (device);
|
2010-09-27 16:29:56 -05:00
|
|
|
if (device_mac_str)
|
|
|
|
|
device_mac = ether_aton (device_mac_str);
|
2010-02-25 09:52:30 -08:00
|
|
|
if (!device_mac) {
|
|
|
|
|
g_set_error (error, 0, 0, "Invalid device MAC address.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mac = nm_setting_wireless_get_mac_address (s_wireless);
|
|
|
|
|
if (mac && memcmp (mac->data, device_mac->ether_addr_octet, ETH_ALEN)) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection's MAC address did not match this device.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: check channel/freq/band against bands the hardware supports
|
|
|
|
|
// FIXME: check encryption against device capabilities
|
|
|
|
|
// FIXME: check bitrate against device capabilities
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
check_bt_compatible (NMDeviceBt *device, NMConnection *connection, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMSettingBluetooth *s_bt;
|
|
|
|
|
const GByteArray *array;
|
|
|
|
|
char *str;
|
|
|
|
|
const char *device_hw_str;
|
|
|
|
|
int addr_match = FALSE;
|
|
|
|
|
const char *bt_type_str;
|
|
|
|
|
guint32 bt_type, bt_capab;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
|
|
|
|
|
if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME)) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection was not a Bluetooth connection.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
|
|
|
|
|
if (!s_bt) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection was not a valid Bluetooth connection.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
array = nm_setting_bluetooth_get_bdaddr (s_bt);
|
|
|
|
|
if (!array || (array->len != ETH_ALEN)) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection did not contain a valid Bluetooth address.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bt_type_str = nm_setting_bluetooth_get_connection_type (s_bt);
|
|
|
|
|
g_assert (bt_type_str);
|
|
|
|
|
|
|
|
|
|
bt_type = NM_BT_CAPABILITY_NONE;
|
|
|
|
|
if (!strcmp (bt_type_str, NM_SETTING_BLUETOOTH_TYPE_DUN))
|
|
|
|
|
bt_type = NM_BT_CAPABILITY_DUN;
|
|
|
|
|
else if (!strcmp (bt_type_str, NM_SETTING_BLUETOOTH_TYPE_PANU))
|
|
|
|
|
bt_type = NM_BT_CAPABILITY_NAP;
|
|
|
|
|
|
|
|
|
|
bt_capab = nm_device_bt_get_capabilities (device);
|
|
|
|
|
if (!(bt_type & bt_capab)) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection was not compatible with the device's capabilities.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device_hw_str = nm_device_bt_get_hw_address (device);
|
|
|
|
|
|
|
|
|
|
str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
|
|
|
|
|
array->data[0], array->data[1], array->data[2],
|
|
|
|
|
array->data[3], array->data[4], array->data[5]);
|
|
|
|
|
addr_match = !strcmp (device_hw_str, str);
|
|
|
|
|
g_free (str);
|
|
|
|
|
|
|
|
|
|
return addr_match;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
static gboolean
|
|
|
|
|
check_olpc_mesh_compatible (NMDeviceOlpcMesh *device, NMConnection *connection, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMSettingOlpcMesh *s_mesh;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
|
|
|
|
|
if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_OLPC_MESH_SETTING_NAME)) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection was not a Mesh connection.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s_mesh = NM_SETTING_OLPC_MESH (nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH));
|
|
|
|
|
if (!s_mesh) {
|
|
|
|
|
g_set_error (error, 0, 0,
|
|
|
|
|
"The connection was not a valid Mesh connection.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
nm_device_is_connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
|
|
|
|
|
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
|
|
|
|
|
|
|
|
|
|
if (NM_IS_DEVICE_ETHERNET (device))
|
|
|
|
|
return check_ethernet_compatible (NM_DEVICE_ETHERNET (device), connection, error);
|
|
|
|
|
else if (NM_IS_DEVICE_WIFI (device))
|
|
|
|
|
return check_wifi_compatible (NM_DEVICE_WIFI (device), connection, error);
|
|
|
|
|
else if (NM_IS_DEVICE_BT (device))
|
|
|
|
|
return check_bt_compatible (NM_DEVICE_BT (device), connection, error);
|
|
|
|
|
// else if (NM_IS_DEVICE_OLPC_MESH (device))
|
|
|
|
|
// return check_olpc_mesh_compatible (NM_DEVICE_OLPC_MESH (device), connection, error);
|
|
|
|
|
|
|
|
|
|
g_set_error (error, 0, 0, "unhandled device type '%s'", G_OBJECT_TYPE_NAME (device));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_client_get_active_connection_by_path:
|
|
|
|
|
* @client: a #NMClient
|
|
|
|
|
* @object_path: the object path to search for
|
|
|
|
|
*
|
|
|
|
|
* Gets a #NMActiveConnection from a #NMClient.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the #NMActiveConnection for the given @object_path or %NULL if none is found.
|
|
|
|
|
**/
|
|
|
|
|
static NMActiveConnection *
|
|
|
|
|
nm_client_get_active_connection_by_path (NMClient *client, const char *object_path)
|
|
|
|
|
{
|
|
|
|
|
const GPtrArray *actives;
|
|
|
|
|
int i;
|
|
|
|
|
NMActiveConnection *active = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
|
|
|
|
|
g_return_val_if_fail (object_path, NULL);
|
|
|
|
|
|
|
|
|
|
actives = nm_client_get_active_connections (client);
|
|
|
|
|
if (!actives)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < actives->len; i++) {
|
|
|
|
|
NMActiveConnection *candidate = g_ptr_array_index (actives, i);
|
|
|
|
|
if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), object_path)) {
|
|
|
|
|
active = candidate;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return active;
|
|
|
|
|
}
|
|
|
|
|
/* -------------------- */
|
|
|
|
|
|
|
|
|
|
static NMActiveConnection *
|
|
|
|
|
get_default_active_connection (NmCli *nmc, NMDevice **device)
|
|
|
|
|
{
|
|
|
|
|
NMActiveConnection *default_ac = NULL;
|
|
|
|
|
NMDevice *non_default_device = NULL;
|
|
|
|
|
NMActiveConnection *non_default_ac = NULL;
|
|
|
|
|
const GPtrArray *connections;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (nmc != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (device != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (*device == NULL, NULL);
|
|
|
|
|
|
|
|
|
|
connections = nm_client_get_active_connections (nmc->client);
|
|
|
|
|
for (i = 0; connections && (i < connections->len); i++) {
|
|
|
|
|
NMActiveConnection *candidate = g_ptr_array_index (connections, i);
|
|
|
|
|
const GPtrArray *devices;
|
|
|
|
|
|
|
|
|
|
devices = nm_active_connection_get_devices (candidate);
|
|
|
|
|
if (!devices || !devices->len)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (nm_active_connection_get_default (candidate)) {
|
|
|
|
|
if (!default_ac) {
|
|
|
|
|
*device = g_ptr_array_index (devices, 0);
|
|
|
|
|
default_ac = candidate;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (!non_default_ac) {
|
|
|
|
|
non_default_device = g_ptr_array_index (devices, 0);
|
|
|
|
|
non_default_ac = candidate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Prefer the default connection if one exists, otherwise return the first
|
|
|
|
|
* non-default connection.
|
|
|
|
|
*/
|
|
|
|
|
if (!default_ac && non_default_ac) {
|
|
|
|
|
default_ac = non_default_ac;
|
|
|
|
|
*device = non_default_device;
|
|
|
|
|
}
|
|
|
|
|
return default_ac;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find a device to activate the connection on.
|
|
|
|
|
* IN: connection: connection to activate
|
|
|
|
|
* iface: device interface name to use (optional)
|
|
|
|
|
* ap: access point to use (optional; valid just for 802-11-wireless)
|
|
|
|
|
* OUT: device: found device
|
|
|
|
|
* spec_object: specific_object path of NMAccessPoint
|
|
|
|
|
* RETURNS: TRUE when a device is found, FALSE otherwise.
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
|
|
|
|
find_device_for_connection (NmCli *nmc, NMConnection *connection, const char *iface, const char *ap,
|
|
|
|
|
NMDevice **device, const char **spec_object, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
const char *con_type;
|
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (nmc != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (device != NULL && *device == NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (spec_object != NULL && *spec_object == NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
con_type = nm_setting_connection_get_connection_type (s_con);
|
|
|
|
|
|
|
|
|
|
if (strcmp (con_type, "vpn") == 0) {
|
|
|
|
|
/* VPN connections */
|
|
|
|
|
NMActiveConnection *active = NULL;
|
|
|
|
|
if (iface) {
|
|
|
|
|
const GPtrArray *connections = nm_client_get_active_connections (nmc->client);
|
|
|
|
|
for (i = 0; connections && (i < connections->len) && !active; i++) {
|
|
|
|
|
NMActiveConnection *candidate = g_ptr_array_index (connections, i);
|
|
|
|
|
const GPtrArray *devices = nm_active_connection_get_devices (candidate);
|
|
|
|
|
if (!devices || !devices->len)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
for (j = 0; devices && (j < devices->len); j++) {
|
|
|
|
|
NMDevice *dev = g_ptr_array_index (devices, j);
|
|
|
|
|
if (!strcmp (iface, nm_device_get_iface (dev))) {
|
|
|
|
|
active = candidate;
|
|
|
|
|
*device = dev;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!active) {
|
|
|
|
|
g_set_error (error, 0, 0, _("no active connection on device '%s'"), iface);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
*spec_object = nm_object_get_path (NM_OBJECT (active));
|
|
|
|
|
return TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
active = get_default_active_connection (nmc, device);
|
|
|
|
|
if (!active) {
|
|
|
|
|
g_set_error (error, 0, 0, _("no active connection or device"));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
*spec_object = nm_object_get_path (NM_OBJECT (active));
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* Other connections */
|
|
|
|
|
NMDevice *found_device = NULL;
|
|
|
|
|
const GPtrArray *devices = nm_client_get_devices (nmc->client);
|
|
|
|
|
|
|
|
|
|
for (i = 0; devices && (i < devices->len) && !found_device; i++) {
|
|
|
|
|
NMDevice *dev = g_ptr_array_index (devices, i);
|
|
|
|
|
|
|
|
|
|
if (iface) {
|
|
|
|
|
const char *dev_iface = nm_device_get_iface (dev);
|
|
|
|
|
if ( !strcmp (dev_iface, iface)
|
|
|
|
|
&& nm_device_is_connection_compatible (dev, connection, NULL)) {
|
|
|
|
|
found_device = dev;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (nm_device_is_connection_compatible (dev, connection, NULL)) {
|
|
|
|
|
found_device = dev;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (found_device && ap && !strcmp (con_type, "802-11-wireless") && NM_IS_DEVICE_WIFI (dev)) {
|
|
|
|
|
char *hwaddr_up = g_ascii_strup (ap, -1);
|
|
|
|
|
const GPtrArray *aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev));
|
|
|
|
|
found_device = NULL; /* Mark as not found; set to the device again later, only if AP matches */
|
|
|
|
|
|
|
|
|
|
for (j = 0; aps && (j < aps->len); j++) {
|
|
|
|
|
NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
|
|
|
|
|
const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
|
|
|
|
|
|
|
|
|
|
if (!strcmp (hwaddr_up, candidate_hwaddr)) {
|
|
|
|
|
found_device = dev;
|
|
|
|
|
*spec_object = nm_object_get_path (NM_OBJECT (candidate_ap));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_free (hwaddr_up);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (found_device) {
|
|
|
|
|
*device = found_device;
|
|
|
|
|
return TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
if (iface)
|
2010-03-20 14:08:06 +01:00
|
|
|
g_set_error (error, 0, 0, _("device '%s' not compatible with connection '%s'"), iface, nm_setting_connection_get_id (s_con));
|
2010-02-25 09:52:30 -08:00
|
|
|
else
|
2010-03-20 14:08:06 +01:00
|
|
|
g_set_error (error, 0, 0, _("no device found for connection '%s'"), nm_setting_connection_get_id (s_con));
|
2010-02-25 09:52:30 -08:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
|
active_connection_state_to_string (NMActiveConnectionState state)
|
|
|
|
|
{
|
|
|
|
|
switch (state) {
|
|
|
|
|
case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
|
|
|
|
|
return _("activating");
|
|
|
|
|
case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
|
|
|
|
|
return _("activated");
|
|
|
|
|
case NM_ACTIVE_CONNECTION_STATE_UNKNOWN:
|
|
|
|
|
default:
|
|
|
|
|
return _("unknown");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
|
vpn_connection_state_to_string (NMVPNConnectionState state)
|
|
|
|
|
{
|
|
|
|
|
switch (state) {
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_PREPARE:
|
|
|
|
|
return _("VPN connecting (prepare)");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_NEED_AUTH:
|
|
|
|
|
return _("VPN connecting (need authentication)");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_CONNECT:
|
|
|
|
|
return _("VPN connecting");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
|
|
|
|
|
return _("VPN connecting (getting IP configuration)");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_ACTIVATED:
|
|
|
|
|
return _("VPN connected");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_FAILED:
|
|
|
|
|
return _("VPN connection failed");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_DISCONNECTED:
|
|
|
|
|
return _("VPN disconnected");
|
|
|
|
|
default:
|
|
|
|
|
return _("unknown");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
|
vpn_connection_state_reason_to_string (NMVPNConnectionStateReason reason)
|
|
|
|
|
{
|
|
|
|
|
switch (reason) {
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_UNKNOWN:
|
|
|
|
|
return _("unknown reason");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_NONE:
|
|
|
|
|
return _("none");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED:
|
|
|
|
|
return _("the user was disconnected");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED:
|
|
|
|
|
return _("the base network connection was interrupted");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED:
|
|
|
|
|
return _("the VPN service stopped unexpectedly");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID:
|
|
|
|
|
return _("the VPN service returned invalid configuration");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT:
|
|
|
|
|
return _("the connection attempt timed out");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT:
|
|
|
|
|
return _("the VPN service did not start in time");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED:
|
|
|
|
|
return _("the VPN service failed to start");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS:
|
|
|
|
|
return _("no valid VPN secrets");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED:
|
|
|
|
|
return _("invalid VPN secrets");
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED:
|
|
|
|
|
return _("the connection was removed");
|
|
|
|
|
default:
|
|
|
|
|
return _("unknown");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NmCli *nmc = (NmCli *) user_data;
|
|
|
|
|
NMActiveConnectionState state;
|
|
|
|
|
|
|
|
|
|
state = nm_active_connection_get_state (active);
|
|
|
|
|
|
|
|
|
|
printf (_("state: %s\n"), active_connection_state_to_string (state));
|
|
|
|
|
|
|
|
|
|
if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
|
|
|
|
|
printf (_("Connection activated\n"));
|
|
|
|
|
quit ();
|
2010-03-31 17:14:35 +02:00
|
|
|
} else if (state == NM_ACTIVE_CONNECTION_STATE_UNKNOWN) {
|
2010-02-25 09:52:30 -08:00
|
|
|
g_string_printf (nmc->return_text, _("Error: Connection activation failed."));
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
|
|
|
|
|
quit ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
vpn_connection_state_cb (NMVPNConnection *vpn,
|
|
|
|
|
NMVPNConnectionState state,
|
|
|
|
|
NMVPNConnectionStateReason reason,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NmCli *nmc = (NmCli *) user_data;
|
|
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_PREPARE:
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_NEED_AUTH:
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_CONNECT:
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
|
|
|
|
|
printf (_("state: %s (%d)\n"), vpn_connection_state_to_string (state), state);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_ACTIVATED:
|
|
|
|
|
printf (_("Connection activated\n"));
|
|
|
|
|
quit ();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_FAILED:
|
|
|
|
|
case NM_VPN_CONNECTION_STATE_DISCONNECTED:
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: Connection activation failed: %s."), vpn_connection_state_reason_to_string (reason));
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
|
|
|
|
|
quit ();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
timeout_cb (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
/* Time expired -> exit nmcli */
|
|
|
|
|
|
|
|
|
|
NmCli *nmc = (NmCli *) user_data;
|
|
|
|
|
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: Timeout %d sec expired."), nmc->timeout);
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_TIMEOUT_EXPIRED;
|
|
|
|
|
quit ();
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
foo_active_connections_changed_cb (NMClient *client,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
/* Call again activate_connection_cb with dummy arguments;
|
|
|
|
|
* the correct ones are taken from its first call.
|
|
|
|
|
*/
|
|
|
|
|
activate_connection_cb (NULL, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
activate_connection_cb (gpointer user_data, const char *path, GError *error)
|
|
|
|
|
{
|
|
|
|
|
NmCli *nmc = (NmCli *) user_data;
|
|
|
|
|
NMActiveConnection *active;
|
|
|
|
|
NMActiveConnectionState state;
|
|
|
|
|
static gulong handler_id = 0;
|
|
|
|
|
static NmCli *orig_nmc;
|
|
|
|
|
static const char *orig_path;
|
|
|
|
|
static GError *orig_error;
|
|
|
|
|
|
|
|
|
|
if (nmc)
|
|
|
|
|
{
|
|
|
|
|
/* Called first time; store actual arguments */
|
|
|
|
|
orig_nmc = nmc;
|
|
|
|
|
orig_path = path;
|
|
|
|
|
orig_error = error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Disconnect the handler not to be run any more */
|
|
|
|
|
if (handler_id != 0) {
|
|
|
|
|
g_signal_handler_disconnect (orig_nmc->client, handler_id);
|
|
|
|
|
handler_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (orig_error) {
|
|
|
|
|
g_string_printf (orig_nmc->return_text, _("Error: Connection activation failed: %s"), orig_error->message);
|
|
|
|
|
orig_nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
|
|
|
|
|
quit ();
|
|
|
|
|
} else {
|
|
|
|
|
active = nm_client_get_active_connection_by_path (orig_nmc->client, orig_path);
|
|
|
|
|
if (!active) {
|
|
|
|
|
/* The active connection path is not in active connections list yet; wait for active-connections signal. */
|
|
|
|
|
/* This is basically the case for VPN connections. */
|
|
|
|
|
if (nmc) {
|
|
|
|
|
/* Called first time, i.e. by nm_client_activate_connection() */
|
|
|
|
|
handler_id = g_signal_connect (orig_nmc->client, "notify::active-connections",
|
|
|
|
|
G_CALLBACK (foo_active_connections_changed_cb), NULL);
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
g_string_printf (orig_nmc->return_text, _("Error: Obtaining active connection for '%s' failed."), orig_path);
|
|
|
|
|
orig_nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
|
|
|
|
|
quit ();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state = nm_active_connection_get_state (active);
|
|
|
|
|
|
|
|
|
|
printf (_("Active connection state: %s\n"), active_connection_state_to_string (state));
|
|
|
|
|
printf (_("Active connection path: %s\n"), orig_path);
|
|
|
|
|
|
2010-07-29 16:16:20 +02:00
|
|
|
if (orig_nmc->nowait_flag || state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
|
2010-02-25 09:52:30 -08:00
|
|
|
/* don't want to wait or already activated */
|
|
|
|
|
quit ();
|
|
|
|
|
} else {
|
|
|
|
|
if (NM_IS_VPN_CONNECTION (active))
|
|
|
|
|
g_signal_connect (NM_VPN_CONNECTION (active), "vpn-state-changed", G_CALLBACK (vpn_connection_state_cb), orig_nmc);
|
|
|
|
|
else
|
|
|
|
|
g_signal_connect (active, "notify::state", G_CALLBACK (active_connection_state_cb), orig_nmc);
|
|
|
|
|
|
|
|
|
|
/* Start timer not to loop forever when signals are not emitted */
|
|
|
|
|
g_timeout_add_seconds (orig_nmc->timeout, timeout_cb, orig_nmc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMCResultCode
|
|
|
|
|
do_connection_up (NmCli *nmc, int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *device = NULL;
|
|
|
|
|
const char *spec_object = NULL;
|
|
|
|
|
gboolean device_found;
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
gboolean is_system;
|
|
|
|
|
const char *con_path;
|
|
|
|
|
const char *con_type;
|
|
|
|
|
const char *iface = NULL;
|
|
|
|
|
const char *ap = NULL;
|
|
|
|
|
gboolean id_specified = FALSE;
|
|
|
|
|
gboolean wait = TRUE;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
/* Set default timeout for connection activation. It can take quite a long time.
|
|
|
|
|
* Using 90 seconds.
|
|
|
|
|
*/
|
|
|
|
|
nmc->timeout = 90;
|
|
|
|
|
|
|
|
|
|
while (argc > 0) {
|
|
|
|
|
if (strcmp (*argv, "id") == 0 || strcmp (*argv, "uuid") == 0) {
|
|
|
|
|
const char *selector = *argv;
|
|
|
|
|
id_specified = TRUE;
|
|
|
|
|
|
|
|
|
|
if (next_arg (&argc, &argv) != 0) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((connection = find_connection (nmc->system_connections, selector, *argv)) == NULL)
|
|
|
|
|
connection = find_connection (nmc->user_connections, selector, *argv);
|
|
|
|
|
|
|
|
|
|
if (!connection) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: Unknown connection: %s."), *argv);
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (strcmp (*argv, "iface") == 0) {
|
|
|
|
|
if (next_arg (&argc, &argv) != 0) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iface = *argv;
|
|
|
|
|
}
|
|
|
|
|
else if (strcmp (*argv, "ap") == 0) {
|
|
|
|
|
if (next_arg (&argc, &argv) != 0) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ap = *argv;
|
|
|
|
|
}
|
|
|
|
|
else if (strcmp (*argv, "--nowait") == 0) {
|
|
|
|
|
wait = FALSE;
|
|
|
|
|
} else if (strcmp (*argv, "--timeout") == 0) {
|
|
|
|
|
if (next_arg (&argc, &argv) != 0) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
nmc->timeout = strtol (*argv, NULL, 10);
|
|
|
|
|
if (errno || nmc->timeout < 0) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: timeout value '%s' is not valid."), *argv);
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
argc--;
|
|
|
|
|
argv++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!id_specified) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: id or uuid has to be specified."));
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* create NMClient */
|
|
|
|
|
if (!nmc->get_client (nmc))
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
|
is_system = (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) ? TRUE : FALSE;
|
|
|
|
|
con_path = nm_connection_get_path (connection);
|
|
|
|
|
|
|
|
|
|
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
con_type = nm_setting_connection_get_connection_type (s_con);
|
|
|
|
|
|
|
|
|
|
device_found = find_device_for_connection (nmc, connection, iface, ap, &device, &spec_object, &error);
|
|
|
|
|
|
|
|
|
|
if (!device_found) {
|
|
|
|
|
if (error)
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: No suitable device found: %s."), error->message);
|
|
|
|
|
else
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: No suitable device found."));
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-29 16:16:20 +02:00
|
|
|
/* Use nowait_flag instead of should_wait because exitting has to be postponed till active_connection_state_cb()
|
|
|
|
|
* is called, giving NM time to check our permissions */
|
|
|
|
|
nmc->nowait_flag = !wait;
|
|
|
|
|
nmc->should_wait = TRUE;
|
2010-02-25 09:52:30 -08:00
|
|
|
nm_client_activate_connection (nmc->client,
|
|
|
|
|
is_system ? NM_DBUS_SERVICE_SYSTEM_SETTINGS : NM_DBUS_SERVICE_USER_SETTINGS,
|
|
|
|
|
con_path,
|
|
|
|
|
device,
|
|
|
|
|
spec_object,
|
|
|
|
|
activate_connection_cb,
|
|
|
|
|
nmc);
|
|
|
|
|
|
|
|
|
|
return nmc->return_value;
|
|
|
|
|
error:
|
|
|
|
|
nmc->should_wait = FALSE;
|
|
|
|
|
return nmc->return_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMCResultCode
|
|
|
|
|
do_connection_down (NmCli *nmc, int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMActiveConnection *active = NULL;
|
|
|
|
|
const GPtrArray *active_cons;
|
|
|
|
|
const char *con_path;
|
|
|
|
|
const char *active_path;
|
|
|
|
|
NMConnectionScope active_service_scope, con_scope;
|
|
|
|
|
gboolean id_specified = FALSE;
|
|
|
|
|
gboolean wait = TRUE;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
while (argc > 0) {
|
|
|
|
|
if (strcmp (*argv, "id") == 0 || strcmp (*argv, "uuid") == 0) {
|
|
|
|
|
const char *selector = *argv;
|
|
|
|
|
id_specified = TRUE;
|
|
|
|
|
|
|
|
|
|
if (next_arg (&argc, &argv) != 0) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((connection = find_connection (nmc->system_connections, selector, *argv)) == NULL)
|
|
|
|
|
connection = find_connection (nmc->user_connections, selector, *argv);
|
|
|
|
|
|
|
|
|
|
if (!connection) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: Unknown connection: %s."), *argv);
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (strcmp (*argv, "--nowait") == 0) {
|
|
|
|
|
wait = FALSE;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
argc--;
|
|
|
|
|
argv++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!id_specified) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: id or uuid has to be specified."));
|
2010-03-24 13:42:47 +01:00
|
|
|
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* create NMClient */
|
|
|
|
|
if (!nmc->get_client (nmc))
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
|
con_path = nm_connection_get_path (connection);
|
|
|
|
|
con_scope = nm_connection_get_scope (connection);
|
|
|
|
|
|
|
|
|
|
active_cons = nm_client_get_active_connections (nmc->client);
|
|
|
|
|
for (i = 0; active_cons && (i < active_cons->len); i++) {
|
|
|
|
|
NMActiveConnection *candidate = g_ptr_array_index (active_cons, i);
|
|
|
|
|
|
|
|
|
|
active_path = nm_active_connection_get_connection (candidate);
|
|
|
|
|
active_service_scope = nm_active_connection_get_scope (candidate);
|
|
|
|
|
if (!strcmp (active_path, con_path) && active_service_scope == con_scope) {
|
|
|
|
|
active = candidate;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (active)
|
|
|
|
|
nm_client_deactivate_connection (nmc->client, active);
|
|
|
|
|
else {
|
|
|
|
|
fprintf (stderr, _("Warning: Connection not active\n"));
|
|
|
|
|
}
|
2010-07-29 16:16:20 +02:00
|
|
|
sleep (1); /* Don't quit immediatelly and give NM time to check our permissions */
|
2010-02-25 09:52:30 -08:00
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
nmc->should_wait = FALSE;
|
|
|
|
|
return nmc->return_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* callback called when connections are obtained from the settings service */
|
|
|
|
|
static void
|
|
|
|
|
get_connections_cb (NMSettingsInterface *settings, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
ArgsInfo *args = (ArgsInfo *) user_data;
|
|
|
|
|
static gboolean system_cb_called = FALSE;
|
|
|
|
|
static gboolean user_cb_called = FALSE;
|
2010-03-22 18:43:28 +01:00
|
|
|
GError *error = NULL;
|
2010-02-25 09:52:30 -08:00
|
|
|
|
|
|
|
|
if (NM_IS_REMOTE_SETTINGS_SYSTEM (settings)) {
|
|
|
|
|
system_cb_called = TRUE;
|
|
|
|
|
args->nmc->system_connections = nm_settings_interface_list_connections (settings);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
user_cb_called = TRUE;
|
|
|
|
|
args->nmc->user_connections = nm_settings_interface_list_connections (settings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* return and wait for the callback of the second settings is called */
|
2010-03-31 17:14:35 +02:00
|
|
|
if ( (args->nmc->system_settings_running && !system_cb_called)
|
|
|
|
|
|| (args->nmc->user_settings_running && !user_cb_called))
|
2010-02-25 09:52:30 -08:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (args->argc == 0) {
|
2010-03-22 18:43:28 +01:00
|
|
|
if (!nmc_terse_option_check (args->nmc->print_output, args->nmc->required_fields, &error))
|
2010-03-24 13:42:47 +01:00
|
|
|
goto opt_error;
|
2010-02-25 09:52:30 -08:00
|
|
|
args->nmc->return_value = do_connections_list (args->nmc, args->argc, args->argv);
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
if (matches (*args->argv, "list") == 0) {
|
|
|
|
|
args->nmc->return_value = do_connections_list (args->nmc, args->argc-1, args->argv+1);
|
|
|
|
|
}
|
|
|
|
|
else if (matches(*args->argv, "status") == 0) {
|
2010-03-22 18:43:28 +01:00
|
|
|
if (!nmc_terse_option_check (args->nmc->print_output, args->nmc->required_fields, &error))
|
2010-03-24 13:42:47 +01:00
|
|
|
goto opt_error;
|
2010-02-25 09:52:30 -08:00
|
|
|
args->nmc->return_value = do_connections_status (args->nmc, args->argc-1, args->argv+1);
|
|
|
|
|
}
|
|
|
|
|
else if (matches(*args->argv, "up") == 0) {
|
|
|
|
|
args->nmc->return_value = do_connection_up (args->nmc, args->argc-1, args->argv+1);
|
|
|
|
|
}
|
|
|
|
|
else if (matches(*args->argv, "down") == 0) {
|
|
|
|
|
args->nmc->return_value = do_connection_down (args->nmc, args->argc-1, args->argv+1);
|
|
|
|
|
}
|
|
|
|
|
else if (matches (*args->argv, "help") == 0) {
|
|
|
|
|
usage ();
|
|
|
|
|
args->nmc->should_wait = FALSE;
|
|
|
|
|
} else {
|
|
|
|
|
usage ();
|
|
|
|
|
g_string_printf (args->nmc->return_text, _("Error: 'con' command '%s' is not valid."), *args->argv);
|
2010-03-24 13:42:47 +01:00
|
|
|
args->nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-02-25 09:52:30 -08:00
|
|
|
args->nmc->should_wait = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!args->nmc->should_wait)
|
|
|
|
|
quit ();
|
2010-03-22 18:43:28 +01:00
|
|
|
return;
|
|
|
|
|
|
2010-03-24 13:42:47 +01:00
|
|
|
opt_error:
|
2010-03-22 18:43:28 +01:00
|
|
|
g_string_printf (args->nmc->return_text, _("Error: %s."), error->message);
|
2010-03-24 13:42:47 +01:00
|
|
|
args->nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
2010-03-22 18:43:28 +01:00
|
|
|
args->nmc->should_wait = FALSE;
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
quit ();
|
|
|
|
|
return;
|
2010-02-25 09:52:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Entry point function for connections-related commands: 'nmcli con' */
|
|
|
|
|
NMCResultCode
|
|
|
|
|
do_connections (NmCli *nmc, int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
DBusGConnection *bus;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
nmc->should_wait = TRUE;
|
|
|
|
|
|
|
|
|
|
args_info.nmc = nmc;
|
|
|
|
|
args_info.argc = argc;
|
|
|
|
|
args_info.argv = argv;
|
|
|
|
|
|
|
|
|
|
/* connect to DBus' system bus */
|
|
|
|
|
bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
|
|
|
|
|
if (error || !bus) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: could not connect to D-Bus."));
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
|
|
|
|
return nmc->return_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* get system settings */
|
|
|
|
|
if (!(nmc->system_settings = nm_remote_settings_system_new (bus))) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: Could not get system settings."));
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
|
|
|
|
return nmc->return_value;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* get user settings */
|
|
|
|
|
if (!(nmc->user_settings = nm_remote_settings_new (bus, NM_CONNECTION_SCOPE_USER))) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: Could not get user settings."));
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
|
|
|
|
return nmc->return_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* find out whether setting services are running */
|
|
|
|
|
g_object_get (nmc->system_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &nmc->system_settings_running, NULL);
|
|
|
|
|
g_object_get (nmc->user_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &nmc->user_settings_running, NULL);
|
|
|
|
|
|
|
|
|
|
if (!nmc->system_settings_running && !nmc->user_settings_running) {
|
|
|
|
|
g_string_printf (nmc->return_text, _("Error: Can't obtain connections: settings services are not running."));
|
|
|
|
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
|
|
|
|
return nmc->return_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* connect to signal "connections-read" - emitted when connections are fetched and ready */
|
|
|
|
|
if (nmc->system_settings_running)
|
|
|
|
|
g_signal_connect (nmc->system_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ,
|
|
|
|
|
G_CALLBACK (get_connections_cb), &args_info);
|
|
|
|
|
|
|
|
|
|
if (nmc->user_settings_running)
|
|
|
|
|
g_signal_connect (nmc->user_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ,
|
|
|
|
|
G_CALLBACK (get_connections_cb), &args_info);
|
|
|
|
|
|
|
|
|
|
dbus_g_connection_unref (bus);
|
|
|
|
|
|
|
|
|
|
/* The rest will be done in get_connection_cb() callback.
|
|
|
|
|
* We need to wait for signals that connections are read.
|
|
|
|
|
*/
|
|
|
|
|
return NMC_RESULT_SUCCESS;
|
|
|
|
|
}
|