~network-manager/network-manager/ubuntu.hardy.07

« back to all changes in this revision

Viewing changes to system-settings/plugins/keyfile/plugin.c

(merge) RELEASE 0.7~~svn20080928t225540+eni0-0ubuntu1 to ubuntu/intrepid

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#define KEYFILE_PLUGIN_NAME "keyfile"
27
27
#define KEYFILE_PLUGIN_INFO "(c) 2007 - 2008 Red Hat, Inc.  To report bugs please use the NetworkManager mailing list."
28
28
 
 
29
#define CONF_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
 
30
 
 
31
static char *plugin_get_hostname (SCPluginKeyfile *plugin);
29
32
static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
30
33
 
31
34
G_DEFINE_TYPE_EXTENDED (SCPluginKeyfile, sc_plugin_keyfile, G_TYPE_OBJECT, 0,
40
43
        GFileMonitor *monitor;
41
44
        guint monitor_id;
42
45
 
 
46
        GFileMonitor *conf_file_monitor;
 
47
        guint conf_file_monitor_id;
 
48
 
 
49
        char *hostname;
 
50
 
43
51
        gboolean disposed;
44
52
} SCPluginKeyfilePrivate;
45
53
 
83
91
static void
84
92
find_by_uuid (gpointer key, gpointer data, gpointer user_data)
85
93
{
86
 
        NMKeyfileConnection *keyfile = NM_KEYFILE_CONNECTION (key);
 
94
        NMKeyfileConnection *keyfile = NM_KEYFILE_CONNECTION (data);
87
95
        FindByUUIDInfo *info = user_data;
88
96
        NMConnection *connection;
89
97
        NMSettingConnection *s_con;
99
107
        }
100
108
}
101
109
 
102
 
static gboolean
 
110
static void
103
111
update_connection_settings (NMExportedConnection *orig,
104
 
                            NMExportedConnection *new,
105
 
                            GError **error)
 
112
                            NMExportedConnection *new)
106
113
{
107
 
        GHashTable *settings;
108
 
        gboolean success;
109
 
 
110
 
        settings = nm_connection_to_hash (nm_exported_connection_get_connection (new));
111
 
        success = nm_exported_connection_update (orig, settings, error);
112
 
        g_hash_table_destroy (settings);
113
 
 
114
 
        return success;
 
114
        NMConnection *wrapped;
 
115
        GHashTable *new_settings;
 
116
 
 
117
        new_settings = nm_connection_to_hash (nm_exported_connection_get_connection (new));
 
118
        wrapped = nm_exported_connection_get_connection (orig);
 
119
        nm_connection_replace_settings (wrapped, new_settings);
 
120
        nm_exported_connection_signal_updated (orig, new_settings);
 
121
        g_hash_table_destroy (new_settings);
115
122
}
116
123
 
117
124
/* Monitoring */
149
156
 
150
157
                        tmp = (NMExportedConnection *) nm_keyfile_connection_new (name);
151
158
                        if (tmp) {
152
 
                                GError *error = NULL;
153
 
 
154
 
                                if (!update_connection_settings (NM_EXPORTED_CONNECTION (connection), tmp, &error)) {
155
 
                                        g_warning ("%s: couldn't update connection settings: (%d) %s",
156
 
                                                   __func__, error ? error->code : 0,
157
 
                                                   error ? error->message : "unknown");
158
 
                                        if (error)
159
 
                                                g_error_free (error);
160
 
                                }
 
159
                                update_connection_settings (NM_EXPORTED_CONNECTION (connection), tmp);
161
160
                                g_object_unref (tmp);
162
161
                        }
