Hi,

On Thu, 2012-08-23 at 11:31 -0700, Ceara Chewning wrote:
> The cmn file compiles with the previously added services, technology, data
> manager, monitor, and interactive files to creat the CLI called cmn. This is
> the program a user would run to use connman from the command line. It is able
> to view and configure service, tehnology, and system properties from connman.
> ---
>  client/cmn.c |  380 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 380 insertions(+)
>  create mode 100644 client/cmn.c
> 
> diff --git a/client/cmn.c b/client/cmn.c
> new file mode 100644
> index 0000000..ba1c9de
> --- /dev/null
> +++ b/client/cmn.c
> @@ -0,0 +1,380 @@
> +/*
> + *
> + *  Connection Manager
> + *
> + *  Copyright (C) 2012  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 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 <unistd.h>
> +#include <getopt.h>
> +#include <string.h>
> +
> +#include <glib.h>
> +
> +#include <dbus/dbus.h>
> +#include <dbus/dbus-glib.h>
> +#include <dbus/dbus-glib-lowlevel.h>
> +
> +#include "client/data_manager.h"
> +#include "client/services.h"
> +#include "client/technology.h"
> +#include "client/interactive.h"
> +#include "client/monitor.h"
> +
> +#define MANDATORY_ARGS 4
> +
> +static char *ipv4[] = {
> +     "Method",
> +     "Address",
> +     "Netmask",
> +     "Gateway",
> +     NULL
> +};
> +
> +static char *ipv6[] = {
> +     "Method",
> +     "Address",
> +     "PrefixLength",
> +     "Gateway",
> +     "Privacy",
> +     NULL
> +};
> +
> +static char *proxy_simple[] = {
> +     "Method",
> +     "URL",
> +     NULL
> +};
> +
> +static GMainLoop *main_loop;
> +
> +static void show_help(void)
> +{
> +     fprintf(stdout, "Usage: cmn <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"

I'd go with 'offlinemode' not needing '--' in front. There is no
technology named offlinemode anyway.

> +     "  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                               Scans for new services\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]\n"
> +     "          if METHOD = manual, cmn will prompt you to enter the 
> Servers/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");
> +}
> +
> +static int monitor_connman(DBusConnection *connection, char *interface,
> +                             char *signal_name)
> +{
> +     char *rule = g_strdup_printf("type='signal',interface='net.connman.%s',"
> +                                     "member='%s'", interface, signal_name);
> +     DBusError err;
> +
> +     dbus_error_init(&err);
> +     dbus_connection_setup_with_g_main(connection, NULL);
> +     dbus_bus_add_match(connection, rule, &err);
> +
> +     if (dbus_error_is_set(&err)) {
> +             fprintf(stderr, "Match Error: %s\n", err.message);
> +             return -1;
> +     }
> +     return 0;
> +}
> +
> +static void switch_args(int argc, char *argv[], int c, DBusConnection *conn,
> +                     struct service_data *service)
> +{
> +     const char *name;
> +     DBusMessage *message;
> +     int num_args = argc - MANDATORY_ARGS;
> +
> +     message = get_message(conn, "GetServices");

See below: split up the option processing with one option table per
command. Then make per-command option processing functions for the
needed functions. This will make it easier to understand and extend the
command line program and the comparison against argv[1] is not needed.

> +
> +     switch (c) {
> +     case 'p':
> +             if (strncmp(argv[1], "services", 8) == 0 && argc > 3) {
> +                     fprintf(stdout, "Properties for %s:\n", argv[3]);
> +                     name = find_service(conn, message, argv[3], service);
> +                     if (name == NULL)
> +                             break;
> +                     list_properties(conn, "GetServices", (char *) name);
> +             }
> +             break;
> +     /* Config options */
> +     case 'a':
> +             if (strncmp(argv[1], "config", 6) == 0 && (*optarg == 'y' ||
> +                                                     *optarg == 'n')) {
> +                     dbus_bool_t val;
> +                     if (*optarg == 'y')
> +                             val = TRUE;
> +                     else if (*optarg == 'n')
> +                             val = FALSE;
> +                     set_service_property(conn, message, argv[2],
> +                                             "AutoConnect", NULL,
> +                                             &val, 0);
> +             }
> +             break;
> +     case 'i':
> +             if (strncmp(argv[1], "config", 6) == 0 && argc > 4)
> +                     set_service_property(conn, message, argv[2],
> +                                     "IPv4.Configuration", ipv4,
> +                                     argv + MANDATORY_ARGS, num_args);
> +             break;
> +     case 'v':
> +             if (strncmp(argv[1], "config", 6) == 0 && argc > 4)
> +                     set_service_property(conn, message, argv[2],
> +                                     "IPv6.Configuration", ipv6,
> +                                     argv + MANDATORY_ARGS, num_args);
> +             break;
> +     case 'h':
> +             show_help();
> +             break;
> +     case 'o':
> +             if (strncmp(argv[1], "enable", 6) == 0) {
> +                     set_manager(conn, "OfflineMode", TRUE);
> +                     fprintf(stdout, "OfflineMode is now enabled\n");
> +             } else if (strncmp(argv[1], "disable", 7) == 0) {
> +                     set_manager(conn, "OfflineMode", FALSE);
> +                     fprintf(stdout, "OfflineMode is now disabled\n");
> +             }
> +             break;
> +     case 'n':
> +             if (strncmp(argv[1], "config", 6) == 0 && argc > 4)
> +                     set_service_property(conn, message, argv[2],
> +                                     "Nameservers.Configuration", NULL,
> +                                     argv + MANDATORY_ARGS, num_args);
> +             break;
> +     case 't':
> +             if (strncmp(argv[1], "config", 6) == 0 && argc > 4)
> +                     set_service_property(conn, message, argv[2],
> +                                     "Timeservers.Configuration", NULL,
> +                                     argv + MANDATORY_ARGS, num_args);
> +             break;
> +     case 'd':
> +             if (strncmp(argv[1], "config", 6) == 0 && argc > 4)
> +                     set_service_property(conn, message, argv[2],
> +                                     "Domains.Configuration", NULL,
> +                                     argv + MANDATORY_ARGS, num_args);
> +             break;
> +     case 'x':
> +             if (strncmp(argv[1], "config", 6) == 0 && argc > 4) {
> +                     if ((strncmp(argv[4], "direct", 6) == 0 && argc < 6) ||
> +                             (strncmp(argv[4], "auto", 4) == 0 && argc < 7))
> +                             set_service_property(conn, message, argv[2],
> +                                     "Proxy.Configuration", proxy_simple,
> +                                     argv + MANDATORY_ARGS, num_args);
> +                     else if (strncmp(argv[4], "manual", 6) == 0
> +                                                               && argc < 6) {
> +                             struct proxy_input input = read_proxy_input();
> +                             store_proxy_input(conn, message, argv[2],
> +                                                             input);
> +                     } else {
> +                             fprintf(stderr, "Incorrect arguments\n");
> +                     }
> +             }
> +             break;
> +     case 's':
> +             if (strncmp(argv[1], "monitor", 7) == 0 && argc < 4) {
> +                     monitor_connman(conn, "Service", "PropertyChanged");
> +                     dbus_connection_add_filter(conn, signal_filter, NULL,
> +                                                                     NULL);
> +             }
> +             break;
> +     case 'c':
> +             if (strncmp(argv[1], "monitor", 7) == 0 && argc < 4) {
> +                     monitor_connman(conn, "Technology", "PropertyChanged");
> +                     dbus_connection_add_filter(conn, signal_filter, NULL,
> +                                                                     NULL);
> +             }
> +             break;
> +     case 'm':
> +             if (strncmp(argv[1], "monitor", 7) == 0 && argc < 4) {
> +                     monitor_connman(conn, "Manager", "PropertyChanged");
> +                     monitor_connman(conn, "Manager", "TechnologyAdded");
> +                     monitor_connman(conn, "Manager", "TechnologyRemoved");
> +                     dbus_connection_add_filter(conn, signal_filter, NULL,
> +                                                                     NULL);
> +             }
> +             break;
> +     default:
> +             fprintf(stderr, "Command not recognized, please check help\n");
> +             exit(EXIT_FAILURE);
> +             break;
> +     }
> +}
> +
> +static gboolean timeout_wait(gpointer data)
> +{
> +     static int i;
> +     i++;
> +     /* Set to whatever number of retries is wanted/needed */
> +     if (i == 1) {
> +             g_main_loop_quit(data);
> +             return FALSE;
> +     }
> +     return TRUE;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +     int c;
> +     int option_index = 0;
> +     struct service_data service;
> +     DBusConnection *connection;
> +     DBusMessage *message;
> +     DBusError err;
> +     static struct option long_options[] = {
> +             {"properties", required_argument, 0, 'p'},
> +             {"autoconnect", required_argument, 0, 'a'},
> +             {"ipv4", required_argument, 0, 'i'},
> +             {"help", no_argument, 0, 'h'},
> +             {"offlinemode", no_argument, 0, 'o'},
> +             {"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'},
> +             {"services", no_argument, 0, 's'},
> +             {"tech", no_argument, 0, 'c'},
> +             {"manager", no_argument, 0, 'm'},
> +             {0, 0, 0, 0}
> +     };

In order to keep the command and option parsing simpler to understand,
split up the options table into multiple ones per command. Don't use one
big table, since now arguments like 'monitor --autoconnect=y' will slip
through without any errors printed. When you do one table of options per
command, then it's also easy to do per-command functions where you don't
have to specify what argv[1] command is being processed.

> +     g_type_init();
> +     main_loop = g_main_loop_new(NULL, TRUE);
> +
> +     dbus_error_init(&err);
> +     connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
> +
> +     if (dbus_error_is_set(&err)) {
> +             fprintf(stderr, "Connection Error: %s\n", err.message);
> +             dbus_error_free(&err);
> +     }
> +
> +     if (connection == NULL) {
> +             fprintf(stderr, "Could not connect to system bus...exiting\n");
> +             exit(EXIT_FAILURE);
> +     }
> +
> +     if (argc < 2 || strncmp(argv[1], "--help", 6) == 0 ||
> +                             strncmp(argv[1], "help", 4) == 0) {
> +             show_help();
> +             g_main_loop_unref(main_loop);
> +             exit(EXIT_SUCCESS);
> +     }
> +     if (strncmp(argv[1], "interactive", 11) == 0)
> +             show_interactive(connection);
> +     if (strncmp(argv[1], "state", 5) == 0)
> +             list_properties(connection, "GetProperties", NULL);
> +
> +     /* Display if no options are given */
> +     if (strncmp(argv[1], "services", 8) == 0) {
> +             if (argc < 3) {
> +                     fprintf(stdout, "List of all services:\n");
> +                     list_properties(connection, "GetServices", NULL);
> +             } else if (argc == 3)
> +                     fprintf(stdout, "Current %s services:\n", argv[2]);
> +     }
> +
> +     /* Show current tech on system */
> +     if (strncmp(argv[1], "tech", 4) == 0 && argc < 3) {
> +             fprintf(stdout, "* All currently connected technology:\n");
> +             list_properties(connection, "GetTechnologies", NULL);
> +     }
> +
> +     if (strncmp(argv[1], "connect", 7) == 0 && argc > 2) {
> +             fprintf(stdout, "Connecting to: %s\n",
> +                     strip_service_path(argv[2]));
> +             connect_service(connection, strip_service_path(argv[2]));
> +     }
> +
> +     if (strncmp(argv[1], "disconnect", 10) == 0 && argc > 2) {
> +             fprintf(stdout, "Disconnecting from: %s\n",
> +                     strip_service_path(argv[2]));
> +             disconnect_service(connection, strip_service_path(argv[2]));
> +     }
> +
> +     if (strncmp(argv[1], "scan", 4) == 0 && argc < 3)
> +             scan_technology(connection);
> +
> +     if (strncmp(argv[1], "enable", 6) == 0 && argc == 3) {
> +             message = get_message(connection, "GetTechnologies");
> +             if (set_technology(connection, message, "Powered", argv[2],
> +                                                             TRUE) == 0)
> +                     fprintf(stdout, "Enabled %s technology\n", argv[2]);
> +             dbus_message_unref(message);
> +     }
> +
> +     if (strncmp(argv[1], "disable", 7) == 0 && argc == 3) {
> +             message = get_message(connection, "GetTechnologies");
> +             if (set_technology(connection, message, "Powered", argv[2],
> +                                                             FALSE) == 0)
> +                     fprintf(stdout, "Disabled %s technology\n", argv[2]);
> +             dbus_message_unref(message);
> +     }
> +
> +     if (strncmp(argv[1], "monitor", 7) == 0 && argc == 2) {
> +             monitor_connman(connection, "Service", "PropertyChanged");
> +             monitor_connman(connection, "Technology", "PropertyChanged");
> +             monitor_connman(connection, "Manager", "PropertyChanged");
> +             monitor_connman(connection, "Manager", "TechnologyAdded");
> +             monitor_connman(connection, "Manager", "TechnologyRemoved");
> +             dbus_connection_add_filter(connection, signal_filter, NULL,
> +                                                                     NULL);
> +     }
> +
> +     if (strncmp(argv[1], "monitor", 7) != 0)
> +             g_timeout_add_full(G_PRIORITY_DEFAULT, 100, timeout_wait,
> +                                                            main_loop, NULL);
> +
> +     /* Get options */
> +     while ((c = getopt_long(argc-1, &argv[1], "",
> +             long_options, &option_index))) {
> +             if (c == -1)
> +                     break;
> +             switch_args(argc, argv, c, connection, &service);
> +     }
> +     g_main_loop_run(main_loop);
> +     g_main_loop_unref(main_loop);
> +     return 0;
> +}
> +

And do drop the 'n' in strncmp when comparing against static strings.

Cheers,

        Patrik


_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to