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