Commit ac5206aa authored by Dan Williams's avatar Dan Williams

2007-11-21 Dan Williams <dcbw@redhat.com>

	* system-settings/*
		- Add Soren's system settings service.  Needs work for distros other
			than Fedora; the backends from NM should mostly migrate to here
			and be converted to GObjects



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3104 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
parent 36650e4a
2007-11-21 Dan Williams <dcbw@redhat.com>
* system-settings/*
- Add Soren's system settings service. Needs work for distros other
than Fedora; the backends from NM should mostly migrate to here
and be converted to GObjects
2007-11-21 Dan Williams <dcbw@redhat.com>
* libnm-util/nm-setting-vpn-properties.c
......
......@@ -9,7 +9,8 @@ SUBDIRS = \
man \
include \
introspection \
callouts
callouts \
system-settings
EXTRA_DIST = \
CONTRIBUTING \
......
......@@ -273,6 +273,7 @@ libnm-glib/libnm_glib.pc
libnm-glib/Makefile
callouts/Makefile
dispatcher-daemon/Makefile
system-settings/Makefile
test/Makefile
test/test-common/Makefile
initscript/Makefile
......
INCLUDES = -I${top_srcdir} \
-I${top_srcdir}/include \
-I${top_srcdir}/libnm-util \
-I${top_srcdir}/libnm-glib
sbin_PROGRAMS = nm-system-settings
nm_system_settings_SOURCES = \
dbus-settings.c \
dbus-settings.h \
main.c \
shvar.c \
shvar.h
nm_system_settings_CPPFLAGS = \
$(DBUS_CFLAGS) \
$(GTHREAD_CFLAGS) \
-DDBUS_API_SUBJECT_TO_CHANGE \
-DG_DISABLE_DEPRECATED \
-DBINDIR=\"$(bindir)\" \
-DSBINDIR=\"$(sbindir)\" \
-DLIBEXECDIR=\"$(libexecdir)\" \
-DDATADIR=\"$(datadir)\" \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DLOCALSTATEDIR=\"$(localstatedir)\" \
-DNM_RUN_DIR=\"$(rundir)\" \
-DGNOMELOCALEDIR=\"$(datadir)/locale\"
nm_system_settings_LDADD = \
$(DBUS_LIBS) \
$(GTHREAD_LIBS) \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/libnm-glib/libnm_glib.la
nm_system_settings_LDFLAGS = -rdynamic
dbusservicedir = $(DBUS_SYS_DIR)
dbusservice_DATA = nm-system-settings.conf
EXTRA_DIST = \
$(dbusservice_DATA)
/* NetworkManager system settings service
*
* Søren Sandmann <sandmann@daimi.au.dk>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2007 Red Hat, Inc.
*/
#include <NetworkManager.h>
#include <nm-connection.h>
#include <dbus/dbus.h>
#include <nm-setting-connection.h>
#include "dbus-settings.h"
#include "nm-utils.h"
static gchar *connection_settings_get_id (NMConnectionSettings *connection);
static void connection_settings_get_secrets (NMConnectionSettings *connection,
const gchar *setting_name,
const gchar **hints,
gboolean request_new,
DBusGMethodInvocation *context);
G_DEFINE_TYPE (NMSysconfigConnectionSettings, nm_sysconfig_connection_settings, NM_TYPE_CONNECTION_SETTINGS);
/*
* NMSysconfigConnectionSettings
*/
static gchar *
connection_settings_get_id (NMConnectionSettings *connection)
{
NMSysconfigConnectionSettings *c = NM_SYSCONFIG_CONNECTION_SETTINGS (connection);
return g_strdup (c->id);
}
static GHashTable *
connection_settings_get_settings (NMConnectionSettings *connection)
{
NMSysconfigConnectionSettings *c = NM_SYSCONFIG_CONNECTION_SETTINGS (connection);
return nm_connection_to_hash (c->connection);
}
static void
connection_settings_get_secrets (NMConnectionSettings *connection,
const gchar *setting_name,
const gchar **hints,
gboolean request_new,
DBusGMethodInvocation *context)
{
}
static void
nm_sysconfig_connection_settings_finalize (GObject *object)
{
G_OBJECT_CLASS (nm_sysconfig_connection_settings_parent_class)->finalize (object);
}
static void
nm_sysconfig_connection_settings_class_init (NMSysconfigConnectionSettingsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
NMConnectionSettingsClass *connection = NM_CONNECTION_SETTINGS_CLASS (class);
object_class->finalize = nm_sysconfig_connection_settings_finalize;
connection->get_id = connection_settings_get_id;
connection->get_settings = connection_settings_get_settings;
connection->get_secrets = connection_settings_get_secrets;
}
static void
nm_sysconfig_connection_settings_init (NMSysconfigConnectionSettings *sysconfig_connection_settings)
{
}
NMSysconfigConnectionSettings *
nm_sysconfig_connection_settings_new (NMConnection *connection,
DBusGConnection *g_conn)
{
NMSysconfigConnectionSettings *settings;
NMSettingConnection *s_con;
settings = g_object_new (nm_sysconfig_connection_settings_get_type(), NULL);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
settings->id = g_strdup (s_con->id);
settings->connection = connection;
nm_connection_settings_register_object (NM_CONNECTION_SETTINGS (settings), g_conn);
return settings;
}
/*
* NMSettings
*/
static GPtrArray *nm_sysconfig_settings_list_connections (NMSettings *settings);
G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, NM_TYPE_SETTINGS);
static GPtrArray *
nm_sysconfig_settings_list_connections (NMSettings *settings)
{
GPtrArray *connections;
NMSysconfigSettings *sysconfig_settings;
GSList *iter;
g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings), NULL);
sysconfig_settings = NM_SYSCONFIG_SETTINGS (settings);
connections = g_ptr_array_new ();
for (iter = sysconfig_settings->connections; iter; iter = g_slist_next (iter)) {
NMConnectionSettings *connection = NM_CONNECTION_SETTINGS (iter->data);
char *path;
path = g_strdup (nm_connection_settings_get_dbus_object_path (connection));
if (path)
g_ptr_array_add (connections, path);
}
/* Return a list of strings with paths to connection settings objects */
return connections;
}
static void
nm_sysconfig_settings_finalize (GObject *object)
{
NMSysconfigSettings *settings = NM_SYSCONFIG_SETTINGS (object);
if (settings->connections) {
g_slist_foreach (settings->connections, (GFunc) g_object_unref, NULL);
g_slist_free (settings->connections);
settings->connections = NULL;
}
G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object);
}
static void
nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
NMSettingsClass *settings_class = NM_SETTINGS_CLASS (class);
object_class->finalize = nm_sysconfig_settings_finalize;
settings_class->list_connections = nm_sysconfig_settings_list_connections;
}
static void
nm_sysconfig_settings_init (NMSysconfigSettings *sysconfig_settings)
{
sysconfig_settings->connections = NULL;
}
NMSysconfigSettings *
nm_sysconfig_settings_new (DBusGConnection *g_conn)
{
NMSysconfigSettings *settings;
settings = g_object_new (nm_sysconfig_settings_get_type (), NULL);
dbus_g_connection_register_g_object (g_conn, NM_DBUS_PATH_SETTINGS, G_OBJECT (settings));
return settings;
}
void
nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings,
NMSysconfigConnectionSettings *connection)
{
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings));
g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION_SETTINGS (connection));
settings->connections = g_slist_append (settings->connections, connection);
nm_settings_signal_new_connection (NM_SETTINGS (settings),
NM_CONNECTION_SETTINGS (connection));
}
/* NetworkManager system settings service
*
* Søren Sandmann <sandmann@daimi.au.dk>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2007 Red Hat, Inc.
*/
#include <nm-connection.h>
#include <nm-settings.h>
typedef struct _NMSysconfigConnectionSettings NMSysconfigConnectionSettings;
typedef struct _NMSysconfigConnectionSettingsClass NMSysconfigConnectionSettingsClass;
/*
* NMSysconfigConnectionSettings
*/
#define NM_TYPE_SYSCONFIG_CONNECTION_SETTINGS (nm_sysconfig_connection_settings_get_type ())
#define NM_SYSCONFIG_CONNECTION_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_CONNECTION_SETTINGS, NMSysconfigConnectionSettings))
#define NM_SYSCONFIG_CONNECTION_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_CONNECTION_SETTINGS, NMSysconfigConnectionSettingsClass))
#define NM_IS_SYSCONFIG_CONNECTION_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION_SETTINGS))
#define NM_IS_SYSCONFIG_CONNECTION_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_CONNECTION_SETTINGS))
#define NM_SYSCONFIG_CONNECTION_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_CONNECTION_SETTINGS, NMSysconfigConnectionSettingsClass))
struct _NMSysconfigConnectionSettings
{
NMConnectionSettings parent_instance;
char *id;
NMConnection *connection;
};
struct _NMSysconfigConnectionSettingsClass
{
NMConnectionSettingsClass parent_class;
};
GType nm_sysconfig_connection_settings_get_type (void);
NMSysconfigConnectionSettings *nm_sysconfig_connection_settings_new (NMConnection *connection,
DBusGConnection *g_conn);
/*
* NMSysconfigSetttings
*/
typedef struct _NMSysconfigSettings NMSysconfigSettings;
typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass;
#define NM_TYPE_SYSCONFIG_SETTINGS (nm_sysconfig_settings_get_type ())
#define NM_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettings))
#define NM_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass))
#define NM_IS_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_SETTINGS))
#define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS))
#define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass))
struct _NMSysconfigSettings
{
NMSettings parent_instance;
GSList *connections;
};
struct _NMSysconfigSettingsClass
{
NMSettingsClass parent_class;
};
GType nm_sysconfig_settings_get_type (void);
NMSysconfigSettings *nm_sysconfig_settings_new (DBusGConnection *g_conn);
void nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings,
NMSysconfigConnectionSettings *connection);
/* NetworkManager system settings service
*
* Søren Sandmann <sandmann@daimi.au.dk>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2007 Red Hat, Inc.
*/
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <nm-connection.h>
#include <nm-settings.h>
#include <NetworkManager.h>
#include <nm-setting-connection.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-wired.h>
#include "dbus-settings.h"
#include "shvar.h"
#define SYSCONFDIR "/etc"
#define PROFILE_DIR SYSCONFDIR "/sysconfig/networking/profiles/"
typedef struct Application
{
DBusConnection *connection;
DBusGConnection *g_connection;
DBusGProxy *bus_proxy;
gboolean started;
NMSysconfigSettings *settings;
char *profile_path;
GMainLoop *loop;
} Application;
static gboolean dbus_init (Application *app);
static void dbus_cleanup (Application *app);
static gboolean start_dbus_service (Application *app);
static void destroy_cb (DBusGProxy *proxy, gpointer user_data);
static gboolean
get_int (const char *str, int *value)
{
char *e;
*value = strtol (str, &e, 0);
if (*e != '\0')
return FALSE;
return TRUE;
}
#define IFCFG_TAG "ifcfg-"
#define BAK_TAG ".bak"
static NMSetting *
make_connection_setting (const char *file, shvarFile *ifcfg, const char *type)
{
NMSettingConnection *s_con;
char *basename = NULL;
int len;
basename = g_path_get_basename (file);
if (!basename)
goto error;
len = strlen (basename);
if (len < strlen (IFCFG_TAG) + 1)
goto error;
if (strncmp (basename, IFCFG_TAG, strlen (IFCFG_TAG)))
goto error;
/* ignore .bak files */
if ((len > 4) && !strcmp (basename + len - 4, BAK_TAG))
goto error;
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
s_con->id = g_strdup_printf ("System %s", basename + strlen (IFCFG_TAG));
s_con->type = g_strdup (type);
s_con->autoconnect = TRUE;
return (NMSetting *) s_con;
error:
g_free (basename);
return NULL;
}
static char *
get_current_profile_name (void)
{
shvarFile * file;
char * buf;
if (!(file = svNewFile (SYSCONFDIR"/sysconfig/network")))
return NULL;
buf = svGetValue (file, "CURRENT_PROFILE");
if (!buf)
buf = strdup ("default");
svCloseFile (file);
return buf;
}
#define SEARCH_TAG "search "
#define NS_TAG "nameserver "
static void
read_profile_resolv_conf (NMSettingIP4Config *s_ip4)
{
char *file;
char *profile;
char *contents = NULL;
char **lines = NULL;
char **line;
profile = get_current_profile_name ();
if (!profile)
return;
file = g_strdup_printf ("/etc/sysconfig/networking/profiles/%s/resolv.conf", profile);
g_free (profile);
if (!file)
return;
if (!g_file_get_contents (file, &contents, NULL, NULL))
goto out;
lines = g_strsplit (contents, "\n", 0);
if (!lines || !*lines)
goto out;
s_ip4->dns = g_array_new (FALSE, FALSE, sizeof (guint32));
for (line = lines; *line; line++) {
if (!strncmp (*line, SEARCH_TAG, strlen (SEARCH_TAG))) {
char **searches;
if (s_ip4->dns_search)
continue;
searches = g_strsplit (*line + strlen (SEARCH_TAG), " ", 0);
if (searches) {
char **item;
for (item = searches; *item; item++)
s_ip4->dns_search = g_slist_append (s_ip4->dns_search, *item);
g_free (searches);
}
} else if (!strncmp (*line, NS_TAG, strlen (NS_TAG))) {
char *pdns = g_strdup (*line + strlen (NS_TAG));
struct in_addr dns;
pdns = g_strstrip (pdns);
if (inet_pton (AF_INET, pdns, &dns)) {
g_array_append_val (s_ip4->dns, dns.s_addr);
} else
g_warning ("Invalid IP4 DNS server address '%s'", pdns);
g_free (pdns);
}
}
out:
if (lines)
g_strfreev (lines);
g_free (file);
}
static NMSetting *
make_ip4_setting (shvarFile *ifcfg)
{
NMSettingIP4Config *s_ip4;
char *value;
NMSettingIP4Address tmp = { 0, 0, 0 };
char *ip4 = NULL, *gw = NULL, *mask = NULL;
gboolean manual = TRUE;
value = svGetValue (ifcfg, "BOOTPROTO");
if (!value)
return NULL;
if (!strcmp (value, "bootp") || !strcmp (value, "dhcp")) {
manual = FALSE;
return NULL;
}
ip4 = svGetValue (ifcfg, "IPADDR");
if (ip4) {
struct in_addr ip4_addr;
if (inet_pton (AF_INET, ip4, &ip4_addr))
tmp.address = ip4_addr.s_addr;
else
g_warning ("Invalid IP4 address '%s'", ip4);
g_free (ip4);
}
gw = svGetValue (ifcfg, "GATEWAY");
if (gw) {
struct in_addr gw_addr;
if (inet_pton (AF_INET, gw, &gw_addr))
tmp.gateway = gw_addr.s_addr;
else
g_warning ("Invalid IP4 gateway '%s'", gw);
g_free (gw);
}
mask = svGetValue (ifcfg, "NETMASK");
if (mask) {
struct in_addr mask_addr;
if (inet_pton (AF_INET, mask, &mask_addr))
tmp.netmask = mask_addr.s_addr;
else
g_warning ("Invalid IP4 netmask '%s'", mask);
g_free (mask);
}
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
s_ip4->manual = manual;
if (tmp.address || tmp.netmask || tmp.gateway) {
NMSettingIP4Address *addr;
addr = g_new0 (NMSettingIP4Address, 1);
memcpy (addr, &tmp, sizeof (NMSettingIP4Address));
s_ip4->addresses = g_slist_append (s_ip4->addresses, addr);
}
read_profile_resolv_conf (s_ip4);
return (NMSetting *) s_ip4;
}
static NMSetting *
make_wired_setting (shvarFile *ifcfg)
{
NMSettingWired *s_wired;
char *value;
int mtu;
s_wired = (NMSettingWired *) nm_setting_wired_new ();
value = svGetValue (ifcfg, "MTU");
if (value) {
if (get_int (value, &mtu)) {
if (mtu >= 0 && mtu < 65536)
s_wired->mtu = mtu;
} else {
g_warning ("Invalid MTU '%s'", value);
}
g_free (value);
}
return (NMSetting *) s_wired;
}
static NMConnection *
wired_connection_from_ifcfg (const char *file, shvarFile *ifcfg)
{
NMConnection *connection = NULL;
NMSetting *con_setting = NULL;
NMSetting *wired_setting = NULL;
g_return_val_if_fail (file != NULL, NULL);
g_return_val_if_fail (ifcfg != NULL, NULL);
connection = nm_connection_new ();
if (!connection) {
g_warning ("Failed to allocate new connection for %s.", file);
return NULL;
}