summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/agent.c79
-rw-r--r--client/commands.c1233
-rw-r--r--client/commands.h4
-rw-r--r--client/dbus_helpers.c98
-rw-r--r--client/dbus_helpers.h24
-rw-r--r--client/input.c76
-rw-r--r--client/input.h4
-rw-r--r--client/peers.c122
-rw-r--r--client/peers.h38
-rw-r--r--client/services.c19
-rw-r--r--client/vpnconnections.c6
11 files changed, 1508 insertions, 195 deletions
diff --git a/client/agent.c b/client/agent.c
index 12b0a984..baa0a87b 100644
--- a/client/agent.c
+++ b/client/agent.c
@@ -95,6 +95,11 @@ static struct agent_data agent_request = {
static struct agent_input_data vpnagent_input_handler[] = {
{ "OpenConnect.Cookie", false, "OpenConnect Cookie? ",
request_input_string_return },
+ { "OpenConnect.ServerCert", false,
+ "OpenConnect server certificate hash? ",
+ request_input_string_return },
+ { "OpenConnect.VPNHost", false, "OpenConnect VPN server? ",
+ request_input_string_return },
{ "Username", false, "VPN username? ", request_input_string_return },
{ "Password", false, "VPN password? ", request_input_string_return },
{ },
@@ -109,7 +114,7 @@ static int confirm_input(char *input)
{
int i;
- if (input == NULL)
+ if (!input)
return -1;
for (i = 0; input[i] != '\0'; i++)
@@ -130,7 +135,7 @@ static int confirm_input(char *input)
static char *strip_path(char *path)
{
char *name = strrchr(path, '/');
- if (name != NULL)
+ if (name)
name++;
else
name = path;
@@ -142,7 +147,7 @@ static char *agent_path(void)
{
static char *path = NULL;
- if (path == NULL)
+ if (!path)
path = g_strdup_printf("/net/connman/connmanctl%d", getpid());
return path;
@@ -150,12 +155,12 @@ static char *agent_path(void)
static void pending_message_remove(struct agent_data *request)
{
- if (request->message != NULL) {
+ if (request->message) {
dbus_message_unref(request->message);
request->message = NULL;
}
- if (request->reply != NULL) {
+ if (request->reply) {
dbus_message_unref(request->reply);
request->reply = NULL;
}
@@ -178,12 +183,12 @@ static void pending_command_complete(char *message)
else
__connmanctl_agent_mode("", NULL, NULL);
- if (agent_request.message != NULL)
+ if (agent_request.message)
next_request = &agent_request;
- else if (vpn_agent_request.message != NULL)
+ else if (vpn_agent_request.message)
next_request = &vpn_agent_request;
- if (next_request == NULL)
+ if (!next_request)
return;
pending_message = next_request->message;
@@ -199,8 +204,8 @@ static void pending_command_complete(char *message)
static bool handle_message(DBusMessage *message, struct agent_data *request,
GDBusMethodFunction function)
{
- if (agent_request.pending_function == NULL &&
- vpn_agent_request.pending_function == NULL)
+ if (!agent_request.pending_function &&
+ !vpn_agent_request.pending_function)
return true;
request->message = dbus_message_ref(message);
@@ -367,9 +372,9 @@ static void request_input_next(struct agent_data *request)
{
int i;
- for (i = 0; request->input[i].attribute != NULL; i++) {
+ for (i = 0; request->input[i].attribute; i++) {
if (request->input[i].requested == true) {
- if(request->input[i].func != NULL)
+ if (request->input[i].func)
__connmanctl_agent_mode(request->input[i].prompt,
request->input[i].func,
request);
@@ -403,7 +408,7 @@ static void request_input_ssid_return(char *input,
struct agent_data *request = user_data;
int len = 0;
- if (input != NULL)
+ if (input)
len = strlen(input);
if (len > 0 && len <= 32) {
@@ -422,7 +427,7 @@ static void request_input_passphrase_return(char *input, void *user_data)
/* TBD passphrase length checking */
- if (input != NULL)
+ if (input)
len = strlen(input);
if (len == 0 && request->input[WPS].requested == false)
@@ -445,7 +450,7 @@ static void request_input_string_return(char *input, void *user_data)
struct agent_data *request = user_data;
int i;
- for (i = 0; request->input[i].attribute != NULL; i++) {
+ for (i = 0; request->input[i].attribute; i++) {
if (request->input[i].requested == true) {
request_input_append(request,
request->input[i].attribute, input);
@@ -464,7 +469,7 @@ static DBusMessage *agent_request_input(DBusConnection *connection,
DBusMessageIter iter, dict, entry, variant;
char *service, *str, *field;
DBusMessageIter dict_entry, field_entry, field_value;
- char *argument, *value, *attr_type;
+ char *argument, *value, *attr_type = NULL;
int i;
@@ -519,7 +524,7 @@ static DBusMessage *agent_request_input(DBusConnection *connection,
dbus_message_iter_next(&dict_entry);
}
- for (i = 0; request->input[i].attribute != NULL; i++) {
+ for (i = 0; request->input[i].attribute; i++) {
if (strcmp(field, request->input[i].attribute) == 0) {
request->input[i].requested = true;
break;
@@ -570,7 +575,7 @@ static int agent_register_return(DBusMessageIter *iter, const char *error,
{
DBusConnection *connection = user_data;
- if (error != NULL) {
+ if (error) {
g_dbus_unregister_interface(connection, agent_path(),
AGENT_INTERFACE);
fprintf(stderr, "Error registering Agent: %s\n", error);
@@ -583,6 +588,13 @@ static int agent_register_return(DBusMessageIter *iter, const char *error,
return -EINPROGRESS;
}
+static void append_path(DBusMessageIter *iter, void *user_data)
+{
+ const char *path = user_data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
+}
+
int __connmanctl_agent_register(DBusConnection *connection)
{
char *path = agent_path();
@@ -595,18 +607,16 @@ int __connmanctl_agent_register(DBusConnection *connection)
agent_connection = connection;
- if (g_dbus_register_interface(connection, path,
+ if (!g_dbus_register_interface(connection, path,
AGENT_INTERFACE, agent_methods,
- NULL, NULL, &agent_request,
- NULL) == FALSE) {
+ NULL, NULL, &agent_request, NULL)) {
fprintf(stderr, "Error: Failed to register Agent callbacks\n");
return 0;
}
result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
CONNMAN_PATH, "net.connman.Manager", "RegisterAgent",
- agent_register_return, connection,
- DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
+ agent_register_return, connection, append_path, path);
if (result != -EINPROGRESS) {
g_dbus_unregister_interface(connection, agent_path(),
@@ -621,7 +631,7 @@ int __connmanctl_agent_register(DBusConnection *connection)
static int agent_unregister_return(DBusMessageIter *iter, const char *error,
void *user_data)
{
- if (error != NULL) {
+ if (error) {
fprintf(stderr, "Error unregistering Agent: %s\n", error);
return 0;
}
@@ -646,8 +656,7 @@ int __connmanctl_agent_unregister(DBusConnection *connection)
result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
CONNMAN_PATH, "net.connman.Manager", "UnregisterAgent",
- agent_unregister_return, NULL,
- DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
+ agent_unregister_return, NULL, append_path, path);
if (result != -EINPROGRESS)
fprintf(stderr, "Error: Failed to unregister Agent\n");
@@ -675,7 +684,7 @@ static int vpn_agent_register_return(DBusMessageIter *iter, const char *error,
{
DBusConnection *connection = user_data;
- if (error != NULL) {
+ if (error) {
g_dbus_unregister_interface(connection, agent_path(),
VPN_AGENT_INTERFACE);
fprintf(stderr, "Error registering VPN Agent: %s\n", error);
@@ -700,10 +709,9 @@ int __connmanctl_vpn_agent_register(DBusConnection *connection)
agent_connection = connection;
- if (g_dbus_register_interface(connection, path,
- VPN_AGENT_INTERFACE, vpn_agent_methods,
- NULL, NULL, &vpn_agent_request,
- NULL) == FALSE) {
+ if (!g_dbus_register_interface(connection, path,
+ VPN_AGENT_INTERFACE, vpn_agent_methods,
+ NULL, NULL, &vpn_agent_request, NULL)) {
fprintf(stderr, "Error: Failed to register VPN Agent "
"callbacks\n");
return 0;
@@ -711,8 +719,8 @@ int __connmanctl_vpn_agent_register(DBusConnection *connection)
result = __connmanctl_dbus_method_call(connection, VPN_SERVICE,
VPN_PATH, "net.connman.vpn.Manager", "RegisterAgent",
- vpn_agent_register_return, connection,
- DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
+ vpn_agent_register_return, connection, append_path,
+ path);
if (result != -EINPROGRESS) {
g_dbus_unregister_interface(connection, agent_path(),
@@ -727,7 +735,7 @@ int __connmanctl_vpn_agent_register(DBusConnection *connection)
static int vpn_agent_unregister_return(DBusMessageIter *iter,
const char *error, void *user_data)
{
- if (error != NULL) {
+ if (error) {
fprintf(stderr, "Error unregistering VPN Agent: %s\n", error);
return 0;
}
@@ -753,8 +761,7 @@ int __connmanctl_vpn_agent_unregister(DBusConnection *connection)
result = __connmanctl_dbus_method_call(connection, VPN_SERVICE,
VPN_PATH, "net.connman.vpn.Manager", "UnregisterAgent",
- vpn_agent_unregister_return, NULL,
- DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
+ vpn_agent_unregister_return, NULL, append_path, path);
if (result != -EINPROGRESS)
fprintf(stderr, "Error: Failed to unregister VPN Agent\n");
diff --git a/client/commands.c b/client/commands.c
index 557a8ffd..9c01fd53 100644
--- a/client/commands.c
+++ b/client/commands.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2012-2014 Intel Corporation. All rights reserved.
*
* 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
@@ -29,6 +29,8 @@
#include <string.h>
#include <errno.h>
#include <stdbool.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <glib.h>
#include <gdbus.h>
@@ -36,11 +38,18 @@
#include "dbus_helpers.h"
#include "input.h"
#include "services.h"
+#include "peers.h"
#include "commands.h"
#include "agent.h"
#include "vpnconnections.h"
static DBusConnection *connection;
+static GHashTable *service_hash;
+static GHashTable *peer_hash;
+static GHashTable *technology_hash;
+static char *session_notify_path;
+static char *session_path;
+static bool session_connected;
struct connman_option {
const char *name;
@@ -74,7 +83,7 @@ static bool check_dbus_name(const char *name)
*/
unsigned int i;
- if (name == NULL || name[0] == '\0')
+ if (!name || name[0] == '\0')
return false;
for (i = 0; name[i] != '\0'; i++)
@@ -89,7 +98,7 @@ static bool check_dbus_name(const char *name)
static int parse_boolean(char *arg)
{
- if (arg == NULL)
+ if (!arg)
return -1;
if (strcasecmp(arg, "no") == 0 ||
@@ -117,10 +126,10 @@ static int parse_args(char *arg, struct connman_option *options)
{
int i;
- if (arg == NULL)
+ if (!arg)
return -1;
- for (i = 0; options[i].name != NULL; i++) {
+ for (i = 0; options[i].name; i++) {
if (strcmp(options[i].name, arg) == 0 ||
(strncmp(arg, "--", 2) == 0 &&
strcmp(&arg[2], options[i].name) == 0))
@@ -137,14 +146,14 @@ static int enable_return(DBusMessageIter *iter, const char *error,
char *str;
str = strrchr(tech, '/');
- if (str != NULL)
+ if (str)
str++;
else
str = tech;
- if (error == NULL) {
+ if (!error)
fprintf(stdout, "Enabled %s\n", str);
- } else
+ else
fprintf(stderr, "Error %s: %s\n", str, error);
g_free(user_data);
@@ -166,7 +175,7 @@ static int cmd_enable(char *args[], int num, struct connman_option *options)
if (check_dbus_name(args[1]) == false)
return -EINVAL;
- if (strcmp(args[1], "offlinemode") == 0) {
+ if (strcmp(args[1], "offline") == 0) {
tech = g_strdup(args[1]);
return __connmanctl_dbus_set_property(connection, "/",
"net.connman.Manager", enable_return, tech,
@@ -186,14 +195,14 @@ static int disable_return(DBusMessageIter *iter, const char *error,
char *str;
str = strrchr(tech, '/');
- if (str != NULL)
+ if (str)
str++;
else
str = tech;
- if (error == NULL) {
+ if (!error)
fprintf(stdout, "Disabled %s\n", str);
- } else
+ else
fprintf(stderr, "Error %s: %s\n", str, error);
g_free(user_data);
@@ -215,7 +224,7 @@ static int cmd_disable(char *args[], int num, struct connman_option *options)
if (check_dbus_name(args[1]) == false)
return -EINVAL;
- if (strcmp(args[1], "offlinemode") == 0) {
+ if (strcmp(args[1], "offline") == 0) {
tech = g_strdup(args[1]);
return __connmanctl_dbus_set_property(connection, "/",
"net.connman.Manager", disable_return, tech,
@@ -233,7 +242,7 @@ static int state_print(DBusMessageIter *iter, const char *error,
{
DBusMessageIter entry;
- if (error != NULL) {
+ if (error) {
fprintf(stderr, "Error: %s", error);
return 0;
}
@@ -252,13 +261,13 @@ static int cmd_state(char *args[], int num, struct connman_option *options)
return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
CONNMAN_PATH, "net.connman.Manager", "GetProperties",
- state_print, NULL, DBUS_TYPE_INVALID);
+ state_print, NULL, NULL, NULL);
}
static int services_list(DBusMessageIter *iter, const char *error,
void *user_data)
{
- if (error == NULL) {
+ if (!error) {
__connmanctl_services_list(iter);
fprintf(stdout, "\n");
} else {
@@ -268,14 +277,26 @@ static int services_list(DBusMessageIter *iter, const char *error,
return 0;
}
-static int services_properties(DBusMessageIter *iter, const char *error,
- void *user_data)
+static int peers_list(DBusMessageIter *iter,
+ const char *error, void *user_data)
+{
+ if (!error) {
+ __connmanctl_peers_list(iter);
+ fprintf(stdout, "\n");
+ } else
+ fprintf(stderr, "Error: %s\n", error);
+
+ return 0;
+}
+
+static int object_properties(DBusMessageIter *iter,
+ const char *error, void *user_data)
{
char *path = user_data;
char *str;
DBusMessageIter dict;
- if (error == NULL) {
+ if (!error) {
fprintf(stdout, "%s\n", path);
dbus_message_iter_recurse(iter, &dict);
@@ -285,7 +306,7 @@ static int services_properties(DBusMessageIter *iter, const char *error,
} else {
str = strrchr(path, '/');
- if (str != NULL)
+ if (str)
str++;
else
str = path;
@@ -323,11 +344,11 @@ static int cmd_services(char *args[], int num, struct connman_option *options)
break;
}
- if (service_name == NULL) {
+ if (!service_name) {
return __connmanctl_dbus_method_call(connection,
CONNMAN_SERVICE, CONNMAN_PATH,
"net.connman.Manager", "GetServices",
- services_list, NULL, DBUS_TYPE_INVALID);
+ services_list, NULL, NULL, NULL);
}
if (check_dbus_name(service_name) == false)
@@ -336,7 +357,34 @@ static int cmd_services(char *args[], int num, struct connman_option *options)
path = g_strdup_printf("/net/connman/service/%s", service_name);
return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
"net.connman.Service", "GetProperties",
- services_properties, path, DBUS_TYPE_INVALID);
+ object_properties, path, NULL, NULL);
+}
+
+static int cmd_peers(char *args[], int num, struct connman_option *options)
+{
+ char *peer_name = NULL;
+ char *path;
+
+ if (num > 2)
+ return -E2BIG;
+
+ if (num == 2)
+ peer_name = args[1];
+
+ if (!peer_name) {
+ return __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager", "GetPeers",
+ peers_list, NULL, NULL, NULL);
+ }
+
+ if (check_dbus_name(peer_name) == false)
+ return -EINVAL;
+
+ path = g_strdup_printf("/net/connman/peer/%s", peer_name);
+ return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ path, "net.connman.Peer", "GetProperties",
+ object_properties, path, NULL, NULL);
}
static int technology_print(DBusMessageIter *iter, const char *error,
@@ -344,7 +392,7 @@ static int technology_print(DBusMessageIter *iter, const char *error,
{
DBusMessageIter array;
- if (error != NULL) {
+ if (error) {
fprintf(stderr, "Error: %s\n", error);
return 0;
}
@@ -378,7 +426,7 @@ static int cmd_technologies(char *args[], int num,
return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
CONNMAN_PATH, "net.connman.Manager", "GetTechnologies",
- technology_print, NULL, DBUS_TYPE_INVALID);
+ technology_print, NULL, NULL, NULL);
}
struct tether_enable {
@@ -393,19 +441,19 @@ static int tether_set_return(DBusMessageIter *iter, const char *error,
char *str;
str = strrchr(tether->path, '/');
- if (str != NULL)
+ if (str)
str++;
else
str = tether->path;
- if (error == NULL) {
+ if (!error) {
fprintf(stdout, "%s tethering for %s\n",
- tether->enable == TRUE ? "Enabled": "Disabled",
+ tether->enable ? "Enabled" : "Disabled",
str);
} else
fprintf(stderr, "Error %s %s tethering: %s\n",
- tether->enable == TRUE ?
- "enabling": "disabling", str, error);
+ tether->enable ?
+ "enabling" : "disabling", str, error);
g_free(tether->path);
g_free(user_data);
@@ -446,9 +494,6 @@ struct tether_properties {
static int tether_update(struct tether_properties *tether)
{
- printf("%d %d %d\n", tether->ssid_result, tether->passphrase_result,
- tether->set_tethering);
-
if (tether->ssid_result == 0 && tether->passphrase_result == 0)
return tether_set("wifi", tether->set_tethering);
@@ -466,7 +511,7 @@ static int tether_set_ssid_return(DBusMessageIter *iter, const char *error,
{
struct tether_properties *tether = user_data;
- if (error == NULL) {
+ if (!error) {
fprintf(stdout, "Wifi SSID set\n");
tether->ssid_result = 0;
} else {
@@ -482,7 +527,7 @@ static int tether_set_passphrase_return(DBusMessageIter *iter,
{
struct tether_properties *tether = user_data;
- if (error == NULL) {
+ if (!error) {
fprintf(stdout, "Wifi passphrase set\n");
tether->passphrase_result = 0;
} else {
@@ -565,7 +610,7 @@ static int scan_return(DBusMessageIter *iter, const char *error,
{
char *path = user_data;
- if (error == NULL) {
+ if (!error) {
char *str = strrchr(path, '/');
str++;
fprintf(stdout, "Scan completed for %s\n", str);
@@ -593,7 +638,7 @@ static int cmd_scan(char *args[], int num, struct connman_option *options)
path = g_strdup_printf("/net/connman/technology/%s", args[1]);
return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
"net.connman.Technology", "Scan",
- scan_return, path, DBUS_TYPE_INVALID);
+ scan_return, path, NULL, NULL);
}
static int connect_return(DBusMessageIter *iter, const char *error,
@@ -601,7 +646,7 @@ static int connect_return(DBusMessageIter *iter, const char *error,
{
char *path = user_data;
- if (error == NULL) {
+ if (!error) {
char *str = strrchr(path, '/');
str++;
fprintf(stdout, "Connected %s\n", str);
@@ -629,7 +674,7 @@ static int cmd_connect(char *args[], int num, struct connman_option *options)
path = g_strdup_printf("/net/connman/service/%s", args[1]);
return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
"net.connman.Service", "Connect",
- connect_return, path, DBUS_TYPE_INVALID);
+ connect_return, path, NULL, NULL);
}
static int disconnect_return(DBusMessageIter *iter, const char *error,
@@ -637,7 +682,7 @@ static int disconnect_return(DBusMessageIter *iter, const char *error,
{
char *path = user_data;
- if (error == NULL) {
+ if (!error) {
char *str = strrchr(path, '/');
str++;
fprintf(stdout, "Disconnected %s\n", str);
@@ -665,7 +710,7 @@ static int cmd_disconnect(char *args[], int num, struct connman_option *options)
path = g_strdup_printf("/net/connman/service/%s", args[1]);
return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
"net.connman.Service", "Disconnect",
- disconnect_return, path, DBUS_TYPE_INVALID);
+ disconnect_return, path, NULL, NULL);
}
static int config_return(DBusMessageIter *iter, const char *error,
@@ -673,7 +718,7 @@ static int config_return(DBusMessageIter *iter, const char *error,
{
char *service_name = user_data;
- if (error != NULL)
+ if (error)
fprintf(stderr, "Error %s: %s\n", service_name, error);
g_free(user_data);
@@ -693,10 +738,10 @@ static void config_append_ipv4(DBusMessageIter *iter,
char **opts = append->opts;
int i = 0;
- if (opts == NULL)
+ if (!opts)
return;
- while (opts[i] != NULL && ipv4[i] != NULL) {
+ while (opts[i] && ipv4[i]) {
__connmanctl_dbus_append_dict_entry(iter, ipv4[i],
DBUS_TYPE_STRING, &opts[i]);
i++;
@@ -710,7 +755,7 @@ static void config_append_ipv6(DBusMessageIter *iter, void *user_data)
struct config_append *append = user_data;
char **opts = append->opts;
- if (opts == NULL)
+ if (!opts)
return;
append->values = 1;
@@ -736,7 +781,7 @@ static void config_append_ipv6(DBusMessageIter *iter, void *user_data)
break;
default:
- if (opts[1] != NULL) {
+ if (opts[1]) {
append->values = 2;
if (g_strcmp0(opts[1], "prefered") != 0 &&
@@ -758,7 +803,7 @@ static void config_append_ipv6(DBusMessageIter *iter, void *user_data)
} else if (g_strcmp0(opts[0], "manual") == 0) {
int i = 1;
- while (opts[i] != NULL && ipv6[i] != NULL) {
+ while (opts[i] && ipv6[i]) {
if (i == 2) {
int value = atoi(opts[i]);
__connmanctl_dbus_append_dict_entry(iter,
@@ -775,7 +820,7 @@ static void config_append_ipv6(DBusMessageIter *iter, void *user_data)
append->values = i;
} else if (g_strcmp0(opts[0], "off") != 0) {
- fprintf(stderr, "Error %s: %s\n", opts[0], strerror(-EINVAL));
+ fprintf(stderr, "Error %s: %s\n", opts[0], strerror(EINVAL));
return;
}
@@ -790,10 +835,10 @@ static void config_append_str(DBusMessageIter *iter, void *user_data)
char **opts = append->opts;
int i = 0;
- if (opts == NULL)
+ if (!opts)
return;
- while (opts[i] != NULL) {
+ while (opts[i]) {
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
&opts[i]);
i++;
@@ -808,10 +853,10 @@ static void append_servers(DBusMessageIter *iter, void *user_data)
char **opts = append->opts;
int i = 1;
- if (opts == NULL)
+ if (!opts)
return;
- while (opts[i] != NULL && g_strcmp0(opts[i], "--excludes") != 0) {
+ while (opts[i] && g_strcmp0(opts[i], "--excludes") != 0) {
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
&opts[i]);
i++;
@@ -826,12 +871,12 @@ static void append_excludes(DBusMessageIter *iter, void *user_data)
char **opts = append->opts;
int i = append->values;
- if (opts == NULL || opts[i] == NULL ||
+ if (!opts || !opts[i] ||
g_strcmp0(opts[i], "--excludes") != 0)
return;
i++;
- while (opts[i] != NULL) {
+ while (opts[i]) {
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
&opts[i]);
i++;
@@ -845,7 +890,7 @@ static void config_append_proxy(DBusMessageIter *iter, void *user_data)
struct config_append *append = user_data;
char **opts = append->opts;
- if (opts == NULL)
+ if (!opts)
return;
if (g_strcmp0(opts[0], "manual") == 0) {
@@ -856,7 +901,7 @@ static void config_append_proxy(DBusMessageIter *iter, void *user_data)
append_excludes, append);
} else if (g_strcmp0(opts[0], "auto") == 0) {
- if (opts[1] != NULL) {
+ if (opts[1]) {
__connmanctl_dbus_append_dict_entry(iter, "URL",
DBUS_TYPE_STRING, &opts[1]);
append->values++;
@@ -881,13 +926,13 @@ static int cmd_config(char *args[], int num, struct connman_option *options)
struct config_append append;
service_name = args[1];
- if (service_name == NULL)
+ if (!service_name)
return -EINVAL;
if (check_dbus_name(service_name) == false)
return -EINVAL;
- while (index < num && args[index] != NULL) {
+ while (index < num && args[index]) {
c = parse_args(args[index], options);
opt_start = &args[index + 1];
append.opts = opt_start;
@@ -985,7 +1030,7 @@ static int cmd_config(char *args[], int num, struct connman_option *options)
CONNMAN_SERVICE, path,
"net.connman.Service", "Remove",
config_return, g_strdup(service_name),
- DBUS_TYPE_INVALID);
+ NULL, NULL);
break;
default:
res = -EINVAL;
@@ -1016,25 +1061,30 @@ static DBusHandlerResult monitor_changed(DBusConnection *connection,
const char *interface, *path;
interface = dbus_message_get_interface(message);
+ if (!interface)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
if (strncmp(interface, "net.connman.", 12) != 0)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- if (strncmp(interface, "net.connman.Agent", 17) == 0 ||
- strncmp(interface, "net.connman.vpn.Agent", 21) == 0)
+ if (!strcmp(interface, "net.connman.Agent") ||
+ !strcmp(interface, "net.connman.vpn.Agent") ||
+ !strcmp(interface, "net.connman.Session") ||
+ !strcmp(interface, "net.connman.Notification"))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
interface = strrchr(interface, '.');
- if (interface != NULL && *interface != '\0')
+ if (interface && *interface != '\0')
interface++;
path = strrchr(dbus_message_get_path(message), '/');
- if (path != NULL && *path != '\0')
+ if (path && *path != '\0')
path++;
__connmanctl_save_rl();
if (dbus_message_is_signal(message, "net.connman.Manager",
- "ServicesChanged") == TRUE) {
+ "ServicesChanged")) {
fprintf(stdout, "%-12s %-20s = {\n", interface,
"ServicesChanged");
@@ -1044,22 +1094,30 @@ static DBusHandlerResult monitor_changed(DBusConnection *connection,
__connmanctl_redraw_rl();
- return DBUS_HANDLER_RESULT_HANDLED;
- }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ } else if (dbus_message_is_signal(message, "net.connman.Manager",
+ "PeersChanged")) {
+ fprintf(stdout, "%-12s %-20s = {\n", interface,
+ "PeersChanged");
+ dbus_message_iter_init(message, &iter);
+ __connmanctl_peers_list(&iter);
+ fprintf(stdout, "\n}\n");
+ __connmanctl_redraw_rl();
- if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
- "ConnectionAdded") == TRUE ||
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ } else if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
+ "ConnectionAdded") ||
dbus_message_is_signal(message,
"net.connman.vpn.Manager",
- "ConnectionRemoved") == TRUE) {
+ "ConnectionRemoved")) {
interface = "vpn.Manager";
path = dbus_message_get_member(message);
} else if (dbus_message_is_signal(message, "net.connman.Manager",
- "TechnologyAdded") == TRUE ||
+ "TechnologyAdded") ||
dbus_message_is_signal(message, "net.connman.Manager",
- "TechnologyRemoved") == TRUE)
+ "TechnologyRemoved"))
path = dbus_message_get_member(message);
fprintf(stdout, "%-12s %-20s ", interface, path);
@@ -1070,7 +1128,7 @@ static DBusHandlerResult monitor_changed(DBusConnection *connection,
__connmanctl_redraw_rl();
- return DBUS_HANDLER_RESULT_HANDLED;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static struct {
@@ -1092,7 +1150,7 @@ static void monitor_add(char *interface)
char *rule;
DBusError err;
- for (i = 0; monitor[i].interface != NULL; i++) {
+ for (i = 0; monitor[i].interface; i++) {
if (monitor[i].enabled == true)
add_filter = false;
@@ -1129,7 +1187,7 @@ static void monitor_del(char *interface)
char *rule;
- for (i = 0; monitor[i].interface != NULL; i++) {
+ for (i = 0; monitor[i].interface; i++) {
if (g_strcmp0(interface, monitor[i].interface) == 0) {
if (monitor[i].enabled == false)
return;
@@ -1250,6 +1308,12 @@ static int cmd_monitor(char *args[], int num, struct connman_option *options)
static int cmd_agent(char *args[], int num, struct connman_option *options)
{
+ if (!__connmanctl_is_interactive()) {
+ fprintf(stderr, "Error: Not supported in non-interactive "
+ "mode\n");
+ return 0;
+ }
+
if (num > 2)
return -E2BIG;
@@ -1282,7 +1346,7 @@ static int vpnconnections_properties(DBusMessageIter *iter, const char *error,
char *str;
DBusMessageIter dict;
- if (error == NULL) {
+ if (!error) {
fprintf(stdout, "%s\n", path);
dbus_message_iter_recurse(iter, &dict);
@@ -1292,7 +1356,7 @@ static int vpnconnections_properties(DBusMessageIter *iter, const char *error,
} else {
str = strrchr(path, '/');
- if (str != NULL)
+ if (str)
str++;
else
str = path;
@@ -1308,7 +1372,7 @@ static int vpnconnections_properties(DBusMessageIter *iter, const char *error,
static int vpnconnections_list(DBusMessageIter *iter, const char *error,
void *user_data)
{
- if (error == NULL)
+ if (!error)
__connmanctl_vpnconnections_list(iter);
else
fprintf(stderr, "Error: %s\n", error);
@@ -1326,12 +1390,12 @@ static int cmd_vpnconnections(char *args[], int num,
vpnconnection_name = args[1];
- if (vpnconnection_name == NULL)
+ if (!vpnconnection_name)
return __connmanctl_dbus_method_call(connection,
VPN_SERVICE, VPN_PATH,
"net.connman.vpn.Manager", "GetConnections",
vpnconnections_list, NULL,
- DBUS_TYPE_INVALID);
+ NULL, NULL);
if (check_dbus_name(vpnconnection_name) == false)
return -EINVAL;
@@ -1340,12 +1404,18 @@ static int cmd_vpnconnections(char *args[], int num,
vpnconnection_name);
return __connmanctl_dbus_method_call(connection, VPN_SERVICE, path,
"net.connman.vpn.Connection", "GetProperties",
- vpnconnections_properties, path, DBUS_TYPE_INVALID);
+ vpnconnections_properties, path, NULL, NULL);
}
static int cmd_vpnagent(char *args[], int num, struct connman_option *options)
{
+ if (!__connmanctl_is_interactive()) {
+ fprintf(stderr, "Error: Not supported in non-interactive "
+ "mode\n");
+ return 0;
+ }
+
if (num > 2)
return -E2BIG;
@@ -1372,11 +1442,561 @@ static int cmd_vpnagent(char *args[], int num, struct connman_option *options)
return 0;
}
+static DBusMessage *session_release(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ __connmanctl_save_rl();
+
+ fprintf(stdout, "Session %s released\n", session_path);
+
+ __connmanctl_redraw_rl();
+
+ g_free(session_path);
+ session_path = NULL;
+ session_connected = false;
+
+ return g_dbus_create_reply(message, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *session_update(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ DBusMessageIter iter, dict;
+
+ __connmanctl_save_rl();
+
+ fprintf(stdout, "Session Update = {\n");
+
+ dbus_message_iter_init(message, &iter);
+ dbus_message_iter_recurse(&iter, &dict);
+
+ __connmanctl_dbus_print(&dict, "", " = ", "\n");
+ fprintf(stdout, "\n}\n");
+
+ dbus_message_iter_recurse(&iter, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, variant;
+ char *field, *state;
+
+ dbus_message_iter_recurse(&dict, &entry);
+
+ dbus_message_iter_get_basic(&entry, &field);
+
+ if (dbus_message_iter_get_arg_type(&entry)
+ == DBUS_TYPE_STRING
+ && !strcmp(field, "State")) {
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &variant);
+ if (dbus_message_iter_get_arg_type(&variant)
+ != DBUS_TYPE_STRING)
+ break;
+
+ dbus_message_iter_get_basic(&variant, &state);
+
+ if (!session_connected && (!strcmp(state, "connected")
+ || !strcmp(state, "online"))) {
+
+ fprintf(stdout, "Session %s connected\n",
+ session_path);
+ session_connected = true;
+
+ break;
+ }
+
+ if (!strcmp(state, "disconnected") &&
+ session_connected) {
+
+ fprintf(stdout, "Session %s disconnected\n",
+ session_path);
+ session_connected = false;
+ }
+ break;
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ __connmanctl_redraw_rl();
+
+ return g_dbus_create_reply(message, DBUS_TYPE_INVALID);
+}
+
+static const GDBusMethodTable notification_methods[] = {
+ { GDBUS_METHOD("Release", NULL, NULL, session_release) },
+ { GDBUS_METHOD("Update", GDBUS_ARGS({"settings", "a{sv}"}),
+ NULL, session_update) },
+ { },
+};
+
+static int session_notify_add(const char *path)
+{
+ if (session_notify_path)
+ return 0;
+
+ if (!g_dbus_register_interface(connection, path,
+ "net.connman.Notification",
+ notification_methods, NULL, NULL,
+ NULL, NULL)) {
+ fprintf(stderr, "Error: Failed to register VPN Agent "
+ "callbacks\n");
+ return -EIO;
+ }
+
+ session_notify_path = g_strdup(path);
+
+ return 0;
+}
+
+static void session_notify_remove(void)
+{
+ if (!session_notify_path)
+ return;
+
+ g_dbus_unregister_interface(connection, session_notify_path,
+ "net.connman.Notification");
+
+ g_free(session_notify_path);
+ session_notify_path = NULL;
+}
+
+static int session_connect_cb(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ if (error) {
+ fprintf(stderr, "Error: %s", error);
+ return 0;
+ }
+
+ return -EINPROGRESS;
+}
+
+
+static int session_connect(void)
+{
+ return __connmanctl_dbus_method_call(connection, "net.connman",
+ session_path, "net.connman.Session", "Connect",
+ session_connect_cb, NULL, NULL, NULL);
+}
+
+static int session_disconnect_cb(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ if (error)
+ fprintf(stderr, "Error: %s", error);
+
+ return 0;
+}
+
+static int session_disconnect(void)
+{
+ return __connmanctl_dbus_method_call(connection, "net.connman",
+ session_path, "net.connman.Session", "Disconnect",
+ session_disconnect_cb, NULL, NULL, NULL);
+}
+
+static int session_create_cb(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ gboolean connect = GPOINTER_TO_INT(user_data);
+ char *str;
+
+ if (error) {
+ fprintf(stderr, "Error creating session: %s", error);
+ session_notify_remove();
+ return 0;
+ }
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH) {
+ fprintf(stderr, "Error creating session: No session path\n");
+ return -EINVAL;
+ }
+
+ g_free(session_path);
+
+ dbus_message_iter_get_basic(iter, &str);
+ session_path = g_strdup(str);
+
+ fprintf(stdout, "Session %s created\n", session_path);
+
+ if (connect)
+ return session_connect();
+
+ return -EINPROGRESS;
+}
+
+static void session_create_append(DBusMessageIter *iter, void *user_data)
+{
+ const char *notify_path = user_data;
+
+ __connmanctl_dbus_append_dict(iter, NULL, NULL);
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
+ &notify_path);
+}
+
+static int session_create(gboolean connect)
+{
+ int res;
+ char *notify_path;
+
+ notify_path = g_strdup_printf("/net/connman/connmanctl%d", getpid());
+ session_notify_add(notify_path);
+
+ res = __connmanctl_dbus_method_call(connection, "net.connman", "/",
+ "net.connman.Manager", "CreateSession",
+ session_create_cb, GINT_TO_POINTER(connect),
+ session_create_append, notify_path);
+
+ g_free(notify_path);
+
+ if (res < 0 && res != -EINPROGRESS)
+ session_notify_remove();
+
+ return res;
+}
+
+static int session_destroy_cb(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ if (error) {
+ fprintf(stderr, "Error destroying session: %s", error);
+ return 0;
+ }
+
+ fprintf(stdout, "Session %s ended\n", session_path);
+
+ g_free(session_path);
+ session_path = NULL;
+ session_connected = false;
+
+ return 0;
+}
+
+static void session_destroy_append(DBusMessageIter *iter, void *user_data)
+{
+ const char *path = user_data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
+}
+
+static int session_destroy(void)
+{
+ return __connmanctl_dbus_method_call(connection, "net.connman", "/",
+ "net.connman.Manager", "DestroySession",
+ session_destroy_cb, NULL,
+ session_destroy_append, session_path);
+}
+
+static int session_config_return(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ char *property_name = user_data;
+
+ if (error)
+ fprintf(stderr, "Error setting session %s: %s\n",
+ property_name, error);
+
+ return 0;
+}
+
+static void session_config_append_array(DBusMessageIter *iter,
+ void *user_data)
+{
+ struct config_append *append = user_data;
+ char **opts = append->opts;
+ int i = 1;
+
+ if (!opts)
+ return;
+
+ while (opts[i] && strncmp(opts[i], "--", 2) != 0) {
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
+ &opts[i]);
+ i++;
+ }
+
+ append->values = i;
+}
+
+static int session_config(char *args[], int num,
+ struct connman_option *options)
+{
+ int index = 0, res = 0;
+ struct config_append append;
+ char c;
+
+ while (index < num && args[index]) {
+ append.opts = &args[index];
+ append.values = 0;
+
+ c = parse_args(args[index], options);
+
+ switch (c) {
+ case 'b':
+ res = __connmanctl_dbus_session_change_array(connection,
+ session_path, session_config_return,
+ "AllowedBearers", "AllowedBearers",
+ session_config_append_array, &append);
+ break;
+ case 't':
+ if (!args[index + 1]) {
+ res = -EINVAL;
+ break;
+ }
+
+ res = __connmanctl_dbus_session_change(connection,
+ session_path, session_config_return,
+ "ConnectionType", "ConnectionType",
+ DBUS_TYPE_STRING, &args[index + 1]);
+ append.values = 2;
+ break;
+
+ default:
+ res = -EINVAL;
+ }
+
+ if (res < 0 && res != -EINPROGRESS) {
+ printf("Error '%s': %s\n", args[index],
+ strerror(-res));
+ return 0;
+ }
+
+ index += append.values;
+ }
+
+ return 0;
+}
+
+static int cmd_session(char *args[], int num, struct connman_option *options)
+{
+ char *command;
+
+ if (num < 2)
+ return -EINVAL;
+
+ command = args[1];
+
+ switch(parse_boolean(command)) {
+ case 0:
+ if (!session_path)
+ return -EALREADY;
+ return session_destroy();
+
+ case 1:
+ if (session_path)
+ return -EALREADY;
+ return session_create(FALSE);
+
+ default:
+ if (!strcmp(command, "connect")) {
+ if (!session_path)
+ return session_create(TRUE);
+
+ return session_connect();
+
+ } else if (!strcmp(command, "disconnect")) {
+
+ if (!session_path) {
+ fprintf(stdout, "Session does not exist\n");
+ return 0;
+ }
+
+ return session_disconnect();
+ } else if (!strcmp(command, "config")) {
+ if (!session_path) {
+ fprintf(stdout, "Session does not exist\n");
+ return 0;
+ }
+
+ if (num == 2)
+ return -EINVAL;
+
+ return session_config(&args[2], num - 2, options);
+ }
+
+ }
+
+ return -EINVAL;
+}
+
static int cmd_exit(char *args[], int num, struct connman_option *options)
{
return 1;
}
+static char *lookup_service(const char *text, int state)
+{
+ static int len = 0;
+ static GHashTableIter iter;
+ gpointer key, value;
+
+ if (state == 0) {
+ g_hash_table_iter_init(&iter, service_hash);
+ len = strlen(text);
+ }
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ const char *service = key;
+ if (strncmp(text, service, len) == 0)
+ return strdup(service);
+ }
+
+ return NULL;
+}
+
+static char *lookup_service_arg(const char *text, int state)
+{
+ if (__connmanctl_input_calc_level() > 1) {
+ __connmanctl_input_lookup_end();
+ return NULL;
+ }
+
+ return lookup_service(text, state);
+}
+
+static char *lookup_peer(const char *text, int state)
+{
+ static GHashTableIter iter;
+ gpointer key, value;
+ static int len = 0;
+
+ if (state == 0) {
+ g_hash_table_iter_init(&iter, peer_hash);
+ len = strlen(text);
+ }
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ const char *peer = key;
+ if (strncmp(text, peer, len) == 0)
+ return strdup(peer);
+ }
+
+ return NULL;
+}
+
+static char *lookup_peer_arg(const char *text, int state)
+{
+ if (__connmanctl_input_calc_level() > 1) {
+ __connmanctl_input_lookup_end();
+ return NULL;
+ }
+
+ return lookup_peer(text, state);
+}
+
+static char *lookup_technology(const char *text, int state)
+{
+ static int len = 0;
+ static GHashTableIter iter;
+ gpointer key, value;
+
+ if (state == 0) {
+ g_hash_table_iter_init(&iter, technology_hash);
+ len = strlen(text);
+ }
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ const char *technology = key;
+ if (strncmp(text, technology, len) == 0)
+ return strdup(technology);
+ }
+
+ return NULL;
+}
+
+static char *lookup_technology_arg(const char *text, int state)
+{
+ if (__connmanctl_input_calc_level() > 1) {
+ __connmanctl_input_lookup_end();
+ return NULL;
+ }
+
+ return lookup_technology(text, state);
+}
+
+static char *lookup_technology_offline(const char *text, int state)
+{
+ static int len = 0;
+ static bool end = false;
+ char *str;
+
+ if (__connmanctl_input_calc_level() > 1) {
+ __connmanctl_input_lookup_end();
+ return NULL;
+ }
+
+ if (state == 0) {
+ len = strlen(text);
+ end = false;
+ }
+
+ if (end)
+ return NULL;
+
+ str = lookup_technology(text, state);
+ if (str)
+ return str;
+
+ end = true;
+
+ if (strncmp(text, "offline", len) == 0)
+ return strdup("offline");
+
+ return NULL;
+}
+
+static char *lookup_on_off(const char *text, int state)
+{
+ char *onoff[] = { "on", "off", NULL };
+ static int idx = 0;
+ static int len = 0;
+
+ char *str;
+
+ if (!state) {
+ idx = 0;
+ len = strlen(text);
+ }
+
+ while (onoff[idx]) {
+ str = onoff[idx];
+ idx++;
+
+ if (!strncmp(text, str, len))
+ return strdup(str);
+ }
+
+ return NULL;
+}
+
+static char *lookup_tether(const char *text, int state)
+{
+ int level;
+
+ level = __connmanctl_input_calc_level();
+ if (level < 2)
+ return lookup_technology(text, state);
+
+ if (level == 2)
+ return lookup_on_off(text, state);
+
+ __connmanctl_input_lookup_end();
+
+ return NULL;
+}
+
+static char *lookup_agent(const char *text, int state)
+{
+ if (__connmanctl_input_calc_level() > 1) {
+ __connmanctl_input_lookup_end();
+ return NULL;
+ }
+
+ return lookup_on_off(text, state);
+}
+
static struct connman_option service_options[] = {
{"properties", 'p', "[<service>] (obsolete)"},
{ NULL, }
@@ -1386,7 +2006,7 @@ static struct connman_option config_options[] = {
{"nameservers", 'n', "<dns1> [<dns2>] [<dns3>]"},
{"timeservers", 't', "<ntp1> [<ntp2>] [...]"},
{"domains", 'd', "<domain1> [<domain2>] [...]"},
- {"ipv6", 'v', "off|auto [enable|disable|prefered]|\n"
+ {"ipv6", 'v', "off|auto [enable|disable|preferred]|\n"
"\t\t\tmanual <address> <prefixlength> <gateway>"},
{"proxy", 'x', "direct|auto <URL>|manual <URL1> [<URL2>] [...]\n"
"\t\t\t[exclude <exclude1> [<exclude2>] [...]]"},
@@ -1407,49 +2027,116 @@ static struct connman_option monitor_options[] = {
{ NULL, }
};
+static struct connman_option session_options[] = {
+ {"bearers", 'b', "<technology1> [<technology2> [...]]"},
+ {"type", 't', "local|internet|any"},
+ { NULL, }
+};
+
+static char *lookup_options(struct connman_option *options, const char *text,
+ int state)
+{
+ static int idx = 0;
+ static int len = 0;
+ const char *str;
+
+ if (state == 0) {
+ idx = 0;
+ len = strlen(text);
+ }
+
+ while (options[idx].name) {
+ str = options[idx].name;
+ idx++;
+
+ if (str && strncmp(text, str, len) == 0)
+ return strdup(str);
+ }
+
+ return NULL;
+}
+
+static char *lookup_monitor(const char *text, int state)
+{
+ int level;
+
+ level = __connmanctl_input_calc_level();
+
+ if (level < 2)
+ return lookup_options(monitor_options, text, state);
+
+ if (level == 2)
+ return lookup_on_off(text, state);
+
+ __connmanctl_input_lookup_end();
+ return NULL;
+}
+
+static char *lookup_config(const char *text, int state)
+{
+ if (__connmanctl_input_calc_level() < 2)
+ return lookup_service(text, state);
+
+ return lookup_options(config_options, text, state);
+}
+
+static char *lookup_session(const char *text, int state)
+{
+ return lookup_options(session_options, text, state);
+}
+
static const struct {
const char *cmd;
const char *argument;
struct connman_option *options;
int (*func) (char *args[], int num, struct connman_option *options);
const char *desc;
+ __connmanctl_lookup_cb cb;
} cmd_table[] = {
{ "state", NULL, NULL, cmd_state,
- "Shows if the system is online or offline" },
+ "Shows if the system is online or offline", NULL },
{ "technologies", NULL, NULL, cmd_technologies,
- "Display technologies" },
+ "Display technologies", NULL },
{ "enable", "<technology>|offline", NULL, cmd_enable,
- "Enables given technology or offline mode" },
+ "Enables given technology or offline mode",
+ lookup_technology_offline },
{ "disable", "<technology>|offline", NULL, cmd_disable,
- "Disables given technology or offline mode"},
+ "Disables given technology or offline mode",
+ lookup_technology_offline },
{ "tether", "<technology> on|off\n"
" wifi [on|off] <ssid> <passphrase> ",
NULL, cmd_tether,
- "Enable, disable tethering, set SSID and passphrase for wifi" },
+ "Enable, disable tethering, set SSID and passphrase for wifi",
+ lookup_tether },
{ "services", "[<service>]", service_options, cmd_services,
- "Display services" },
+ "Display services", lookup_service_arg },
+ { "peers", "[peer]", NULL, cmd_peers,
+ "Display peers", lookup_peer_arg },
{ "scan", "<technology>", NULL, cmd_scan,
- "Scans for new services for given technology" },
+ "Scans for new services for given technology",
+ lookup_technology_arg },
{ "connect", "<service>", NULL, cmd_connect,
- "Connect a given service" },
+ "Connect a given service", lookup_service_arg },
{ "disconnect", "<service>", NULL, cmd_disconnect,
- "Disconnect a given service" },
+ "Disconnect a given service", lookup_service_arg },
{ "config", "<service>", config_options, cmd_config,
- "Set service configuration options" },
+ "Set service configuration options", lookup_config },
{ "monitor", "[off]", monitor_options, cmd_monitor,
- "Monitor signals from interfaces" },
+ "Monitor signals from interfaces", lookup_monitor },
{ "agent", "on|off", NULL, cmd_agent,
- "Agent mode" },
+ "Agent mode", lookup_agent },
{"vpnconnections", "[<connection>]", NULL, cmd_vpnconnections,
- "Display VPN connections" },
+ "Display VPN connections", NULL },
{ "vpnagent", "on|off", NULL, cmd_vpnagent,
- "VPN Agent mode" },
+ "VPN Agent mode", lookup_agent },
+ { "session", "on|off|connect|disconnect|config", session_options,
+ cmd_session, "Enable or disable a session", lookup_session },
{ "help", NULL, NULL, cmd_help,
- "Show help" },
+ "Show help", NULL },
{ "exit", NULL, NULL, cmd_exit,
- "Exit" },
+ "Exit", NULL },
{ "quit", NULL, NULL, cmd_exit,
- "Quit" },
+ "Quit", NULL },
{ NULL, },
};
@@ -1461,20 +2148,20 @@ static int cmd_help(char *args[], int num, struct connman_option *options)
if (interactive == false)
fprintf(stdout, "Usage: connmanctl [[command] [args]]\n");
- for (i = 0; cmd_table[i].cmd != NULL; i++) {
+ for (i = 0; cmd_table[i].cmd; i++) {
const char *cmd = cmd_table[i].cmd;
const char *argument = cmd_table[i].argument;
const char *desc = cmd_table[i].desc;
- printf("%-16s%-22s%s\n", cmd != NULL? cmd: "",
- argument != NULL? argument: "",
- desc != NULL? desc: "");
+ printf("%-16s%-22s%s\n", cmd? cmd: "",
+ argument? argument: "",
+ desc? desc: "");
- if (cmd_table[i].options != NULL) {
- for (j = 0; cmd_table[i].options[j].name != NULL;
+ if (cmd_table[i].options) {
+ for (j = 0; cmd_table[i].options[j].name;
j++) {
const char *options_desc =
- cmd_table[i].options[j].desc != NULL ?
+ cmd_table[i].options[j].desc ?
cmd_table[i].options[j].desc: "";
printf(" --%-16s%s\n",
@@ -1491,15 +2178,37 @@ static int cmd_help(char *args[], int num, struct connman_option *options)
return 0;
}
+__connmanctl_lookup_cb __connmanctl_get_lookup_func(const char *text)
+{
+ int i, cmdlen, textlen;
+
+ if (!text)
+ return NULL;
+
+ textlen = strlen(text);
+
+ for (i = 0; cmd_table[i].cmd; i++) {
+ cmdlen = strlen(cmd_table[i].cmd);
+
+ if (textlen > cmdlen && text[cmdlen] != ' ')
+ continue;
+
+ if (strncmp(cmd_table[i].cmd, text, cmdlen) == 0)
+ return cmd_table[i].cb;
+ }
+
+ return NULL;
+}
+
int __connmanctl_commands(DBusConnection *dbus_conn, char *argv[], int argc)
{
int i, result;
connection = dbus_conn;
- for (i = 0; cmd_table[i].cmd != NULL; i++) {
+ for (i = 0; cmd_table[i].cmd; i++) {
if (g_strcmp0(cmd_table[i].cmd, argv[0]) == 0 &&
- cmd_table[i].func != NULL) {
+ cmd_table[i].func) {
result = cmd_table[i].func(argv, argc,
cmd_table[i].options);
if (result < 0 && result != -EINPROGRESS)
@@ -1523,7 +2232,7 @@ char *__connmanctl_lookup_command(const char *text, int state)
len = strlen(text);
}
- while (cmd_table[i].cmd != NULL) {
+ while (cmd_table[i].cmd) {
const char *command = cmd_table[i].cmd;
i++;
@@ -1534,3 +2243,311 @@ char *__connmanctl_lookup_command(const char *text, int state)
return NULL;
}
+
+static char *get_path(char *full_path)
+{
+ char *path;
+
+ path = strrchr(full_path, '/');
+ if (path && *path != '\0')
+ path++;
+ else
+ path = full_path;
+
+ return path;
+}
+
+static void add_service_id(const char *path)
+{
+ g_hash_table_replace(service_hash, g_strdup(path),
+ GINT_TO_POINTER(TRUE));
+}
+
+static void remove_service_id(const char *path)
+{
+ g_hash_table_remove(service_hash, path);
+}
+
+static void services_added(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+ char *path = NULL;
+
+ while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
+
+ dbus_message_iter_recurse(iter, &array);
+ if (dbus_message_iter_get_arg_type(&array) !=
+ DBUS_TYPE_OBJECT_PATH)
+ return;
+
+ dbus_message_iter_get_basic(&array, &path);
+ add_service_id(get_path(path));
+
+ dbus_message_iter_next(iter);
+ }
+}
+
+static void update_services(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+ char *path;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ services_added(&array);
+
+ dbus_message_iter_next(iter);
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ while (dbus_message_iter_get_arg_type(&array) ==
+ DBUS_TYPE_OBJECT_PATH) {
+ dbus_message_iter_get_basic(&array, &path);
+ remove_service_id(get_path(path));
+
+ dbus_message_iter_next(&array);
+ }
+}
+
+static int populate_service_hash(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ update_services(iter);
+ return 0;
+}
+
+static void add_peer_id(const char *path)
+{
+ g_hash_table_replace(peer_hash, g_strdup(path), GINT_TO_POINTER(TRUE));
+}
+
+static void remove_peer_id(const char *path)
+{
+ g_hash_table_remove(peer_hash, path);
+}
+
+static void peers_added(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+ char *path = NULL;
+
+ while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
+
+ dbus_message_iter_recurse(iter, &array);
+ if (dbus_message_iter_get_arg_type(&array) !=
+ DBUS_TYPE_OBJECT_PATH)
+ return;
+
+ dbus_message_iter_get_basic(&array, &path);
+ add_peer_id(get_path(path));
+
+ dbus_message_iter_next(iter);
+ }
+}
+
+static void update_peers(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+ char *path;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ peers_added(&array);
+
+ dbus_message_iter_next(iter);
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ while (dbus_message_iter_get_arg_type(&array) ==
+ DBUS_TYPE_OBJECT_PATH) {
+ dbus_message_iter_get_basic(&array, &path);
+ remove_peer_id(get_path(path));
+
+ dbus_message_iter_next(&array);
+ }
+}
+
+static int populate_peer_hash(DBusMessageIter *iter,
+ const char *error, void *user_data)
+{
+ update_peers(iter);
+ return 0;
+}
+
+static void add_technology_id(const char *path)
+{
+ g_hash_table_replace(technology_hash, g_strdup(path),
+ GINT_TO_POINTER(TRUE));
+}
+
+static void remove_technology_id(const char *path)
+{
+ g_hash_table_remove(technology_hash, path);
+}
+
+static void remove_technology(DBusMessageIter *iter)
+{
+ char *path = NULL;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH)
+ return;
+
+ dbus_message_iter_get_basic(iter, &path);
+ remove_technology_id(get_path(path));
+}
+
+static void add_technology(DBusMessageIter *iter)
+{
+ char *path = NULL;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH)
+ return;
+
+ dbus_message_iter_get_basic(iter, &path);
+ add_technology_id(get_path(path));
+}
+
+static void update_technologies(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
+ DBusMessageIter object_path;
+
+ dbus_message_iter_recurse(&array, &object_path);
+
+ add_technology(&object_path);
+
+ dbus_message_iter_next(&array);
+ }
+}
+
+static int populate_technology_hash(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ update_technologies(iter);
+
+ return 0;
+}
+
+static DBusHandlerResult monitor_completions_changed(
+ DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ bool *enabled = user_data;
+ DBusMessageIter iter;
+ DBusHandlerResult handled;
+
+ if (*enabled)
+ handled = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ else
+ handled = DBUS_HANDLER_RESULT_HANDLED;
+
+ if (dbus_message_is_signal(message, "net.connman.Manager",
+ "ServicesChanged")) {
+ dbus_message_iter_init(message, &iter);
+ update_services(&iter);
+ return handled;
+ }
+
+ if (dbus_message_is_signal(message, "net.connman.Manager",
+ "PeersChanged")) {
+ dbus_message_iter_init(message, &iter);
+ update_peers(&iter);
+ return handled;
+ }
+
+ if (dbus_message_is_signal(message, "net.connman.Manager",
+ "TechnologyAdded")) {
+ dbus_message_iter_init(message, &iter);
+ add_technology(&iter);
+ return handled;
+ }
+
+ if (dbus_message_is_signal(message, "net.connman.Manager",
+ "TechnologyRemoved")) {
+ dbus_message_iter_init(message, &iter);
+ remove_technology(&iter);
+ return handled;
+ }
+
+ if (!g_strcmp0(dbus_message_get_interface(message),
+ "net.connman.Manager"))
+ return handled;
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+void __connmanctl_monitor_completions(DBusConnection *dbus_conn)
+{
+ bool *manager_enabled = NULL;
+ DBusError err;
+ int i;
+
+ for (i = 0; monitor[i].interface; i++) {
+ if (!strcmp(monitor[i].interface, "Manager")) {
+ manager_enabled = &monitor[i].enabled;
+ break;
+ }
+ }
+
+ if (!dbus_conn) {
+ g_hash_table_destroy(service_hash);
+ g_hash_table_destroy(technology_hash);
+
+ dbus_bus_remove_match(connection,
+ "type='signal',interface='net.connman.Manager'", NULL);
+ dbus_connection_remove_filter(connection,
+ monitor_completions_changed,
+ manager_enabled);
+ return;
+ }
+
+ connection = dbus_conn;
+
+ service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ peer_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ technology_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager", "GetServices",
+ populate_service_hash, NULL, NULL, NULL);
+
+ __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager", "GetPeers",
+ populate_peer_hash, NULL, NULL, NULL);
+
+ __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager", "GetTechnologies",
+ populate_technology_hash, NULL, NULL, NULL);
+
+ dbus_connection_add_filter(connection,
+ monitor_completions_changed, manager_enabled,
+ NULL);
+
+ dbus_error_init(&err);
+ dbus_bus_add_match(connection,
+ "type='signal',interface='net.connman.Manager'", &err);
+
+ if (dbus_error_is_set(&err))
+ fprintf(stderr, "Error: %s\n", err.message);
+}
diff --git a/client/commands.h b/client/commands.h
index b2d606c6..d5d1becf 100644
--- a/client/commands.h
+++ b/client/commands.h
@@ -29,8 +29,12 @@
extern "C" {
#endif
+typedef char *(*__connmanctl_lookup_cb)(const char *text, int state);
+
int __connmanctl_commands(DBusConnection *connection, char *argv[], int argc);
char *__connmanctl_lookup_command(const char *text, int state);
+void __connmanctl_monitor_completions(DBusConnection *dbus_conn);
+__connmanctl_lookup_cb __connmanctl_get_lookup_func(const char *text);
#ifdef __cplusplus
}
diff --git a/client/dbus_helpers.c b/client/dbus_helpers.c
index 0d79f97c..826111f2 100644
--- a/client/dbus_helpers.c
+++ b/client/dbus_helpers.c
@@ -43,7 +43,7 @@ void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
char *str;
DBusMessageIter entry;
- if (pre == NULL)
+ if (!pre)
pre = "";
while ((arg_type = dbus_message_iter_get_arg_type(iter))
@@ -87,7 +87,7 @@ void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
case DBUS_TYPE_BOOLEAN:
dbus_message_iter_get_basic(iter, &b);
- if (b == FALSE)
+ if (!b)
fprintf(stdout, "False");
else
fprintf(stdout, "True");
@@ -123,7 +123,7 @@ void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
break;
}
- if (dbus_message_iter_has_next(iter) == TRUE)
+ if (dbus_message_iter_has_next(iter))
fprintf(stdout, "%s", sep);
dbus_message_iter_next(iter);
@@ -177,14 +177,13 @@ static int send_method_call(DBusConnection *connection,
DBusPendingCall *call;
struct dbus_callback *callback;
- if (dbus_connection_send_with_reply(connection, message, &call,
- TIMEOUT) == FALSE)
+ if (!dbus_connection_send_with_reply(connection, message, &call, TIMEOUT))
goto end;
- if (call == NULL)
- goto end;
+ if (!call)
+ goto end;
- if (cb != NULL) {
+ if (cb) {
callback = g_new0(struct dbus_callback, 1);
callback->cb = cb;
callback->user_data = user_data;
@@ -230,20 +229,22 @@ static int append_variant(DBusMessageIter *iter, const char *property,
int __connmanctl_dbus_method_call(DBusConnection *connection,
const char *service, const char *path, const char *interface,
const char *method, connmanctl_dbus_method_return_func_t cb,
- void *user_data, int arg1, ...)
+ void *user_data, connmanctl_dbus_append_func_t append_func,
+ void *append_data)
{
DBusMessage *message;
- va_list args;
+ DBusMessageIter iter;
message = dbus_message_new_method_call(service, path, interface,
method);
- if (message == NULL)
+ if (!message)
return -ENOMEM;
- va_start(args, arg1);
- dbus_message_append_args_valist(message, arg1, args);
- va_end(args);
+ if (append_func) {
+ dbus_message_iter_init_append(message, &iter);
+ append_func(&iter, append_data);
+ }
return send_method_call(connection, message, cb, user_data);
}
@@ -259,7 +260,7 @@ int __connmanctl_dbus_set_property(DBusConnection *connection,
message = dbus_message_new_method_call("net.connman", path,
interface, "SetProperty");
- if (message == NULL)
+ if (!message)
return -ENOMEM;
dbus_message_iter_init_append(message, &iter);
@@ -272,6 +273,22 @@ int __connmanctl_dbus_set_property(DBusConnection *connection,
return send_method_call(connection, message, cb, user_data);
}
+void __connmanctl_dbus_append_dict(DBusMessageIter *iter,
+ connmanctl_dbus_append_func_t append_fn, void *append_data)
+{
+ DBusMessageIter dict;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ if (append_fn)
+ append_fn(&dict, append_data);
+
+ dbus_message_iter_close_container(iter, &dict);
+}
+
void __connmanctl_dbus_append_dict_entry(DBusMessageIter *iter,
const char *property, int type, void *value)
{
@@ -298,7 +315,7 @@ int __connmanctl_dbus_set_property_dict(DBusConnection *connection,
message = dbus_message_new_method_call("net.connman", path,
interface, "SetProperty");
- if (message == NULL)
+ if (!message)
return -ENOMEM;
dbus_message_iter_init_append(message, &iter);
@@ -378,7 +395,54 @@ int __connmanctl_dbus_set_property_array(DBusConnection *connection,
message = dbus_message_new_method_call("net.connman", path,
interface, "SetProperty");
- if (message == NULL)
+ if (!message)
+ return -ENOMEM;
+
+ dbus_message_iter_init_append(message, &iter);
+
+ append_variant_array(&iter, property, append_fn, append_user_data);
+
+ return send_method_call(connection, message, cb, user_data);
+}
+
+int __connmanctl_dbus_session_change(DBusConnection *connection,
+ const char *session_path,
+ connmanctl_dbus_method_return_func_t cb, void * user_data,
+ const char *property, int type, void *value)
+{
+ DBusMessage *message;
+ DBusMessageIter iter;
+
+ message = dbus_message_new_method_call("net.connman", session_path,
+ "net.connman.Session", "Change");
+
+ if (!message)
+ return -ENOMEM;
+
+ dbus_message_iter_init_append(message, &iter);
+
+ if (append_variant(&iter, property, type, value) < 0) {
+ dbus_message_unref(message);
+ return -EINVAL;
+ }
+
+ return send_method_call(connection, message, cb, user_data);
+}
+
+int __connmanctl_dbus_session_change_array(DBusConnection *connection,
+ const char *session_path,
+ connmanctl_dbus_method_return_func_t cb, void *user_data,
+ const char *property,
+ connmanctl_dbus_append_func_t append_fn,
+ void *append_user_data)
+{
+ DBusMessage *message;
+ DBusMessageIter iter;
+
+ message = dbus_message_new_method_call("net.connman", session_path,
+ "net.connman.Session", "Change");
+
+ if (!message)
return -ENOMEM;
dbus_message_iter_init_append(message, &iter);
diff --git a/client/dbus_helpers.h b/client/dbus_helpers.h
index 9fc21648..395808ac 100644
--- a/client/dbus_helpers.h
+++ b/client/dbus_helpers.h
@@ -39,21 +39,27 @@ void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
typedef int (*connmanctl_dbus_method_return_func_t)(DBusMessageIter *iter,
const char *error, void *user_data);
+
+typedef void (*connmanctl_dbus_append_func_t)(DBusMessageIter *iter,
+ void *user_data);
+
int __connmanctl_dbus_method_call(DBusConnection *connection,
const char *service, const char *path, const char *interface,
const char *method, connmanctl_dbus_method_return_func_t cb,
- void * user_data, int arg1, ...);
+ void * user_data, connmanctl_dbus_append_func_t append_fn,
+ void *append_data);
int __connmanctl_dbus_set_property(DBusConnection *connection,
const char *path, const char *interface,
connmanctl_dbus_method_return_func_t cb, void * user_data,
const char *property, int type, void *value);
-typedef void (*connmanctl_dbus_append_func_t)(DBusMessageIter *iter,
- void *user_data);
+void __connmanctl_dbus_append_dict(DBusMessageIter *iter,
+ connmanctl_dbus_append_func_t append_fn, void *append_data);
void __connmanctl_dbus_append_dict_entry(DBusMessageIter *iter,
const char *property, int type, void *value);
+
int __connmanctl_dbus_set_property_dict(DBusConnection *connection,
const char *path, const char *interface,
connmanctl_dbus_method_return_func_t cb, void * user_data,
@@ -71,6 +77,18 @@ int __connmanctl_dbus_set_property_array(DBusConnection *connection,
connmanctl_dbus_append_func_t append_fn,
void *append_user_data);
+int __connmanctl_dbus_session_change(DBusConnection *connection,
+ const char *session_path,
+ connmanctl_dbus_method_return_func_t cb, void * user_data,
+ const char *property, int type, void *value);
+
+int __connmanctl_dbus_session_change_array(DBusConnection *connection,
+ const char *session_path,
+ connmanctl_dbus_method_return_func_t cb, void *user_data,
+ const char *property,
+ connmanctl_dbus_append_func_t append_fn,
+ void *append_user_data);
+
#ifdef __cplusplus
}
#endif
diff --git a/client/input.c b/client/input.c
index 8d6ecca7..97058712 100644
--- a/client/input.c
+++ b/client/input.c
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2012-2014 Intel Corporation. All rights reserved.
*
* 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
@@ -45,7 +45,7 @@ static int saved_point;
void __connmanctl_quit(void)
{
- if (main_loop != NULL)
+ if (main_loop)
g_main_loop_quit(main_loop);
}
@@ -85,7 +85,7 @@ static void rl_handler(char *input)
char **args, **trim_args;
int num, len, err, i;
- if (input == NULL) {
+ if (!input) {
rl_newline(1, '\n');
g_main_loop_quit(main_loop);
return;
@@ -135,17 +135,51 @@ static char **complete_agent(const char *text, int start, int end)
return NULL;
}
-static char **complete_command(const char *text, int start, int end)
+/* Return how many parameters we have typed */
+int __connmanctl_input_calc_level(void)
{
- char **command = NULL;
+ int count = 0;
+ char *ptr;
+
+ ptr = rl_line_buffer;
+
+ while (*ptr) {
+ if (*ptr == ' ') {
+ if (*(ptr + 1) == ' ') {
+ ptr++;
+ continue;
+ } else
+ count++;
+ }
+ ptr++;
+ }
+
+ return count;
+}
+void __connmanctl_input_lookup_end(void)
+{
rl_attempted_completion_over = 1;
+}
- if (start == 0)
- command = rl_completion_matches(text,
+static char **complete_command(const char *text, int start, int end)
+{
+ if (start == 0) {
+ return rl_completion_matches(text,
__connmanctl_lookup_command);
- return command;
+ } else {
+ __connmanctl_lookup_cb cb;
+ char **str = NULL;
+
+ cb = __connmanctl_get_lookup_func(rl_line_buffer);
+ if (cb)
+ str = rl_completion_matches(text, cb);
+ else
+ rl_attempted_completion_over = 1;
+
+ return str;
+ }
}
static struct {
@@ -164,7 +198,7 @@ void __connmanctl_agent_mode(const char *prompt,
agent_handler.cb = input_handler;
agent_handler.user_data = user_data;
- if (input_handler != NULL)
+ if (input_handler)
rl_callback_handler_install(prompt, rl_agent_handler);
else {
rl_set_prompt(prompt);
@@ -200,17 +234,20 @@ int __connmanctl_input_init(int argc, char *argv[])
return 1;
}
- channel = g_io_channel_unix_new(fileno(stdin));
- source = g_io_add_watch(channel, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
- input_handler, NULL);
- g_io_channel_unref(channel);
-
if (argc < 2) {
interactive = true;
+ channel = g_io_channel_unix_new(fileno(stdin));
+ source = g_io_add_watch(channel,
+ G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
+ input_handler, NULL);
+ g_io_channel_unref(channel);
+
+ __connmanctl_monitor_completions(connection);
+
__connmanctl_command_mode();
- err = -EINPROGRESS;
+ err = -EINPROGRESS;
} else {
interactive = false;
@@ -219,7 +256,7 @@ int __connmanctl_input_init(int argc, char *argv[])
err = __connmanctl_commands(connection, help, 1);
else
err = __connmanctl_commands(connection, argv + 1,
- argc -1);
+ argc - 1);
}
if (err == -EINPROGRESS) {
@@ -229,15 +266,16 @@ int __connmanctl_input_init(int argc, char *argv[])
err = 0;
}
- g_source_remove(source);
+ if (interactive) {
+ g_source_remove(source);
+ __connmanctl_monitor_completions(NULL);
- if (interactive == true) {
rl_callback_handler_remove();
rl_message("");
}
dbus_connection_unref(connection);
- if (main_loop != NULL)
+ if (main_loop)
g_main_loop_unref(main_loop);
if (err < 0)
diff --git a/client/input.h b/client/input.h
index fb800779..c7256a41 100644
--- a/client/input.h
+++ b/client/input.h
@@ -2,7 +2,7 @@
*
* Connection Manager
*
- * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2012-2014 Intel Corporation. All rights reserved.
*
* 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
@@ -33,6 +33,8 @@ void __connmanctl_quit(void);
bool __connmanctl_is_interactive(void);
void __connmanctl_save_rl(void);
void __connmanctl_redraw_rl(void);
+int __connmanctl_input_calc_level(void);
+void __connmanctl_input_lookup_end(void);
typedef void (* connmanctl_input_func_t) (char *input, void *user_data);
void __connmanctl_agent_mode(const char *prompt,
connmanctl_input_func_t input_handler, void *user_data);
diff --git a/client/peers.c b/client/peers.c
new file mode 100644
index 00000000..bf1aa0ea
--- /dev/null
+++ b/client/peers.c
@@ -0,0 +1,122 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2014 Intel Corporation. All rights reserved.
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "peers.h"
+
+static void print_peer(char *path, DBusMessageIter *iter)
+{
+ char *name = "", *state = "";
+ char *str, *property;
+ DBusMessageIter entry, val;
+ int count = 0;
+
+ while (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
+ dbus_message_iter_recurse(iter, &entry);
+ dbus_message_iter_get_basic(&entry, &property);
+
+ if (strcmp(property, "Name") == 0) {
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &val);
+ dbus_message_iter_get_basic(&val, &name);
+ } else if (strcmp(property, "State") == 0) {
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &val);
+ dbus_message_iter_get_basic(&val, &state);
+ }
+
+ dbus_message_iter_next(iter);
+ count++;
+ }
+
+ str = strrchr(path, '/');
+ if (str)
+ str++;
+ else
+ str = path;
+
+ if (count > 0)
+ fprintf(stdout, "%s %s %s", name, state, str);
+ else
+ fprintf(stdout, "%s %s", "unchanged", str);
+}
+
+static void list_peer_array(DBusMessageIter *iter)
+{
+ DBusMessageIter array, dict;
+ char *path = NULL;
+
+ while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
+ dbus_message_iter_recurse(iter, &array);
+ if (dbus_message_iter_get_arg_type(&array)
+ != DBUS_TYPE_OBJECT_PATH)
+ return;
+
+ dbus_message_iter_get_basic(&array, &path);
+
+ dbus_message_iter_next(&array);
+ if (dbus_message_iter_get_arg_type(&array)
+ == DBUS_TYPE_ARRAY) {
+ dbus_message_iter_recurse(&array, &dict);
+ print_peer(path, &dict);
+ }
+
+ if (dbus_message_iter_has_next(iter))
+ fprintf(stdout, "\n");
+
+ dbus_message_iter_next(iter);
+ }
+}
+
+void __connmanctl_peers_list(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+ char *path;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ list_peer_array(&array);
+
+ dbus_message_iter_next(iter);
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ fprintf(stdout, "\n}, {");
+
+ dbus_message_iter_recurse(iter, &array);
+ while (dbus_message_iter_get_arg_type(&array)
+ == DBUS_TYPE_OBJECT_PATH) {
+ dbus_message_iter_get_basic(&array, &path);
+ fprintf(stdout, "\n%s %s", "removed", path);
+
+ dbus_message_iter_next(&array);
+ }
+
+}
diff --git a/client/peers.h b/client/peers.h
new file mode 100644
index 00000000..fdf7ce76
--- /dev/null
+++ b/client/peers.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2014 Intel Corporation. All rights reserved.
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __CONNMANCTL_PEERS_H
+#define __CONNMANCTL_PEERS_H
+
+#include <dbus/dbus.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void __connmanctl_peers_list(DBusMessageIter *iter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CONNMANCTL_PEERS_H */
diff --git a/client/services.c b/client/services.c
index 045947c8..0c18669b 100644
--- a/client/services.c
+++ b/client/services.c
@@ -57,11 +57,17 @@ static void print_service(char *path, DBusMessageIter *iter)
dbus_message_iter_recurse(&entry, &val);
dbus_message_iter_get_basic(&val, &str);
- if (str != NULL) {
+ if (str) {
if (strcmp(str, "online") == 0)
state = 'O';
else if (strcmp(str, "ready") == 0)
state = 'R';
+ else if (!strcmp(str, "association"))
+ state = 'a';
+ else if (!strcmp(str, "configuration"))
+ state = 'c';
+ else if (!strcmp(str, "disconnect"))
+ state = 'd';
}
} else if (strcmp(property, "AutoConnect") == 0) {
@@ -80,18 +86,15 @@ static void print_service(char *path, DBusMessageIter *iter)
}
str = strrchr(path, '/');
- if (str != NULL)
+ if (str)
str++;
else
str = path;
- if (count > 0) {
- if (*name == '\0')
- name = "<hidden>";
-
+ if (count > 0)
fprintf(stdout, "%c%c%c %-20s %s", favorite != 0 ? '*' : ' ',
autoconn != 0 ? 'A' : ' ', state, name, str);
- } else
+ else
fprintf(stdout, "%-24s %s", "unchanged", str);
}
@@ -117,7 +120,7 @@ static void list_service_array(DBusMessageIter *iter)
print_service(path, &dict);
}
- if (dbus_message_iter_has_next(iter) == TRUE)
+ if (dbus_message_iter_has_next(iter))
fprintf(stdout, "\n");
dbus_message_iter_next(iter);
diff --git a/client/vpnconnections.c b/client/vpnconnections.c
index f4b8d3cb..d7bcbfee 100644
--- a/client/vpnconnections.c
+++ b/client/vpnconnections.c
@@ -53,7 +53,7 @@ static void print_connection(char *path, DBusMessageIter *iter)
dbus_message_iter_recurse(&entry, &val);
dbus_message_iter_get_basic(&val, &str);
- if (str != NULL) {
+ if (str) {
if (strcmp(str, "ready") == 0)
state = 'R';
else if (strcmp(str, "configuration") == 0)
@@ -67,7 +67,7 @@ static void print_connection(char *path, DBusMessageIter *iter)
}
str = strrchr(path, '/');
- if (str != NULL)
+ if (str)
str++;
else
str = path;
@@ -101,7 +101,7 @@ void __connmanctl_vpnconnections_list(DBusMessageIter *iter)
print_connection(path, &dict);
}
- if (dbus_message_iter_has_next(&array) == TRUE)
+ if (dbus_message_iter_has_next(&array))
fprintf(stdout, "\n");
dbus_message_iter_next(&array);