d73ef6a57954a92d8081e5406ae7ef4ddf420522
[connman] / src / iface-storage.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007  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                 DBG("known network %s", list[i]);
66
67                 if (g_str_equal(list[i], network) == TRUE) {
68                         DBG("found network %s", network);
69
70                         result = g_key_file_get_string(keyfile, network,
71                                                                 "PSK", NULL);
72                         if (result == NULL)
73                                 result = g_strdup("");
74                         break;
75                 }
76         }
77
78         g_strfreev(list);
79
80 done:
81         g_key_file_free(keyfile);
82
83         g_free(pathname);
84
85         return result;
86 }
87
88 int __connman_iface_load(struct connman_iface *iface)
89 {
90         GKeyFile *keyfile;
91         gchar *pathname, *str;
92         gchar **list;
93         gsize list_len;
94
95         DBG("iface %p", iface);
96
97         if (iface->identifier == NULL)
98                 return -EIO;
99
100         pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR,
101                                                         iface->identifier);
102         if (pathname == NULL)
103                 return -ENOMEM;
104
105         keyfile = g_key_file_new();
106
107         g_key_file_set_list_separator(keyfile, ',');
108
109         if (g_key_file_load_from_file(keyfile, pathname, 0, NULL) == FALSE)
110                 goto done;
111
112         if (g_key_file_has_group(keyfile, GROUP_CONFIG) == FALSE)
113                 goto done;
114
115         str = g_key_file_get_string(keyfile, GROUP_CONFIG, "Policy", NULL);
116         if (str != NULL) {
117                 iface->policy = __connman_iface_string2policy(str);
118                 g_free(str);
119         }
120
121         list = g_key_file_get_string_list(keyfile, GROUP_CONFIG,
122                                         "KnownNetworks", &list_len, NULL);
123
124         g_strfreev(list);
125
126         str = g_key_file_get_string(keyfile, GROUP_CONFIG,
127                                                 "LastNetwork", NULL);
128         if (str != NULL) {
129                 g_free(iface->network.identifier);
130                 iface->network.identifier = str;
131
132                 str = g_key_file_get_string(keyfile,
133                                 iface->network.identifier, "PSK", NULL);
134                 if (str != NULL) {
135                         g_free(iface->network.passphrase);
136                         iface->network.passphrase = str;
137                 }
138         }
139
140 done:
141         g_key_file_free(keyfile);
142
143         g_free(pathname);
144
145         return 0;
146 }
147
148 static void do_update(GKeyFile *keyfile, struct connman_iface *iface)
149 {
150         const char *str;
151
152         DBG("iface %p", iface);
153
154         str = __connman_iface_policy2string(iface->policy);
155         g_key_file_set_string(keyfile, GROUP_CONFIG, "Policy", str);
156
157         if (iface->network.identifier != NULL) {
158                 g_key_file_set_string(keyfile, GROUP_CONFIG,
159                                 "LastNetwork", iface->network.identifier);
160         } else
161                 g_key_file_remove_key(keyfile, GROUP_CONFIG,
162                                                 "LastNetwork", NULL);
163
164         if (iface->network.identifier != NULL)
165                 g_key_file_set_string(keyfile, iface->network.identifier,
166                                         "PSK", iface->network.passphrase);
167 }
168
169 int __connman_iface_store(struct connman_iface *iface)
170 {
171         GKeyFile *keyfile;
172         gchar *pathname, *data = NULL;
173         gsize length;
174
175         DBG("iface %p", iface);
176
177         if (iface->identifier == NULL)
178                 return -EIO;
179
180         pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR,
181                                                         iface->identifier);
182         if (pathname == NULL)
183                 return -ENOMEM;
184
185         keyfile = g_key_file_new();
186
187         if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE)
188                 goto update;
189
190         if (length > 0) {
191                 if (g_key_file_load_from_data(keyfile, data, length,
192                                 G_KEY_FILE_KEEP_COMMENTS, NULL) == FALSE)
193                         goto done;
194         }
195
196         g_free(data);
197
198 update:
199         do_update(keyfile, iface);
200
201         data = g_key_file_to_data(keyfile, &length, NULL);
202
203         g_file_set_contents(pathname, data, length, NULL);
204
205 done:
206         g_free(data);
207
208         g_key_file_free(keyfile);
209
210         g_free(pathname);
211
212         return 0;
213 }
214
215 int __connman_iface_store_current_network(struct connman_iface *iface)
216 {
217         GKeyFile *keyfile;
218         gchar *pathname, *data = NULL;
219         gsize length;
220
221         DBG("iface %p", iface);
222
223         if (iface->identifier == NULL)
224                 return -EIO;
225
226         pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR,
227                                                         iface->identifier);
228         if (pathname == NULL)
229                 return -ENOMEM;
230
231         keyfile = g_key_file_new();
232
233         if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE)
234                 goto update;
235
236         if (length > 0) {
237                 if (g_key_file_load_from_data(keyfile, data, length,
238                                 G_KEY_FILE_KEEP_COMMENTS, NULL) == FALSE)
239                         goto done;
240         }
241
242         g_free(data);
243
244 update:
245         g_key_file_set_string(keyfile, GROUP_CONFIG,
246                                 "LastNetwork", iface->network.identifier);
247
248         data = g_key_file_to_data(keyfile, &length, NULL);
249
250         g_file_set_contents(pathname, data, length, NULL);
251
252 done:
253         g_free(data);
254
255         g_key_file_free(keyfile);
256
257         g_free(pathname);
258
259         return 0;
260 }