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