diff options
author | Zhang zhengguang <zhengguang.zhang@intel.com> | 2014-07-17 10:37:39 +0800 |
---|---|---|
committer | Zhang zhengguang <zhengguang.zhang@intel.com> | 2014-07-17 10:37:39 +0800 |
commit | 1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7 (patch) | |
tree | 6e991827d28537f7f40f20786c2354fd04a9fdad /client | |
parent | fbe905ab58ecc31fe64c410c5f580cadc30e7f04 (diff) | |
download | connman-1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7.tar.gz connman-1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7.tar.bz2 connman-1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7.zip |
Imported Upstream version 1.24upstream/1.24
Diffstat (limited to 'client')
-rw-r--r-- | client/agent.c | 79 | ||||
-rw-r--r-- | client/commands.c | 1233 | ||||
-rw-r--r-- | client/commands.h | 4 | ||||
-rw-r--r-- | client/dbus_helpers.c | 98 | ||||
-rw-r--r-- | client/dbus_helpers.h | 24 | ||||
-rw-r--r-- | client/input.c | 76 | ||||
-rw-r--r-- | client/input.h | 4 | ||||
-rw-r--r-- | client/peers.c | 122 | ||||
-rw-r--r-- | client/peers.h | 38 | ||||
-rw-r--r-- | client/services.c | 19 | ||||
-rw-r--r-- | client/vpnconnections.c | 6 |
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, + ¬ify_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); |