Remove backup files at cleanup stage
[connman] / src / iface-storage.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2008  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 <errno.h>
27 #include <arpa/inet.h>
28
29 #include <glib.h>
30
31 #include "connman.h"
32
33 #define GROUP_CONFIG  "Config"
34
35 char *__connman_iface_find_passphrase(struct connman_iface *iface,
36                                                         const char *network)
37 {
38         GKeyFile *keyfile;
39         gchar *pathname, *result = NULL;
40         gchar **list;
41         gsize list_len;
42         int i;
43
44         if (iface->identifier == NULL)
45                 return NULL;
46
47         pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR,
48                                                         iface->identifier);
49         if (pathname == NULL)
50                 return NULL;
51
52         keyfile = g_key_file_new();
53
54         g_key_file_set_list_separator(keyfile, ',');
55
56         if (g_key_file_load_from_file(keyfile, pathname, 0, NULL) == FALSE)
57                 goto done;
58
59         if (g_key_file_has_group(keyfile, GROUP_CONFIG) == FALSE)
60                 goto done;
61
62         list = g_key_file_get_string_list(keyfile, GROUP_CONFIG,
63                                         "KnownNetworks", &list_len, NULL);
64         for (i = 0; i < list_len; i++) {
65                 if (g_str_equal(list[i], network) == TRUE) {
66                         result = g_key_file_get_string(keyfile, network,
67                                                                 "PSK", NULL);
68                         if (result == NULL)
69                                 result = g_strdup("");
70                         break;
71                 }
72         }
73
74         g_strfreev(list);
75
76 done:
77         g_key_file_free(keyfile);
78
79         g_free(pathname);
80
81         return result;
82 }
83
84 int __connman_iface_load(struct connman_iface *iface)
85 {
86         GKeyFile *keyfile;
87         gchar *pathname, *str;
88         gchar **list;
89         gsize list_len;
90
91         DBG("iface %p", iface);
92
93         if (iface->identifier == NULL)
94                 return -EIO;
95
96         pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR,
97                                                         iface->identifier);
98         if (pathname == NULL)
99                 return -ENOMEM;
100
101         keyfile = g_key_file_new();
102
103         g_key_file_set_list_separator(keyfile, ',');
104
105         if (g_key_file_load_from_file(keyfile, pathname, 0, NULL) == FALSE)
106                 goto done;
107
108         if (g_key_file_has_group(keyfile, GROUP_CONFIG) == FALSE)
109                 goto done;
110
111         str = g_key_file_get_string(keyfile, GROUP_CONFIG, "Policy", NULL);
112         if (str != NULL) {
113                 iface->policy = __connman_iface_string2policy(str);
114                 g_free(str);
115         }
116
117         list = g_key_file_get_string_list(keyfile, GROUP_CONFIG,
118                                         "KnownNetworks", &list_len, NULL);
119
120         g_strfreev(list);
121
122         str = g_key_file_get_string(keyfile, GROUP_CONFIG,
123                                                 "LastNetwork", NULL);
124         if (str != NULL) {
125                 g_free(iface->network.identifier);
126                 iface->network.identifier = str;
127
128                 str = g_key_file_get_string(keyfile,
129                                 iface->network.identifier, "PSK", NULL);
130                 if (str != NULL) {
131                         g_free(iface->network.passphrase);
132                         iface->network.passphrase = str;
133                 }
134         }
135
136 done:
137         g_key_file_free(keyfile);
138
139         g_free(pathname);
140
141         return 0;
142 }
143
144 static void do_update(GKeyFile *keyfile, struct connman_iface *iface)
145 {
146         const char *str;
147
148         DBG("iface %p", iface);
149
150         str = __connman_iface_policy2string(iface->policy);
151         g_key_file_set_string(keyfile, GROUP_CONFIG, "Policy", str);
152
153         if (iface->network.identifier != NULL) {
154                 g_key_file_set_string(keyfile, GROUP_CONFIG,
155                                 "LastNetwork", iface->network.identifier);
156         } else
157                 g_key_file_remove_key(keyfile, GROUP_CONFIG,
158                                                 "LastNetwork", NULL);
159
160         if (iface->network.identifier != NULL)
161                 g_key_file_set_string(keyfile, iface->network.identifier,
162                                         "PSK", iface->network.passphrase);
163 }
164
165 int __connman_iface_store(struct connman_iface *iface)
166 {
167         GKeyFile *keyfile;
168         gchar *pathname, *data = NULL;
169         gsize length;
170
171         DBG("iface %p", iface);
172
173         if (iface->identifier == NULL)
174                 return -EIO;
175
176         pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR,
177                                                         iface->identifier);
178         if (pathname == NULL)
179                 return -ENOMEM;
180
181         keyfile = g_key_file_new();
182
183         if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE)
184                 goto update;
185
186         if (length > 0) {
187                 if (g_key_file_load_from_data(keyfile, data, length,
188                                 G_KEY_FILE_KEEP_COMMENTS, NULL) == FALSE)
189                         goto done;
190         }
191
192         g_free(data);
193
194 update:
195         do_update(keyfile, iface);
196
197         data = g_key_file_to_data(keyfile, &length, NULL);
198
199         g_file_set_contents(pathname, data, length, NULL);
200
201 done:
202         g_free(data);
203
204         g_key_file_free(keyfile);
205
206         g_free(pathname);
207
208         return 0;
209 }
210
211 int __connman_iface_store_current_network(struct connman_iface *iface)
212 {
213         GKeyFile *keyfile;
214         gchar *pathname, *data = NULL;
215         gsize length;
216
217         DBG("iface %p", iface);
218
219         if (iface->identifier == NULL)
220                 return -EIO;
221
222         pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR,
223                                                         iface->identifier);
224         if (pathname == NULL)
225                 return -ENOMEM;
226
227         keyfile = g_key_file_new();
228
229         if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE)
230                 goto update;
231
232         if (length > 0) {
233                 if (g_key_file_load_from_data(keyfile, data, length,
234                                 G_KEY_FILE_KEEP_COMMENTS, NULL) == FALSE)
235                         goto done;
236         }
237
238         g_free(data);
239
240 update:
241         g_key_file_set_string(keyfile, GROUP_CONFIG,
242                                 "LastNetwork", iface->network.identifier);
243
244         data = g_key_file_to_data(keyfile, &length, NULL);
245
246         g_file_set_contents(pathname, data, length, NULL);
247
248 done:
249         g_free(data);
250
251         g_key_file_free(keyfile);
252
253         g_free(pathname);
254
255         return 0;
256 }
257
258 int __connman_iface_load_networks(struct connman_iface *iface)
259 {
260         GKeyFile *keyfile;
261         gchar *pathname;
262         gchar **list;
263         gsize list_len;
264         int i;
265
266         if (iface->identifier == NULL)
267                 return -1;
268
269         pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR,
270                                                         iface->identifier);
271         if (pathname == NULL)
272                 return -1;
273
274         keyfile = g_key_file_new();
275
276         g_key_file_set_list_separator(keyfile, ',');
277
278         if (g_key_file_load_from_file(keyfile, pathname, 0, NULL) == FALSE)
279                 goto done;
280
281         if (g_key_file_has_group(keyfile, GROUP_CONFIG) == FALSE)
282                 goto done;
283
284         list = g_key_file_get_string_list(keyfile, GROUP_CONFIG,
285                                         "KnownNetworks", &list_len, NULL);
286         for (i = 0; i < list_len; i++) {
287                 gchar *psk;
288
289                 DBG("Known network %s", list[i]);
290
291                 psk = g_key_file_get_string(keyfile, list[i], "PSK", NULL);
292
293                 __connman_iface_add_network(iface, list[i], psk);
294         }
295
296         g_strfreev(list);
297
298 done:
299         g_key_file_free(keyfile);
300
301         g_free(pathname);
302
303         return 0;
304 }