163
162
                } else {
185
184
                                 */
186
185
                                if (found) {
187
186
                                        const char *old_filename = nm_keyfile_connection_get_filename (connection);
188
 
                                        GError *error = NULL;
189
187
 
190
188
                                        /* Removing from the hash table should drop the last reference,
191
189
                                         * but of course we want to keep the connection around.
196
194
                                        /* Updating settings should update the NMKeyfileConnection's
197
195
                                         * filename property too.
198
196
                                         */
199
 
                                        if (!update_connection_settings (NM_EXPORTED_CONNECTION (found),
200
 
                                                                         NM_EXPORTED_CONNECTION (connection),
201
 
                                                                         &error)) {
202
 
                                                g_warning ("%s: couldn't update connection settings: (%d) %s",
203
 
                                                           __func__, error ? error->code : 0,
204
 
                                                           error ? error->message : "unknown");
205
 
                                                g_error_free (error);
206
 
                                        }
 
197
                                        update_connection_settings (NM_EXPORTED_CONNECTION (found),
 
198
                                                                    NM_EXPORTED_CONNECTION (connection));
207
199
 
208
200
                                        /* Re-insert the connection back into the hash with the new filename */
209
201
                                        g_hash_table_insert (priv->hash,
229
221
}
230
222
 
231
223
static void
 
224
conf_file_changed (GFileMonitor *monitor,
 
225
                                   GFile *file,
 
226
                                   GFile *other_file,
 
227
                                   GFileMonitorEvent event_type,
 
228
                                   gpointer data)
 
229
{
 
230
        SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (data);
 
231
        SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
 
232
        char *tmp;
 
233
 
 
234
        switch (event_type) {
 
235
        case G_FILE_MONITOR_EVENT_DELETED:
 
236
        case G_FILE_MONITOR_EVENT_CREATED:
 
237
        case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
 
238
                g_signal_emit_by_name (self, "unmanaged-devices-changed");
 
239
 
 
240
                /* hostname */
 
241
                tmp = plugin_get_hostname (self);
 
242
                if ((tmp && !priv->hostname)
 
243
                        || (!tmp && priv->hostname)
 
244
                        || (priv->hostname && tmp && strcmp (priv->hostname, tmp))) {
 
245
 
 
246
                        g_free (priv->hostname);
 
247
                        priv->hostname = tmp;
 
248
                        tmp = NULL;
 
249
                        g_object_notify (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
 
250
                }
 
251
 
 
252
                g_free (tmp);
 
253
 
 
254
                break;
 
255
        default:
 
256
                break;
 
257
        }
 
258
}
 
259
 
 
260
static void
232
261
setup_monitoring (NMSystemConfigInterface *config)
233
262
{
234
263
        SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
245
274
                priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (dir_changed), config);
246
275
                priv->monitor = monitor;
247
276
        }
 
277
 
 
278
        file = g_file_new_for_path (CONF_FILE);
 
279
        monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
 
280
        g_object_unref (file);
 
281
 
 
282
        if (monitor) {
 
283
                priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config);
 
284
                priv->conf_file_monitor = monitor;
 
285
        }
248
286
}
249
287
 
250
288
static void
281
319
        return write_connection (connection, NULL, error);
282
320
}
283
321
 
 
322
static GSList *
 
323
get_unmanaged_devices (NMSystemConfigInterface *config)
 
324
{
 
325
        GKeyFile *key_file;
 
326
        GSList *unmanaged_devices = NULL;
 
327
        GError *error = NULL;
 
328
 
 
329
        key_file = g_key_file_new ();
 
330
        if (g_key_file_load_from_file (key_file, CONF_FILE, G_KEY_FILE_NONE, &error)) {
 
331
                char *str;
 
332
 
 
333
                str = g_key_file_get_value (key_file, "keyfile", "unmanaged-devices", NULL);
 
334
                if (str) {
 
335
                        char **udis;
 
336
                        int i;
 
337
 
 
338
                        udis = g_strsplit (str, ";", -1);
 
339
                        g_free (str);
 
340
 
 
341
                        for (i = 0; udis[i] != NULL; i++)
 
342
                                unmanaged_devices = g_slist_append (unmanaged_devices, udis[i]);
 
343
 
 
344
                        g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */
 
345
                }
 
346
        } else {
 
347
                g_warning ("Error parsing file '%s': %s", CONF_FILE, error->message);
 
348
                g_error_free (error);
 
349
        }
 
350
 
 
351
        g_key_file_free (key_file);
 
352
 
 
353
        return unmanaged_devices;
 
354
}
 
355
 
 
356
static char *
 
357
plugin_get_hostname (SCPluginKeyfile *plugin)
 
358
{
 
359
        GKeyFile *key_file;
 
360
        char *hostname = NULL;
 
361
        GError *error = NULL;
 
362
 
 
363
        key_file = g_key_file_new ();
 
364
        if (g_key_file_load_from_file (key_file, CONF_FILE, G_KEY_FILE_NONE, &error))
 
365
                hostname = g_key_file_get_value (key_file, "keyfile", "hostname", NULL);
 
366
        else {
 
367
                g_warning ("Error parsing file '%s': %s", CONF_FILE, error->message);
 
368
                g_error_free (error);
 
369
        }
 
370
 
 
371
        g_key_file_free (key_file);
 
372
 
 
373
        return hostname;
 
374
}
 
375
 
 
376
static gboolean
 
377
plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname)
 
