diff options
| author | Michael Biebl <biebl@debian.org> | 2012-06-29 20:12:44 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2012-06-29 20:12:44 +0200 |
| commit | 867254ea7c2b193fecf8cd36cc6e5dc53c290d92 (patch) | |
| tree | 7c698b403882736ab70c3efd524c3460f08c391c /cli/src | |
| parent | de06e5715e780baade318f3490ac7a4c9ce84e32 (diff) | |
Imported Upstream version 0.9.5.95 upstream/0.9.5.95
Diffstat (limited to 'cli/src')
| -rw-r--r-- | cli/src/Makefile.in | 11 | ||||
| -rw-r--r-- | cli/src/common.c | 198 | ||||
| -rw-r--r-- | cli/src/common.h | 4 | ||||
| -rw-r--r-- | cli/src/connections.c | 260 | ||||
| -rw-r--r-- | cli/src/devices.c | 723 | ||||
| -rw-r--r-- | cli/src/network-manager.c | 158 | ||||
| -rw-r--r-- | cli/src/settings.c | 64 | ||||
| -rw-r--r-- | cli/src/settings.h | 2 | ||||
| -rw-r--r-- | cli/src/utils.c | 38 | ||||
| -rw-r--r-- | cli/src/utils.h | 2 |
10 files changed, 1186 insertions, 274 deletions
diff --git a/cli/src/Makefile.in b/cli/src/Makefile.in index ea5214e5..854628c2 100644 --- a/cli/src/Makefile.in +++ b/cli/src/Makefile.in @@ -48,7 +48,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -172,6 +172,10 @@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ INTLTOOL_MERGE = @INTLTOOL_MERGE@ INTLTOOL_PERL = @INTLTOOL_PERL@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ @@ -267,6 +271,9 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ @@ -305,6 +312,8 @@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ diff --git a/cli/src/common.c b/cli/src/common.c index e9a5d760..193ea33f 100644 --- a/cli/src/common.c +++ b/cli/src/common.c @@ -358,3 +358,201 @@ print_dhcp6_config (NMDHCP6Config *dhcp6, NmCli *nmc, const char *group_prefix) return FALSE; } +const char * +nmc_device_state_to_string (NMDeviceState state) +{ + switch (state) { + case NM_DEVICE_STATE_UNMANAGED: + return _("unmanaged"); + case NM_DEVICE_STATE_UNAVAILABLE: + return _("unavailable"); + case NM_DEVICE_STATE_DISCONNECTED: + return _("disconnected"); + case NM_DEVICE_STATE_PREPARE: + return _("connecting (prepare)"); + case NM_DEVICE_STATE_CONFIG: + return _("connecting (configuring)"); + case NM_DEVICE_STATE_NEED_AUTH: + return _("connecting (need authentication)"); + case NM_DEVICE_STATE_IP_CONFIG: + return _("connecting (getting IP configuration)"); + case NM_DEVICE_STATE_IP_CHECK: + return _("connecting (checking IP connectivity)"); + case NM_DEVICE_STATE_SECONDARIES: + return _("connecting (starting secondary connections)"); + case NM_DEVICE_STATE_ACTIVATED: + return _("connected"); + case NM_DEVICE_STATE_DEACTIVATING: + return _("deactivating"); + case NM_DEVICE_STATE_FAILED: + return _("connection failed"); + default: + return _("unknown"); + } +} + +const char * +nmc_device_reason_to_string (NMDeviceStateReason reason) +{ + switch (reason) { + case NM_DEVICE_STATE_REASON_NONE: + return _("No reason given"); + + case NM_DEVICE_STATE_REASON_UNKNOWN: + return _("Unknown error"); + + case NM_DEVICE_STATE_REASON_NOW_MANAGED: + return _("Device is now managed"); + + case NM_DEVICE_STATE_REASON_NOW_UNMANAGED: + return _("Device is now unmanaged"); + + case NM_DEVICE_STATE_REASON_CONFIG_FAILED: + return _("The device could not be readied for configuration"); + + case NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE: + return _("IP configuration could not be reserved (no available address, timeout, etc)"); + + case NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED: + return _("The IP configuration is no longer valid"); + + case NM_DEVICE_STATE_REASON_NO_SECRETS: + return _("Secrets were required, but not provided"); + + case NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT: + return _("802.1X supplicant disconnected"); + + case NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED: + return _("802.1X supplicant configuration failed"); + + case NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED: + return _("802.1X supplicant failed"); + + case NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT: + return _("802.1X supplicant took too long to authenticate"); + + case NM_DEVICE_STATE_REASON_PPP_START_FAILED: + return _("PPP service failed to start"); + + case NM_DEVICE_STATE_REASON_PPP_DISCONNECT: + return _("PPP service disconnected"); + + case NM_DEVICE_STATE_REASON_PPP_FAILED: + return _("PPP failed"); + + case NM_DEVICE_STATE_REASON_DHCP_START_FAILED: + return _("DHCP client failed to start"); + + case NM_DEVICE_STATE_REASON_DHCP_ERROR: + return _("DHCP client error"); + + case NM_DEVICE_STATE_REASON_DHCP_FAILED: + return _("DHCP client failed"); + + case NM_DEVICE_STATE_REASON_SHARED_START_FAILED: + return _("Shared connection service failed to start"); + + case NM_DEVICE_STATE_REASON_SHARED_FAILED: + return _("Shared connection service failed"); + + case NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED: + return _("AutoIP service failed to start"); + + case NM_DEVICE_STATE_REASON_AUTOIP_ERROR: + return _("AutoIP service error"); + + case NM_DEVICE_STATE_REASON_AUTOIP_FAILED: + return _("AutoIP service failed"); + + case NM_DEVICE_STATE_REASON_MODEM_BUSY: + return _("The line is busy"); + + case NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE: + return _("No dial tone"); + + case NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER: + return _("No carrier could be established"); + + case NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT: + return _("The dialing request timed out"); + + case NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED: + return _("The dialing attempt failed"); + + case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: + return _("Modem initialization failed"); + + case NM_DEVICE_STATE_REASON_GSM_APN_FAILED: + return _("Failed to select the specified APN"); + + case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING: + return _("Not searching for networks"); + + case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED: + return _("Network registration denied"); + + case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT: + return _("Network registration timed out"); + + case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED: + return _("Failed to register with the requested network"); + + case NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED: + return _("PIN check failed"); + + case NM_DEVICE_STATE_REASON_FIRMWARE_MISSING: + return _("Necessary firmware for the device may be missing"); + + case NM_DEVICE_STATE_REASON_REMOVED: + return _("The device was removed"); + + case NM_DEVICE_STATE_REASON_SLEEPING: + return _("NetworkManager went to sleep"); + + case NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: + return _("The device's active connection disappeared"); + + case NM_DEVICE_STATE_REASON_USER_REQUESTED: + return _("Device disconnected by user or client"); + + case NM_DEVICE_STATE_REASON_CARRIER: + return _("Carrier/link changed"); + + case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: + return _("The device's existing connection was assumed"); + + case NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE: + return _("The supplicant is now available"); + + case NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND: + return _("The modem could not be found"); + + case NM_DEVICE_STATE_REASON_BT_FAILED: + return _("The Bluetooth connection failed or timed out"); + + case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: + return _("GSM Modem's SIM card not inserted"); + + case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: + return _("GSM Modem's SIM PIN required"); + + case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: + return _("GSM Modem's SIM PUK required"); + + case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: + return _("GSM Modem's SIM wrong"); + + case NM_DEVICE_STATE_REASON_INFINIBAND_MODE: + return _("InfiniBand device does not support connected mode"); + + case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: + return _("A dependency of the connection failed"); + + case NM_DEVICE_STATE_REASON_BR2684_FAILED: + return _("A problem with the RFC 2684 Ethernet over ADSL bridge"); + + default: + return _("Unknown"); + } +} + diff --git a/cli/src/common.h b/cli/src/common.h index 85015a9f..89412d28 100644 --- a/cli/src/common.h +++ b/cli/src/common.h @@ -28,6 +28,7 @@ #include <nm-ip6-config.h> #include <nm-dhcp4-config.h> #include <nm-dhcp6-config.h> +#include <nm-device.h> #include "nmcli.h" @@ -36,4 +37,7 @@ gboolean print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_pref gboolean print_dhcp4_config (NMDHCP4Config *dhcp4, NmCli *nmc, const char *group_prefix); gboolean print_dhcp6_config (NMDHCP6Config *dhcp6, NmCli *nmc, const char *group_prefix); +const char * nmc_device_state_to_string (NMDeviceState state); +const char * nmc_device_reason_to_string (NMDeviceStateReason reason); + #endif /* NMC_COMMON_H */ diff --git a/cli/src/connections.c b/cli/src/connections.c index ea5211f5..8e654864 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -33,6 +33,7 @@ #include <nm-client.h> #include <nm-device-ethernet.h> +#include <nm-device-adsl.h> #include <nm-device-wifi.h> #if WITH_WIMAX #include <nm-device-wimax.h> @@ -92,6 +93,7 @@ static NmcOutputField nmc_fields_settings_names[] = { SETTING_FIELD (NM_SETTING_INFINIBAND_SETTING_NAME, 0), /* 16 */ SETTING_FIELD (NM_SETTING_BOND_SETTING_NAME, 0), /* 17 */ SETTING_FIELD (NM_SETTING_VLAN_SETTING_NAME, 0), /* 18 */ + SETTING_FIELD (NM_SETTING_ADSL_SETTING_NAME, 0), /* 19 */ {NULL, NULL, 0, NULL, 0} }; #define NMC_FIELDS_SETTINGS_NAMES_ALL_X NM_SETTING_CONNECTION_SETTING_NAME","\ @@ -104,6 +106,7 @@ static NmcOutputField nmc_fields_settings_names[] = { NM_SETTING_SERIAL_SETTING_NAME","\ NM_SETTING_PPP_SETTING_NAME","\ NM_SETTING_PPPOE_SETTING_NAME","\ + NM_SETTING_ADSL_SETTING_NAME","\ NM_SETTING_GSM_SETTING_NAME","\ NM_SETTING_CDMA_SETTING_NAME","\ NM_SETTING_BLUETOOTH_SETTING_NAME","\ @@ -178,6 +181,7 @@ typedef struct { extern GMainLoop *loop; static ArgsInfo args_info; +static guint progress_id = 0; /* ID of event source for displaying progress */ static void usage (void) @@ -210,6 +214,11 @@ static const char *real_con_commands[] = { static void quit (void) { + if (progress_id) { + g_source_remove (progress_id); + nmc_terminal_erase_line (); + } + g_main_loop_quit (loop); /* quit main loop */ } @@ -432,6 +441,15 @@ nmc_connection_detail (NMConnection *connection, NmCli *nmc) continue; } } + + if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[19].name)) { + NMSettingAdsl *s_adsl = nm_connection_get_setting_adsl (connection); + if (s_adsl) { + setting_adsl_details (s_adsl, nmc); + was_output = TRUE; + continue; + } + } } if (print_settings_array) @@ -687,6 +705,21 @@ fill_in_fields_con_status (NMActiveConnection *active, GSList *con_list) if (dev_str->len > 0) g_string_truncate (dev_str, dev_str->len - 1); /* Cut off last ',' */ + /* Fill field values */ + nmc_fields_con_status[0].value = nmc_fields_status_details_groups[0].name; + nmc_fields_con_status[1].value = _("N/A"); + nmc_fields_con_status[2].value = nm_active_connection_get_uuid (active); + nmc_fields_con_status[3].value = dev_str->str; + nmc_fields_con_status[4].value = active_connection_state_to_string (state); + nmc_fields_con_status[5].value = nm_active_connection_get_default (active) ? _("yes") : _("no"); + nmc_fields_con_status[6].value = nm_active_connection_get_default6 (active) ? _("yes") : _("no"); + nmc_fields_con_status[7].value = nm_active_connection_get_specific_object (active); + nmc_fields_con_status[8].value = NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no"); + nmc_fields_con_status[9].value = nm_object_get_path (NM_OBJECT (active)); + nmc_fields_con_status[10].value = nm_active_connection_get_connection (active); + nmc_fields_con_status[11].value = _("N/A"); + nmc_fields_con_status[12].value = nm_active_connection_get_master (active); + for (iter = con_list; iter; iter = g_slist_next (iter)) { NMConnection *connection = (NMConnection *) iter->data; const char *con_path = nm_connection_get_path (connection); @@ -696,20 +729,9 @@ fill_in_fields_con_status (NMActiveConnection *active, GSList *con_list) s_con = nm_connection_get_setting_connection (connection); g_assert (s_con != NULL); - /* Fill field values */ - nmc_fields_con_status[0].value = nmc_fields_status_details_groups[0].name; + /* Fill field values that depend on NMConnection */ nmc_fields_con_status[1].value = nm_setting_connection_get_id (s_con); - nmc_fields_con_status[2].value = nm_setting_connection_get_uuid (s_con); - nmc_fields_con_status[3].value = dev_str->str; - nmc_fields_con_status[4].value = active_connection_state_to_string (state); - nmc_fields_con_status[5].value = nm_active_connection_get_default (active) ? _("yes") : _("no"); - nmc_fields_con_status[6].value = nm_active_connection_get_default6 (active) ? _("yes") : _("no"); - nmc_fields_con_status[7].value = nm_active_connection_get_specific_object (active); - nmc_fields_con_status[8].value = NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no"); - nmc_fields_con_status[9].value = nm_object_get_path (NM_OBJECT (active)); - nmc_fields_con_status[10].value = nm_active_connection_get_connection (active); nmc_fields_con_status[11].value = nm_setting_connection_get_zone (s_con); - nmc_fields_con_status[12].value = nm_active_connection_get_master (active); success = TRUE; break; @@ -1336,10 +1358,12 @@ active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpoin 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")); + if (nmc->print_output == NMC_PRINT_PRETTY) { + nmc_terminal_erase_line (); + printf (_("Connection successfully activated (D-Bus active path: %s)\n"), + nm_object_get_path (NM_OBJECT (active))); + } quit (); } else if (state == NM_ACTIVE_CONNECTION_STATE_UNKNOWN) { g_string_printf (nmc->return_text, _("Error: Connection activation failed.")); @@ -1361,17 +1385,22 @@ vpn_connection_state_cb (NMVPNConnection *vpn, 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); + /* no operation */ break; case NM_VPN_CONNECTION_STATE_ACTIVATED: - printf (_("Connection activated\n")); + if (nmc->print_output == NMC_PRINT_PRETTY) { + nmc_terminal_erase_line (); + printf (_("VPN connection successfully activated (D-Bus active path: %s)\n"), + nm_object_get_path (NM_OBJECT (vpn))); + } 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)); + 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; @@ -1381,6 +1410,85 @@ vpn_connection_state_cb (NMVPNConnection *vpn, } } +/* --- VPN state workaround BEGIN --- */ +static NMVPNConnectionState +dbus_get_vpn_state (const char *path) +{ + DBusGConnection *connection; + DBusGProxy *proxy; + GError *error = NULL; + GValue value = {0,}; + NMVPNConnectionState state = NM_VPN_CONNECTION_STATE_UNKNOWN; + + connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); + proxy = dbus_g_proxy_new_for_name (connection, + NM_DBUS_SERVICE, + path, + "org.freedesktop.DBus.Properties"); + if (!proxy) { + g_warning ("%s: couldn't create D-Bus object proxy.", __func__); + dbus_g_connection_unref (connection); + return NM_VPN_CONNECTION_STATE_UNKNOWN; + } + + /* Get VpnState property for object 'path' through D-Bus Get() call. */ + if (dbus_g_proxy_call (proxy, + "Get", &error, + G_TYPE_STRING, NM_DBUS_INTERFACE_VPN_CONNECTION, + G_TYPE_STRING, "VpnState", + G_TYPE_INVALID, + G_TYPE_VALUE, &value, G_TYPE_INVALID)) { + + state = g_value_get_uint (&value); + } else { + g_warning ("Error in getting active connection 'Vpn' property: (%d) %s", + error->code, error->message); + g_error_free (error); + } + + g_object_unref (proxy); + dbus_g_connection_unref (connection); + + return state; +} + +typedef struct { + NmCli *nmc; + NMVPNConnection *vpn; +} VpnGetStateInfo; + +static gboolean +get_vpn_state_cb (gpointer user_data) +{ + VpnGetStateInfo *info = (VpnGetStateInfo *) user_data; + NmCli *nmc = info->nmc; + NMVPNConnection *vpn = info->vpn; + NMVPNConnectionState state; + + if (!NM_IS_OBJECT (vpn)) { + /* Active connection failed and dissapeared, quit. */ + g_string_printf (nmc->return_text, _("Error: Connection activation failed.")); + nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; + quit (); + g_free (info); + return FALSE; + } + + state = dbus_get_vpn_state (nm_object_get_path (NM_OBJECT (vpn))); + + vpn_connection_state_cb (vpn, state, NM_VPN_CONNECTION_STATE_REASON_UNKNOWN, nmc); + + if ( state == NM_VPN_CONNECTION_STATE_ACTIVATED + || state == NM_VPN_CONNECTION_STATE_FAILED + || state == NM_VPN_CONNECTION_STATE_DISCONNECTED) { + + g_free (info); + return FALSE; + } else + return TRUE; +} +/* --- VPN state workaround END --- */ + static gboolean timeout_cb (gpointer user_data) { @@ -1394,10 +1502,58 @@ timeout_cb (gpointer user_data) return FALSE; } +static gboolean +progress_cb (gpointer user_data) +{ + const char *str = (const char *) user_data; + + nmc_terminal_show_progress (str); + + return TRUE; +} + +static gboolean +progress_device_cb (gpointer user_data) +{ + NMDevice *device = (NMDevice *) user_data; + + nmc_terminal_show_progress (device ? nmc_device_state_to_string (nm_device_get_state (device)) : ""); + + return TRUE; +} + +static gboolean +progress_vpn_cb (gpointer user_data) +{ + NMVPNConnection *vpn = (NMVPNConnection *) user_data; + const char *str; + + /* VPN state workaround */ +#if 0 + str = NM_IS_VPN_CONNECTION (vpn) ? + vpn_connection_state_to_string (nm_vpn_connection_get_vpn_state (vpn)) : + ""; +#endif + str = NM_IS_OBJECT (vpn) ? + vpn_connection_state_to_string (dbus_get_vpn_state (nm_object_get_path (NM_OBJECT (vpn)))) : + ""; + + nmc_terminal_show_progress (str); + + return TRUE; +} + +typedef struct { + NmCli *nmc; + NMDevice *device; +} ActivateConnectionInfo; + static void activate_connection_cb (NMClient *client, NMActiveConnection *active, GError *error, gpointer user_data) { - NmCli *nmc = (NmCli *) user_data; + ActivateConnectionInfo *info = (ActivateConnectionInfo *) user_data; + NmCli *nmc = info->nmc; + NMDevice *device = info->device; NMActiveConnectionState state; if (error) { @@ -1407,27 +1563,61 @@ activate_connection_cb (NMClient *client, NMActiveConnection *active, GError *er } else { 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"), nm_object_get_path (NM_OBJECT (active))); - if (nmc->nowait_flag || state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - /* don't want to wait or already activated */ + /* User doesn't want to wait or already activated */ + if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED && nmc->print_output == NMC_PRINT_PRETTY) { + printf (_("Connection successfully activated (D-Bus active path: %s)\n"), + nm_object_get_path (NM_OBJECT (active))); + } quit (); } else { - if (NM_IS_VPN_CONNECTION (active)) - g_signal_connect (NM_VPN_CONNECTION (active), "vpn-state-changed", G_CALLBACK (vpn_connection_state_cb), nmc); - else + if (NM_IS_VPN_CONNECTION (active)) { + VpnGetStateInfo *vpn_info; + + /* Monitor VPN state */ + g_signal_connect (G_OBJECT (active), "vpn-state-changed", G_CALLBACK (vpn_connection_state_cb), nmc); + + /* Start progress indication showing VPN states */ + if (nmc->print_output == NMC_PRINT_PRETTY) { + if (progress_id) + g_source_remove (progress_id); + progress_id = g_timeout_add (120, progress_vpn_cb, NM_VPN_CONNECTION (active)); + } + + /* --- workaround BEGIN --- */ + /* There is a bug in libnm-glib or dbus-glib - 'vpn-state-changed' signal + * is never issued. After inspection it appears that PropertiesChanged and + * VpnStateChanged D-Bus signals are not processed, even if they are seen + * on D-Bus (checked via dbus-monitor). Until the bug is identified and + * fixed, we check the VPN state every second. + */ + vpn_info = g_malloc0 (sizeof (VpnGetStateInfo)); + vpn_info->nmc = nmc; + vpn_info->vpn = NM_VPN_CONNECTION (active); + g_timeout_add_seconds (1, get_vpn_state_cb, vpn_info); + /* --- workaround END --- */ + } else { g_signal_connect (active, "notify::state", G_CALLBACK (active_connection_state_cb), nmc); + /* Start progress indication showing device states */ + if (nmc->print_output == NMC_PRINT_PRETTY) { + if (progress_id) + g_source_remove (progress_id); + progress_id = g_timeout_add (120, progress_device_cb, device); + } + } + /* Start timer not to loop forever when signals are not emitted */ g_timeout_add_seconds (nmc->timeout, timeout_cb, nmc); } } + g_free (info); } static NMCResultCode do_connection_up (NmCli *nmc, int argc, char **argv) { + ActivateConnectionInfo *info; NMDevice *device = NULL; const char *spec_object = NULL; gboolean device_found; @@ -1566,12 +1756,21 @@ do_connection_up (NmCli *nmc, int argc, char **argv) */ nmc->nowait_flag = !wait; nmc->should_wait = TRUE; + + info = g_malloc0 (sizeof (ActivateConnectionInfo)); + info->nmc = nmc; + info->device = device; + nm_client_activate_connection (nmc->client, connection, device, spec_object, activate_connection_cb, - nmc); + info); + + /* Start progress indication */ + if (nmc->print_output == NMC_PRINT_PRETTY) + progress_id = g_timeout_add (120, progress_cb, "preparing"); return nmc->return_value; error: @@ -1769,7 +1968,7 @@ parse_cmd (NmCli *nmc, int argc, char **argv) nmc->return_value = do_connections_list (nmc, argc, argv); } else { - if (matches (*argv, "list") == 0) { + if (matches (*argv, "list") == 0) { nmc->return_value = do_connections_list (nmc, argc-1, argv+1); } else if (matches(*argv, "status") == 0) { @@ -1836,7 +2035,7 @@ do_connections (NmCli *nmc, int argc, char **argv) else { while (real_con_commands[i] && matches (*argv, real_con_commands[i]) != 0) i++; - if (real_con_commands[i] != NULL) + if (real_con_commands[i] != NULL) real_cmd = TRUE; } @@ -1847,6 +2046,9 @@ do_connections (NmCli *nmc, int argc, char **argv) if (!nmc_versions_match (nmc)) return nmc->return_value; + /* Get NMClient object early */ + nmc->get_client (nmc); + nmc->should_wait = TRUE; args_info.nmc = nmc; diff --git a/cli/src/devices.c b/cli/src/devices.c index 0b1b6d6e..6b9367b4 100644 --- a/cli/src/devices.c +++ b/cli/src/devices.c @@ -23,6 +23,7 @@ #include <string.h> #include <stdlib.h> #include <errno.h> +#include <netinet/ether.h> #include <glib.h> #include <glib/gi18n.h> @@ -30,6 +31,7 @@ #include <nm-client.h> #include <nm-device.h> #include <nm-device-ethernet.h> +#include <nm-device-adsl.h> #include <nm-device-wifi.h> #include <nm-device-modem.h> #include <nm-device-bt.h> @@ -46,6 +48,7 @@ #include <nm-vpn-connection.h> #include <nm-setting-connection.h> #include <nm-setting-wired.h> +#include <nm-setting-adsl.h> #include <nm-setting-pppoe.h> #include <nm-setting-wireless.h> #include <nm-setting-gsm.h> @@ -105,17 +108,20 @@ static NmcOutputField nmc_fields_dev_list_general[] = { {"VENDOR", N_("VENDOR"), 20, NULL, 0}, /* 3 */ {"PRODUCT", N_("PRODUCT"), 50, NULL, 0}, /* 4 */ {"DRIVER", N_("DRIVER"), 9, NULL, 0}, /* 5 */ - {"HWADDR", N_("HWADDR"), 19, NULL, 0}, /* 6 */ - {"STATE", N_("STATE"), 14, NULL, 0}, /* 7 */ - {"REASON", N_("REASON"), 25, NULL, 0}, /* 8 */ - {"UDI", N_("UDI"), 64, NULL, 0}, /* 9 */ - {"IP-IFACE", N_("IP-IFACE"), 10, NULL, 0}, /* 10 */ - {"NM-MANAGED", N_("NM-MANAGED"), 15, NULL, 0}, /* 11 */ - {"FIRMWARE-MISSING", N_("FIRMWARE-MISSING"), 18, NULL, 0}, /* 12 */ - {"CONNECTION", N_("CONNECTION"), 51, NULL, 0}, /* 13 */ + {"DRIVER-VERSION", N_("DRIVER-VERSION"), 18, NULL, 0}, /* 6 */ + {"FIRMWARE-VERSION", N_("FIRMWARE-VERSION"), 18, NULL, 0}, /* 7 */ + {"HWADDR", N_("HWADDR"), 19, NULL, 0}, /* 8 */ + {"STATE", N_("STATE"), 14, NULL, 0}, /* 9 */ + {"REASON", N_("REASON"), 25, NULL, 0}, /* 10 */ + {"UDI", N_("UDI"), 64, NULL, 0}, /* 11 */ + {"IP-IFACE", N_("IP-IFACE"), 10, NULL, 0}, /* 12 */ + {"NM-MANAGED", N_("NM-MANAGED"), 15, NULL, 0}, /* 13 */ + {"AUTOCONNECT", N_("AUTOCONNECT"), 15, NULL, 0}, /* 14 */ + {"FIRMWARE-MISSING", N_("FIRMWARE-MISSING"), 18, NULL, 0}, /* 15 */ + {"CONNECTION", N_("CONNECTION"), 51, NULL, 0}, /* 16 */ {NULL, NULL, 0, NULL, 0} }; -#define NMC_FIELDS_DEV_LIST_GENERAL_ALL "NAME,DEVICE,TYPE,VENDOR,PRODUCT,DRIVER,HWADDR,STATE,REASON,UDI,IP-IFACE,NM-MANAGED,FIRMWARE-MISSING,CONNECTION" +#define NMC_FIELDS_DEV_LIST_GENERAL_ALL "NAME,DEVICE,TYPE,VENDOR,PRODUCT,DRIVER,DRIVER-VERSION,FIRMWARE-VERSION,HWADDR,STATE,REASON,UDI,IP-IFACE,NM-MANAGED,AUTOCONNECT,FIRMWARE-MISSING,CONNECTION" #define NMC_FIELDS_DEV_LIST_GENERAL_COMMON "NAME,DEVICE,TYPE,VENDOR,PRODUCT,DRIVER,HWADDR,STATE" /* Available fields for 'dev list' - CAPABILITIES part */ @@ -208,6 +214,8 @@ static NmcOutputField nmc_fields_dev_wimax_list[] = { /* glib main loop variable - defined in nmcli.c */ extern GMainLoop *loop; +static guint progress_id = 0; /* ID of event source for displaying progress */ + static void usage (void) { @@ -222,6 +230,8 @@ usage (void) " list [iface <iface>]\n" " disconnect iface <iface> [--nowait] [--timeout <timeout>]\n" " wifi [list [iface <iface>] [bssid <BSSID>]]\n" + " wifi connect <(B)SSID> [password <password>] [wep-key-type key|phrase] [iface <iface>] [bssid <BSSID>] [name <name>]\n" + " [--private] [--nowait] [--timeout <timeout>]\n" #if WITH_WIMAX " wimax [list [iface <iface>] [nsp <name>]]\n\n" #endif @@ -232,201 +242,12 @@ usage (void) static void quit (void) { - g_main_loop_quit (loop); /* quit main loop */ -} - -static const char * -device_state_to_string (NMDeviceState state) -{ - switch (state) { - case NM_DEVICE_STATE_UNMANAGED: - return _("unmanaged"); - case NM_DEVICE_STATE_UNAVAILABLE: - return _("unavailable"); - case NM_DEVICE_STATE_DISCONNECTED: - return _("disconnected"); - case NM_DEVICE_STATE_PREPARE: - return _("connecting (prepare)"); - case NM_DEVICE_STATE_CONFIG: - return _("connecting (configuring)"); - case NM_DEVICE_STATE_NEED_AUTH: - return _("connecting (need authentication)"); - case NM_DEVICE_STATE_IP_CONFIG: - return _("connecting (getting IP configuration)"); - case NM_DEVICE_STATE_IP_CHECK: - return _("connecting (checking IP connectivity)"); - case NM_DEVICE_STATE_SECONDARIES: - return _("connecting (starting secondary connections)"); - case NM_DEVICE_STATE_ACTIVATED: - return _("connected"); - case NM_DEVICE_STATE_DEACTIVATING: - return _("deactivating"); - case NM_DEVICE_STATE_FAILED: - return _("connection failed"); - default: - return _("unknown"); + if (progress_id) { + g_source_remove (progress_id); + nmc_terminal_erase_line (); } -} - -static const char * -device_reason_to_string (NMDeviceStateReason reason) -{ - switch (reason) { - case NM_DEVICE_STATE_REASON_NONE: - return _("No reason given"); - - case NM_DEVICE_STATE_REASON_UNKNOWN: - return _("Unknown error"); - - case NM_DEVICE_STATE_REASON_NOW_MANAGED: - return _("Device is now managed"); - - case NM_DEVICE_STATE_REASON_NOW_UNMANAGED: - return _("Device is now unmanaged"); - - case NM_DEVICE_STATE_REASON_CONFIG_FAILED: - return _("The device could not be readied for configuration"); - - case NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE: - return _("IP configuration could not be reserved (no available address, timeout, etc)"); - - case NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED: - return _("The IP configuration is no longer valid"); - - case NM_DEVICE_STATE_REASON_NO_SECRETS: - return _("Secrets were required, but not provided"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT: - return _("802.1X supplicant disconnected"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED: - return _("802.1X supplicant configuration failed"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED: - return _("802.1X supplicant failed"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT: - return _("802.1X supplicant took too long to authenticate"); - - case NM_DEVICE_STATE_REASON_PPP_START_FAILED: - return _("PPP service failed to start"); - - case NM_DEVICE_STATE_REASON_PPP_DISCONNECT: - return _("PPP service disconnected"); - - case NM_DEVICE_STATE_REASON_PPP_FAILED: - return _("PPP failed"); - - case NM_DEVICE_STATE_REASON_DHCP_START_FAILED: - return _("DHCP client failed to start"); - - case NM_DEVICE_STATE_REASON_DHCP_ERROR: - return _("DHCP client error"); - - case NM_DEVICE_STATE_REASON_DHCP_FAILED: - return _("DHCP client failed"); - - case NM_DEVICE_STATE_REASON_SHARED_START_FAILED: - return _("Shared connection service failed to start"); - - case NM_DEVICE_STATE_REASON_SHARED_FAILED: - return _("Shared connection service failed"); - - case NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED: - return _("AutoIP service failed to start"); - - case NM_DEVICE_STATE_REASON_AUTOIP_ERROR: - return _("AutoIP service error"); - - case NM_DEVICE_STATE_REASON_AUTOIP_FAILED: - return _("AutoIP service failed"); - - case NM_DEVICE_STATE_REASON_MODEM_BUSY: - return _("The line is busy"); - - case NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE: - return _("No dial tone"); - - case NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER: - return _("No carrier could be established"); - case NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT: - return _("The dialing request timed out"); - - case NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED: - return _("The dialing attempt failed"); - - case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: - return _("Modem initialization failed"); - - case NM_DEVICE_STATE_REASON_GSM_APN_FAILED: - return _("Failed to select the specified APN"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING: - return _("Not searching for networks"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED: - return _("Network registration denied"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT: - return _("Network registration timed out"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED: - return _("Failed to register with the requested network"); - - case NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED: - return _("PIN check failed"); - - case NM_DEVICE_STATE_REASON_FIRMWARE_MISSING: - return _("Necessary firmware for the device may be missing"); - - case NM_DEVICE_STATE_REASON_REMOVED: - return _("The device was removed"); - - case NM_DEVICE_STATE_REASON_SLEEPING: - return _("NetworkManager went to sleep"); - - case NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: - return _("The device's active connection disappeared"); - - case NM_DEVICE_STATE_REASON_USER_REQUESTED: - return _("Device disconnected by user or client"); - - case NM_DEVICE_STATE_REASON_CARRIER: - return _("Carrier/link changed"); - - case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: - return _("The device's existing connection was assumed"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE: - return _("The supplicant is now available"); - - case NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND: - return _("The modem could not be found"); - - case NM_DEVICE_STATE_REASON_BT_FAILED: - return _("The Bluetooth connection failed or timed out"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: - return _("GSM Modem's SIM card not inserted"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: - return _("GSM Modem's SIM PIN required"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: - return _("GSM Modem's SIM PUK required"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: - return _("GSM Modem's SIM wrong"); - - case NM_DEVICE_STATE_REASON_INFINIBAND_MODE: - return _("InfiniBand device does not support connected mode"); - - case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: - return _("A dependency of the connection failed"); - default: - return _("Unknown"); - } + g_main_loop_quit (loop); /* quit main loop */ } /* Convert device type to string. Use setting names strings to match with @@ -440,6 +261,8 @@ device_type_to_string (NMDevice *device) switch (nm_device_get_device_type (device)) { case NM_DEVICE_TYPE_ETHERNET: return NM_SETTING_WIRED_SETTING_NAME; + case NM_DEVICE_TYPE_ADSL: + return NM_SETTING_ADSL_SETTING_NAME; case NM_DEVICE_TYPE_WIFI: return NM_SETTING_WIRELESS_SETTING_NAME; case NM_DEVICE_TYPE_MODEM: @@ -505,7 +328,7 @@ ap_wpa_rsn_flags_to_string (NM80211ApSecurityFlags flags) i = 0; while (flags_str[i]) - g_free (flags_str[i++]); + g_free (flags_str[i++]); return ret_str; } @@ -745,8 +568,8 @@ show_device_info (gpointer data, gpointer user_data) else if (NM_IS_DEVICE_VLAN (device)) hwaddr = nm_device_vlan_get_hw_address (NM_DEVICE_VLAN (device)); - state_str = g_strdup_printf ("%d (%s)", state, device_state_to_string (state)); - reason_str = g_strdup_printf ("%d (%s)", reason, device_reason_to_string (reason)); + state_str = g_strdup_printf ("%d (%s)", state, nmc_device_state_to_string (state)); + reason_str = g_strdup_printf ("%d (%s)", reason, nmc_device_reason_to_string (reason)); nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[0].name; /* "GENERAL"*/ nmc->allowed_fields[1].value = nm_device_get_iface (device); @@ -754,14 +577,17 @@ show_device_info (gpointer data, gpointer user_data) nmc->allowed_fields[3].value = nm_device_get_vendor (device); nmc->allowed_fields[4].value = nm_device_get_product (device); nmc->allowed_fields[5].value = nm_device_get_driver (device) ? nm_device_get_driver (device) : _("(unknown)"); - nmc->allowed_fields[6].value = hwaddr ? hwaddr : _("(unknown)"); - nmc->allowed_fields[7].value = state_str; - nmc->allowed_fields[8].value = reason_str; - nmc->allowed_fields[9].value = nm_device_get_udi (device); - nmc->allowed_fields[10].value = nm_device_get_ip_iface (device); - nmc->allowed_fields[11].value = nm_device_get_managed (device) ? _("yes") : _("no"); - nmc->allowed_fields[12].value = nm_device_get_firmware_missing (device) ? _("yes") : _("no"); - nmc->allowed_fields[13].value = (acon = nm_device_get_active_connection (device)) ? + nmc->allowed_fields[6].value = nm_device_get_driver_version (device); + nmc->allowed_fields[7].value = nm_device_get_firmware_version (device); + nmc->allowed_fields[8].value = hwaddr ? hwaddr : _("(unknown)"); + nmc->allowed_fields[9].value = state_str; + nmc->allowed_fields[10].value = reason_str; + nmc->allowed_fields[11].value = nm_device_get_udi (device); + nmc->allowed_fields[12].value = nm_device_get_ip_iface (device); + nmc->allowed_fields[13].value = nm_device_get_managed (device) ? _("yes") : _("no"); + nmc->allowed_fields[14].value = nm_device_get_autoconnect (device) ? _("yes") : _("no"); + nmc->allowed_fields[15].value = nm_device_get_firmware_missing (device) ? _("yes") : _("no"); + nmc->allowed_fields[16].value = (acon = nm_device_get_active_connection (device)) ? nm_object_get_path (NM_OBJECT (acon)) : _("not connected"); nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX; @@ -975,7 +801,7 @@ show_device_status (NMDevice *device, NmCli *nmc) { nmc->allowed_fields[0].value = nm_device_get_iface (device); nmc->allowed_fields[1].value = device_type_to_string (device); - nmc->allowed_fields[2].value = device_state_to_string (nm_device_get_state (device)); + nmc->allowed_fields[2].value = nmc_device_state_to_string (nm_device_get_state (device)); nmc->allowed_fields[3].value = nm_object_get_path (NM_OBJECT (device)); nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */ @@ -1110,7 +936,7 @@ do_devices_list (NmCli *nmc, int argc, char **argv) device = candidate; } if (!device) { - g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface); + g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto error; } @@ -1151,6 +977,16 @@ timeout_cb (gpointer user_data) return FALSE; } +static gboolean +progress_cb (gpointer user_data) +{ + NMDevice *device = (NMDevice *) user_data; + + nmc_terminal_show_progress (device ? nmc_device_state_to_string (nm_device_get_state (device)) : ""); + + return TRUE; +} + static void disconnect_device_cb (NMDevice *device, GError *error, gpointer user_data) { @@ -1166,10 +1002,13 @@ disconnect_device_cb (NMDevice *device, GError *error, gpointer user_data) quit (); } else { state = nm_device_get_state (device); - printf (_("Device state: %d (%s)\n"), state, device_state_to_string (state)); if (nmc->nowait_flag || state == NM_DEVICE_STATE_DISCONNECTED) { /* Don't want to wait or device already disconnected */ + if (state == NM_DEVICE_STATE_DISCONNECTED && nmc->print_output == NMC_PRINT_PRETTY) { + nmc_terminal_erase_line (); + printf (_("Device '%s' has been disconnected.\n"), nm_device_get_iface (device)); + } quit (); } else { g_signal_connect (device, "notify::state", G_CALLBACK (device_state_cb), nmc); @@ -1273,6 +1112,10 @@ do_device_disconnect (NmCli *nmc, int argc, char **argv) nmc->should_wait = TRUE; nm_device_disconnect (device, disconnect_device_cb, nmc); + /* Start progress indication */ + if (nmc->print_output == NMC_PRINT_PRETTY) + progress_id = g_timeout_add (120, progress_cb, device); + error: return nmc->return_value; } @@ -1399,7 +1242,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) } if (!device) { - g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface); + g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto error; } @@ -1419,7 +1262,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) g_free (bssid_up); } if (!ap) { - g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), bssid_user); + g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), bssid_user); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto error; } @@ -1436,7 +1279,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) show_acces_point_info (device, nmc); } } else { - g_string_printf (nmc->return_text, _("Error: Device '%s' is not a WiFi device."), iface); + g_string_printf (nmc->return_text, _("Error: Device '%s' is not a WiFi device."), iface); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto error; } @@ -1473,7 +1316,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv) } } if (!ap) { - g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), bssid_user); + g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), bssid_user); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto error; } @@ -1490,6 +1333,433 @@ error: return nmc->return_value; } +static void +monitor_device_state_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) +{ + NmCli *nmc = (NmCli *) user_data; + NMDeviceState state; + NMDeviceStateReason reason; + + state = nm_device_get_state_reason (device, &reason); + + if (state == NM_DEVICE_STATE_ACTIVATED) { + if (nmc->print_output == NMC_PRINT_PRETTY) { + NMActiveConnection *active = nm_device_get_active_connection (device); + + nmc_terminal_erase_line (); + printf (_("Connection with UUID '%s' created and activated on device '%s'\n"), + nm_active_connection_get_uuid (active), nm_device_get_iface (device)); + } + quit (); + } else if (state == NM_DEVICE_STATE_FAILED) { + g_string_printf (nmc->return_text, _("Error: Connection activation failed: (%d) %s."), + reason, nmc_device_reason_to_string (reason)); + nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; + quit (); + } +} + +typedef struct { + NmCli *nmc; + NMDevice *device; +} AddAndActivateInfo; + +static void +add_and_activate_cb (NMClient *client, + NMActiveConnection *active, + const char *connection_path, + GError *error, + gpointer user_data) +{ + AddAndActivateInfo *info = (AddAndActivateInfo *) user_data; + NmCli *nmc = info->nmc; + NMDevice *device = info->device; + NMActiveConnectionState state; + + if (error) { + g_string_printf (nmc->return_text, _("Error: Failed to add/activate new connection: (%d) %s"), + error->code, error->message); + nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; + quit (); + } else { + state = nm_active_connection_get_state (active); + + if (state == NM_ACTIVE_CONNECTION_STATE_UNKNOWN) { + g_string_printf (nmc->return_text, _("Error: Failed to add/activate new connection: Unknown error")); + nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; + quit (); + } + + if (nmc->nowait_flag || state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { + /* User doesn't want to wait or already activated */ + if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED && nmc->print_output == NMC_PRINT_PRETTY) { + printf (_("Connection with UUID '%s' created and activated on device '%s'\n"), + nm_active_connection_get_uuid (active), nm_device_get_iface (device)); + } + quit (); + } else { + g_signal_connect (device, "notify::state", G_CALLBACK (monitor_device_state_cb), nmc); + g_timeout_add_seconds (nmc->timeout, timeout_cb, nmc); /* Exit if timeout expires */ + + if (nmc->print_output == NMC_PRINT_PRETTY) + progress_id = g_timeout_add (120, progress_cb, device); + } + } + + g_free (info); +} + +/* + * Find a Wi-Fi device with 'iface' in 'devices' array. If 'iface' is NULL, + * the first Wi-Fi device is returned. 'idx' parameter is updated to the point + * where the function finished so that the function can be called repeatedly + * to get next matching device. + * Returns: found device or NULL + */ +static NMDevice * +find_wifi_device_by_iface (const GPtrArray *devices, const char *iface, int *idx) +{ + NMDevice *device = NULL; + int i; + + for (i = *idx; devices && (i < devices->len); i++) { + NMDevice *candidate = g_ptr_array_index (devices, i); + const char *dev_iface = nm_device_get_iface (candidate); + + if (!NM_IS_DEVICE_WIFI (candidate)) + continue; + + if (iface) { + /* If a iface was specified then use it. */ + if (strcmp (dev_iface, iface) == 0) { + device = candidate; + break; + } + } else { + /* Else return the first Wi-Fi device. */ + device = candidate; + break; + } + } + + *idx = i + 1; + return device; +} + +/* + * Find AP on 'device' according to 'bssid' or 'ssid' parameter. + * Returns: found AP or NULL + */ +static NMAccessPoint * +find_ap_on_device (NMDevice *device, GByteArray *bssid, const char *ssid) +{ + const GPtrArray *aps; + NMAccessPoint *ap = NULL; + int i; + + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL); + g_return_val_if_fail ((bssid && !ssid) || (!bssid && ssid), NULL); + + aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device)); + for (i = 0; aps && (i < aps->len); i++) { + NMAccessPoint *candidate_ap = g_ptr_array_index (aps, i); + + if (ssid) { + /* Parameter is SSID */ + const GByteArray *candidate_ssid = nm_access_point_get_ssid (candidate_ap); + char *ssid_tmp = nm_utils_ssid_to_utf8 (candidate_ssid); + + /* Compare SSIDs */ + if (strcmp (ssid, ssid_tmp) == 0) { + ap = candidate_ap; + g_free (ssid_tmp); + break; + } + g_free (ssid_tmp); + } else if (bssid) { + /* Parameter is BSSID */ + const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap); + char *bssid_up = nm_utils_hwaddr_ntoa (bssid->data, ARPHRD_ETHER); + + /* Compare BSSIDs */ + if (strcmp (bssid_up, candidate_bssid) == 0) { + ap = candidate_ap; + g_free (bssid_up); + break; + } + g_free (bssid_up); + } + } + + return ap; +} + +static NMCResultCode +do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv) +{ + NMDevice *device = NULL; + NMAccessPoint *ap = NULL; + NMConnection *connection = NULL; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + AddAndActivateInfo *info; + const char *param_user = NULL; + const char *iface = NULL; + const char *bssid = NULL; + const char *password = NULL; + const char *con_name = NULL; + gboolean private = FALSE; + gboolean wait = TRUE; + gboolean wep_passphrase = FALSE; + GByteArray *bssid1_arr = NULL; + GByteArray *bssid2_arr = NULL; + const GPtrArray *devices; + int devices_idx; + GError *error = NULL; + + /* Default timeout for waiting for operation completion */ + nmc->timeout = 90; + + /* Get the first compulsory argument (SSID or BSSID) */ + if (argc > 0) { + param_user = *argv; + bssid1_arr = nm_utils_hwaddr_atoba (param_user, ARPHRD_ETHER); + + argc--; + argv++; + } else { + g_string_printf (nmc->return_text, _("Error: SSID or BSSID are missing.")); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + + /* Get the rest of the parameters */ + while (argc > 0) { + if (strcmp (*argv, "iface") == 0) { + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + iface = *argv; + } else if (strcmp (*argv, "bssid") == 0) { + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + bssid = *argv; + bssid2_arr = nm_utils_hwaddr_atoba (bssid, ARPHRD_ETHER); + if (!bssid2_arr) { + g_string_printf (nmc->return_text, _("Error: bssid argument value '%s' is not a valid BSSID."), + bssid); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + } else if (strcmp (*argv, "password") == 0) { + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + password = *argv; + } else if (strcmp (*argv, "wep-key-type") == 0) { + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + if (strcmp (*argv, "key") == 0) + wep_passphrase = FALSE; + else if (strcmp (*argv, "phrase") == 0) + wep_passphrase = TRUE; + else { + g_string_printf (nmc->return_text, + _("Error: wep-key-type argument value '%s' is invalid, use 'key' or 'phrase'."), + *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + } else if (strcmp (*argv, "name") == 0) { + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + con_name = *argv; + } else if (strcmp (*argv, "--private") == 0) { + private = TRUE; + } 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); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + 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); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + } else { + fprintf (stderr, _("Unknown parameter: %s\n"), *argv); + } + + argc--; + argv++; + } + + /* Verify SSID/BSSID parameters */ + if (bssid1_arr && bssid2_arr && memcmp (bssid1_arr->data, bssid2_arr->data, ETH_ALEN)) { + g_string_printf (nmc->return_text, _("Error: BSSID to connect to (%s) differs from bssid argument (%s)."), + param_user, bssid); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + if (!bssid1_arr && strlen (param_user) > 32) { + g_string_printf (nmc->return_text, _("Error: Parameter '%s' is neither SSID nor BSSID."), param_user); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + + if (!nmc_is_nm_running (nmc, &error)) { + if (error) { + g_string_printf (nmc->return_text, _("Error: Can't find out if NetworkManager is running: %s."), error->message); + nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + g_error_free (error); + } else { + g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); + nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; + } + goto error; + } + + if (!nmc_versions_match (nmc)) + goto error; + + nmc->get_client (nmc); + devices = nm_client_get_devices (nmc->client); + + /* Find a device to activate the connection on */ + devices_idx = 0; + device = find_wifi_device_by_iface (devices, iface, &devices_idx); + + if (!device) { + if (iface) + g_string_printf (nmc->return_text, _("Error: Device '%s' is not a Wi-Fi device."), iface); + else + g_string_printf (nmc->return_text, _("Error: No Wi-Fi device found.")); + nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + goto error; + } + + /* Find an AP to connect to */ + ap = find_ap_on_device (device, bssid1_arr, bssid1_arr ? NULL : param_user); + if (!ap && !iface) { + /* AP not found. iface was not specified, so try finding the AP on another device. */ + while ((device = find_wifi_device_by_iface (devices, NULL, &devices_idx)) != NULL) { + ap = find_ap_on_device (device, bssid1_arr, bssid1_arr ? NULL : param_user); + if (ap) + break; + } + } + + if (!ap) { + if (!bssid1_arr) + g_string_printf (nmc->return_text, _("Error: No network with SSID '%s' found."), param_user); + else + g_string_printf (nmc->return_text, _("Error: No access point with BSSID '%s' found."), param_user); + nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + goto error; + } + + /* If there are some connection data from user, create a connection and + * fill them into proper settings. */ + if (con_name || private || bssid2_arr || password) + connection = nm_connection_new (); + + if (con_name || private) { + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + /* Set user provided connection name */ + if (con_name) + g_object_set (s_con, NM_SETTING_CONNECTION_ID, con_name, NULL); + + /* Connection will only be visible to this user when '--private' is specified */ + if (private) + nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL); + } + if (bssid2_arr) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + /* 'bssid' parameter is used to restrict the conenction only to the BSSID */ + g_object_set (s_wifi, NM_SETTING_WIRELESS_BSSID, bssid2_arr, NULL); + } + if (password) { + NM80211ApFlags flags = nm_access_point_get_flags (ap); + NM80211ApSecurityFlags wpa_flags = nm_access_point_get_wpa_flags (ap); + NM80211ApSecurityFlags rsn_flags = nm_access_point_get_rsn_flags (ap); + + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + /* Set password for WEP or WPA-PSK. */ + if (flags & NM_802_11_AP_FLAGS_PRIVACY) { + if (wpa_flags == NM_802_11_AP_SEC_NONE && rsn_flags == NM_802_11_AP_SEC_NONE) { + /* WEP */ + nm_setting_wireless_security_set_wep_key (s_wsec, 0, password); + g_object_set (G_OBJECT (s_wsec), + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + wep_passphrase ? NM_WEP_KEY_TYPE_PASSPHRASE: NM_WEP_KEY_TYPE_KEY, + NULL); + } else if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) + && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { + /* WPA PSK */ + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_PSK, password, NULL); + } + } + // FIXME: WPA-Enterprise is not supported yet. + // We are not able to determine and fill all the parameters for + // 802.1X authentication automatically without user providing + // the data. Adding nmcli options for the 8021x setting would + // clutter the command. However, that could be solved later by + // implementing add/edit connections support for nmcli. + } + + /* nowait_flag indicates user input. should_wait says whether quit in start(). + * We have to delay exit after add_and_activate_cb() is called, even if + * the user doesn't want to wait, in order to give NM time to check our + * permissions. */ + nmc->nowait_flag = !wait; + nmc->should_wait = TRUE; + + info = g_malloc0 (sizeof (AddAndActivateInfo)); + info->nmc = nmc; + info->device = device; + + nm_client_add_and_activate_connection (nmc->client, + connection, + device, + nm_object_get_path (NM_OBJECT (ap)), + add_and_activate_cb, + info); + +error: + if (bssid1_arr) + g_byte_array_free (bssid1_arr, TRUE); + if (bssid2_arr) + g_byte_array_free (bssid2_arr, TRUE); + + return nmc->return_value; +} + static NMCResultCode do_device_wifi (NmCli *nmc, int argc, char **argv) { @@ -1498,8 +1768,9 @@ do_device_wifi (NmCli *nmc, int argc, char **argv) else if (argc > 0) { if (matches (*argv, "list") == 0) { nmc->return_value = do_device_wifi_list (nmc, argc-1, argv+1); - } - else { + } else if (matches (*argv, "connect") == 0) { + nmc->return_value = do_device_wifi_connect_network (nmc, argc-1, argv+1); + } else { g_string_printf (nmc->return_text, _("Error: 'dev wifi' command '%s' is not valid."), *argv); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; } @@ -1618,7 +1889,7 @@ do_device_wimax_list (NmCli *nmc, int argc, char **argv) } if (!device) { - g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface); + g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto error; } @@ -1638,7 +1909,7 @@ do_device_wimax_list (NmCli *nmc, int argc, char **argv) g_free (nsp_up); } if (!nsp) { - g_string_printf (nmc->return_text, _("Error: NSP with name '%s' not found."), nsp_user); + g_string_printf (nmc->return_text, _("Error: NSP with name '%s' not found."), nsp_user); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto error; } @@ -1649,7 +1920,7 @@ do_device_wimax_list (NmCli *nmc, int argc, char **argv) show_nsp_info (device, nmc); } } else { - g_string_printf (nmc->return_text, _("Error: Device '%s' is not a WiMAX device."), iface); + g_string_printf (nmc->return_text, _("Error: Device '%s' is not a WiMAX device."), iface); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto error; } @@ -1680,7 +1951,7 @@ do_device_wimax_list (NmCli *nmc, int argc, char **argv) } } if (!nsp) { - g_string_printf (nmc->return_text, _("Error: Access point with nsp '%s' not found."), nsp_user); + g_string_printf (nmc->return_text, _("Error: Access point with nsp '%s' not found."), nsp_user); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto error; } diff --git a/cli/src/network-manager.c b/cli/src/network-manager.c index c23c9fae..927eadd1 100644 --- a/cli/src/network-manager.c +++ b/cli/src/network-manager.c @@ -14,7 +14,7 @@ * 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 - 2011 Red Hat, Inc. + * (C) Copyright 2010 - 2012 Red Hat, Inc. */ #include "config.h" @@ -57,6 +57,16 @@ static NmcOutputField nmc_fields_nm_status[] = { #define NMC_FIELDS_NM_WWAN "WWAN" #define NMC_FIELDS_NM_WIMAX "WIMAX" +/* Available fields for 'nm permissions' */ +static NmcOutputField nmc_fields_nm_permissions[] = { + {"PERMISSION", N_("PERMISSION"), 57, NULL, 0}, /* 0 */ + {"VALUE", N_("VALUE"), 10, NULL, 0}, /* 1 */ + {NULL, NULL, 0, NULL, 0} +}; +#define NMC_FIELDS_NM_PERMISSIONS_ALL "PERMISSION,VALUE" +#define NMC_FIELDS_NM_PERMISSIONS_COMMON "PERMISSION,VALUE" + + /* glib main loop variable - defined in nmcli.c */ extern GMainLoop *loop; @@ -66,18 +76,20 @@ usage (void) fprintf (stderr, _("Usage: nmcli nm { COMMAND | help }\n\n" #if WITH_WIMAX - " COMMAND := { status | enable | sleep | wifi | wwan | wimax }\n\n" + " COMMAND := { status | permissions | enable | sleep | wifi | wwan | wimax }\n\n" #else - " COMMAND := { status | enable | sleep | wifi | wwan }\n\n" + " COMMAND := { status | permissions | enable | sleep | wifi | wwan }\n\n" #endif " status\n" + " permissions\n" " enable [true|false]\n" " sleep [true|false]\n" " wifi [on|off]\n" " wwan [on|off]\n" #if WITH_WIMAX - " wimax [on|off]\n\n" + " wimax [on|off]\n" #endif + "\n" )); } @@ -135,7 +147,7 @@ show_nm_status (NmCli *nmc) fields_str = fields_common; else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0) fields_str = fields_all; - else + else fields_str = nmc->required_fields; nmc->allowed_fields = nmc_fields_nm_status; @@ -203,6 +215,129 @@ error: return nmc->return_value; } +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX "org.freedesktop.NetworkManager.enable-disable-wimax" +#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" +#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" +#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected" +#define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME "org.freedesktop.NetworkManager.settings.modify.hostname" + +static const char * +permission_to_string (NMClientPermission perm) +{ + switch (perm) { + case NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK: + return NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK; + case NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI: + return NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI; + case NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN: + return NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN; + case NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX: + return NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX; + case NM_CLIENT_PERMISSION_SLEEP_WAKE: + return NM_AUTH_PERMISSION_SLEEP_WAKE; + case NM_CLIENT_PERMISSION_NETWORK_CONTROL: + return NM_AUTH_PERMISSION_NETWORK_CONTROL; + case NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED: + return NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED; + case NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN: + return NM_AUTH_PERMISSION_WIFI_SHARE_OPEN; + case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM: + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN: + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + case NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME: + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME; + default: + return _("unknown"); + } +} + +static const char * +permission_result_to_string (NMClientPermissionResult perm_result) +{ + + switch (perm_result) { + case NM_CLIENT_PERMISSION_RESULT_YES: + return _("yes"); + case NM_CLIENT_PERMISSION_RESULT_NO: + return _("no"); + case NM_CLIENT_PERMISSION_RESULT_AUTH: + return _("auth"); + default: + return _("unknown"); + } +} + +static NMCResultCode +show_nm_permissions (NmCli *nmc) +{ + NMClientPermission perm; + GError *error = NULL; + const char *fields_str; + const char *fields_all = NMC_FIELDS_NM_PERMISSIONS_ALL; + const char *fields_common = NMC_FIELDS_NM_PERMISSIONS_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; + + 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; + + nmc->allowed_fields = nmc_fields_nm_permissions; + nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error); + + if (error) { + if (error->code == 0) + g_string_printf (nmc->return_text, _("Error: 'nm permissions': %s"), error->message); + else + g_string_printf (nmc->return_text, _("Error: 'nm permissions': %s; allowed fields: %s"), error->message, NMC_FIELDS_NM_PERMISSIONS_ALL); + g_error_free (error); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + return nmc->return_value; + } + + if (!nmc_is_nm_running (nmc, &error)) { + if (error) { + g_string_printf (nmc->return_text, _("Error: Can't find out if NetworkManager is running: %s."), error->message); + nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + g_error_free (error); + } else { + g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); + nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; + } + goto error; + } + + nmc->get_client (nmc); /* create NMClient */ + + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES; + nmc->print_fields.header_name = _("NetworkManager permissions"); + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ + + for (perm = NM_CLIENT_PERMISSION_NONE + 1; perm <= NM_CLIENT_PERMISSION_LAST; perm++) { + NMClientPermissionResult perm_result = nm_client_get_permission_result (nmc->client, perm); + + set_val_str (nmc->allowed_fields, 0, permission_to_string (perm)); + set_val_str (nmc->allowed_fields, 1, permission_result_to_string (perm_result)); + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag; + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */ + } + return NMC_RESULT_SUCCESS; + +error: + return nmc->return_value; +} + /* libnm-glib doesn't provide API fro Sleep method - implement D-Bus call ourselves */ static void networking_set_sleep (NmCli *nmc, gboolean in_sleep) { @@ -214,8 +349,8 @@ static void networking_set_sleep (NmCli *nmc, gboolean in_sleep) if (!connection) { g_string_printf (nmc->return_text, _("Error: Couldn't connect to system bus: %s"), err->message); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; - g_error_free (err); - goto gone; + g_error_free (err); + goto gone; } proxy = dbus_g_proxy_new_for_name (connection, @@ -226,8 +361,8 @@ static void networking_set_sleep (NmCli *nmc, gboolean in_sleep) g_string_printf (nmc->return_text, _("Error: Couldn't create D-Bus object proxy.")); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; goto gone; - } - + } + if (!dbus_g_proxy_call (proxy, "Sleep", &err, G_TYPE_BOOLEAN, in_sleep, G_TYPE_INVALID, G_TYPE_INVALID)) { g_string_printf (nmc->return_text, _("Error in sleep: %s"), err->message); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; @@ -267,6 +402,11 @@ do_network_manager (NmCli *nmc, int argc, char **argv) goto opt_error; nmc->return_value = show_nm_status (nmc); } + else if (matches (*argv, "permissions") == 0) { + if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error)) + goto opt_error; + nmc->return_value = show_nm_permissions (nmc); + } else if (matches (*argv, "enable") == 0) { if (next_arg (&argc, &argv) != 0) { /* no argument, show current state of networking */ diff --git a/cli/src/settings.c b/cli/src/settings.c index bf422920..e67bd8f0 100644 --- a/cli/src/settings.c +++ b/cli/src/settings.c @@ -348,6 +348,26 @@ static NmcOutputField nmc_fields_setting_pppoe[] = { NM_SETTING_PPPOE_PASSWORD #define NMC_FIELDS_SETTING_PPPOE_COMMON NMC_FIELDS_SETTING_PPP_ALL +/* Available fields for NM_SETTING_ADSL_SETTING_NAME */ +static NmcOutputField nmc_fields_setting_adsl[] = { + SETTING_FIELD ("name", 10), /* 0 */ + SETTING_FIELD (NM_SETTING_ADSL_USERNAME, 15), /* 1 */ + SETTING_FIELD (NM_SETTING_ADSL_PASSWORD, 15), /* 2 */ + SETTING_FIELD (NM_SETTING_ADSL_VPI, 10), /* 3 */ + SETTING_FIELD (NM_SETTING_ADSL_VCI, 10), /* 4 */ + SETTING_FIELD (NM_SETTING_ADSL_ENCAPSULATION, 10), /* 5 */ + SETTING_FIELD (NM_SETTING_ADSL_PROTOCOL, 10), /* 6 */ + {NULL, NULL, 0, NULL, 0} +}; +#define NMC_FIELDS_SETTING_ADSL_ALL "name"","\ + NM_SETTING_ADSL_USERNAME","\ + NM_SETTING_ADSL_PASSWORD","\ + NM_SETTING_ADSL_VPI","\ + NM_SETTING_ADSL_VCI","\ + NM_SETTING_ADSL_ENCAPSULATION","\ + NM_SETTING_ADSL_PROTOCOL +#define NMC_FIELDS_SETTING_ADSL_COMMON NMC_FIELDS_SETTING_ADSL_ALL + /* Available fields for NM_SETTING_GSM_SETTING_NAME */ static NmcOutputField nmc_fields_setting_gsm[] = { SETTING_FIELD ("name", 10), /* 0 */ @@ -607,10 +627,11 @@ vlan_priorities_to_string (NMSettingVlan *s_vlan, NMVlanPriorityMap map) for (i = 0; i < nm_setting_vlan_get_num_priorities (s_vlan, map); i++) { guint32 from, to; - nm_setting_vlan_get_priority (s_vlan, map, i, &from, &to); - g_string_append_printf (priorities, "%d:%d,", from, to); + if (nm_setting_vlan_get_priority (s_vlan, map, i, &from, &to)) + g_string_append_printf (priorities, "%d:%d,", from, to); } - g_string_truncate (priorities, priorities->len-1); /* chop off trailing ',' */ + if (priorities->len) + g_string_truncate (priorities, priorities->len-1); /* chop off trailing ',' */ return g_string_free (priorities, FALSE); } @@ -917,11 +938,11 @@ setting_wireless_details (NMSettingWireless *s_wireless, NmCli *nmc) nmc->allowed_fields[2].value = nm_setting_wireless_get_mode (s_wireless); nmc->allowed_fields[3].value = nm_setting_wireless_get_band (s_wireless); nmc->allowed_fields[4].value = channel_str; - nmc->allowed_fields[5].value = bssid_str ? bssid_str : _("not set"); + nmc->allowed_fields[5].value = bssid_str; nmc->allowed_fields[6].value = rate_str; nmc->allowed_fields[7].value = tx_power_str; - nmc->allowed_fields[8].value = device_mac_str ? device_mac_str : _("not set"); - nmc->allowed_fields[9].value = cloned_mac_str ? cloned_mac_str : _("not set"); + nmc->allowed_fields[8].value = device_mac_str; + nmc->allowed_fields[9].value = cloned_mac_str; nmc->allowed_fields[10].value = mac_blacklist->str; nmc->allowed_fields[11].value = strcmp (mtu_str, "0") ? mtu_str : _("auto"); nmc->allowed_fields[12].value = seen_bssids->str; @@ -1715,3 +1736,34 @@ setting_vlan_details (NMSettingVlan *s_vlan, NmCli *nmc) return TRUE; } +gboolean +setting_adsl_details (NMSettingAdsl *s_adsl, NmCli *nmc) +{ + 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; + + g_return_val_if_fail (NM_IS_SETTING_ADSL (s_adsl), FALSE); + + nmc->allowed_fields = nmc_fields_setting_adsl; + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_ADSL_ALL, nmc->allowed_fields, NULL); + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES; + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print field names */ + + nmc->allowed_fields[0].value = NM_SETTING_ADSL_SETTING_NAME; + nmc->allowed_fields[1].value = nm_setting_adsl_get_username (s_adsl); + nmc->allowed_fields[2].value = nm_setting_adsl_get_password (s_adsl); + nmc->allowed_fields[3].value = g_strdup_printf ("%d", nm_setting_adsl_get_vpi (s_adsl)); + nmc->allowed_fields[4].value = g_strdup_printf ("%d", nm_setting_adsl_get_vci (s_adsl)); + nmc->allowed_fields[5].value = nm_setting_adsl_get_encapsulation (s_adsl); + nmc->allowed_fields[6].value = nm_setting_adsl_get_protocol (s_adsl); + + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX; + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */ + + g_free ((char*) nmc->allowed_fields[3].value); + g_free ((char*) nmc->allowed_fields[4].value); + + return TRUE; +} + diff --git a/cli/src/settings.h b/cli/src/settings.h index 964d6648..3309bd0a 100644 --- a/cli/src/settings.h +++ b/cli/src/settings.h @@ -22,6 +22,7 @@ #include <nm-setting-connection.h> #include <nm-setting-wired.h> +#include <nm-setting-adsl.h> #include <nm-setting-8021x.h> #include <nm-setting-wireless.h> #include <nm-setting-wireless-security.h> @@ -63,5 +64,6 @@ gboolean setting_wimax_details (NMSettingWimax *s_wimax, NmCli *nmc); gboolean setting_infiniband_details (NMSettingInfiniband *s_infiniband, NmCli *nmc); gboolean setting_bond_details (NMSettingBond *s_bond, NmCli *nmc); gboolean setting_vlan_details (NMSettingVlan *s_vlan, NmCli *nmc); +gboolean setting_adsl_details (NMSettingAdsl *s_adsl, NmCli *nmc); #endif /* NMC_SETTINGS_H */ diff --git a/cli/src/utils.c b/cli/src/utils.c index 24bc998c..8030d5e1 100644 --- a/cli/src/utils.c +++ b/cli/src/utils.c @@ -69,7 +69,7 @@ ssid_to_printable (const char *str, gsize len) int i; if (str == NULL || len == 0) - return NULL; + return NULL; if (g_utf8_validate (str, len, NULL)) return g_strdup_printf ("'%.*s'", (int) len, str); @@ -137,6 +137,38 @@ nmc_ip6_address_as_string (const struct in6_addr *ip, GError **error) } /* + * Erase terminal line using ANSI escape sequences. + * It prints <ESC>[2K sequence to erase the line and then \r to return back + * to the beginning of the line. + * + * http://www.termsys.demon.co.uk/vtansi.htm + */ +void +nmc_terminal_erase_line (void) +{ + printf ("\33[2K\r"); + fflush (stdout); +} + +/* + * Print animated progress for an operation. + * Repeated calls of the function will show rotating slash in terminal followed + * by the string passed in 'str' argument. + */ +void +nmc_terminal_show_progress (const char *str) +{ + static int idx = 0; + const char slashes[4] = {'|', '/', '-', '\\'}; + + nmc_terminal_erase_line (); + printf ("%c %s", slashes[idx++], str ? str : ""); + fflush (stdout); + if (idx == 4) + idx = 0; +} + +/* * Find out how many columns an UTF-8 string occupies on the screen */ int @@ -244,7 +276,7 @@ print_fields (const NmcPrintFields fields, const NmcOutputField field_values[]) int table_width = 0; char *line = NULL; char *indent_str; - const char *not_set_str = _("not set"); + const char *not_set_str = "--"; int i; gboolean multiline = fields.flags & NMC_PF_FLAG_MULTILINE; gboolean terse = fields.flags & NMC_PF_FLAG_TERSE; @@ -439,7 +471,7 @@ nmc_is_nm_running (NmCli *nmc, GError **error) g_set_error (error, 0, 0, "%s", nmc->return_text->str); goto done; } - + if (!org_freedesktop_DBus_name_has_owner (proxy, NM_DBUS_SERVICE, &has_owner, &err)) { g_string_printf (nmc->return_text, _("Error: NameHasOwner request failed: %s"), (err && err->message) ? err->message : _("(unknown)")); diff --git a/cli/src/utils.h b/cli/src/utils.h index a22ae144..81ce1633 100644 --- a/cli/src/utils.h +++ b/cli/src/utils.h @@ -30,6 +30,8 @@ int next_arg (int *argc, char ***argv); char *ssid_to_printable (const char *str, gsize len); char *nmc_ip4_address_as_string (guint32 ip, GError **error); char *nmc_ip6_address_as_string (const struct in6_addr *ip, GError **error); +void nmc_terminal_erase_line (void); +void nmc_terminal_show_progress (const char *str); int nmc_string_screen_width (const char *start, const char *end); void set_val_str (NmcOutputField fields_array[], guint32 index, const char *value); void set_val_arr (NmcOutputField fields_array[], guint32 index, const char **value); |