client: Fix up header inclusion mess
[platform/upstream/connman.git] / client / commands.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2012  Intel Corporation. All rights reserved.
6  *
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.
11  *
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.
16  *
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
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <getopt.h>
32
33 #include <glib.h>
34 #include <gdbus.h>
35
36 #include "services.h"
37 #include "technology.h"
38 #include "data_manager.h"
39 #include "monitor.h"
40 #include "interactive.h"
41
42 #define MANDATORY_ARGS 3
43
44 static char *ipv4[] = {
45         "Method",
46         "Address",
47         "Netmask",
48         "Gateway",
49         NULL
50 };
51
52 static char *ipv6[] = {
53         "Method",
54         "Address",
55         "PrefixLength",
56         "Gateway",
57         "Privacy",
58         NULL
59 };
60
61 static char *proxy_simple[] = {
62         "Method",
63         "URL",
64         NULL
65 };
66
67 void show_help(void)
68 {
69         printf("Usage: connmanctl <command> [args]\n"
70         "  enable                             Enables given technology\n"
71         "        <technology>\n"
72         "        offlinemode                  Enables OfflineMode\n"
73         "  disable                            Disables given technology\n"
74         "        <technology>\n"
75         "        offlinemode                  Disables OfflineMode\n"
76         "  state                              Shows if the system is online or offline\n"
77         "  services                           Display list of all services\n"
78         "        --properties <service name>  Show properties of service\n"
79         "  technologies                       Current technology on the system\n"
80         "  scan <technology>                  Scans for new services on the given technology\n"
81         "  connect <service>                  Connect to a given service\n"
82         "  disconnect <service>               Disconnect from service\n"
83         "  config <service> [arg]             Set certain config options\n"
84         "        --autoconnect=y/n            Set autoconnect to service\n"
85         "        --nameservers <names>        Set manual name servers\n"
86         "        --timeservers <names>        Set manual time servers\n"
87         "        --domains <domains>          Set manual domains\n"
88         "        --ipv4                       Set ipv4 configuration\n"
89         "          [METHOD|DHCP|AUTO|MANUAL] [IP] [NETMASK] [GATEWAY]\n"
90         "        --ipv6                       Set ipv6 configuration\n"
91         "          [METHOD|AUTO|MANUAL|OFF] [IP] [PREFIXLENGTH] [GATEWAY]\n"
92         "          [PRIVACY|DISABLED|ENABLED|PREFERED]\n"
93         "        --proxy                      Set proxy configuration\n"
94         "          [METHOD|URL|SERVERS|EXCLUDES]\n"
95         "          if METHOD = manual, enter 'servers' then the list of servers\n"
96         "                         then enter 'excludes' then the list of excludes\n"
97         "        --remove                     Remove the service from favorite\n"
98         "  monitor                            Monitor signals from all Connman interfaces\n"
99         "        --services                   Monitor signals from the Service interface\n"
100         "        --tech                       Monitor signals from the Technology interface\n"
101         "        --manager                    Monitor signals from the Manager interface\n"
102         "  help, --help, (no arguments)       Show this dialogue\n"
103         "  exit, quit, q                      Quit interactive mode\n"
104         "\nNote: arguments and output are considered EXPERIMENTAL for now.\n\n");
105 }
106
107 int service_switch(int argc, char *argv[], int c, DBusConnection *conn,
108                                                 struct service_data *service)
109 {
110         const char *name;
111         DBusMessage *message;
112         int error = 0;
113
114         message = get_message(conn, "GetServices");
115         if (message == NULL)
116                 return -ENOMEM;
117
118         switch (c) {
119         case 'p':
120                 name = find_service(conn, message, argv[2], service);
121                 if (name == NULL) {
122                         error = -ENXIO;
123                         break;
124                 }
125
126                 error = list_properties(conn, "GetServices", (char *) name);
127                 break;
128         default:
129                 fprintf(stderr, "Command not recognized, please check help\n");
130                 error = -EINVAL;
131                 break;
132         }
133
134         dbus_message_unref(message);
135
136         return error;
137 }
138
139 int config_switch(int argc, char *argv[], int c, DBusConnection *conn)
140 {
141         DBusMessage *message;
142         int num_args = argc - MANDATORY_ARGS;
143         int error = 0;
144         dbus_bool_t val;
145
146         message = get_message(conn, "GetServices");
147         if (message == NULL)
148                 return -ENOMEM;
149
150         switch (c) {
151         case 'a':
152                 switch (*optarg) {
153                 case 'y':
154                 case '1':
155                 case 't':
156                         val = TRUE;
157                         break;
158                 case 'n':
159                 case '0':
160                 case 'f':
161                         val = FALSE;
162                         break;
163                 default:
164                         return -EINVAL;
165                 }
166                 error = set_service_property(conn, message, argv[1],
167                                                 "AutoConnect", NULL,
168                                                 &val, 0);
169                 break;
170         case 'i':
171                 error = set_service_property(conn, message, argv[1],
172                                         "IPv4.Configuration", ipv4,
173                                         argv + MANDATORY_ARGS, num_args);
174                 break;
175         case 'v':
176                 error = set_service_property(conn, message, argv[1],
177                                         "IPv6.Configuration", ipv6,
178                                         argv + MANDATORY_ARGS, num_args);
179                 break;
180         case 'n':
181                 error = set_service_property(conn, message, argv[1],
182                                         "Nameservers.Configuration", NULL,
183                                         argv + MANDATORY_ARGS, num_args);
184                 break;
185         case 't':
186                 error = set_service_property(conn, message, argv[1],
187                                         "Timeservers.Configuration", NULL,
188                                         argv + MANDATORY_ARGS, num_args);
189                 break;
190         case 'd':
191                 error = set_service_property(conn, message, argv[1],
192                                         "Domains.Configuration", NULL,
193                                         argv + MANDATORY_ARGS, num_args);
194                 break;
195         case 'x':
196                 if ((strcmp(argv[3], "direct") == 0 && argc < 5) ||
197                         (strcmp(argv[3], "auto") == 0 && argc < 6)) {
198                         error = set_service_property(conn, message, argv[1],
199                                         "Proxy.Configuration", proxy_simple,
200                                         argv + MANDATORY_ARGS, num_args);
201                 } else if (strcmp(argv[3], "manual") == 0
202                                   && strcmp(argv[4], "servers") == 0
203                                   && argc > 5) {
204                         argc -= 5;
205                         error = store_proxy_input(conn, message, argv[1],
206                                                                 argc, &argv[5]);
207                 } else {
208                         fprintf(stderr, "Incorrect arguments\n");
209                         error = -EINVAL;
210                 }
211                 break;
212         case 'r':
213                 error = remove_service(conn, message, argv[1]);
214                 break;
215         default:
216                 fprintf(stderr, "Command not recognized, please check help\n");
217                 error = -EINVAL;
218                 break;
219         }
220
221         dbus_message_unref(message);
222
223         return error;
224 }
225
226 int monitor_switch(int argc, char *argv[], int c, DBusConnection *conn)
227 {
228         int error;
229
230         switch (c) {
231         case 's':
232                 error = monitor_connman(conn, "Service", "PropertyChanged");
233                 if (error != 0)
234                         return error;
235                 if (dbus_connection_add_filter(conn, service_property_changed,
236                                                         NULL, NULL) == FALSE)
237                         return -ENOMEM;
238                 printf("Now monitoring the service interface.\n");
239                 break;
240         case 'c':
241                 error = monitor_connman(conn, "Technology", "PropertyChanged");
242                 if (error != 0)
243                         return error;
244                 if (dbus_connection_add_filter(conn, tech_property_changed,
245                                                         NULL, NULL) == FALSE)
246                         return -ENOMEM;
247                 printf("Now monitoring the technology interface.\n");
248                 break;
249         case 'm':
250                 error = monitor_connman(conn, "Manager", "PropertyChanged");
251                 if (error != 0)
252                         return error;
253                 error = monitor_connman(conn, "Manager", "TechnologyAdded");
254                 if (error != 0)
255                         return error;
256                 error = monitor_connman(conn, "Manager", "TechnologyRemoved");
257                 if (error != 0)
258                         return error;
259                 error = monitor_connman(conn, "Manager", "ServicesChanged");
260                 if (error != 0)
261                         return error;
262                 if (dbus_connection_add_filter(conn, manager_property_changed,
263                                                         NULL, NULL) == FALSE)
264                         return -ENOMEM;
265                 if (dbus_connection_add_filter(conn, tech_added_removed,
266                                                         NULL, NULL) == FALSE)
267                         return -ENOMEM;
268                 if (dbus_connection_add_filter(conn, manager_services_changed,
269                                                         NULL, NULL) == FALSE)
270                         return -ENOMEM;
271                 printf("Now monitoring the manager interface.\n");
272                 break;
273         default:
274                 fprintf(stderr, "Command not recognized, please check help\n");
275                 return -EINVAL;
276                 break;
277         }
278         return 0;
279 }
280
281 int commands_no_options(DBusConnection *connection, char *argv[], int argc)
282 {
283         DBusMessage *message = NULL;
284         int error = 0;
285
286
287         if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "help") == 0  ||
288                                                 strcmp(argv[0], "h") == 0) {
289                 show_help();
290         } else if (strcmp(argv[0], "state") == 0) {
291                 if (argc != 1) {
292                         fprintf(stderr, "State cannot accept an argument, "
293                                                                 "see help\n");
294                         error = -EINVAL;
295                 } else
296                         error = list_properties(connection,
297                                                 "GetProperties", NULL);
298         } else if (strcmp(argv[0], "technologies") == 0) {
299                 if (argc != 1) {
300                         fprintf(stderr, "Tech cannot accept an argument, "
301                                                                 "see help\n");
302                         error = -EINVAL;
303                 } else
304                         error = list_properties(connection,
305                                                 "GetTechnologies", NULL);
306         } else if (strcmp(argv[0], "connect") == 0) {
307                 if (argc != 2) {
308                         fprintf(stderr, "Connect requires a service name or "
309                                                         "path, see help\n");
310                         error = -EINVAL;
311                 } else
312                         error = connect_service(connection,
313                                                 strip_service_path(argv[1]));
314                 if (error == 0)
315                         printf("Connected to: %s\n",
316                                                 strip_service_path(argv[1]));
317         } else if (strcmp(argv[0], "disconnect") == 0) {
318                 if (argc != 2) {
319                         fprintf(stderr, "Disconnect requires a service name or "
320                                                         "path, see help\n");
321                         error = -EINVAL;
322                 } else
323                         error = disconnect_service(connection,
324                                                 strip_service_path(argv[1]));
325                 if (error == 0)
326                         printf("Disconnected from: %s\n",
327                                                 strip_service_path(argv[1]));
328         } else if (strcmp(argv[0], "scan") == 0) {
329                 if (argc != 2) {
330                         fprintf(stderr, "Scan requires a service name or path, "
331                                                                 "see help\n");
332                         error = -EINVAL;
333                 }
334                 message = get_message(connection, "GetTechnologies");
335                 if (message == NULL)
336                         error = -ENOMEM;
337                 else
338                         error = scan_technology(connection, message, argv[1]);
339         } else if (strcmp(argv[0], "enable") == 0) {
340                 if (argc != 2) {
341                         fprintf(stderr, "Enable requires a technology name or "
342                                 "the argument 'offlinemode', see help\n");
343                         error = -EINVAL;
344                 } else if (strcmp(argv[1], "offlinemode") == 0) {
345                         error = set_manager(connection, "OfflineMode", TRUE);
346                         if (error == 0)
347                                 printf("OfflineMode is now enabled\n");
348                 } else {
349                         message = get_message(connection, "GetTechnologies");
350                         if (message == NULL)
351                                 error = -ENOMEM;
352                         else
353                                 error = set_technology(connection, message,
354                                                 "Powered", argv[1], TRUE);
355                         if (error == 0)
356                                 printf("Enabled %s technology\n", argv[1]);
357                 }
358         } else if (strcmp(argv[0], "disable") == 0) {
359                 if (argc != 2) {
360                         fprintf(stderr, "Disable requires a technology name or "
361                                 "the argument 'offlinemode' see help\n");
362                         error = -EINVAL;
363                 } else if (strcmp(argv[1], "offlinemode") == 0) {
364                         error = set_manager(connection, "OfflineMode", FALSE);
365                         if (error == 0)
366                                 printf("OfflineMode is now disabled\n");
367                 } else {
368                         message = get_message(connection, "GetTechnologies");
369                         if (message == NULL)
370                                 error = -ENOMEM;
371                         else
372                                 error = set_technology(connection, message,
373                                                 "Powered", argv[1], FALSE);
374                         if (error == 0)
375                                 printf("Disabled %s technology\n", argv[1]);
376                 }
377         } else
378                 return -1;
379
380         if (message != NULL)
381                 dbus_message_unref(message);
382
383         return error;
384 }
385
386 int commands_options(DBusConnection *connection, char *argv[], int argc)
387 {
388         int error, c;
389         int option_index = 0;
390         struct service_data service;
391
392         static struct option service_options[] = {
393                 {"properties", required_argument, 0, 'p'},
394                 {0, 0, 0, 0}
395         };
396
397         static struct option config_options[] = {
398                 {"nameservers", required_argument, 0, 'n'},
399                 {"timeservers", required_argument, 0, 't'},
400                 {"domains", required_argument, 0, 'd'},
401                 {"ipv6", required_argument, 0, 'v'},
402                 {"proxy", required_argument, 0, 'x'},
403                 {"autoconnect", required_argument, 0, 'a'},
404                 {"ipv4", required_argument, 0, 'i'},
405                 {"remove", 0, 0, 'r'},
406                 {0, 0, 0, 0}
407         };
408
409         static struct option monitor_options[] = {
410                 {"services", no_argument, 0, 's'},
411                 {"tech", no_argument, 0, 'c'},
412                 {"manager", no_argument, 0, 'm'},
413                 {0, 0, 0, 0}
414         };
415
416         if (strcmp(argv[0], "services") == 0) {
417                 if (argc > 3) {
418                         fprintf(stderr, "Too many arguments for services, "
419                                                                 "see help\n");
420                         return -EINVAL;
421                 }
422                 if (argc < 2) {
423                         printf("List of all services:\n");
424                         error = list_properties(connection, "GetServices", NULL);
425                         if (error != 0)
426                                 return error;
427                 } else {
428                         while ((c = getopt_long(argc, argv, "", service_options,
429                                                 &option_index))) {
430                                 if (c == -1) {
431                                         if (option_index == 0) {
432                                                 printf("Services takes an "
433                                                         "option, see help.\n");
434                                                 return -EINVAL;
435                                         }
436                                         break;
437                                 }
438                                 error = service_switch(argc, argv, c,
439                                                                 connection,
440                                                                 &service);
441                                 if (error != 0)
442                                         return error;
443                                 option_index++;
444                         }
445                 }
446         } else if (strcmp(argv[0], "config") == 0) {
447                 if (argc < 3) {
448                         fprintf(stderr, "Config requires an option, "
449                                                                 "see help\n");
450                         return -EINVAL;
451                 }
452                 while ((c = getopt_long(argc, argv, "", config_options,
453                                                         &option_index))) {
454                         if (c == -1) {
455                                 if (option_index == 0) {
456                                         printf("Config requires an option, "
457                                                         "see help\n");
458                                         return -EINVAL;
459                                 }
460                                 break;
461                         }
462                         error = config_switch(argc, argv, c, connection);
463                         if (error != 0)
464                                 return error;
465                         option_index++;
466                 }
467         } else if (strcmp(argv[0], "monitor") == 0) {
468                 if (argc > 2) {
469                         fprintf(stderr, "Too many arguments for monitor, "
470                                                                 "see help\n");
471                         return -EINVAL;
472                 }
473                 if (argc < 2) {
474                         error = monitor_connman(connection, "Service",
475                                                         "PropertyChanged");
476                         if (error != 0)
477                                 return error;
478                         error = monitor_connman(connection, "Technology",
479                                                         "PropertyChanged");
480                         if (error != 0)
481                                 return error;
482                         error = monitor_connman(connection, "Manager",
483                                                         "PropertyChanged");
484                         if (error != 0)
485                                 return error;
486                         error = monitor_connman(connection, "Manager",
487                                                         "TechnologyAdded");
488                         if (error != 0)
489                                 return error;
490                         error = monitor_connman(connection, "Manager",
491                                                         "TechnologyRemoved");
492                         if (error != 0)
493                                 return error;
494                         error = monitor_connman(connection, "Manager",
495                                                         "ServicesChanged");
496                         if (error != 0)
497                                 return error;
498                         if (dbus_connection_add_filter(connection,
499                                         service_property_changed, NULL, NULL)
500                                                                 == FALSE)
501                                 return -ENOMEM;
502                         if (dbus_connection_add_filter(connection,
503                                         tech_property_changed, NULL, NULL)
504                                                                 == FALSE)
505                                 return -ENOMEM;
506                         if (dbus_connection_add_filter(connection,
507                                         tech_added_removed, NULL, NULL)
508                                                                 == FALSE)
509                                 return -ENOMEM;
510                         if (dbus_connection_add_filter(connection,
511                                         manager_property_changed, NULL, NULL)
512                                                                 == FALSE)
513                                 return -ENOMEM;
514                         if (dbus_connection_add_filter(connection,
515                                         manager_services_changed, NULL, NULL)
516                                                                 == FALSE)
517                                 return -ENOMEM;
518                         printf("Now monitoring all interfaces.\n");
519                 } else
520                         while ((c = getopt_long(argc, argv, "", monitor_options,
521                                                         &option_index))) {
522                                 if (c == -1) {
523                                         if (option_index == 0) {
524                                                 printf("Monitor takes an "
525                                                         "option, see help\n");
526                                                 return -EINVAL;
527                                         }
528                                         break;
529                                 }
530                                 error = monitor_switch(argc, argv, c, connection);
531                                 if (error != 0)
532                                         return error;
533                                 option_index++;
534                         }
535         } else
536                 return -1;
537         return 0;
538 }