client: Fix some memory leaks in data_manager part
[platform/upstream/connman.git] / client / data_manager.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2012  Intel Corporation. All rights reserved.
6  *  it under the terms of the GNU General Public License version 2 as
7  *  published by the Free Software Foundation.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdint.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <errno.h>
26
27 #include <glib.h>
28
29 #include "src/connman.h"
30 #include "client/services.h"
31 #include "client/technology.h"
32 #include "client/data_manager.h"
33 #include "gdbus/gdbus.h"
34 #include "include/dbus.h"
35
36 static void extract_manager_properties(DBusMessage *message)
37 {
38         DBusMessageIter iter, array;
39
40         dbus_message_iter_init(message, &iter);
41         dbus_message_iter_recurse(&iter, &array);
42         extract_properties(&array);
43 }
44
45 int store_proxy_input(DBusConnection *connection, DBusMessage *message,
46                                 char *name, int num_args, char *argv[])
47 {
48         int i, j, k;
49         int error = 0;
50         gchar **servers = NULL;
51         gchar **excludes = NULL;
52
53         for (i = 0; strcmp(argv[i], "excludes") != 0; i++) {
54                 servers = g_try_realloc(servers, (i + 1) * sizeof(char *));
55                 if (servers == NULL) {
56                         fprintf(stderr, "Could not allocate memory for list\n");
57                         return -ENOMEM;
58                 }
59                 servers[i] = g_strdup(argv[i]);
60                 /* In case the user doesn't enter "excludes" */
61                 if (i + 1 == num_args) {
62                         i++;
63                         j = 0;
64                         goto free_servers;
65                 }
66         }
67         for (j = 0; j + (i + 1) != num_args; j++) {
68                 excludes = g_try_realloc(excludes, (j + 1) * sizeof(char *));
69                 if (excludes == NULL) {
70                         fprintf(stderr, "Could not allocate memory for list\n");
71                         return -ENOMEM;
72                 }
73                 excludes[j] = g_strdup(argv[j + (i + 1)]);
74         }
75
76 free_servers:
77         error = set_proxy_manual(connection, message, name, servers, excludes,
78                                                                         i, j);
79
80         for (k = 0; k < j - 1; k++)
81                 g_free(excludes[k]);
82         g_free(excludes);
83
84         for (k = 0; k < i - 1; k++)
85                 g_free(servers[k]);
86         g_free(servers);
87
88         return error;
89 }
90
91 int connect_service(DBusConnection *connection, char *name)
92 {
93         DBusMessage *message, *message_connect = NULL;
94         struct service_data service;
95         char *path = NULL;
96         const char *path_name;
97         DBusError err;
98         int err_ret = 0;
99
100         message = get_message(connection, "GetServices");
101         if (message == NULL)
102                 return -ENOMEM;
103
104         path_name = find_service(connection, message, name, &service);
105         if (path_name == NULL) {
106                 err_ret = -ENXIO;
107                 goto error;
108         }
109
110         path = g_strdup_printf("/net/connman/service/%s", path_name);
111         message_connect = dbus_message_new_method_call("net.connman", path,
112                                                 "net.connman.Service",
113                                                 "Connect");
114         if (message_connect == NULL) {
115                 err_ret = -ENOMEM;
116                 goto error;
117         }
118
119         dbus_error_init(&err);
120         dbus_connection_send_with_reply_and_block(connection, message_connect,
121                                                                 -1, &err);
122
123         if (dbus_error_is_set(&err)) {
124                 printf("Connection failed; error: '%s'\n", err.message);
125                 err_ret = -EINVAL;
126                 goto error;
127         }
128
129         dbus_connection_send(connection, message_connect, NULL);
130         dbus_connection_flush(connection);
131
132 error:
133         if (message != NULL)
134                 dbus_message_unref(message);
135         if (message_connect != NULL)
136                 dbus_message_unref(message_connect);
137         g_free(path);
138
139         return err_ret;
140 }
141
142 int disconnect_service(DBusConnection *connection, char *name)
143 {
144         DBusMessage *message, *message_disconnect = NULL;
145         struct service_data service;
146         char *path = NULL;
147         const char *path_name;
148         DBusError err;
149         int err_ret = 0;
150
151         message = get_message(connection, "GetServices");
152         if (message == NULL)
153                 return -ENOMEM;
154
155         path_name = find_service(connection, message, name, &service);
156         if (path_name == NULL) {
157                 err_ret = -ENXIO;
158                 goto error;
159         }
160
161         path = g_strdup_printf("/net/connman/service/%s", path_name);
162         printf("%s\n", path);
163         message_disconnect = dbus_message_new_method_call("net.connman", path,
164                                                           "net.connman.Service",
165                                                           "Disconnect");
166         if (message_disconnect == NULL) {
167                 err_ret = -ENOMEM;
168                 goto error;
169         }
170
171         dbus_error_init(&err);
172         dbus_connection_send_with_reply_and_block(connection,
173                                                   message_disconnect,
174                                                   -1, &err);
175
176         if (dbus_error_is_set(&err)) {
177                 printf("Connection failed; error: '%s'\n", err.message);
178                 err_ret = -EINVAL;
179                 goto error;
180         }
181
182         dbus_connection_send(connection, message_disconnect, NULL);
183         dbus_connection_flush(connection);
184
185 error:
186         if (message != NULL)
187                 dbus_message_unref(message);
188         if (message_disconnect != NULL)
189                 dbus_message_unref(message_disconnect);
190         g_free(path);
191
192         return err_ret;
193 }
194
195 int set_manager(DBusConnection *connection, char *key, dbus_bool_t value)
196 {
197         DBusMessage *message;
198         DBusMessageIter iter;
199
200         message = dbus_message_new_method_call("net.connman", "/",
201                                                 "net.connman.Manager",
202                                                 "SetProperty");
203         if (message == NULL)
204                 return -ENOMEM;
205
206         dbus_message_iter_init_append(message, &iter);
207         connman_dbus_property_append_basic(&iter, (const char *) key,
208                                                 DBUS_TYPE_BOOLEAN, &value);
209         dbus_connection_send(connection, message, NULL);
210         dbus_connection_flush(connection);
211         dbus_message_unref(message);
212
213         return 0;
214 }
215
216 /* Call with any given function we want connman to respond to */
217 DBusMessage *get_message(DBusConnection *connection, char *function)
218 {
219         DBusMessage *message, *reply;
220         DBusError error;
221
222         message = dbus_message_new_method_call(CONNMAN_SERVICE,
223                                                 CONNMAN_MANAGER_PATH,
224                                                 CONNMAN_MANAGER_INTERFACE,
225                                                 function);
226         if (message == NULL)
227                 return NULL;
228
229         dbus_error_init(&error);
230
231         reply = dbus_connection_send_with_reply_and_block(connection,
232                                                            message, -1, &error);
233         if (dbus_error_is_set(&error) == TRUE) {
234                 fprintf(stderr, "%s\n", error.message);
235                 dbus_error_free(&error);
236         } else if (reply == NULL)
237                 fprintf(stderr, "Failed to receive message\n");
238
239         dbus_message_unref(message);
240
241         return reply;
242 }
243
244 int list_properties(DBusConnection *connection, char *function,
245                         char *service_name)
246 {
247         DBusMessage *message;
248
249         message = get_message(connection, function);
250         if (message == NULL)
251                 return -ENOMEM;
252
253         if (strcmp(function, "GetProperties") == 0)
254                 extract_manager_properties(message);
255
256         else if (strcmp(function, "GetServices") == 0 && service_name != NULL)
257                 extract_services(message, service_name);
258
259         else if (strcmp(function, "GetServices") == 0 && service_name == NULL)
260                 get_services(message);
261
262         else if (strcmp(function, "GetTechnologies") == 0)
263                 extract_tech(message);
264
265         dbus_message_unref(message);
266
267         return 0;
268 }