Add generic suffix handling to storage helpers
[platform/upstream/connman.git] / src / storage.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2009  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 <unistd.h>
27
28 #include "connman.h"
29
30 #define PROFILE_SUFFIX  "profile"
31
32 static GSList *storage_list = NULL;
33
34 static gint compare_priority(gconstpointer a, gconstpointer b)
35 {
36         const struct connman_storage *storage1 = a;
37         const struct connman_storage *storage2 = b;
38
39         return storage2->priority - storage1->priority;
40 }
41
42 /**
43  * connman_storage_register:
44  * @storage: storage module
45  *
46  * Register a new storage module
47  *
48  * Returns: %0 on success
49  */
50 int connman_storage_register(struct connman_storage *storage)
51 {
52         DBG("storage %p name %s", storage, storage->name);
53
54         storage_list = g_slist_insert_sorted(storage_list, storage,
55                                                         compare_priority);
56
57         return 0;
58 }
59
60 /**
61  * connman_storage_unregister:
62  * @storage: storage module
63  *
64  * Remove a previously registered storage module
65  */
66 void connman_storage_unregister(struct connman_storage *storage)
67 {
68         DBG("storage %p name %s", storage, storage->name);
69
70         storage_list = g_slist_remove(storage_list, storage);
71 }
72
73 GKeyFile *__connman_storage_open(const char *ident, const char *suffix)
74 {
75         GKeyFile *keyfile;
76         gchar *pathname, *data = NULL;
77         gboolean result;
78         gsize length;
79
80         DBG("ident %s suffix %s", ident, suffix);
81
82         pathname = g_strdup_printf("%s/%s.%s", STORAGEDIR, ident, suffix);
83         if (pathname == NULL)
84                 return NULL;
85
86         result = g_file_get_contents(pathname, &data, &length, NULL);
87
88         g_free(pathname);
89
90         keyfile = g_key_file_new();
91
92         if (result == FALSE)
93                 goto done;
94
95         if (length > 0)
96                 g_key_file_load_from_data(keyfile, data, length, 0, NULL);
97
98         g_free(data);
99
100 done:
101         DBG("keyfile %p", keyfile);
102
103         return keyfile;
104 }
105
106 void __connman_storage_close(const char *ident, const char *suffix,
107                                         GKeyFile *keyfile, gboolean save)
108 {
109         gchar *pathname, *data = NULL;
110         gsize length = 0;
111
112         DBG("ident %s suffix %s keyfile %p save %d",
113                                         ident, suffix, keyfile, save);
114
115         if (save == FALSE) {
116                 g_key_file_free(keyfile);
117                 return;
118         }
119
120         pathname = g_strdup_printf("%s/%s.%s", STORAGEDIR, ident, suffix);
121         if (pathname == NULL)
122                 return;
123
124         data = g_key_file_to_data(keyfile, &length, NULL);
125
126         if (g_file_set_contents(pathname, data, length, NULL) == FALSE)
127                 connman_error("Failed to store information");
128
129         g_free(data);
130
131         g_free(pathname);
132
133         g_key_file_free(keyfile);
134 }
135
136 void __connman_storage_delete(const char *ident, const char *suffix)
137 {
138         gchar *pathname;
139
140         DBG("ident %s suffix %s", ident, suffix);
141
142         pathname = g_strdup_printf("%s/%s.%s", STORAGEDIR, ident, suffix);
143         if (pathname == NULL)
144                 return;
145
146         if (unlink(pathname) < 0)
147                 connman_error("Failed to remove %s", pathname);
148 }
149
150 GKeyFile *__connman_storage_open_profile(const char *ident)
151 {
152         return __connman_storage_open(ident, PROFILE_SUFFIX);
153 }
154
155 void __connman_storage_close_profile(const char *ident,
156                                         GKeyFile *keyfile, gboolean save)
157 {
158         __connman_storage_close(ident, PROFILE_SUFFIX, keyfile, save);
159 }
160
161 void __connman_storage_delete_profile(const char *ident)
162 {
163         __connman_storage_delete(ident, PROFILE_SUFFIX);
164 }
165
166 int __connman_storage_init_profile(void)
167 {
168         GSList *list;
169
170         DBG("");
171
172         for (list = storage_list; list; list = list->next) {
173                 struct connman_storage *storage = list->data;
174
175                 if (storage->profile_init) {
176                         if (storage->profile_init() == 0)
177                                 return 0;
178                 }
179         }
180
181         return -ENOENT;
182 }
183
184 int __connman_storage_load_profile(struct connman_profile *profile)
185 {
186         GSList *list;
187
188         DBG("profile %p", profile);
189
190         for (list = storage_list; list; list = list->next) {
191                 struct connman_storage *storage = list->data;
192
193                 if (storage->profile_load) {
194                         if (storage->profile_load(profile) == 0)
195                                 return 0;
196                 }
197         }
198
199         return -ENOENT;
200 }
201
202 int __connman_storage_save_profile(struct connman_profile *profile)
203 {
204         GSList *list;
205
206         DBG("profile %p", profile);
207
208         for (list = storage_list; list; list = list->next) {
209                 struct connman_storage *storage = list->data;
210
211                 if (storage->profile_save) {
212                         if (storage->profile_save(profile) == 0)
213                                 return 0;
214                 }
215         }
216
217         return -ENOENT;
218 }
219
220 int __connman_storage_load_service(struct connman_service *service)
221 {
222         GSList *list;
223
224         DBG("service %p", service);
225
226         for (list = storage_list; list; list = list->next) {
227                 struct connman_storage *storage = list->data;
228
229                 if (storage->service_load) {
230                         if (storage->service_load(service) == 0)
231                                 return 0;
232                 }
233         }
234
235         return -ENOENT;
236 }
237
238 int __connman_storage_save_service(struct connman_service *service)
239 {
240         GSList *list;
241
242         DBG("service %p", service);
243
244         for (list = storage_list; list; list = list->next) {
245                 struct connman_storage *storage = list->data;
246
247                 if (storage->service_save) {
248                         if (storage->service_save(service) == 0)
249                                 return 0;
250                 }
251         }
252
253         return -ENOENT;
254 }
255
256 int __connman_storage_load_device(struct connman_device *device)
257 {
258         GSList *list;
259
260         DBG("device %p", device);
261
262         for (list = storage_list; list; list = list->next) {
263                 struct connman_storage *storage = list->data;
264
265                 if (storage->device_load) {
266                         if (storage->device_load(device) == 0)
267                                 return 0;
268                 }
269         }
270
271         return -ENOENT;
272 }
273
274 int __connman_storage_save_device(struct connman_device *device)
275 {
276         GSList *list;
277
278         DBG("device %p", device);
279
280         for (list = storage_list; list; list = list->next) {
281                 struct connman_storage *storage = list->data;
282
283                 if (storage->device_save) {
284                         if (storage->device_save(device) == 0)
285                                 return 0;
286                 }
287         }
288
289         return -ENOENT;
290 }
291
292 int __connman_storage_init(void)
293 {
294         DBG("");
295
296         return 0;
297 }
298
299 void __connman_storage_cleanup(void)
300 {
301         DBG("");
302 }