378
{
 
379
        SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
 
380
        GKeyFile *key_file;
 
381
        GError *error = NULL;
 
382
        gboolean result = FALSE;
 
383
 
 
384
        key_file = g_key_file_new ();
 
385
        if (g_key_file_load_from_file (key_file, CONF_FILE, G_KEY_FILE_NONE, &error)) {
 
386
                char *data;
 
387
                gsize len;
 
388
 
 
389
                g_key_file_set_string (key_file, "keyfile", "hostname", hostname);
 
390
 
 
391
                data = g_key_file_to_data (key_file, &len, &error);
 
392
                if (data) {
 
393
                        g_file_set_contents (CONF_FILE, data, len, &error);
 
394
                        g_free (data);
 
395
 
 
396
                        g_free (priv->hostname);
 
397
                        priv->hostname = hostname ? g_strdup (hostname) : NULL;
 
398
                        result = TRUE;
 
399
                }
 
400
 
 
401
                if (error) {
 
402
                        g_warning ("Error saving hostname: %s", error->message);
 
403
                        g_error_free (error);
 
404
                }
 
405
        } else {
 
406
                g_warning ("Error parsing file '%s': %s", CONF_FILE, error->message);
 
407
                g_error_free (error);
 
408
        }
 
409
 
 
410
        g_key_file_free (key_file);
 
411
 
 
412
        return result;
 
413
}
 
414
 
284
415
/* GObject */
285
416
 
286
417
static void
287
418
sc_plugin_keyfile_init (SCPluginKeyfile *plugin)
288
419
{
 
420
        SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
 
421
 
 
422
        priv->hostname = plugin_get_hostname (plugin);
289
423
}
290
424
 
291
425
static void
299
433
        case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
300
434
                g_value_set_string (value, KEYFILE_PLUGIN_INFO);
301
435
                break;
 
436
        case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
 
437
                g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS | 
 
438
                                                  NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
 
439
                break;
 
440
        case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
 
441
                g_value_set_string (value, SC_PLUGIN_KEYFILE_GET_PRIVATE (object)->hostname);
 
442
                break;
 
443
        default:
 
444
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
445
                break;
 
446
        }
 
447
}
 
448
 
 
449
static void
 
450
set_property (GObject *object, guint prop_id,
 
451
                          const GValue *value, GParamSpec *pspec)
 
452
{
 
453
        const char *hostname;
 
454
 
 
455
        switch (prop_id) {
 
456
        case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
 
457
                hostname = g_value_get_string (value);
 
458
                if (hostname && strlen (hostname) < 1)
 
459
                        hostname = NULL;
 
460
                plugin_set_hostname (SC_PLUGIN_KEYFILE (object), hostname);
 
461
                break;
302
462
        default:
303
463
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
304
464
                break;
323
483
                g_object_unref (priv->monitor);
324
484
        }
325
485
 
 
486
        if (priv->conf_file_monitor) {
 
487
                if (priv->conf_file_monitor_id)
 
488
                        g_signal_handler_disconnect (priv->conf_file_monitor, priv->conf_file_monitor_id);
 
489
 
 
490
                g_file_monitor_cancel (priv->conf_file_monitor);
 
491
                g_object_unref (priv->conf_file_monitor);
 
492
        }
 
493
 
 
494
        g_free (priv->hostname);
 
495
 
326
496
        if (priv->hash)
327
497
                g_hash_table_destroy (priv->hash);
328
498
 
338
508
 
339
509
        object_class->dispose = dispose;
340
510
        object_class->get_property = get_property;
341
 
 
342
 
        g_object_class_override_property (object_class,
343
 
                                                            NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
344
 
                                                            NM_SYSTEM_CONFIG_INTERFACE_NAME);
345
 
 
346
 
        g_object_class_override_property (object_class,
347
 
                                                            NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
348
 
                                                            NM_SYSTEM_CONFIG_INTERFACE_INFO);
 
511
        object_class->set_property = set_property;
 
512
 
 
513
        g_object_class_override_property (object_class,
 
514
                                          NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
 
515
                                          NM_SYSTEM_CONFIG_INTERFACE_NAME);
 
516
 
 
517
        g_object_class_override_property (object_class,
 
518
                                          NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
 
519
                                          NM_SYSTEM_CONFIG_INTERFACE_INFO);
 
520
 
 
521
        g_object_class_override_property (object_class,
 
522
                                          NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
 
523
                                          NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
 
524
 
 
525
        g_object_class_override_property (object_class,
 
526
                                          NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
 
527
                                          NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
349
528
}
350
529
 
351
530
static void
354
533
        /* interface implementation */
355
534
        system_config_interface_class->get_connections = get_connections;
356
535
        system_config_interface_class->add_connection = add_connection;
 
536
        system_config_interface_class->get_unmanaged_devices = get_unmanaged_devices;
357
537
}
358
538
 
359
539
G_MODULE_EXPORT GObject *