5 * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36 #include "dbus_helpers.h"
41 static DBusConnection *connection;
43 struct connman_option {
49 static char *ipv4[] = {
57 static char *ipv6[] = {
65 static int cmd_help(char *args[], int num, struct connman_option *options);
67 static int parse_boolean(char *arg)
72 if (strcasecmp(arg, "no") == 0 ||
73 strcasecmp(arg, "false") == 0 ||
74 strcasecmp(arg, "off" ) == 0 ||
75 strcasecmp(arg, "disable" ) == 0 ||
76 strcasecmp(arg, "n") == 0 ||
77 strcasecmp(arg, "f") == 0 ||
78 strcasecmp(arg, "0") == 0)
81 if (strcasecmp(arg, "yes") == 0 ||
82 strcasecmp(arg, "true") == 0 ||
83 strcasecmp(arg, "on") == 0 ||
84 strcasecmp(arg, "enable" ) == 0 ||
85 strcasecmp(arg, "y") == 0 ||
86 strcasecmp(arg, "t") == 0 ||
87 strcasecmp(arg, "1") == 0)
93 static int parse_args(char *arg, struct connman_option *options)
100 for (i = 0; options[i].name != NULL; i++) {
101 if (strcmp(options[i].name, arg) == 0 ||
102 (strncmp(arg, "--", 2) == 0 &&
103 strcmp(&arg[2], options[i].name) == 0))
104 return options[i].val;
110 static void enable_return(DBusMessageIter *iter, const char *error,
113 char *tech = user_data;
116 str = strrchr(tech, '/');
123 fprintf(stdout, "Enabled %s\n", str);
125 fprintf(stderr, "Error %s: %s\n", str, error);
130 static int cmd_enable(char *args[], int num, struct connman_option *options)
133 dbus_bool_t b = TRUE;
141 if (strcmp(args[1], "offlinemode") == 0) {
142 tech = g_strdup(args[1]);
143 return __connmanctl_dbus_set_property(connection, "/",
144 "net.connman.Manager", enable_return, tech,
145 "OfflineMode", DBUS_TYPE_BOOLEAN, &b);
148 tech = g_strdup_printf("/net/connman/technology/%s", args[1]);
149 return __connmanctl_dbus_set_property(connection, tech,
150 "net.connman.Technology", enable_return, tech,
151 "Powered", DBUS_TYPE_BOOLEAN, &b);
154 static void disable_return(DBusMessageIter *iter, const char *error,
157 char *tech = user_data;
160 str = strrchr(tech, '/');
167 fprintf(stdout, "Disabled %s\n", str);
169 fprintf(stderr, "Error %s: %s\n", str, error);
174 static int cmd_disable(char *args[], int num, struct connman_option *options)
177 dbus_bool_t b = FALSE;
185 if (strcmp(args[1], "offlinemode") == 0) {
186 tech = g_strdup(args[1]);
187 return __connmanctl_dbus_set_property(connection, "/",
188 "net.connman.Manager", disable_return, tech,
189 "OfflineMode", DBUS_TYPE_BOOLEAN, &b);
192 tech = g_strdup_printf("/net/connman/technology/%s", args[1]);
193 return __connmanctl_dbus_set_property(connection, tech,
194 "net.connman.Technology", disable_return, tech,
195 "Powered", DBUS_TYPE_BOOLEAN, &b);
198 static void state_print(DBusMessageIter *iter, const char *error,
201 DBusMessageIter entry;
204 fprintf(stderr, "Error: %s", error);
208 dbus_message_iter_recurse(iter, &entry);
209 __connmanctl_dbus_print(&entry, " ", " = ", "\n");
210 fprintf(stdout, "\n");
213 static int cmd_state(char *args[], int num, struct connman_option *options)
218 return __connmanctl_dbus_method_call(connection, "/",
219 "net.connman.Manager", "GetProperties",
220 state_print, NULL, DBUS_TYPE_INVALID);
223 static void services_list(DBusMessageIter *iter, const char *error,
227 __connmanctl_services_list(iter);
228 fprintf(stdout, "\n");
230 fprintf(stderr, "Error: %s\n", error);
234 static void services_properties(DBusMessageIter *iter, const char *error,
237 char *path = user_data;
239 DBusMessageIter dict;
242 fprintf(stdout, "%s\n", path);
244 dbus_message_iter_recurse(iter, &dict);
245 __connmanctl_dbus_print(&dict, " ", " = ", "\n");
247 fprintf(stdout, "\n");
250 str = strrchr(path, '/');
256 fprintf(stderr, "Error %s: %s\n", str, error);
262 static int cmd_services(char *args[], int num, struct connman_option *options)
264 char *service_name = NULL;
271 c = parse_args(args[1], options);
278 service_name = args[2];
283 service_name = args[1];
287 if (service_name == NULL) {
288 return __connmanctl_dbus_method_call(connection, "/",
289 "net.connman.Manager", "GetServices",
290 services_list, NULL, DBUS_TYPE_INVALID);
293 path = g_strdup_printf("/net/connman/service/%s", service_name);
294 return __connmanctl_dbus_method_call(connection, path,
295 "net.connman.Service", "GetProperties",
296 services_properties, path, DBUS_TYPE_INVALID);
299 static void technology_print(DBusMessageIter *iter, const char *error,
302 DBusMessageIter array;
305 fprintf(stderr, "Error: %s\n", error);
309 dbus_message_iter_recurse(iter, &array);
310 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
311 DBusMessageIter entry, dict;
314 dbus_message_iter_recurse(&array, &entry);
315 dbus_message_iter_get_basic(&entry, &path);
316 fprintf(stdout, "%s\n", path);
318 dbus_message_iter_next(&entry);
320 dbus_message_iter_recurse(&entry, &dict);
321 __connmanctl_dbus_print(&dict, " ", " = ", "\n");
322 fprintf(stdout, "\n");
324 dbus_message_iter_next(&array);
328 static int cmd_technologies(char *args[], int num,
329 struct connman_option *options)
334 return __connmanctl_dbus_method_call(connection, "/",
335 "net.connman.Manager", "GetTechnologies",
336 technology_print, NULL, DBUS_TYPE_INVALID);
339 struct tether_enable {
344 static void tether_set_return(DBusMessageIter *iter, const char *error,
347 struct tether_enable *tether = user_data;
350 str = strrchr(tether->path, '/');
357 fprintf(stdout, "%s tethering for %s\n",
358 tether->enable == TRUE ? "Enabled": "Disabled",
361 fprintf(stderr, "Error %s %s tethering: %s\n",
362 tether->enable == TRUE ?
363 "enabling": "disabling", str, error);
365 g_free(tether->path);
369 static int tether_set(char *technology, int set_tethering)
371 struct tether_enable *tether = g_new(struct tether_enable, 1);
373 switch(set_tethering) {
375 tether->enable = TRUE;
378 tether->enable = FALSE;
385 tether->path = g_strdup_printf("/net/connman/technology/%s",
388 return __connmanctl_dbus_set_property(connection, tether->path,
389 "net.connman.Technology", tether_set_return,
390 tether, "Tethering", DBUS_TYPE_BOOLEAN,
394 struct tether_properties {
396 int passphrase_result;
400 static void tether_update(struct tether_properties *tether)
402 printf("%d %d %d\n", tether->ssid_result, tether->passphrase_result,
403 tether->set_tethering);
405 if (tether->ssid_result == 0 && tether->passphrase_result == 0)
406 tether_set("wifi", tether->set_tethering);
408 if (tether->ssid_result != -EINPROGRESS &&
409 tether->passphrase_result != -EINPROGRESS)
413 static void tether_set_ssid_return(DBusMessageIter *iter, const char *error,
416 struct tether_properties *tether = user_data;
419 fprintf(stdout, "Wifi SSID set\n");
420 tether->ssid_result = 0;
422 fprintf(stderr, "Error setting wifi SSID: %s\n", error);
423 tether->ssid_result = -EINVAL;
426 tether_update(tether);
429 static void tether_set_passphrase_return(DBusMessageIter *iter,
430 const char *error, void *user_data)
432 struct tether_properties *tether = user_data;
435 fprintf(stdout, "Wifi passphrase set\n");
436 tether->passphrase_result = 0;
438 fprintf(stderr, "Error setting wifi passphrase: %s\n", error);
439 tether->passphrase_result = -EINVAL;
442 tether_update(tether);
445 static int tether_set_ssid(char *ssid, char *passphrase, int set_tethering)
447 struct tether_properties *tether = g_new(struct tether_properties, 1);
449 tether->set_tethering = set_tethering;
451 tether->ssid_result = __connmanctl_dbus_set_property(connection,
452 "/net/connman/technology/wifi",
453 "net.connman.Technology",
454 tether_set_ssid_return, tether,
455 "TetheringIdentifier", DBUS_TYPE_STRING, &ssid);
457 tether->passphrase_result =__connmanctl_dbus_set_property(connection,
458 "/net/connman/technology/wifi",
459 "net.connman.Technology",
460 tether_set_passphrase_return, tether,
461 "TetheringPassphrase", DBUS_TYPE_STRING, &passphrase);
463 if (tether->ssid_result != -EINPROGRESS &&
464 tether->passphrase_result != -EINPROGRESS) {
472 static int cmd_tether(char *args[], int num, struct connman_option *options)
474 char *ssid, *passphrase;
480 passphrase = args[num - 1];
481 ssid = args[num - 2];
483 set_tethering = parse_boolean(args[2]);
485 if (strcmp(args[1], "wifi") == 0) {
490 if (num == 5 && set_tethering == -1)
497 return tether_set_ssid(ssid, passphrase, set_tethering);
503 if (set_tethering == -1)
506 return tether_set(args[1], set_tethering);
509 static void scan_return(DBusMessageIter *iter, const char *error,
512 char *path = user_data;
515 char *str = strrchr(path, '/');
517 fprintf(stdout, "Scan completed for %s\n", str);
519 fprintf(stderr, "Error %s: %s", path, error);
524 static int cmd_scan(char *args[], int num, struct connman_option *options)
534 path = g_strdup_printf("/net/connman/technology/%s", args[1]);
535 return __connmanctl_dbus_method_call(connection, path,
536 "net.connman.Technology", "Scan",
537 scan_return, path, DBUS_TYPE_INVALID);
540 static void connect_return(DBusMessageIter *iter, const char *error,
543 char *path = user_data;
546 char *str = strrchr(path, '/');
548 fprintf(stdout, "Connected %s\n", str);
550 fprintf(stderr, "Error %s: %s\n", path, error);
555 static int cmd_connect(char *args[], int num, struct connman_option *options)
565 path = g_strdup_printf("/net/connman/service/%s", args[1]);
566 return __connmanctl_dbus_method_call(connection, path,
567 "net.connman.Service", "Connect",
568 connect_return, path, DBUS_TYPE_INVALID);
571 static void disconnect_return(DBusMessageIter *iter, const char *error,
574 char *path = user_data;
577 char *str = strrchr(path, '/');
579 fprintf(stdout, "Disconnected %s\n", str);
581 fprintf(stderr, "Error %s: %s\n", path, error);
586 static int cmd_disconnect(char *args[], int num, struct connman_option *options)
596 path = g_strdup_printf("/net/connman/service/%s", args[1]);
597 return __connmanctl_dbus_method_call(connection, path,
598 "net.connman.Service", "Disconnect",
599 disconnect_return, path, DBUS_TYPE_INVALID);
604 static void config_return(DBusMessageIter *iter, const char *error,
607 char *service_name = user_data;
610 fprintf(stderr, "Error %s: %s\n", service_name, error);
615 struct config_append {
620 static void config_append_ipv4(DBusMessageIter *iter,
623 struct config_append *append = user_data;
624 char **opts = append->opts;
630 while (opts[i] != NULL && ipv4[i] != NULL) {
631 __connmanctl_dbus_append_dict_entry(iter, ipv4[i],
632 DBUS_TYPE_STRING, &opts[i]);
639 static void config_append_ipv6(DBusMessageIter *iter, void *user_data)
641 struct config_append *append = user_data;
642 char **opts = append->opts;
649 if (g_strcmp0(opts[0], "auto") == 0) {
652 switch (parse_boolean(opts[1])) {
657 __connmanctl_dbus_append_dict_entry(iter, "Privacy",
658 DBUS_TYPE_STRING, &str);
665 __connmanctl_dbus_append_dict_entry(iter, "Privacy",
666 DBUS_TYPE_STRING, &str);
670 if (opts[1] != NULL) {
673 if (g_strcmp0(opts[0], "prefered") != 0) {
674 fprintf(stderr, "Error %s: %s\n",
681 __connmanctl_dbus_append_dict_entry(iter,
682 "Privacy", DBUS_TYPE_STRING,
687 } else if (g_strcmp0(opts[0], "manual") == 0) {
690 while (opts[i] != NULL && ipv6[i] != NULL) {
692 int value = atoi(opts[i]);
693 __connmanctl_dbus_append_dict_entry(iter,
694 ipv6[i], DBUS_TYPE_BYTE,
697 __connmanctl_dbus_append_dict_entry(iter,
698 ipv6[i], DBUS_TYPE_STRING,
706 } else if (g_strcmp0(opts[0], "off") != 0) {
707 fprintf(stderr, "Error %s: %s\n", opts[0], strerror(-EINVAL));
712 __connmanctl_dbus_append_dict_entry(iter, "Method", DBUS_TYPE_STRING,
716 static void config_append_str(DBusMessageIter *iter, void *user_data)
718 struct config_append *append = user_data;
719 char **opts = append->opts;
725 while (opts[i] != NULL) {
726 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
734 static void append_servers(DBusMessageIter *iter, void *user_data)
736 struct config_append *append = user_data;
737 char **opts = append->opts;
743 while (opts[i] != NULL && g_strcmp0(opts[i], "--excludes") != 0) {
744 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
752 static void append_excludes(DBusMessageIter *iter, void *user_data)
754 struct config_append *append = user_data;
755 char **opts = append->opts;
756 int i = append->values;
758 if (opts == NULL || opts[i] == NULL ||
759 g_strcmp0(opts[i], "--excludes") != 0)
763 while (opts[i] != NULL) {
764 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
772 static void config_append_proxy(DBusMessageIter *iter, void *user_data)
774 struct config_append *append = user_data;
775 char **opts = append->opts;
780 if (g_strcmp0(opts[0], "manual") == 0) {
781 __connmanctl_dbus_append_dict_string_array(iter, "Servers",
782 append_servers, append);
784 __connmanctl_dbus_append_dict_string_array(iter, "Excludes",
785 append_excludes, append);
787 } else if (g_strcmp0(opts[0], "auto") == 0) {
788 if (opts[1] != NULL) {
789 __connmanctl_dbus_append_dict_entry(iter, "URL",
790 DBUS_TYPE_STRING, &opts[1]);
794 } else if (g_strcmp0(opts[0], "direct") != 0)
797 __connmanctl_dbus_append_dict_entry(iter, "Method",DBUS_TYPE_STRING,
803 static int cmd_config(char *args[], int num, struct connman_option *options)
805 int result = 0, res = 0, index = 2, oldindex = 0;
807 char *service_name, *path;
810 struct config_append append;
812 service_name = args[1];
813 if (service_name == NULL)
816 while (index < num && args[index] != NULL) {
817 c = parse_args(args[index], options);
818 opt_start = &args[index + 1];
819 append.opts = opt_start;
825 path = g_strdup_printf("/net/connman/service/%s", service_name);
829 switch (parse_boolean(*opt_start)) {
844 res = __connmanctl_dbus_set_property(connection,
845 path, "net.connman.Service",
847 g_strdup(service_name),
849 DBUS_TYPE_BOOLEAN, &val);
853 res = __connmanctl_dbus_set_property_dict(connection,
854 path, "net.connman.Service",
855 config_return, g_strdup(service_name),
856 "IPv4.Configuration", DBUS_TYPE_STRING,
857 config_append_ipv4, &append);
858 index += append.values;
862 res = __connmanctl_dbus_set_property_dict(connection,
863 path, "net.connman.Service",
864 config_return, g_strdup(service_name),
865 "IPv6.Configuration", DBUS_TYPE_STRING,
866 config_append_ipv6, &append);
867 index += append.values;
871 res = __connmanctl_dbus_set_property_array(connection,
872 path, "net.connman.Service",
873 config_return, g_strdup(service_name),
874 "Nameservers.Configuration",
875 DBUS_TYPE_STRING, config_append_str,
877 index += append.values;
881 res = __connmanctl_dbus_set_property_array(connection,
882 path, "net.connman.Service",
883 config_return, g_strdup(service_name),
884 "Timeservers.Configuration",
885 DBUS_TYPE_STRING, config_append_str,
887 index += append.values;
891 res = __connmanctl_dbus_set_property_array(connection,
892 path, "net.connman.Service",
893 config_return, g_strdup(service_name),
894 "Domains.Configuration",
895 DBUS_TYPE_STRING, config_append_str,
897 index += append.values;
901 res = __connmanctl_dbus_set_property_dict(connection,
902 path, "net.connman.Service",
903 config_return, g_strdup(service_name),
904 "Proxy.Configuration",
905 DBUS_TYPE_STRING, config_append_proxy,
907 index += append.values;
910 res = __connmanctl_dbus_method_call(connection,
911 path, "net.connman.Service", "Remove",
912 config_return, g_strdup(service_name),
923 if (res == -EINPROGRESS)
924 result = -EINPROGRESS;
926 printf("Error '%s': %s\n", args[oldindex],
937 static DBusHandlerResult monitor_changed(DBusConnection *connection,
938 DBusMessage *message, void *user_data)
940 DBusMessageIter iter;
941 const char *interface, *path;
943 interface = dbus_message_get_interface(message);
944 if (strncmp(interface, "net.connman.", 12) != 0)
945 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
947 interface = strrchr(interface, '.');
948 if (interface != NULL && *interface != '\0')
951 path = strrchr(dbus_message_get_path(message), '/');
952 if (path != NULL && *path != '\0')
955 __connmanctl_save_rl();
957 if (dbus_message_is_signal(message, "net.connman.Manager",
958 "ServicesChanged") == TRUE) {
960 fprintf(stdout, "%-12s %-20s = {\n", interface,
962 dbus_message_iter_init(message, &iter);
963 __connmanctl_services_list(&iter);
964 fprintf(stdout, "\n}\n");
966 __connmanctl_redraw_rl();
968 return DBUS_HANDLER_RESULT_HANDLED;
971 if (dbus_message_is_signal(message, "net.connman.Manager",
972 "TechnologyAdded") == TRUE)
973 path = "TechnologyAdded";
975 if (dbus_message_is_signal(message, "net.connman.Manager",
976 "TechnologyRemoved") == TRUE)
977 path = "TechnologyRemoved";
979 fprintf(stdout, "%-12s %-20s ", interface, path);
980 dbus_message_iter_init(message, &iter);
982 __connmanctl_dbus_print(&iter, "", " = ", " = ");
983 fprintf(stdout, "\n");
985 __connmanctl_redraw_rl();
987 return DBUS_HANDLER_RESULT_HANDLED;
990 static bool monitor_s = false;
991 static bool monitor_t = false;
992 static bool monitor_m = false;
994 static void monitor_add(char *interface)
999 if (monitor_s == false && monitor_t == false && monitor_m == false)
1000 dbus_connection_add_filter(connection, monitor_changed,
1003 if (g_strcmp0(interface, "Service") == 0) {
1004 if (monitor_s == true)
1007 } else if (g_strcmp0(interface, "Technology") == 0) {
1008 if (monitor_t == true)
1011 } else if (g_strcmp0(interface, "Manager") == 0) {
1012 if (monitor_m == true)
1018 dbus_error_init(&err);
1019 rule = g_strdup_printf("type='signal',interface='net.connman.%s'",
1021 dbus_bus_add_match(connection, rule, &err);
1024 if (dbus_error_is_set(&err))
1025 fprintf(stderr, "Error: %s\n", err.message);
1028 static void monitor_del(char *interface)
1032 if (g_strcmp0(interface, "Service") == 0) {
1033 if (monitor_s == false)
1036 } else if (g_strcmp0(interface, "Technology") == 0) {
1037 if (monitor_t == false)
1040 } else if (g_strcmp0(interface, "Manager") == 0) {
1041 if (monitor_m == false)
1047 rule = g_strdup_printf("type='signal',interface='net.connman.%s'",
1049 dbus_bus_remove_match(connection, rule, NULL);
1052 if (monitor_s == false && monitor_t == false && monitor_m == false)
1053 dbus_connection_remove_filter(connection, monitor_changed,
1057 static int cmd_monitor(char *args[], int num, struct connman_option *options)
1066 switch (parse_boolean(args[2])) {
1076 c = parse_args(args[1], options);
1079 monitor_add("Service");
1080 monitor_add("Technology");
1081 monitor_add("Manager");
1086 monitor_add("Service");
1088 monitor_del("Service");
1093 monitor_add("Technology");
1095 monitor_del("Technology");
1100 monitor_add("Manager");
1102 monitor_del("Manager");
1106 switch(parse_boolean(args[1])) {
1108 monitor_del("Service");
1109 monitor_del("Technology");
1110 monitor_del("Manager");
1114 monitor_add("Service");
1115 monitor_add("Technology");
1116 monitor_add("Manager");
1125 return -EINPROGRESS;
1130 static int cmd_exit(char *args[], int num, struct connman_option *options)
1135 static struct connman_option service_options[] = {
1136 {"properties", 'p', "[<service>] (obsolete)"},
1140 static struct connman_option config_options[] = {
1141 {"nameservers", 'n', "<dns1> [<dns2>] [<dns3>]"},
1142 {"timeservers", 't', "<ntp1> [<ntp2>] [...]"},
1143 {"domains", 'd', "<domain1> [<domain2>] [...]"},
1144 {"ipv6", 'v', "off|auto [enable|disable|prefered]|\n"
1145 "\t\t\tmanual <address> <prefixlength> <gateway>"},
1146 {"proxy", 'x', "direct|auto <URL>|manual <URL1> [<URL2>] [...]\n"
1147 "\t\t\t[exclude <exclude1> [<exclude2>] [...]]"},
1148 {"autoconnect", 'a', "yes|no"},
1149 {"ipv4", 'i', "off|dhcp|manual <address> <netmask> <gateway>"},
1150 {"remove", 'r', " Remove service"},
1154 static struct connman_option monitor_options[] = {
1155 {"services", 's', "[off] Monitor only services"},
1156 {"tech", 'c', "[off] Monitor only technologies"},
1157 {"manager", 'm', "[off] Monitor only manager interface"},
1161 static const struct {
1163 const char *argument;
1164 struct connman_option *options;
1165 int (*func) (char *args[], int num, struct connman_option *options);
1168 { "state", NULL, NULL, cmd_state,
1169 "Shows if the system is online or offline" },
1170 { "technologies", NULL, NULL, cmd_technologies,
1171 "Display technologies" },
1172 { "enable", "<technology>|offline", NULL, cmd_enable,
1173 "Enables given technology or offline mode" },
1174 { "disable", "<technology>|offline", NULL, cmd_disable,
1175 "Disables given technology or offline mode"},
1176 { "tether", "<technology> on|off\n"
1177 " wifi [on|off] <ssid> <passphrase> ",
1179 "Enable, disable tethering, set SSID and passphrase for wifi" },
1180 { "services", "[<service>]", service_options, cmd_services,
1181 "Display services" },
1182 { "scan", "<technology>", NULL, cmd_scan,
1183 "Scans for new services for given technology" },
1184 { "connect", "<service>", NULL, cmd_connect,
1185 "Connect a given service" },
1186 { "disconnect", "<service>", NULL, cmd_disconnect,
1187 "Disconnect a given service" },
1188 { "config", "<service>", config_options, cmd_config,
1189 "Set service configuration options" },
1190 { "monitor", "[off]", monitor_options, cmd_monitor,
1191 "Monitor signals from interfaces" },
1192 { "help", NULL, NULL, cmd_help,
1194 { "exit", NULL, NULL, cmd_exit,
1196 { "quit", NULL, NULL, cmd_exit,
1201 static int cmd_help(char *args[], int num, struct connman_option *options)
1203 bool interactive = __connmanctl_is_interactive();
1206 if (interactive == false)
1207 fprintf(stdout, "Usage: connmanctl [[command] [args]]\n");
1209 for (i = 0; cmd_table[i].cmd != NULL; i++) {
1210 const char *cmd = cmd_table[i].cmd;
1211 const char *argument = cmd_table[i].argument;
1212 const char *desc = cmd_table[i].desc;
1214 printf("%-12s%-22s%s\n", cmd != NULL? cmd: "",
1215 argument != NULL? argument: "",
1216 desc != NULL? desc: "");
1218 if (cmd_table[i].options != NULL) {
1219 for (j = 0; cmd_table[i].options[j].name != NULL;
1221 const char *options_desc =
1222 cmd_table[i].options[j].desc != NULL ?
1223 cmd_table[i].options[j].desc: "";
1225 printf(" --%-12s%s\n",
1226 cmd_table[i].options[j].name,
1232 if (interactive == false)
1233 fprintf(stdout, "\nNote: arguments and output are considered "
1234 "EXPERIMENTAL for now.\n");
1239 int __connmanctl_commands(DBusConnection *dbus_conn, char *argv[], int argc)
1243 connection = dbus_conn;
1245 for (i = 0; cmd_table[i].cmd != NULL; i++) {
1246 if (g_strcmp0(cmd_table[i].cmd, argv[0]) == 0 &&
1247 cmd_table[i].func != NULL) {
1248 result = cmd_table[i].func(argv, argc,
1249 cmd_table[i].options);
1250 if (result < 0 && result != -EINPROGRESS)
1251 fprintf(stderr, "Error '%s': %s\n", argv[0],
1257 fprintf(stderr, "Error '%s': Unknown command\n", argv[0]);
1261 char *__connmanctl_lookup_command(const char *text, int state)
1271 while (cmd_table[i].cmd != NULL) {
1272 const char *command = cmd_table[i].cmd;
1276 if (strncmp(text, command, len) == 0)
1277 return strdup(command);