2007-08-12 Dan Williams <dcbw@redhat.com>

* Makefile.am
	  configure.in
	  callouts/Makefile.am
	  callouts/nm-dhcp-client-action.c
	  callouts/nm-dhcp-client.conf
		- Add dhclient-executed callout that takes the place of dhclient-script
		and dhcdbd, pushing DHCP options out to the system bus as a signal that
		NM then listens for



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2664 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2007-08-12 15:21:15 +00:00
parent 0bcb537495
commit ff4c26f965
6 changed files with 367 additions and 1 deletions

View file

@ -1,3 +1,14 @@
2007-08-12 Dan Williams <dcbw@redhat.com>
* Makefile.am
configure.in
callouts/Makefile.am
callouts/nm-dhcp-client-action.c
callouts/nm-dhcp-client.conf
- Add dhclient-executed callout that takes the place of dhclient-script
and dhcdbd, pushing DHCP options out to the system bus as a signal that
NM then listens for
2007-08-09 Tambet Ingo <tambet@gmail.com>
[Based on patch by Helmut Schaa <hschaa@suse.de>]

View file

@ -10,7 +10,8 @@ SUBDIRS = \
po \
man \
include \
introspection
introspection \
callouts
EXTRA_DIST = \
CONTRIBUTING \

22
callouts/Makefile.am Normal file
View file

@ -0,0 +1,22 @@
dbusservicedir = $(DBUS_SYS_DIR)
dbusservice_DATA = nm-dhcp-client.conf
calloutdir = $(sysconfdir)/NetworkManager/callouts
callout_PROGRAMS = nm-dhcp-client.action
nm_dhcp_client_action_SOURCES = \
nm-dhcp-client-action.c
nm_dhcp_client_action_CPPFLAGS = \
$(DBUS_CFLAGS) \
$(GTHREAD_CFLAGS) \
-DDBUS_API_SUBJECT_TO_CHANGE \
-DG_DISABLE_DEPRECATED \
-DSYSCONFDIR=\"$(sysconfdir)\"
nm_dhcp_client_action_LDADD = \
$(DBUS_LIBS) \
$(GTHREAD_LIBS)
EXTRA_DIST = $(dbusservice_DATA)

View file

