dnsproxy: Only one copy of the relevant buffers will be made to a TCP request
[framework/connectivity/connman.git] / client / main.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-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 version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <dbus/dbus.h>
32
33 #define CONNMAN_SERVICE                 "net.connman"
34
35 #define CONNMAN_MANAGER_INTERFACE       CONNMAN_SERVICE ".Manager"
36 #define CONNMAN_MANAGER_PATH            "/"
37
38 struct service_data {
39         const char *path;
40         const char *name;
41         dbus_bool_t favorite;
42 };
43
44 static DBusMessage *get_services(DBusConnection *connection)
45 {
46         DBusMessage *message, *reply;
47         DBusError error;
48
49         message = dbus_message_new_method_call(CONNMAN_SERVICE,
50                                                 CONNMAN_MANAGER_PATH,
51                                                 CONNMAN_MANAGER_INTERFACE,
52                                                         "GetServices");
53         if (message == NULL)
54                 return NULL;
55
56         dbus_error_init(&error);
57
58         reply = dbus_connection_send_with_reply_and_block(connection,
59                                                         message, -1, &error);
60         if (reply == NULL) {
61                 if (dbus_error_is_set(&error) == TRUE) {
62                         fprintf(stderr, "%s\n", error.message);
63                         dbus_error_free(&error);
64                 } else
65                         fprintf(stderr, "Failed to get properties\n");
66                 dbus_message_unref(message);
67                 return NULL;
68         }
69
70         dbus_message_unref(message);
71
72         return reply;
73 }
74
75 static DBusMessage *lookup_service(DBusConnection *connection,
76                                                         const char *pattern)
77 {
78         DBusMessage *message, *reply;
79         DBusError error;
80
81         message = dbus_message_new_method_call(CONNMAN_SERVICE,
82                                                 CONNMAN_MANAGER_PATH,
83                                                 CONNMAN_MANAGER_INTERFACE,
84                                                         "LookupService");
85         if (message == NULL)
86                 return NULL;
87
88         dbus_message_append_args(message, DBUS_TYPE_STRING, &pattern,
89                                                         DBUS_TYPE_INVALID);
90
91         dbus_error_init(&error);
92
93         reply = dbus_connection_send_with_reply_and_block(connection,
94                                                         message, -1, &error);
95         if (reply == NULL) {
96                 if (dbus_error_is_set(&error) == TRUE) {
97                         fprintf(stderr, "%s\n", error.message);
98                         dbus_error_free(&error);
99                 } else
100                         fprintf(stderr, "Failed to get properties\n");
101                 dbus_message_unref(message);
102                 return NULL;
103         }
104
105         dbus_message_unref(message);
106
107         return reply;
108 }
109
110 static void extract_properties(DBusMessageIter *dict,
111                                         struct service_data *service)
112 {
113         while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
114                 DBusMessageIter entry, value;
115                 const char *key;
116
117                 dbus_message_iter_recurse(dict, &entry);
118                 dbus_message_iter_get_basic(&entry, &key);
119
120                 dbus_message_iter_next(&entry);
121
122                 dbus_message_iter_recurse(&entry, &value);
123
124                 //type = dbus_message_iter_get_arg_type(&value);
125                 //dbus_message_iter_get_basic(&value, &val);
126
127                 if (strcmp(key, "Name") == 0)
128                         dbus_message_iter_get_basic(&value, &service->name);
129                 else if (strcmp(key, "Favorite") == 0)
130                         dbus_message_iter_get_basic(&value, &service->favorite);
131
132                 dbus_message_iter_next(dict);
133         }
134 }
135
136 static void extract_services(DBusMessage *message)
137 {
138         DBusMessageIter iter, array;
139
140         dbus_message_iter_init(message, &iter);
141         dbus_message_iter_recurse(&iter, &array);
142
143         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
144                 DBusMessageIter entry, dict;
145                 struct service_data service;
146                 const char *path;
147
148                 dbus_message_iter_recurse(&array, &entry);
149                 dbus_message_iter_get_basic(&entry, &path);
150
151                 service.path = strrchr(path, '/') + 1;
152
153                 dbus_message_iter_next(&entry);
154
155                 dbus_message_iter_recurse(&entry, &dict);
156                 extract_properties(&dict, &service);
157
158                 printf("%c %-20s { %-50s }\n",
159                                 service.favorite == TRUE ? '*' : ' ',
160                                                 service.name, service.path);
161
162                 dbus_message_iter_next(&array);
163         }
164 }
165
166 static int cmd_list_services(DBusConnection *connection)
167 {
168         DBusMessage *message;
169
170         message = get_services(connection);
171         if (message == NULL)
172                 return -1;
173
174         extract_services(message);
175
176         dbus_message_unref(message);
177
178         return 0;
179 }
180
181 static int cmd_show_service(DBusConnection *connection, const char *pattern)
182 {
183         DBusMessage *message;
184         const char *path;
185
186         message = lookup_service(connection, pattern);
187         if (message == NULL)
188                 return -1;
189
190         dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
191                                                         DBUS_TYPE_INVALID);
192
193         printf("Service: %s\n", path);
194
195         dbus_message_unref(message);
196
197         return 0;
198 }
199
200 static void usage(const char *program)
201 {
202         printf("ConnMan utility ver %s\n\n", VERSION);
203
204         printf("Usage:\n"
205                 "\t%s <command> [options]\n\n", program);
206
207         printf("Commands:\n"
208                 "\thelp\n"
209                 "\tlist\n"
210                 "\tshow <service>\n"
211                 "\n");
212 }
213
214 int main(int argc, char *argv[])
215 {
216         DBusConnection *conn;
217
218         if (argc > 1 && strcmp(argv[1], "help") == 0) {
219                 usage(argv[0]);
220                 exit(0);
221         }
222
223         conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
224         if (!conn) {
225                 fprintf(stderr, "Can't get on system bus\n");
226                 exit(1);
227         }
228
229         if (argc > 1) {
230                 if (strcmp(argv[1], "list") == 0)
231                         cmd_list_services(conn);
232                 else if (strcmp(argv[1], "show") == 0) {
233                         if (argc > 2)
234                                 cmd_show_service(conn, argv[2]);
235                         else
236                                 usage(argv[0]);
237                 }
238         } else
239                 usage(argv[0]);
240
241         dbus_connection_unref(conn);
242
243         return 0;
244 }