2686a620b52a6c9736f0b0aa8be0fe544ab62901
[strongswan.git] / src / frontends / maemo / src / strongswan-connections.c
1 /*
2 * Copyright (C) 2010 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <glib.h>
17 #include <libgnomevfs/gnome-vfs.h>
18
19 #include "strongswan-connections.h"
20
21 /* connections are stored in ~/.config/strongswan/connections */
22 #define CONFIG_DIR_NAME "strongswan"
23 #define CONFIG_FILE_NAME "connections"
24
25 #define STRONGSWAN_CONNECTIONS_GET_PRIVATE(object) \
26 (G_TYPE_INSTANCE_GET_PRIVATE ((object), STRONGSWAN_TYPE_CONNECTIONS, StrongswanConnectionsPrivate))
27
28 struct _StrongswanConnectionsPrivate
29 {
30 GKeyFile *key_file;
31 gchar *path;
32 GnomeVFSMonitorHandle *monitor;
33 GHashTable *connections;
34 GtkTreeModel *model;
35 };
36
37 #ifndef USE_DYNAMIC_TYPES
38 G_DEFINE_TYPE (StrongswanConnections, strongswan_connections, G_TYPE_OBJECT);
39 #else
40 G_DEFINE_DYNAMIC_TYPE (StrongswanConnections, strongswan_connections, G_TYPE_OBJECT);
41 void strongswan_connections_register (GTypeModule *type_module)
42 {
43 strongswan_connections_register_type (type_module);
44 }
45 #endif
46
47 static void
48 strongswan_connections_load_connections (StrongswanConnections *connections)
49 {
50 StrongswanConnectionsPrivate *priv = connections->priv;
51 GHashTableIter iter;
52 gpointer key, value;
53 gchar **groups;
54 guint i;
55
56 g_hash_table_remove_all (priv->connections);
57 groups = g_key_file_get_groups (priv->key_file, NULL);
58 for (i = 0; groups[i]; i++)
59 {
60 StrongswanConnection *conn;
61 conn = strongswan_connection_new_from_key_file(priv->key_file,
62 groups[i]);
63 if (conn != NULL)
64 {
65 g_hash_table_insert (priv->connections,
66 g_strdup(groups[i]),
67 conn);
68 }
69 }
70 g_strfreev (groups);
71
72 gtk_list_store_clear (GTK_LIST_STORE (priv->model));
73 g_hash_table_iter_init (&iter, priv->connections);
74 while (g_hash_table_iter_next (&iter, &key, &value))
75 {
76 gtk_list_store_insert_with_values (GTK_LIST_STORE (priv->model),
77 NULL,
78 -1,
79 0, key,
80 -1);
81 }
82 }
83
84 static void
85 strongswan_connections_load_config (StrongswanConnections *connections)
86 {
87 StrongswanConnectionsPrivate *priv = connections->priv;
88 GError *error = NULL;
89
90 if (priv->key_file)
91 {
92 g_key_file_free (priv->key_file);
93 }
94
95 priv->key_file = g_key_file_new ();
96 if (!g_key_file_load_from_file (priv->key_file,
97 priv->path,
98 G_KEY_FILE_KEEP_COMMENTS,
99 &error))
100 {
101 if (g_error_matches (error,
102 G_KEY_FILE_ERROR,
103 G_KEY_FILE_ERROR_PARSE))
104 {
105 g_debug ("Failed to parse config file '%s', treated as empty: %s",
106 priv->path, error->message);
107 g_error_free (error);
108 }
109 else
110 {
111 g_debug ("Could not read config file '%s': %s",
112 priv->path, error->message);
113 g_error_free (error);
114 }
115 }
116
117 strongswan_connections_load_connections (connections);
118 }
119
120 static void
121 strongswan_connections_file_changed (GnomeVFSMonitorHandle *handle,
122 const gchar *monitor_uri,
123 const gchar *info_uri,
124 GnomeVFSMonitorEventType event_type,
125 StrongswanConnections *connections)
126 {
127 strongswan_connections_load_config (connections);
128 }
129
130
131 static void
132 strongswan_connections_init (StrongswanConnections *connections)
133 {
134 StrongswanConnectionsPrivate *priv;
135 connections->priv = STRONGSWAN_CONNECTIONS_GET_PRIVATE (connections);
136 priv = connections->priv;
137
138 priv->path = g_build_filename (g_get_user_config_dir (),
139 CONFIG_DIR_NAME,
140 CONFIG_FILE_NAME,
141 NULL);
142
143 priv->connections = g_hash_table_new_full (g_str_hash,
144 g_str_equal,
145 g_free,
146 g_object_unref);
147
148 priv->model = GTK_TREE_MODEL (gtk_list_store_new (2,
149 G_TYPE_STRING,
150 G_TYPE_STRING));
151 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->model),
152 0,
153 GTK_SORT_ASCENDING);
154 }
155
156 static void
157 strongswan_connections_constructed (GObject *object)
158 {
159 StrongswanConnectionsPrivate *priv;
160 GnomeVFSResult result;
161
162 if (G_OBJECT_CLASS (strongswan_connections_parent_class)->constructed)
163 {
164 G_OBJECT_CLASS (strongswan_connections_parent_class)->constructed (object);
165 }
166
167 g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
168 priv = STRONGSWAN_CONNECTIONS (object)->priv;
169
170 result = gnome_vfs_monitor_add (&priv->monitor,
171 priv->path,
172 GNOME_VFS_MONITOR_FILE,
173 (GnomeVFSMonitorCallback) strongswan_connections_file_changed,
174 object);
175 if (result != GNOME_VFS_OK)
176 {
177 g_warning ("Could not monitor '%s': %s",
178 priv->path,
179 gnome_vfs_result_to_string (result));
180 }
181
182 strongswan_connections_load_config (STRONGSWAN_CONNECTIONS (object));
183 }
184
185 static void
186 strongswan_connections_dispose (GObject *object)
187 {
188 StrongswanConnectionsPrivate *priv;
189
190 g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
191 priv = STRONGSWAN_CONNECTIONS (object)->priv;
192
193 if (priv->model)
194 {
195 priv->model = (g_object_unref (priv->model), NULL);
196 }
197
198 G_OBJECT_CLASS (strongswan_connections_parent_class)->dispose (object);
199 }
200
201 static void
202 strongswan_connections_finalize (GObject *object)
203 {
204 StrongswanConnectionsPrivate *priv;
205
206 g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
207 priv = STRONGSWAN_CONNECTIONS (object)->priv;
208
209 priv->path = (g_free (priv->path), NULL);
210 priv->monitor = (gnome_vfs_monitor_cancel (priv->monitor), NULL);
211 priv->key_file = (g_key_file_free (priv->key_file), NULL);
212 priv->connections = (g_hash_table_destroy (priv->connections), NULL);
213
214 G_OBJECT_CLASS (strongswan_connections_parent_class)->finalize (object);
215 }
216
217 static void
218 strongswan_connections_class_init (StrongswanConnectionsClass *klass)
219 {
220 GObjectClass *object_class = G_OBJECT_CLASS (klass);
221
222 object_class->constructed = strongswan_connections_constructed;
223 object_class->dispose = strongswan_connections_dispose;
224 object_class->finalize = strongswan_connections_finalize;
225
226 g_type_class_add_private (klass, sizeof (StrongswanConnectionsPrivate));
227 }
228
229 #ifdef USE_DYNAMIC_TYPES
230 static void
231 strongswan_connections_class_finalize (StrongswanConnectionsClass *klass)
232 {
233 }
234 #endif
235
236 GtkTreeModel *
237 strongswan_connections_get_model (StrongswanConnections *self)
238 {
239 StrongswanConnectionsPrivate *priv = self->priv;
240 return g_object_ref (priv->model);
241 }
242
243 void
244 strongswan_connections_setup_column_renderers (StrongswanConnections *self,
245 GtkCellLayout *layout)
246 {
247 GtkCellRenderer *renderer;
248 renderer = gtk_cell_renderer_text_new ();
249 gtk_cell_layout_pack_start (layout,
250 renderer,
251 TRUE);
252 gtk_cell_layout_add_attribute (layout,
253 renderer,
254 "text", 0);
255 }
256
257 StrongswanConnections *
258 strongswan_connections_new (void)
259 {
260 StrongswanConnections *connections;
261 connections = g_object_new (STRONGSWAN_TYPE_CONNECTIONS,
262 NULL);
263 return connections;
264 }
265
266 StrongswanConnection *
267 strongswan_connections_get_connection (StrongswanConnections *self,
268 const gchar *name)
269 {
270 StrongswanConnectionsPrivate *priv = self->priv;
271 g_return_val_if_fail (name != NULL, NULL);
272 return g_hash_table_lookup (priv->connections, name);
273 }
274
275 static void
276 strongswan_connections_save_connections (StrongswanConnections *self)
277 {
278 StrongswanConnectionsPrivate *priv = self->priv;
279 gchar *data;
280 gsize size;
281 GError *error = NULL;
282
283 data = g_key_file_to_data (priv->key_file, &size, NULL);
284 if (!g_file_set_contents (priv->path, data, size, &error))
285 {
286 g_warning ("Failed to save connections to '%s': %s",
287 priv->path, error->message);
288 g_error_free (error);
289 }
290 g_free (data);
291 }
292
293 void
294 strongswan_connections_save_connection (StrongswanConnections *self,
295 StrongswanConnection *conn)
296 {
297 StrongswanConnectionsPrivate *priv = self->priv;
298
299 strongswan_connection_save_to_key_file (priv->key_file, conn);
300
301 strongswan_connections_save_connections (self);
302 }
303
304 void
305 strongswan_connections_remove_connection (StrongswanConnections *self,
306 const gchar *name)
307 {
308 StrongswanConnectionsPrivate *priv = self->priv;
309
310 g_key_file_remove_group (priv->key_file, name, NULL);
311
312 strongswan_connections_save_connections (self);
313 }
314