summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCeara Chewning <ceara.k.chewning@intel.com>2012-09-12 15:05:55 -0700
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-09-14 16:32:00 +0300
commitcfcb41b997d17e047ae2fa6e356babccca140f3b (patch)
treec1cdae6cae04c9d77b5ee584e2f7cc6693de9c68
parent800d3a8630992f400f2d0336a2e337db2456928f (diff)
downloadconnman-cfcb41b997d17e047ae2fa6e356babccca140f3b.tar.gz
connman-cfcb41b997d17e047ae2fa6e356babccca140f3b.tar.bz2
connman-cfcb41b997d17e047ae2fa6e356babccca140f3b.zip
client: Implement command line client commands
Implement all of the command handling that connmanctl uses. Both the main program and interactive mode should use the same commands, thus there is no separation between the abilities of the two modes.
-rw-r--r--client/commands.c526
1 files changed, 526 insertions, 0 deletions
diff --git a/client/commands.c b/client/commands.c
new file mode 100644
index 00000000..7dca753f
--- /dev/null
+++ b/client/commands.c
@@ -0,0 +1,526 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+
+#include <glib.h>
+#include <gdbus.h>
+
+#include "client/services.h"
+#include "client/technology.h"
+#include "client/data_manager.h"
+#include "client/monitor.h"
+#include "client/interactive.h"
+#include "gdbus/gdbus.h"
+
+#define MANDATORY_ARGS 3
+
+static char *ipv4[] = {
+ "Method",
+ "Address",
+ "Netmask",
+ "Gateway",
+ NULL
+};
+
+static char *ipv6[] = {
+ "Method",
+ "Address",
+ "PrefixLength",
+ "Gateway",
+ "Privacy",
+ NULL
+};
+
+static char *proxy_simple[] = {
+ "Method",
+ "URL",
+ NULL
+};
+
+void show_help(void)
+{
+ printf("Usage: connmanctl <command> [args]\n"
+ " enable Enables given technology\n"
+ " <technology>\n"
+ " offlinemode Enables OfflineMode\n"
+ " disable Disables given technology\n"
+ " <technology>\n"
+ " offlinemode Disables OfflineMode\n"
+ " state Shows if the system is online or offline\n"
+ " services Display list of all services\n"
+ " --properties <service name> Show properties of service\n"
+ " tech Current technology on the system\n"
+ " scan <technology> Scans for new services on the given technology\n"
+ " connect <service> Connect to a given service\n"
+ " disconnect <service> Disconnect from service\n"
+ " config <service> [arg] Set certain config options\n"
+ " --autoconnect=y/n Set autoconnect to service\n"
+ " --nameservers <names> Set manual name servers\n"
+ " --timeservers <names> Set manual time servers\n"
+ " --domains <domains> Set manual domains\n"
+ " --ipv4 Set ipv4 configuration\n"
+ " [METHOD|DHCP|AUTO|MANUAL] [IP] [NETMASK] [GATEWAY]\n"
+ " --ipv6 Set ipv6 configuration\n"
+ " [METHOD|AUTO|MANUAL|OFF] [IP] [PREFIXLENGTH] [GATEWAY]\n"
+ " [PRIVACY|DISABLED|ENABLED|PREFERED]\n"
+ " --proxy Set proxy configuration\n"
+ " [METHOD|URL|SERVERS|EXCLUDES]\n"
+ " if METHOD = manual, enter 'servers' then the list of servers\n"
+ " then enter 'excludes' then the list of excludes\n"
+ " monitor Monitor signals from all Connman interfaces\n"
+ " --services Monitor signals from the Service interface\n"
+ " --tech Monitor signals from the Technology interface\n"
+ " --manager Monitor signals from the Manager interface\n"
+ " help, --help, (no arguments) Show this dialogue\n"
+ " interactive Drop into the interactive shell\n"
+ " exit, quit, q Quit interactive mode\n");
+}
+
+int service_switch(int argc, char *argv[], int c, DBusConnection *conn,
+ struct service_data *service)
+{
+ const char *name;
+ DBusMessage *message;
+ int error;
+
+ message = get_message(conn, "GetServices");
+
+ switch (c) {
+ case 'p':
+ name = find_service(conn, message, argv[2], service);
+ if (name == NULL)
+ return -ENXIO;
+ error = list_properties(conn, "GetServices", (char *) name);
+ if (error != 0)
+ return error;
+ break;
+ default:
+ fprintf(stderr, "Command not recognized, please check help\n");
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+int config_switch(int argc, char *argv[], int c, DBusConnection *conn)
+{
+ DBusMessage *message;
+ int num_args = argc - MANDATORY_ARGS;
+ int error;
+ dbus_bool_t val;
+
+ message = get_message(conn, "GetServices");
+
+ switch (c) {
+ case 'a':
+ if (*optarg != 'y' || *optarg != 'n' || *optarg != '1' ||
+ *optarg != '0' || *optarg != 't' ||
+ *optarg != 'f')
+ return -EINVAL;
+ if (*optarg == 'y' || *optarg == '1' ||
+ *optarg == 't')
+ val = TRUE;
+ else if (*optarg == 'n' || *optarg == '0' ||
+ *optarg == 'f')
+ val = FALSE;
+ error = set_service_property(conn, message, argv[1],
+ "AutoConnect", NULL,
+ &val, 0);
+ if (error != 0)
+ return error;
+ break;
+ case 'i':
+ error = set_service_property(conn, message, argv[1],
+ "IPv4.Configuration", ipv4,
+ argv + MANDATORY_ARGS, num_args);
+ if (error != 0)
+ return error;
+ break;
+ case 'v':
+ error = set_service_property(conn, message, argv[1],
+ "IPv6.Configuration", ipv6,
+ argv + MANDATORY_ARGS, num_args);
+ if (error != 0)
+ return error;
+ break;
+ case 'n':
+ error = set_service_property(conn, message, argv[1],
+ "Nameservers.Configuration", NULL,
+ argv + MANDATORY_ARGS, num_args);
+ if (error != 0)
+ return error;
+ break;
+ case 't':
+ error = set_service_property(conn, message, argv[1],
+ "Timeservers.Configuration", NULL,
+ argv + MANDATORY_ARGS, num_args);
+ if (error != 0)
+ return error;
+ break;
+ case 'd':
+ error = set_service_property(conn, message, argv[1],
+ "Domains.Configuration", NULL,
+ argv + MANDATORY_ARGS, num_args);
+ if (error != 0)
+ return error;
+ break;
+ case 'x':
+ if ((strcmp(argv[3], "direct") == 0 && argc < 5) ||
+ (strcmp(argv[3], "auto") == 0 && argc < 6)) {
+ error = set_service_property(conn, message, argv[1],
+ "Proxy.Configuration", proxy_simple,
+ argv + MANDATORY_ARGS, num_args);
+ if (error != 0)
+ return error;
+ } else if (strcmp(argv[3], "manual") == 0
+ && strcmp(argv[4], "servers") == 0
+ && argc > 5) {
+ argc -= 5;
+ error = store_proxy_input(conn, message, argv[1],
+ argc, &argv[5]);
+ if (error != 0)
+ return error;
+ } else {
+ fprintf(stderr, "Incorrect arguments\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ fprintf(stderr, "Command not recognized, please check help\n");
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+int monitor_switch(int argc, char *argv[], int c, DBusConnection *conn)
+{
+ int error;
+
+ switch (c) {
+ case 's':
+ error = monitor_connman(conn, "Service", "PropertyChanged");
+ if (error != 0)
+ return error;
+ if (dbus_connection_add_filter(conn, service_property_changed,
+ NULL, NULL) == FALSE)
+ return -ENOMEM;
+ printf("Now monitoring the service interface.\n");
+ break;
+ case 'c':
+ error = monitor_connman(conn, "Technology", "PropertyChanged");
+ if (error != 0)
+ return error;
+ if (dbus_connection_add_filter(conn, tech_property_changed,
+ NULL, NULL) == FALSE)
+ return -ENOMEM;
+ printf("Now monitoring the technology interface.\n");
+ break;
+ case 'm':
+ error = monitor_connman(conn, "Manager", "PropertyChanged");
+ if (error != 0)
+ return error;
+ error = monitor_connman(conn, "Manager", "TechnologyAdded");
+ if (error != 0)
+ return error;
+ error = monitor_connman(conn, "Manager", "TechnologyRemoved");
+ if (error != 0)
+ return error;
+ error = monitor_connman(conn, "Manager", "ServicesChanged");
+ if (error != 0)
+ return error;
+ if (dbus_connection_add_filter(conn, manager_property_changed,
+ NULL, NULL) == FALSE)
+ return -ENOMEM;
+ if (dbus_connection_add_filter(conn, tech_added_removed,
+ NULL, NULL) == FALSE)
+ return -ENOMEM;
+ if (dbus_connection_add_filter(conn, manager_services_changed,
+ NULL, NULL) == FALSE)
+ return -ENOMEM;
+ printf("Now monitoring the manager interface.\n");
+ break;
+ default:
+ fprintf(stderr, "Command not recognized, please check help\n");
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+int commands_no_options(DBusConnection *connection, char *argv[], int argc)
+{
+ int error;
+ DBusMessage *message;
+
+
+ if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "help") == 0 ||
+ strcmp(argv[0], "h") == 0) {
+ show_help();
+ } else if (strcmp(argv[0], "state") == 0) {
+ if (argc != 1) {
+ fprintf(stderr, "State cannot accept an argument, "
+ "see help\n");
+ return -EINVAL;
+ }
+ error = list_properties(connection, "GetProperties", NULL);
+ if (error != 0)
+ return error;
+ } else if (strcmp(argv[0], "tech") == 0) {
+ if (argc != 1) {
+ fprintf(stderr, "Tech cannot accept an argument, "
+ "see help\n");
+ return -EINVAL;
+ }
+ error = list_properties(connection, "GetTechnologies", NULL);
+ if (error != 0)
+ return error;
+ } else if (strcmp(argv[0], "connect") == 0) {
+ if (argc != 2) {
+ fprintf(stderr, "Connect requires a service name or "
+ "path, see help\n");
+ return -EINVAL;
+ }
+ error = connect_service(connection, strip_service_path(argv[1]));
+ if (error != 0)
+ return error;
+ printf("Connected to: %s\n", strip_service_path(argv[1]));
+ } else if (strcmp(argv[0], "disconnect") == 0) {
+ if (argc != 2) {
+ fprintf(stderr, "Disconnect requires a service name or "
+ "path, see help\n");
+ return -EINVAL;
+ }
+ error = disconnect_service(connection, strip_service_path(argv[1]));
+ if (error != 0)
+ return error;
+ printf("Disconnected from: %s\n", strip_service_path(argv[1]));
+ } else if (strcmp(argv[0], "scan") == 0) {
+ if (argc != 2) {
+ fprintf(stderr, "Scan requires a service name or path, "
+ "see help\n");
+ return -EINVAL;
+ }
+ message = get_message(connection, "GetTechnologies");
+ error = scan_technology(connection, message, argv[1]);
+ if (error != 0)
+ return error;
+ dbus_message_unref(message);
+ } else if (strcmp(argv[0], "enable") == 0) {
+ if (argc != 2) {
+ fprintf(stderr, "Enable requires a technology name or "
+ "the argument 'offlinemode', see help\n");
+ return -EINVAL;
+ }
+ if (strcmp(argv[1], "offlinemode") == 0) {
+ error = set_manager(connection, "OfflineMode", TRUE);
+ if (error != 0)
+ return error;
+ printf("OfflineMode is now enabled\n");
+ } else {
+ message = get_message(connection, "GetTechnologies");
+ error = set_technology(connection, message, "Powered",
+ argv[1], TRUE);
+ if (error != 0)
+ return error;
+ printf("Enabled %s technology\n", argv[1]);
+ dbus_message_unref(message);
+ }
+ } else if (strcmp(argv[0], "disable") == 0) {
+ if (argc != 2) {
+ fprintf(stderr, "Disable requires a technology name or "
+ "the argument 'offlinemode' see help\n");
+ return -EINVAL;
+ }
+ if (strcmp(argv[1], "offlinemode") == 0) {
+ error = set_manager(connection, "OfflineMode", FALSE);
+ if (error != 0)
+ return error;
+ printf("OfflineMode is now disabled\n");
+ } else {
+ message = get_message(connection, "GetTechnologies");
+ error = set_technology(connection, message, "Powered",
+ argv[1], FALSE);
+ if (error != 0)
+ return error;
+ printf("Disabled %s technology\n", argv[1]);
+ dbus_message_unref(message);
+ }
+ } else
+ return -1;
+ return 0;
+}
+
+int commands_options(DBusConnection *connection, char *argv[], int argc)
+{
+ int error, c;
+ int option_index = 0;
+ struct service_data service;
+
+ static struct option service_options[] = {
+ {"properties", required_argument, 0, 'p'},
+ {0, 0, 0, 0}
+ };
+
+ static struct option config_options[] = {
+ {"nameservers", required_argument, 0, 'n'},
+ {"timeservers", required_argument, 0, 't'},
+ {"domains", required_argument, 0, 'd'},
+ {"ipv6", required_argument, 0, 'v'},
+ {"proxy", required_argument, 0, 'x'},
+ {"autoconnect", required_argument, 0, 'a'},
+ {"ipv4", required_argument, 0, 'i'},
+ {0, 0, 0, 0}
+ };
+
+ static struct option monitor_options[] = {
+ {"services", no_argument, 0, 's'},
+ {"tech", no_argument, 0, 'c'},
+ {"manager", no_argument, 0, 'm'},
+ {0, 0, 0, 0}
+ };
+
+ if (strcmp(argv[0], "services") == 0) {
+ if (argc > 3) {
+ fprintf(stderr, "Too many arguments for services, "
+ "see help\n");
+ return -EINVAL;
+ }
+ if (argc < 2) {
+ printf("List of all services:\n");
+ error = list_properties(connection, "GetServices", NULL);
+ if (error != 0)
+ return error;
+ } else {
+ while ((c = getopt_long(argc, argv, "", service_options,
+ &option_index))) {
+ if (c == -1) {
+ if (option_index == 0) {
+ printf("Services takes an "
+ "option, see help.\n");
+ return -EINVAL;
+ }
+ break;
+ }
+ error = service_switch(argc, argv, c,
+ connection,
+ &service);
+ if (error != 0)
+ return error;
+ option_index++;
+ }
+ }
+ } else if (strcmp(argv[0], "config") == 0) {
+ if (argc < 3) {
+ fprintf(stderr, "Config requires an option, "
+ "see help\n");
+ return -EINVAL;
+ }
+ while ((c = getopt_long(argc, argv, "", config_options,
+ &option_index))) {
+ if (c == -1) {
+ if (option_index == 0) {
+ printf("Config requires an option, "
+ "see help\n");
+ return -EINVAL;
+ }
+ break;
+ }
+ error = config_switch(argc, argv, c, connection);
+ if (error != 0)
+ return error;
+ option_index++;
+ }
+ } else if (strcmp(argv[0], "monitor") == 0) {
+ if (argc > 2) {
+ fprintf(stderr, "Too many arguments for monitor, "
+ "see help\n");
+ return -EINVAL;
+ }
+ if (argc < 2) {
+ error = monitor_connman(connection, "Service",
+ "PropertyChanged");
+ if (error != 0)
+ return error;
+ error = monitor_connman(connection, "Technology",
+ "PropertyChanged");
+ if (error != 0)
+ return error;
+ error = monitor_connman(connection, "Manager",
+ "PropertyChanged");
+ if (error != 0)
+ return error;
+ error = monitor_connman(connection, "Manager",
+ "TechnologyAdded");
+ if (error != 0)
+ return error;
+ error = monitor_connman(connection, "Manager",
+ "TechnologyRemoved");
+ if (error != 0)
+ return error;
+ error = monitor_connman(connection, "Manager",
+ "ServicesChanged");
+ if (error != 0)
+ return error;
+ if (dbus_connection_add_filter(connection,
+ service_property_changed, NULL, NULL)
+ == FALSE)
+ return -ENOMEM;
+ if (dbus_connection_add_filter(connection,
+ tech_property_changed, NULL, NULL)
+ == FALSE)
+ return -ENOMEM;
+ if (dbus_connection_add_filter(connection,
+ tech_added_removed, NULL, NULL)
+ == FALSE)
+ return -ENOMEM;
+ if (dbus_connection_add_filter(connection,
+ manager_property_changed, NULL, NULL)
+ == FALSE)
+ return -ENOMEM;
+ if (dbus_connection_add_filter(connection,
+ manager_services_changed, NULL, NULL)
+ == FALSE)
+ return -ENOMEM;
+ printf("Now monitoring all interfaces.\n");
+ } else
+ while ((c = getopt_long(argc, argv, "", monitor_options,
+ &option_index))) {
+ if (c == -1) {
+ if (option_index == 0) {
+ printf("Monitor takes an "
+ "option, see help\n");
+ return -EINVAL;
+ }
+ break;
+ }
+ error = monitor_switch(argc, argv, c, connection);
+ if (error != 0)
+ return error;
+ option_index++;
+ }
+ } else
+ return -1;
+ return 0;
+}