@ -0,0 +1,317 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2007 Red Hat, Inc.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#define NM_DHCP_CLIENT_DBUS_SERVICE "org.freedesktop.nm_dhcp_client"
#define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client"
/**
* Start a dict in a dbus message. Should be paired with a call to
* {@link wpa_dbus_dict_close_write}.
*
* @param iter A valid dbus message iterator
* @param iter_dict (out) A dict iterator to pass to further dict functions
* @return TRUE on success, FALSE on failure
*
*/
dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
DBusMessageIter *iter_dict)
{
dbus_bool_t result;
if (!iter || !iter_dict)
return FALSE;
result = dbus_message_iter_open_container(
iter,
DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
iter_dict);
return result;
}
/**
* End a dict element in a dbus message. Should be paired with
* a call to {@link wpa_dbus_dict_open_write}.
*
* @param iter valid dbus message iterator, same as passed to
* wpa_dbus_dict_open_write()
* @param iter_dict a dbus dict iterator returned from
* {@link wpa_dbus_dict_open_write}
* @return TRUE on success, FALSE on failure
*
*/
dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
DBusMessageIter *iter_dict)
{
if (!iter || !iter_dict)
return FALSE;
return dbus_message_iter_close_container(iter, iter_dict);
}
static dbus_bool_t _wpa_dbus_add_dict_entry_start(
DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
const char *key, const int value_type)
{
if (!dbus_message_iter_open_container(iter_dict,
DBUS_TYPE_DICT_ENTRY, NULL,
iter_dict_entry))
return FALSE;
if (!dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
&key))
return FALSE;
return TRUE;
}
static dbus_bool_t _wpa_dbus_add_dict_entry_end(
DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
DBusMessageIter *iter_dict_val)
{
if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
return FALSE;
if (!dbus_message_iter_close_container(iter_dict, iter_dict_entry))
return FALSE;
return TRUE;
}
static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
DBusMessageIter *iter_dict, const char *key,
const char *value, const dbus_uint32_t value_len)
{
DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
dbus_uint32_t i;
if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
key, DBUS_TYPE_ARRAY))
return FALSE;
if (!dbus_message_iter_open_container(&iter_dict_entry,
DBUS_TYPE_VARIANT,
DBUS_TYPE_ARRAY_AS_STRING
DBUS_TYPE_BYTE_AS_STRING,
&iter_dict_val))
return FALSE;
if (!dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
DBUS_TYPE_BYTE_AS_STRING,
&iter_array))
return FALSE;
for (i = 0; i < value_len; i++) {
if (!dbus_message_iter_append_basic(&iter_array,
DBUS_TYPE_BYTE,
&(value[i])))
return FALSE;
}
if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
return FALSE;
if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
&iter_dict_val))
return FALSE;
return TRUE;
}
/**
* Add a byte array entry to the dict.
*
* @param iter_dict A valid DBusMessageIter returned from
* {@link wpa_dbus_dict_open_write}
* @param key The key of the dict item
* @param value The byte array
* @param value_len The length of the byte array, in bytes
* @return TRUE on success, FALSE on failure
*
*/
dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
const char *key,
const char *value,
const dbus_uint32_t value_len)
{
if (!key)
return FALSE;
if (!value && (value_len != 0))
return FALSE;
return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
value_len);
}
dbus_bool_t
build_message (DBusMessage * message)
{
char ** env = NULL;
char ** item;
dbus_bool_t success = FALSE;
DBusMessageIter iter, iter_dict;
dbus_message_iter_init_append (message, &iter);
if (!wpa_dbus_dict_open_write (&iter, &iter_dict))
goto out;
/* List environment and format for dbus dict */
env = g_listenv ();
for (item = env; *item; item++) {
const char * val = g_getenv (*item);
/* Value passed as a byte array rather than a string, because there are
* no character encoding guarantees with DHCP, and D-Bus requires
* strings to be UTF-8.
*/
if (!wpa_dbus_dict_append_byte_array (&iter_dict,
*item,
val ? val : "\0",
val ? strlen (val) : 1)) {
fprintf (stderr, "Error: failed to add item '%s' to signal\n",
*item);
goto out;
}
}
if (!wpa_dbus_dict_close_write (&iter, &iter_dict))
goto out;
success = TRUE;
out:
g_strfreev (env);
return success;
}
DBusConnection *
dbus_init (void)
{
DBusConnection * connection;
DBusError error;
int ret, flags;
dbus_connection_set_change_sigpipe (TRUE);
dbus_error_init (&error);
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
if (dbus_error_is_set (&error)) {
fprintf (stderr, "Error: could not get the system bus. Make sure "
"the message bus daemon is running! Message: (%s) %s\n",
error.name,
error.message);
goto error;
}
dbus_connection_set_exit_on_disconnect (connection, FALSE);
#if (DBUS_VERSION_MAJOR == 0) && (DBUS_VERSION_MINOR < 60)
flags = DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT;
#else
flags = DBUS_NAME_FLAG_DO_NOT_QUEUE;
#endif
dbus_error_init (&error);
ret = dbus_bus_request_name (connection,
NM_DHCP_CLIENT_DBUS_SERVICE,
flags,
&error);
if (dbus_error_is_set (&error)) {
fprintf (stderr, "Error: Could not acquire the NM DHCP client service. "
"Message: (%s) %s\n",
error.name,
error.message);
goto error;
}
if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
fprintf (stderr, "Error: Could not acquire the NM DHCP client service "
"as it is already taken. Return: %d\n",
ret);
goto error;
}
return connection;
error:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
if (connection)
dbus_connection_unref (connection);
return NULL;
}
int
main (int argc, char *argv[])
{
DBusConnection * connection;
DBusMessage * message;
dbus_bool_t result;
g_type_init ();
/* Get a connection to the system bus */
connection = dbus_init ();
if (connection == NULL)
exit (1);
message = dbus_message_new_signal ("/", NM_DHCP_CLIENT_DBUS_IFACE, "Event");
if (message == NULL) {
fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n");
exit (1);
}
/* Dump environment variables into the message */
result = build_message (message);
if (result == FALSE) {
fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n");
exit (1);
}
/* queue the message */
result = dbus_connection_send (connection, message, NULL);
if (!result) {
fprintf (stderr, "Error: Could not send send DHCP Event signal.\n");
exit (1);
}
dbus_message_unref (message);
/* Send out the message */
dbus_connection_flush (connection);
return 0;
}

View file

@ -0,0 +1,14 @@
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
<allow own="org.freedesktop.nm_dhcp_client"/>
<allow send_interface="org.freedesktop.nm_dhcp_client"/>
</policy>
<policy context="default">
<deny own="org.freedesktop.nm_dhcp_client"/>
<deny send_interface="org.freedesktop.nm_dhcp_client"/>
</policy>
</busconfig>

View file

@ -323,6 +323,7 @@ libnm-util/libnm-util.pc
libnm-util/Makefile
libnm-glib/libnm-glib.pc
libnm-glib/Makefile
callouts/Makefile
dispatcher-daemon/Makefile
gnome/Makefile
gnome/libnm_glib/libnm_glib.pc