static int cmd_help(char *args[], int num, struct option *options);
-void show_help(void)
+static int parse_args(char *arg, struct option *options)
{
- 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"
- " technologies 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"
- " --remove Remove the service from favorite\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"
- " exit, quit, q Quit interactive mode\n"
- "\nNote: arguments and output are considered EXPERIMENTAL for now.\n\n");
-}
-
-int service_switch(int argc, char *argv[], int c, DBusConnection *conn,
- struct service_data *service)
-{
- const char *name;
- DBusMessage *message;
- int error = 0;
-
- message = get_message(conn, "GetServices");
- if (message == NULL)
- return -ENOMEM;
-
- switch (c) {
- case 'p':
- name = find_service(conn, message, argv[2], service);
- if (name == NULL) {
- error = -ENXIO;
- break;
- }
-
- error = list_properties(conn, "GetServices", (char *) name);
- break;
- default:
- fprintf(stderr, "Command not recognized, please check help\n");
- error = -EINVAL;
- break;
- }
-
- dbus_message_unref(message);
-
- return error;
-}
-
-int config_switch(int argc, char *argv[], int c, DBusConnection *conn)
-{
- DBusMessage *message;
- int num_args = argc - MANDATORY_ARGS;
- int error = 0;
- dbus_bool_t val;
+ int i;
- message = get_message(conn, "GetServices");
- if (message == NULL)
- return -ENOMEM;
+ if (arg == NULL)
+ return -1;
- switch (c) {
- case 'a':
- switch (*optarg) {
- case 'y':
- case '1':
- case 't':
- val = TRUE;
- break;
- case 'n':
- case '0':
- case 'f':
- val = FALSE;
- break;
- default:
- return -EINVAL;
- }
- error = set_service_property(conn, message, argv[1],
- "AutoConnect", NULL,
- &val, 0);
- break;
- case 'i':
- error = set_service_property(conn, message, argv[1],
- "IPv4.Configuration", ipv4,
- argv + MANDATORY_ARGS, num_args);
- break;
- case 'v':
- error = set_service_property(conn, message, argv[1],
- "IPv6.Configuration", ipv6,
- argv + MANDATORY_ARGS, num_args);
- break;
- case 'n':
- error = set_service_property(conn, message, argv[1],
- "Nameservers.Configuration", NULL,
- argv + MANDATORY_ARGS, num_args);
- break;
- case 't':
- error = set_service_property(conn, message, argv[1],
- "Timeservers.Configuration", NULL,
- argv + MANDATORY_ARGS, num_args);
- break;
- case 'd':
- error = set_service_property(conn, message, argv[1],
- "Domains.Configuration", NULL,
- argv + MANDATORY_ARGS, num_args);
- 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);
- } 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]);
- } else {
- fprintf(stderr, "Incorrect arguments\n");
- error = -EINVAL;
- }
- break;
- case 'r':
- error = remove_service(conn, message, argv[1]);
- break;
- default:
- fprintf(stderr, "Command not recognized, please check help\n");
- error = -EINVAL;
- break;
+ for (i = 0; options[i].name != NULL; i++) {
+ if (strcmp(options[i].name, arg) == 0 ||
+ (strncmp(arg, "--", 2) == 0 &&
+ strcmp(&arg[2], options[i].name) == 0))
+ return options[i].val;
}
- dbus_message_unref(message);
-
- return error;
+ return '?';
}
int monitor_switch(int argc, char *argv[], int c, DBusConnection *conn)
static int cmd_services(char *args[], int num, struct option *options)
{
- return -1;
+ char *service_name = NULL;
+ int err = 0;
+ int c;
+ DBusMessage *message;
+
+ if (num > 3)
+ return -E2BIG;
+
+ c = parse_args(args[1], options);
+ switch (c) {
+ case -1:
+ break;
+ case 'p':
+ if (num < 3)
+ return -EINVAL;
+ service_name = args[2];
+ break;
+ default:
+ if (num > 2)
+ return -E2BIG;
+ service_name = args[1];
+ break;
+ }
+
+ message = get_message(connection, "GetServices");
+ if (message == NULL)
+ return -ENOMEM;
+
+ err = list_properties(connection, "GetServices", service_name);
+ dbus_message_unref(message);
+
+ return err;
}
static int cmd_technologies(char *args[], int num, struct option *options)
static int cmd_config(char *args[], int num, struct option *options)
{
- return -1;
+ int res = 0, index = 2, oldindex = 0;
+ int c;
+ char *service_name;
+ DBusMessage *message;
+ char **opt_start;
+ dbus_bool_t val;
+
+ service_name = args[1];
+ if (service_name == NULL)
+ return -EINVAL;
+
+ while (index < num && args[index] != NULL) {
+ c = parse_args(args[index], options);
+ opt_start = &args[index + 1];
+ res = 0;
+
+ message = get_message(connection, "GetServices");
+ if (message == NULL)
+ return -ENOMEM;
+
+ oldindex = index;
+
+ switch (c) {
+ case 'a':
+ switch (parse_boolean(*opt_start)) {
+ case 1:
+ val = TRUE;
+ break;
+ case 0:
+ val = FALSE;
+ break;
+ default:
+ res = -EINVAL;
+ break;
+ }
+ if (res == 0)
+ res = set_service_property(connection, message,
+ service_name, "AutoConnect",
+ NULL, &val, 0);
+ break;
+ case 'i':
+ res = set_service_property(connection, message,
+ service_name, "IPv4.Configuration",
+ ipv4, opt_start, 0);
+ if (res < 0)
+ index += 4;
+ break;
+ case 'v':
+ res = set_service_property(connection, message,
+ service_name, "IPv6.Configuration",
+ ipv6, opt_start, 0);
+ if (res < 0)
+ index += 5;
+ break;
+ case 'n':
+ res = set_service_property(connection, message,
+ service_name,
+ "Nameservers.Configuration",
+ NULL, opt_start, 0);
+ break;
+ case 't':
+ res = set_service_property(connection, message,
+ service_name,
+ "Timeservers.Configuration",
+ NULL, opt_start, 0);
+ break;
+ case 'd':
+ res = set_service_property(connection, message,
+ service_name,
+ "Domains.Configuration",
+ NULL, opt_start, 0);
+ break;
+ case 'x':
+ if (*opt_start == NULL) {
+ res = -EINVAL;
+ break;
+ }
+
+ if (strcmp(*opt_start, "direct") == 0) {
+ res = set_service_property(connection, message,
+ service_name,
+ "Proxy.Configuration",
+ proxy_simple, opt_start, 1);
+ break;
+ }
+
+ if (strcmp(*opt_start, "auto") == 0) {
+ res = set_service_property(connection, message,
+ service_name,
+ "Proxy.Configuration",
+ proxy_simple, opt_start, 1);
+ break;
+ }
+
+ if (strcmp(*opt_start, "manual") == 0) {
+ char **url_start = &args[index + 2];
+
+ if (*url_start != NULL &&
+ strcmp(*url_start,
+ "servers") == 0) {
+ url_start = &args[index + 3];
+ index++;
+ }
+ res = store_proxy_input(connection,
+ message, service_name,
+ 0, url_start);
+ }
+
+ break;
+ case 'r':
+ res = remove_service(connection, message, service_name);
+ break;
+ default:
+ res = -EINVAL;
+ break;
+ }
+
+ dbus_message_unref(message);
+
+ if (res < 0) {
+ printf("Error '%s': %s\n", args[oldindex],
+ strerror(-res));
+ } else
+ index += res;
+
+ index++;
+ }
+
+ return 0;
}
static int cmd_monitor(char *args[], int num, struct option *options)
return 0;
}
+static struct option service_options[] = {
+ {"properties", required_argument, 0, 'p'},
+ { NULL, }
+};
+
+static const char *service_desc[] = {
+ "[<service>] (obsolete)",
+ NULL
+};
+
+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'},
+ {"remove", 0, 0, 'r'},
+ { NULL, }
+};
+
+static const char *config_desc[] = {
+ "<dns1> [<dns2>] [<dns3>]",
+ "<ntp1> [<ntp2>] [...]",
+ "<domain1> [<domain2>] [...]",
+ "off|auto|manual <address> <prefixlength> <gateway> <privacy>",
+ "direct|auto <URL>|manual <URL1> [<URL2>] [...]\n"
+ " [exclude <exclude1> [<exclude2>] [...]]",
+ "yes|no",
+ "off|dhcp|manual <address> <prefixlength> <gateway>",
+ " Remove service",
+ NULL
+};
+
+static struct option monitor_options[] = {
+ {"services", no_argument, 0, 's'},
+ {"tech", no_argument, 0, 'c'},
+ {"manager", no_argument, 0, 'm'},
+ { NULL, }
+};
+
+static const char *monitor_desc[] = {
+ " Monitor only services",
+ " Monitor only technologies",
+ " Monitor only manager interface",
+ NULL
+};
+
static const struct {
const char *cmd;
const char *argument;
cmd_disable, "Disables given technology or offline mode"},
{ "state", NULL, NULL, NULL,
cmd_state, "Shows if the system is online or offline" },
- { "services", NULL, NULL, NULL,
+ { "services", "[<service>]", service_options, &service_desc[0],
cmd_services, "Display services" },
{ "technologies", NULL, NULL, NULL,
cmd_technologies, "Display technologies" },
cmd_connect, "Connect a given service" },
{ "disconnect", "<service>", NULL, NULL,
cmd_disconnect, "Disconnect a given service" },
- { "config", "<service>", NULL, NULL,
+ { "config", "<service>", config_options, &config_desc[0],
cmd_config, "Set service configuration options" },
- { "monitor", NULL, NULL, NULL,
+ { "monitor", NULL, monitor_options, &monitor_desc[0],
cmd_monitor, "Monitor signals from interfaces" },
{ "help", NULL, NULL, NULL,
cmd_help, "Show help" },
static int cmd_help(char *args[], int num, struct option *options)
{
- return -1;
+ int i, j;
+
+ for (i = 0; cmd_table[i].cmd != NULL; i++) {
+ const char *cmd = cmd_table[i].cmd;
+ const char *argument = cmd_table[i].argument;
+ const char *desc = cmd_table[i].desc;
+
+ printf("%-12s%-22s%s\n", cmd != NULL? cmd: "",
+ argument != NULL? argument: "",
+ desc != NULL? desc: "");
+
+ if (cmd_table[i].options != NULL) {
+ for (j = 0; cmd_table[i].options[j].name != NULL;
+ j++) {
+ const char *options_desc =
+ cmd_table[i].options_desc != NULL ?
+ cmd_table[i].options_desc[j]: "";
+
+ printf(" --%-12s%s\n",
+ cmd_table[i].options[j].name,
+ options_desc);
+ }
+ }
+ }
+
+ return 0;
}
int commands(DBusConnection *connection, char *argv[], int argc)
{
- int i;
+ int i, result;
for (i = 0; cmd_table[i].cmd != NULL; i++) {
if (g_strcmp0(cmd_table[i].cmd, argv[0]) == 0 &&
cmd_table[i].func != NULL) {
- return cmd_table[i].func(argv, argc,
+ result = cmd_table[i].func(argv, argc,
cmd_table[i].options);
+ if (result < 0)
+ printf("Error '%s': %s\n", argv[0],
+ strerror(-result));
+ return 0;
}
}
DBusMessage *message = NULL;
int error = 0;
-
if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "help") == 0 ||
strcmp(argv[0], "h") == 0) {
- show_help();
+ printf("Usage: connmanctl [[command] [args]]\n");
+ cmd_help(NULL, 0, NULL);
+ printf("\nNote: arguments and output are considered "
+ "EXPERIMENTAL for now.\n\n");
} else if (strcmp(argv[0], "state") == 0) {
if (argc != 1) {
fprintf(stderr, "State cannot accept an argument, "
{
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'},
- {"remove", 0, 0, 'r'},
- {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 (strcmp(argv[0], "monitor") == 0) {
if (argc > 2) {
fprintf(stderr, "Too many arguments for monitor, "
"see help\n");