3f152c2b5f675e560eb533d8709c140ee1e95b1f
[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 G_DEFINE_TYPE (StrongswanConnections, strongswan_connections, G_TYPE_OBJECT);
38
39 static void
40 strongswan_connections_load_connections (StrongswanConnections *connections)
41 {
42 StrongswanConnectionsPrivate *priv = connections->priv;
43 GHashTableIter iter;
44 gpointer key, value;
45 gchar **groups;
46 guint i;
47
48 g_hash_table_remove_all (priv->connections);
49 groups = g_key_file_get_groups (priv->key_file, NULL);
50 for (i = 0; groups[i]; i++)
51 {
52 StrongswanConnection *conn;
53 conn = strongswan_connection_new_from_key_file(priv->key_file,
54 groups[i]);
55 if (conn != NULL)
56 {
57 g_hash_table_insert (priv->connections,
58 g_strdup(groups[i]),
59 conn);
60 }
61 }
62 g_strfreev (groups);
63
64 gtk_list_store_clear (GTK_LIST_STORE (priv->model));
65 g_hash_table_iter_init (&iter, priv->connections);
66 while (g_hash_table_iter_next (&iter, &key, &value))
67 {
68 gtk_list_store_insert_with_values (GTK_LIST_STORE (priv->model),
69 NULL,
70 -1,
71 0, key,
72 -1);
73 }
74 }
75
76 static void
77 strongswan_connections_load_config (StrongswanConnections *connections)
78 {
79 StrongswanConnectionsPrivate *priv = connections->priv;
80 GError *error = NULL;
81
82 if (priv->key_file)
83 {
84 g_key_file_free (priv->key_file);
85 }
86
87 priv->key_file = g_key_file_new ();
88 if (!g_key_file_load_from_file (priv->key_file,
89 priv->path,
90 G_KEY_FILE_KEEP_COMMENTS,
91 &error))
92 {
93 if (g_error_matches (error,
94 G_KEY_FILE_ERROR,
95 G_KEY_FILE_ERROR_PARSE))
96 {
97 g_debug ("Failed to parse config file '%s', treated as empty: %s",
98 priv->path, error->message);
99 g_error_free (error);
100 }
101 else
102 {
103 g_debug ("Could not read config file '%s': %s",
104 priv->path, error->message);
105 g_error_free (error);
106 }
107 }
108
109 strongswan_connections_load_connections (connections);
110 }
111
112 static void
113 strongswan_connections_file_changed (GnomeVFSMonitorHandle *handle,
114 const gchar *monitor_uri,
115 const gchar *info_uri,
116 GnomeVFSMonitorEventType event_type,
117 StrongswanConnections *connections)
118 {
119 strongswan_connections_load_config (connections);
120 }
121
122
123 static void
124 strongswan_connections_init (StrongswanConnections *connections)
125 {
126 StrongswanConnectionsPrivate *priv;
127 connections->priv = STRONGSWAN_CONNECTIONS_GET_PRIVATE (connections);
128 priv = connections->priv;
129
130 priv->path = g_build_filename (g_get_user_config_dir (),
131 CONFIG_DIR_NAME,
132 CONFIG_FILE_NAME,
133 NULL);
134
135 priv->connections = g_hash_table_new_full (g_str_hash,
136 g_str_equal,
137 g_free,
138 g_object_unref);
139
140 priv->model = GTK_TREE_MODEL (gtk_list_store_new (2,
141 G_TYPE_STRING,
142 G_TYPE_STRING));
143 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->model),
144 0,
145 GTK_SORT_ASCENDING);
146 }
147
148 static void
149 strongswan_connections_constructed (GObject *object)
150 {
151 StrongswanConnectionsPrivate *priv;
152 GnomeVFSResult result;
153
154 if (G_OBJECT_CLASS (strongswan_connections_parent_class)->constructed)
155 {
156 G_OBJECT_CLASS (strongswan_connections_parent_class)->constructed (object);
157 }
158
159 g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
160 priv = STRONGSWAN_CONNECTIONS (object)->priv;
161
162 result = gnome_vfs_monitor_add (&priv->monitor,
163 priv->path,
164 GNOME_VFS_MONITOR_FILE,
165 (GnomeVFSMonitorCallback) strongswan_connections_file_changed,
166 object);
167 if (result != GNOME_VFS_OK)
168 {
169 g_warning ("Could not monitor '%s': %s",
170 priv->path,
171 gnome_vfs_result_to_string (result));
172 }
173
174 strongswan_connections_load_config (STRONGSWAN_CONNECTIONS (object));
175 }
176
177 static void
178 strongswan_connections_dispose (GObject *object)
179 {
180 StrongswanConnectionsPrivate *priv;
181
182 g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
183 priv = STRONGSWAN_CONNECTIONS (object)->priv;
184
185 if (priv->model)
186 {
187 priv->model = (g_object_unref (priv->model), NULL);
188 }
189
190 G_OBJECT_CLASS (strongswan_connections_parent_class)->dispose (object);
191 }
192
193 static void
194 strongswan_connections_finalize (GObject *object)
195 {
196 StrongswanConnectionsPrivate *priv;
197
198 g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
199 priv = STRONGSWAN_CONNECTIONS (object)->priv;
200
201 priv->path = (g_free (priv->path), NULL);
202 priv->monitor = (gnome_vfs_monitor_cancel (priv->monitor), NULL);
203 priv->key_file = (g_key_file_free (priv->key_file), NULL);
204 priv->connections = (g_hash_table_destroy (priv->connections), NULL);
205
206 G_OBJECT_CLASS (strongswan_connections_parent_class)->finalize (object);
207 }
208
209 static void
210 strongswan_connections_class_init (StrongswanConnectionsClass *klass)
211 {
212 GObjectClass *object_class = G_OBJECT_CLASS (klass);
213
214 object_class->constructed = strongswan_connections_constructed;
215 object_class->dispose = strongswan_connections_dispose;
216 object_class->finalize = strongswan_connections_finalize;
217
218 g_type_class_add_private (klass, sizeof (StrongswanConnectionsPrivate));
219 }
220
221 GtkTreeModel *
222 strongswan_connections_get_model (StrongswanConnections *self)
223 {
224 StrongswanConnectionsPrivate *priv = self->priv;
225 return g_object_ref (priv->model);
226 }
227
228 void
229 strongswan_connections_setup_column_renderers (StrongswanConnections *self,
230 GtkCellLayout *layout)
231 {
232 GtkCellRenderer *renderer;
233 renderer = gtk_cell_renderer_text_new ();
234 gtk_cell_layout_pack_start (layout,
235 renderer,
236 TRUE);
237 gtk_cell_layout_add_attribute (layout,
238 renderer,
239 "text", 0);
240 }
241
242 StrongswanConnections *
243 strongswan_connections_new (void)
244 {
245 StrongswanConnections *connections;
246 connections = g_object_new (STRONGSWAN_TYPE_CONNECTIONS,
247 NULL);
248 return connections;
249 }
250
251 StrongswanConnection *
252 strongswan_connections_get_connection (StrongswanConnections *self,
253 const gchar *name)
254 {
255 StrongswanConnectionsPrivate *priv = self->priv;
256 g_return_val_if_fail (name != NULL, NULL);
257 return g_hash_table_lookup (priv->connections, name);
258 }
259
260 static void
261 strongswan_connections_save_connections (StrongswanConnections *self)
262 {
263 StrongswanConnectionsPrivate *priv = self->priv;
264 gchar *data;
265 gsize size;
266 GError *error = NULL;
267
268 data = g_key_file_to_data (priv->key_file, &size, NULL);
269 if (!g_file_set_contents (priv->path, data, size, &error))
270 {
271 g_warning ("Failed to save connections to '%s': %s",
272 priv->path, error->message);
273 g_error_free (error);
274 }
275 g_free (data);
276 }
277
278 void
279 strongswan_connections_save_connection (StrongswanConnections *self,
280 StrongswanConnection *conn)
281 {
282 StrongswanConnectionsPrivate *priv = self->priv;
283
284 strongswan_connection_save_to_key_file (priv->key_file, conn);
285
286 strongswan_connections_save_connections (self);
287 }
288
289 void
290 strongswan_connections_remove_connection (StrongswanConnections *self,
291 const gchar *name)
292 {
293 StrongswanConnectionsPrivate *priv = self->priv;
294
295 g_key_file_remove_group (priv->key_file, name, NULL);
296
297 strongswan_connections_save_connections (self);
298 }
299