client: Implement command line client commands
authorCeara Chewning <ceara.k.chewning@intel.com>
Wed, 12 Sep 2012 22:05:55 +0000 (15:05 -0700)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Fri, 14 Sep 2012 13:32:00 +0000 (16:32 +0300)
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.

client/commands.c [new file with mode: 0644]

diff --git a/client/commands.c b/client/commands.c
new file mode 100644 (file)
index 0000000..7dca753
--- /dev/null
@@ -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;
+}