mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-20 09:00:26 +01:00
The old NMExportedConnection was used for both client and server-side classes, which was a mistake and made the code very complicated to follow. Additionally, all PolicyKit operations were synchronous, and PK operations can block for a long time (ie for user input) before returning, so they need to be async. But NMExportedConnection and NMSysconfigConnection didn't allow for async PK ops at all. Use this opportunity to clean up the mess and create GInterfaces that both server and client objects implement, so that the connection editor and applet can operate on generic objects like they did before (using the interfaces) but can perform specific operations (like async PK verification of callers) depending on whether they are local or remote or whatever.
640 lines
20 KiB
C
640 lines
20 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
|
|
/* NetworkManager system settings service (ifupdown)
|
|
*
|
|
* Alexander Sack <asac@ubuntu.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* (C) Copyright 2007,2008 Canonical Ltd.
|
|
* (C) Copyright 2009 Red Hat, Inc.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <sys/inotify.h>
|
|
|
|
#include <net/ethernet.h>
|
|
#include <netinet/ether.h>
|
|
|
|
#include <gmodule.h>
|
|
#include <glib-object.h>
|
|
#include <glib/gi18n.h>
|
|
#include <glib.h>
|
|
#include <nm-setting-connection.h>
|
|
|
|
#include "interface_parser.h"
|
|
|
|
#include "NetworkManager.h"
|
|
#include "nm-system-config-interface.h"
|
|
#include "nm-setting-ip4-config.h"
|
|
#include "nm-setting-wireless.h"
|
|
#include "nm-setting-wired.h"
|
|
#include "nm-setting-ppp.h"
|
|
|
|
#include "nm-ifupdown-connection.h"
|
|
#include "plugin.h"
|
|
#include "parser.h"
|
|
#include "nm-inotify-helper.h"
|
|
|
|
#include <nm-utils.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
|
|
#include <gudev/gudev.h>
|
|
|
|
#define IFUPDOWN_PLUGIN_NAME "ifupdown"
|
|
#define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd. To report bugs please use the NetworkManager mailing list."
|
|
#define IFUPDOWN_SYSTEM_HOSTNAME_FILE "/etc/hostname"
|
|
|
|
#define IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
|
|
#define IFUPDOWN_KEY_FILE_GROUP "ifupdown"
|
|
#define IFUPDOWN_KEY_FILE_KEY_MANAGED "managed"
|
|
#define IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT TRUE
|
|
|
|
/* #define ALWAYS_UNMANAGE TRUE */
|
|
#ifndef ALWAYS_UNMANAGE
|
|
# define ALWAYS_UNMANAGE FALSE
|
|
#endif
|
|
|
|
typedef struct {
|
|
GUdevClient *client;
|
|
|
|
GHashTable *iface_connections;
|
|
gchar* hostname;
|
|
|
|
GHashTable *well_known_ifaces;
|
|
gboolean unmanage_well_known;
|
|
|
|
gulong inotify_event_id;
|
|
int inotify_system_hostname_wd;
|
|
} SCPluginIfupdownPrivate;
|
|
|
|
static void
|
|
system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
|
|
|
|
G_DEFINE_TYPE_EXTENDED (SCPluginIfupdown, sc_plugin_ifupdown, G_TYPE_OBJECT, 0,
|
|
G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
|
|
system_config_interface_init))
|
|
|
|
#define SC_PLUGIN_IFUPDOWN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFUPDOWN, SCPluginIfupdownPrivate))
|
|
|
|
static void
|
|
sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class);
|
|
|
|
static void
|
|
SCPluginIfupdown_init (NMSystemConfigInterface *config);
|
|
|
|
/* Returns the plugins currently known list of connections. The returned
|
|
* list is freed by the system settings service.
|
|
*/
|
|
static GSList*
|
|
SCPluginIfupdown_get_connections (NMSystemConfigInterface *config);
|
|
|
|
/*
|
|
* Return a list of device specifications which NetworkManager should not
|
|
* manage. Returned list will be freed by the system settings service, and
|
|
* each element must be allocated using g_malloc() or its variants.
|
|
*/
|
|
static GSList*
|
|
SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config);
|
|
|
|
|
|
/* GObject */
|
|
static void
|
|
GObject__get_property (GObject *object, guint prop_id,
|
|
GValue *value, GParamSpec *pspec);
|
|
|
|
static void
|
|
GObject__set_property (GObject *object, guint prop_id,
|
|
const GValue *value, GParamSpec *pspec);
|
|
|
|
static void
|
|
GObject__dispose (GObject *object);
|
|
|
|
static void
|
|
GObject__finalize (GObject *object);
|
|
|
|
/* other helpers */
|
|
static const char *
|
|
get_hostname (NMSystemConfigInterface *config);
|
|
|
|
|
|
static void
|
|
update_system_hostname(NMInotifyHelper *inotify_helper,
|
|
struct inotify_event *evt,
|
|
const char *path,
|
|
NMSystemConfigInterface *config);
|
|
|
|
|
|
static void
|
|
system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
|
|
{
|
|
system_config_interface_class->init = SCPluginIfupdown_init;
|
|
system_config_interface_class->get_connections = SCPluginIfupdown_get_connections;
|
|
system_config_interface_class->get_unmanaged_specs = SCPluginIfupdown_get_unmanaged_specs;
|
|
}
|
|
|
|
static void
|
|
sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
|
|
|
|
g_type_class_add_private (req_class, sizeof (SCPluginIfupdownPrivate));
|
|
|
|
object_class->dispose = GObject__dispose;
|
|
object_class->finalize = GObject__finalize;
|
|
object_class->get_property = GObject__get_property;
|
|
object_class->set_property = GObject__set_property;
|
|
|
|
g_object_class_override_property (object_class,
|
|
NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
|
|
NM_SYSTEM_CONFIG_INTERFACE_NAME);
|
|
|
|
g_object_class_override_property (object_class,
|
|
NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
|
|
NM_SYSTEM_CONFIG_INTERFACE_INFO);
|
|
|
|
g_object_class_override_property (object_class,
|
|
NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
|
|
NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
|
|
|
|
g_object_class_override_property (object_class,
|
|
NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
|
|
NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
|
|
}
|
|
|
|
static void
|
|
bind_device_to_connection (SCPluginIfupdown *self,
|
|
GUdevDevice *device,
|
|
NMExportedConnection *exported)
|
|
{
|
|
GByteArray *mac_address;
|
|
NMConnection *connection;
|
|
NMSetting *s_wired = NULL;
|
|
NMSetting *s_wifi = NULL;
|
|
const char *iface, *address;
|
|
struct ether_addr *tmp_mac;
|
|
|
|
iface = g_udev_device_get_name (device);
|
|
if (!iface) {
|
|
PLUGIN_WARN ("SCPluginIfupdown", "failed to get ifname for device.");
|
|
return;
|
|
}
|
|
|
|
connection = nm_exported_connection_get_connection (exported);
|
|
if (!connection) {
|
|
PLUGIN_WARN ("SCPluginIfupdown", "no device locking possible. "
|
|
"NMExportedConnection doesnt have a real connection.");
|
|
return;
|
|
}
|
|
|
|
address = g_udev_device_get_sysfs_attr (device, "address");
|
|
if (!address || !strlen (address)) {
|
|
PLUGIN_WARN ("SCPluginIfupdown", "failed to get MAC address for %s", iface);
|
|
return;
|
|
}
|
|
|
|
tmp_mac = ether_aton (address);
|
|
if (!tmp_mac) {
|
|
PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s",
|
|
address, iface);
|
|
return;
|
|
}
|
|
|
|
mac_address = g_byte_array_sized_new (ETH_ALEN);
|
|
g_byte_array_append (mac_address, &(tmp_mac->ether_addr_octet[0]), ETH_ALEN);
|
|
|
|
s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
|
|
s_wifi = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
|
|
if (s_wifi) {
|
|
PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting");
|
|
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL);
|
|
} else if (s_wifi) {
|
|
PLUGIN_PRINT ("SCPluginIfupdown", "locking wireless connection setting");
|
|
g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL);
|
|
}
|
|
|
|
g_byte_array_free (mac_address, TRUE);
|
|
}
|
|
|
|
static void
|
|
udev_device_added (SCPluginIfupdown *self, GUdevDevice *device)
|
|
{
|
|
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
|
|
const char *iface, *path;
|
|
NMExportedConnection *exported;
|
|
|
|
iface = g_udev_device_get_name (device);
|
|
path = g_udev_device_get_sysfs_path (device);
|
|
if (!iface || !path)
|
|
return;
|
|
|
|
PLUGIN_PRINT("SCPlugin-Ifupdown",
|
|
"devices added (path: %s, iface: %s)", path, iface);
|
|
|
|
/* if we have a configured connection for this particular iface
|
|
* we want to either unmanage the device or lock it
|
|
*/
|
|
exported = (NMExportedConnection *) g_hash_table_lookup (priv->iface_connections, iface);
|
|
if (!exported)
|
|
return;
|
|
|
|
g_hash_table_insert (priv->well_known_ifaces, g_strdup (iface), g_object_ref (device));
|
|
|
|
if (ALWAYS_UNMANAGE || priv->unmanage_well_known)
|
|
g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
|
else
|
|
bind_device_to_connection (self, device, exported);
|
|
}
|
|
|
|
static void
|
|
udev_device_removed (SCPluginIfupdown *self, GUdevDevice *device)
|
|
{
|
|
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
|
|
const char *iface, *path;
|
|
|
|
iface = g_udev_device_get_name (device);
|
|
path = g_udev_device_get_sysfs_path (device);
|
|
if (!iface || !path)
|
|
return;
|
|
|
|
PLUGIN_PRINT("SCPlugin-Ifupdown",
|
|
"devices removed (path: %s, iface: %s)", path, iface);
|
|
|
|
if (!g_hash_table_remove (priv->well_known_ifaces, iface))
|
|
return;
|
|
|
|
if (ALWAYS_UNMANAGE || priv->unmanage_well_known)
|
|
g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
|
}
|
|
|
|
static void
|
|
handle_uevent (GUdevClient *client,
|
|
const char *action,
|
|
GUdevDevice *device,
|
|
gpointer user_data)
|
|
{
|
|
SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (user_data);
|
|
const char *subsys;
|
|
|
|
g_return_if_fail (action != NULL);
|
|
|
|
/* A bit paranoid */
|
|
subsys = g_udev_device_get_subsystem (device);
|
|
g_return_if_fail (subsys != NULL);
|
|
g_return_if_fail (strcmp (subsys, "net") == 0);
|
|
|
|
if (!strcmp (action, "add"))
|
|
udev_device_added (self, device);
|
|
else if (!strcmp (action, "remove"))
|
|
udev_device_removed (self, device);
|
|
}
|
|
|
|
static void
|
|
SCPluginIfupdown_init (NMSystemConfigInterface *config)
|
|
{
|
|
SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (config);
|
|
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
|
|
GHashTable *auto_ifaces;
|
|
if_block *block = NULL;
|
|
NMInotifyHelper *inotify_helper;
|
|
GKeyFile* keyfile;
|
|
GError *error = NULL;
|
|
GList *keys, *iter;
|
|
const char *subsys[2] = { "net", NULL };
|
|
|
|
auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
if(!priv->iface_connections)
|
|
priv->iface_connections = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
if(!priv->well_known_ifaces)
|
|
priv->well_known_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
|
|
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "init!");
|
|
|
|
priv->client = g_udev_client_new (subsys);
|
|
if (!priv->client) {
|
|
PLUGIN_WARN ("SCPlugin-Ifupdown", " error initializing libgudev");
|
|
} else
|
|
g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
|
|
|
|
priv->unmanage_well_known = IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT;
|
|
|
|
inotify_helper = nm_inotify_helper_get ();
|
|
priv->inotify_event_id = g_signal_connect (inotify_helper,
|
|
"event",
|
|
G_CALLBACK (update_system_hostname),
|
|
config);
|
|
|
|
priv->inotify_system_hostname_wd =
|
|
nm_inotify_helper_add_watch (inotify_helper, IFUPDOWN_SYSTEM_HOSTNAME_FILE);
|
|
|
|
update_system_hostname (inotify_helper, NULL, NULL, config);
|
|
|
|
/* Read in all the interfaces */
|
|
ifparser_init ();
|
|
block = ifparser_getfirst ();
|
|
while (block) {
|
|
if(!strcmp ("auto", block->type))
|
|
g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1));
|
|
else if (!strcmp ("iface", block->type) && strcmp ("lo", block->name)) {
|
|
NMExportedConnection *exported;
|
|
|
|
g_hash_table_remove (priv->iface_connections, block->name);
|
|
|
|
exported = NM_EXPORTED_CONNECTION (nm_ifupdown_connection_new (block));
|
|
ifupdown_update_connection_from_if_block (nm_exported_connection_get_connection (exported),
|
|
block);
|
|
g_hash_table_insert (priv->iface_connections, block->name, exported);
|
|
}
|
|
block = block->next;
|
|
}
|
|
|
|
/* Make 'auto' interfaces autoconnect=TRUE */
|
|
keys = g_hash_table_get_keys (priv->iface_connections);
|
|
for (iter = keys; iter; iter = g_list_next (iter)) {
|
|
NMExportedConnection *exported;
|
|
NMConnection *wrapped;
|
|
NMSetting *setting;
|
|
|
|
if (!g_hash_table_lookup (auto_ifaces, iter->data))
|
|
continue;
|
|
|
|
exported = g_hash_table_lookup (priv->iface_connections, iter->data);
|
|
wrapped = nm_exported_connection_get_connection (exported);
|
|
setting = NM_SETTING (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
|
|
g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL);
|
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect");
|
|
}
|
|
g_list_free (keys);
|
|
g_hash_table_destroy (auto_ifaces);
|
|
|
|
keyfile = g_key_file_new ();
|
|
if (!g_key_file_load_from_file (keyfile,
|
|
IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE,
|
|
G_KEY_FILE_NONE,
|
|
&error)) {
|
|
nm_info ("loading system config file (%s) caused error: (%d) %s",
|
|
IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE,
|
|
error ? error->code : -1,
|
|
error && error->message ? error->message : "(unknown)");
|
|
} else {
|
|
gboolean manage_well_known;
|
|
error = NULL;
|
|
|
|
manage_well_known = g_key_file_get_boolean (keyfile,
|
|
IFUPDOWN_KEY_FILE_GROUP,
|
|
IFUPDOWN_KEY_FILE_KEY_MANAGED,
|
|
&error);
|
|
if (error) {
|
|
nm_info ("getting keyfile key '%s' in group '%s' failed: (%d) %s",
|
|
IFUPDOWN_KEY_FILE_GROUP,
|
|
IFUPDOWN_KEY_FILE_KEY_MANAGED,
|
|
error ? error->code : -1,
|
|
error && error->message ? error->message : "(unknown)");
|
|
} else
|
|
priv->unmanage_well_known = !manage_well_known;
|
|
}
|
|
PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed");
|
|
if (keyfile)
|
|
g_key_file_free (keyfile);
|
|
|
|
/* Add well-known interfaces */
|
|
keys = g_udev_client_query_by_subsystem (priv->client, "net");
|
|
for (iter = keys; iter; iter = g_list_next (iter)) {
|
|
udev_device_added (self, G_UDEV_DEVICE (iter->data));
|
|
g_object_unref (G_UDEV_DEVICE (iter->data));
|
|
}
|
|
g_list_free (keys);
|
|
|
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "end _init.");
|
|
}
|
|
|
|
|
|
/* Returns the plugins currently known list of connections. The returned
|
|
* list is freed by the system settings service.
|
|
*/
|
|
static GSList*
|
|
SCPluginIfupdown_get_connections (NMSystemConfigInterface *config)
|
|
{
|
|
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
|
|
GSList *connections = NULL;
|
|
GList *priv_list = g_hash_table_get_values(priv->iface_connections);
|
|
GList *it = priv_list;
|
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "(%d) ... get_connections.", GPOINTER_TO_UINT(config));
|
|
|
|
while(it) {
|
|
NMExportedConnection *conn = it->data;
|
|
connections = g_slist_append(connections, conn);
|
|
it = it->next;
|
|
}
|
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "(%d) connections count: %d", GPOINTER_TO_UINT(config), g_slist_length(connections));
|
|
return connections;
|
|
}
|
|
|
|
/*
|
|
* Return a list of device specifications which NetworkManager should not
|
|
* manage. Returned list will be freed by the system settings service, and
|
|
* each element must be allocated using g_malloc() or its variants.
|
|
*/
|
|
static GSList*
|
|
SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config)
|
|
{
|
|
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
|
|
GList *devs, *iter;
|
|
GSList *specs = NULL;
|
|
|
|
if (!ALWAYS_UNMANAGE && !priv->unmanage_well_known)
|
|
return NULL;
|
|
|
|
devs = g_hash_table_get_values (priv->well_known_ifaces);
|
|
PLUGIN_PRINT("Ifupdown", "get unmanaged devices count: %d", g_list_length (devs));
|
|
|
|
for (iter = devs; iter; iter = g_list_next (iter)) {
|
|
GUdevDevice *device = G_UDEV_DEVICE (iter->data);
|
|
const char *address;
|
|
char *spec;
|
|
|
|
address = g_udev_device_get_sysfs_attr (device, "address");
|
|
if (!address)
|
|
continue;
|
|
|
|
spec = g_strdup_printf ("mac:%s", address);
|
|
specs = g_slist_append (specs, spec);
|
|
}
|
|
g_list_free (devs);
|
|
return specs;
|
|
}
|
|
|
|
|
|
static const char *
|
|
get_hostname (NMSystemConfigInterface *config)
|
|
{
|
|
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
|
|
return priv->hostname;
|
|
}
|
|
|
|
static void
|
|
update_system_hostname(NMInotifyHelper *inotify_helper,
|
|
struct inotify_event *evt,
|
|
const char *path,
|
|
NMSystemConfigInterface *config)
|
|
{
|
|
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
|
|
gchar *hostname_file = NULL;
|
|
gsize hostname_file_len = 0;
|
|
GError *error = NULL;
|
|
|
|
PLUGIN_PRINT ("SCPlugin-Ifupdown", "update_system_hostname");
|
|
|
|
if (evt && evt->wd != priv->inotify_system_hostname_wd)
|
|
return;
|
|
|
|
if(!g_file_get_contents ( IFUPDOWN_SYSTEM_HOSTNAME_FILE,
|
|
&hostname_file,
|
|
&hostname_file_len,
|
|
&error)) {
|
|
nm_warning ("update_system_hostname() - couldn't read "
|
|
IFUPDOWN_SYSTEM_HOSTNAME_FILE " (%d/%s)",
|
|
error->code, error->message);
|
|
return;
|
|
}
|
|
|
|
if (priv->hostname)
|
|
g_free(priv->hostname);
|
|
|
|
priv->hostname = g_strstrip(hostname_file);
|
|
|
|
g_object_notify (G_OBJECT (config), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
|
|
}
|
|
|
|
static void
|
|
write_system_hostname(NMSystemConfigInterface *config,
|
|
const char *newhostname)
|
|
{
|
|
GError *error = NULL;
|
|
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
|
|
PLUGIN_PRINT ("SCPlugin-Ifupdown", "write_system_hostname: %s", newhostname);
|
|
|
|
g_return_if_fail (newhostname);
|
|
|
|
if(!g_file_set_contents ( IFUPDOWN_SYSTEM_HOSTNAME_FILE,
|
|
newhostname,
|
|
-1,
|
|
&error)) {
|
|
nm_warning ("update_system_hostname() - couldn't write hostname (%s) to "
|
|
IFUPDOWN_SYSTEM_HOSTNAME_FILE " (%d/%s)",
|
|
newhostname, error->code, error->message);
|
|
} else {
|
|
priv->hostname = g_strdup (newhostname);
|
|
}
|
|
g_object_notify (G_OBJECT (config), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
|
|
}
|
|
|
|
|
|
static void
|
|
sc_plugin_ifupdown_init (SCPluginIfupdown *plugin)
|
|
{
|
|
}
|
|
|
|
static void
|
|
GObject__get_property (GObject *object, guint prop_id,
|
|
GValue *value, GParamSpec *pspec)
|
|
{
|
|
NMSystemConfigInterface *self = NM_SYSTEM_CONFIG_INTERFACE (object);
|
|
|
|
switch (prop_id) {
|
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
|
|
g_value_set_string (value, IFUPDOWN_PLUGIN_NAME);
|
|
break;
|
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
|
|
g_value_set_string (value, IFUPDOWN_PLUGIN_INFO);
|
|
break;
|
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
|
|
g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
|
|
break;
|
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
|
|
{
|
|
g_value_set_string (value, get_hostname(self));
|
|
break;
|
|
}
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
GObject__set_property (GObject *object, guint prop_id,
|
|
const GValue *value, GParamSpec *pspec)
|
|
{
|
|
switch (prop_id) {
|
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
|
|
{
|
|
const gchar *hostname = g_value_get_string (value);
|
|
if (hostname && strlen (hostname) < 1)
|
|
hostname = NULL;
|
|
write_system_hostname(NM_SYSTEM_CONFIG_INTERFACE(object),
|
|
hostname);
|
|
break;
|
|
}
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
GObject__dispose (GObject *object)
|
|
{
|
|
SCPluginIfupdown *plugin = SC_PLUGIN_IFUPDOWN (object);
|
|
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (plugin);
|
|
NMInotifyHelper *inotify_helper = nm_inotify_helper_get ();
|
|
|
|
g_signal_handler_disconnect (inotify_helper, priv->inotify_event_id);
|
|
|
|
if (priv->inotify_system_hostname_wd >= 0)
|
|
nm_inotify_helper_remove_watch (inotify_helper, priv->inotify_system_hostname_wd);
|
|
|
|
if (priv->well_known_ifaces)
|
|
g_hash_table_destroy(priv->well_known_ifaces);
|
|
|
|
if (priv->client)
|
|
g_object_unref (priv->client);
|
|
|
|
G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
GObject__finalize (GObject *object)
|
|
{
|
|
G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->finalize (object);
|
|
}
|
|
|
|
G_MODULE_EXPORT GObject *
|
|
nm_system_config_factory (void)
|
|
{
|
|
static SCPluginIfupdown *singleton = NULL;
|
|
|
|
if (!singleton)
|
|
singleton = SC_PLUGIN_IFUPDOWN (g_object_new (SC_TYPE_PLUGIN_IFUPDOWN, NULL));
|
|
else
|
|
g_object_ref (singleton);
|
|
|
|
return G_OBJECT (singleton);
|
|
}
|
|
|