Add skeleton for storage drivers
[connman] / 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 "connman.h"
27
28 static GSList *storage_list = NULL;
29
30 static gint compare_priority(gconstpointer a, gconstpointer b)
31 {
32         const struct connman_storage *storage1 = a;
33         const struct connman_storage *storage2 = b;
34
35         return storage2->priority - storage1->priority;
36 }
37
38 /**
39  * connman_storage_register:
40  * @storage: storage module
41  *
42  * Register a new storage module
43  *
44  * Returns: %0 on success
45  */
46 int connman_storage_register(struct connman_storage *storage)
47 {
48         DBG("storage %p name %s", storage, storage->name);
49
50         storage_list = g_slist_insert_sorted(storage_list, storage,
51                                                         compare_priority);
52
53         return 0;
54 }
55
56 /**
57  * connman_storage_unregister:
58  * @storage: storage module
59  *
60  * Remove a previously registered storage module
61  */
62 void connman_storage_unregister(struct connman_storage *storage)
63 {
64         DBG("storage %p name %s", storage, storage->name);
65
66         storage_list = g_slist_remove(storage_list, storage);
67 }
68
69 int __connman_storage_init(void)
70 {
71         DBG("");
72
73         return 0;
74 }
75
76 void __connman_storage_cleanup(void)
77 {
78         DBG("");
79 }
80
81 static int do_load(GKeyFile *keyfile, struct connman_element *element)
82 {
83         const gchar *value;
84
85         DBG("element %p name %s", element, element->name);
86
87         value = g_key_file_get_string(keyfile, element->path,
88                                                 "Policy", NULL);
89         if (value != NULL)
90                 element->policy = __connman_element_string2policy(value);
91
92         if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK)
93                 element->remember = g_key_file_get_boolean(keyfile,
94                                         element->path, "Remember", NULL);
95
96         value = g_key_file_get_string(keyfile, element->path,
97                                                 "WiFi.Security", NULL);
98         if (value != NULL)
99                 connman_element_set_property(element,
100                                 CONNMAN_PROPERTY_ID_WIFI_SECURITY, &value);
101
102         value = g_key_file_get_string(keyfile, element->path,
103                                                 "WiFi.Passphrase", NULL);
104         if (value != NULL)
105                 connman_element_set_property(element,
106                                 CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE, &value);
107
108         return 0;
109 }
110
111 int __connman_element_load(struct connman_element *element)
112 {
113         GKeyFile *keyfile;
114         gchar *pathname, *data = NULL;
115         gsize length;
116
117         DBG("element %p name %s", element, element->name);
118
119         pathname = g_strdup_printf("%s/elements.conf", STORAGEDIR);
120         if (pathname == NULL)
121                 return -ENOMEM;
122
123         keyfile = g_key_file_new();
124
125         if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE) {
126                 g_free(pathname);
127                 return -ENOENT;
128         }
129
130         g_free(pathname);
131
132         if (g_key_file_load_from_data(keyfile, data, length,
133                                                         0, NULL) == FALSE) {
134                 g_free(data);
135                 return -EILSEQ;
136         }
137
138         g_free(data);
139
140         do_load(keyfile, element);
141
142         g_key_file_free(keyfile);
143
144         return 0;
145 }
146
147 static void do_update(GKeyFile *keyfile, struct connman_element *element)
148 {
149         GSList *list;
150         char *value;
151         const char *str;
152
153         DBG("element %p name %s", element, element->name);
154
155         g_key_file_set_string(keyfile, element->path, "Name", element->name);
156
157         str = __connman_element_policy2string(element->policy);
158         if (str != NULL)
159                 g_key_file_set_string(keyfile, element->path, "Policy", str);
160
161         //g_key_file_set_boolean(keyfile, element->path, "Enabled",
162         //                                              element->enabled);
163
164         if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK)
165                 g_key_file_set_boolean(keyfile, element->path, "Remember",
166                                                         element->remember);
167
168         __connman_element_lock(element);
169
170         for (list = element->properties; list; list = list->next) {
171                 struct connman_property *property = list->data;
172
173                 if (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)
174                         continue;
175
176                 if (property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE)
177                         continue;
178
179                 if (property->type == DBUS_TYPE_STRING)
180                         g_key_file_set_string(keyfile, element->path,
181                                         property->name, property->value);
182         }
183
184         __connman_element_unlock(element);
185
186         if (connman_element_get_value(element,
187                         CONNMAN_PROPERTY_ID_WIFI_SECURITY, &value) == 0)
188                 g_key_file_set_string(keyfile, element->path,
189                                                 "WiFi.Security", value);
190
191         if (connman_element_get_value(element,
192                         CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE, &value) == 0)
193                 g_key_file_set_string(keyfile, element->path,
194                                                 "WiFi.Passphrase", value);
195 }
196
197 int __connman_element_store(struct connman_element *element)
198 {
199         GKeyFile *keyfile;
200         gchar *pathname, *data = NULL;
201         gsize length;
202
203         DBG("element %p name %s", element, element->name);
204
205         if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE &&
206                                 element->type != CONNMAN_ELEMENT_TYPE_NETWORK)
207                 return -EINVAL;
208
209         if (element->subtype == CONNMAN_ELEMENT_SUBTYPE_FAKE)
210                 return -EINVAL;
211
212         pathname = g_strdup_printf("%s/elements.conf", STORAGEDIR);
213         if (pathname == NULL)
214                 return -ENOMEM;
215
216         keyfile = g_key_file_new();
217
218         if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE)
219                 goto update;
220
221         if (length > 0) {
222                 if (g_key_file_load_from_data(keyfile, data, length,
223                                                         0, NULL) == FALSE)
224                         goto done;
225         }
226
227         g_free(data);
228
229 update:
230         do_update(keyfile, element);
231
232         data = g_key_file_to_data(keyfile, &length, NULL);
233
234         g_file_set_contents(pathname, data, length, NULL);
235
236 done:
237         g_free(data);
238
239         g_key_file_free(keyfile);
240
241         g_free(pathname);
242
243         return 0;
244 }