Maemo: Changed the input mode of several text boxes.
[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 /* ensure that the directory exists */
143 gchar *dir = g_path_get_dirname (priv->path);
144 g_mkdir_with_parents (dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
145 g_free (dir);
146
147 priv->connections = g_hash_table_new_full (g_str_hash,
148 g_str_equal,
149 g_free,
150 g_object_unref);
151
152 priv->model = GTK_TREE_MODEL (gtk_list_store_new (2,
153 G_TYPE_STRING,
154 G_TYPE_STRING));
155 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->model),
156 0,
157 GTK_SORT_ASCENDING);
158 }
159
160 static void
161 strongswan_connections_constructed (GObject *object)
162 {
163 StrongswanConnectionsPrivate *priv;
164 GnomeVFSResult result;
165
166 if (G_OBJECT_CLASS (strongswan_connections_parent_class)->constructed)
167 {
168 G_OBJECT_CLASS (strongswan_connections_parent_class)->constructed (object);
169 }
170
171 g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
172 priv = STRONGSWAN_CONNECTIONS (object)->priv;
173
174 result = gnome_vfs_monitor_add (&priv->monitor,
175 priv->path,
176 GNOME_VFS_MONITOR_FILE,
177 (GnomeVFSMonitorCallback) strongswan_connections_file_changed,
178 object);
179 if (result != GNOME_VFS_OK)
180 {
181 g_warning ("Could not monitor '%s': %s",
182 priv->path,
183 gnome_vfs_result_to_string (result));
184 }
185
186 strongswan_connections_load_config (STRONGSWAN_CONNECTIONS (object));
187 }
188
189 static void
190 strongswan_connections_dispose (GObject *object)
191 {
192 StrongswanConnectionsPrivate *priv;
193
194 g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
195 priv = STRONGSWAN_CONNECTIONS (object)->priv;
196
197 if (priv->model)
198 {
199 priv->model = (g_object_unref (priv->model), NULL);
200 }
201
202 G_OBJECT_CLASS (strongswan_connections_parent_class)->dispose (object);
203 }
204
205 static void
206 strongswan_connections_finalize (GObject *object)
207 {
208 StrongswanConnectionsPrivate *priv;
209
210 g_return_if_fail (STRONGSWAN_IS_CONNECTIONS (object));
211 priv = STRONGSWAN_CONNECTIONS (object)->priv;
212
213 priv->path = (g_free (priv->path), NULL);
214 priv->monitor = (gnome_vfs_monitor_cancel (priv->monitor), NULL);
215 priv->key_file = (g_key_file_free (priv->key_file), NULL);
216 priv->connections = (g_hash_table_destroy (priv->connections), NULL);
217
218 G_OBJECT_CLASS (strongswan_connections_parent_class)->finalize (object);
219 }
220
221 static void
222 strongswan_connections_class_init (StrongswanConnectionsClass *klass)
223 {
224 GObjectClass *object_class = G_OBJECT_CLASS (klass);
225
226 object_class->constructed = strongswan_connections_constructed;
227 object_class->dispose = strongswan_connections_dispose;
228 object_class->finalize = strongswan_connections_finalize;
229
230 g_type_class_add_private (klass, sizeof (StrongswanConnectionsPrivate));
231 }
232
233 #ifdef USE_DYNAMIC_TYPES
234 static void
235 strongswan_connections_class_finalize (StrongswanConnectionsClass *klass)
236 {
237 }
238 #endif
239
240 GtkTreeModel *
241 strongswan_connections_get_model (StrongswanConnections *self)
242 {
243 StrongswanConnectionsPrivate *priv = self->priv;
244 return g_object_ref (priv->model);
245 }
246
247 void
248 strongswan_connections_setup_column_renderers (StrongswanConnections *self,
249 GtkCellLayout *layout)
250 {
251 GtkCellRenderer *renderer;
252 renderer = gtk_cell_renderer_text_new ();
253 gtk_cell_layout_pack_start (layout,
254 renderer,
255 TRUE);
256 gtk_cell_layout_add_attribute (layout,
257 renderer,
258 "text", 0);
259 }
260
261 StrongswanConnections *
262 strongswan_connections_new (void)
263 {
264 StrongswanConnections *connections;
265 connections = g_object_new (STRONGSWAN_TYPE_CONNECTIONS,
266 NULL);
267 return connections;
268 }
269
270 StrongswanConnection *
271 strongswan_connections_get_connection (StrongswanConnections *self,
272 const gchar *name)
273 {
274 StrongswanConnectionsPrivate *priv = self->priv;
275 g_return_val_if_fail (name != NULL, NULL);
276 return g_hash_table_lookup (priv->connections, name);
277 }
278
279 static void
280 strongswan_connections_save_connections (StrongswanConnections *self)
281 {
282 StrongswanConnectionsPrivate *priv = self->priv;
283 gchar *data;
284 gsize size;
285 GError *error = NULL;
286
287 data = g_key_file_to_data (priv->key_file, &size, NULL);
288 if (!g_file_set_contents (priv->path, data, size, &error))
289 {
290 g_warning ("Failed to save connections to '%s': %s",
291 priv->path, error->message);
292 g_error_free (error);
293 }
294 g_free (data);
295 }
296
297 void
298 strongswan_connections_save_connection (StrongswanConnections *self,
299 StrongswanConnection *conn)
300 {
301 StrongswanConnectionsPrivate *priv = self->priv;
302
303 strongswan_connection_save_to_key_file (priv->key_file, conn);
304
305 strongswan_connections_save_connections (self);
306 }
307
308 void
309 strongswan_connections_remove_connection (StrongswanConnections *self,
310 const gchar *name)
311 {
312 StrongswanConnectionsPrivate *priv = self->priv;
313
314 g_key_file_remove_group (priv->key_file, name, NULL);
315
316 strongswan_connections_save_connections (self);
317 }
318