+diff -urN -x .svn hotplug2-0.9/hotplug2-dnode.c hotplug2/hotplug2-dnode.c
+--- hotplug2-0.9/hotplug2-dnode.c 2006-09-26 17:35:35.000000000 +0200
++++ hotplug2/hotplug2-dnode.c 2007-07-09 01:17:14.869504000 +0200
+@@ -27,6 +27,7 @@
+
+ #include "mem_utils.h"
+ #include "hotplug2.h"
++#include "hotplug2_utils.h"
+ #include "parser_utils.h"
+
+ #define MODALIAS_MAX_LEN 1024
+@@ -45,59 +46,17 @@
+
+ #define TEST_INPUT_BIT(i,bm) (bm[i / BITS_PER_LONG] & (((unsigned long)1) << (i%BITS_PER_LONG)))
+
+-int init_netlink_socket() {
+- int netlink_socket;
+- struct sockaddr_nl snl;
+- int buffersize = 16 * 1024 * 1024;
+-
+- memset(&snl, 0x00, sizeof(struct sockaddr_nl));
+- snl.nl_family = AF_NETLINK;
+- snl.nl_pid = getpid();
+- snl.nl_groups = 1;
+- netlink_socket = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+- if (netlink_socket == -1) {
+- ERROR("opening netlink","Failed socket: %s.", strerror(errno));
+- return -1;
+- }
+-
+- if (setsockopt(netlink_socket, SOL_SOCKET, SO_SNDBUFFORCE, &buffersize, sizeof(buffersize))) {
+- ERROR("opening netlink","Failed setsockopt: %s. (non-critical)", strerror(errno));
+-
+- /* Somewhat safe default. */
+- buffersize = 106496;
+-
+- if (setsockopt(netlink_socket, SOL_SOCKET, SO_SNDBUF, &buffersize, sizeof(buffersize))) {
+- ERROR("opening netlink","Failed setsockopt: %s. (critical)", strerror(errno));
+- }
+- }
+-
+- if (connect(netlink_socket, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl))) {
+- ERROR("opening netlink","Failed bind: %s.", strerror(errno));
+- close(netlink_socket);
+- return -1;
+- }
+-
+- return netlink_socket;
+-}
+-
+-inline event_seqnum_t get_kernel_seqnum() {
+- FILE *fp;
+-
+- char filename[64];
+- char seqnum[64];
+-
+- strcpy(filename, sysfs_seqnum_path);
+-
+- fp = fopen(filename, "r");
+- if (fp == NULL)
+- return 0;
+-
+- fread(seqnum, 1, 64, fp);
+- fclose(fp);
+-
+- return strtoull(seqnum, NULL, 0);
+-}
+-
++/**
++ * Parses a bitmap; output is a list of offsets of bits of a bitmap
++ * of arbitrary size that are set to 1.
++ *
++ * @1 Name of the bitmap parsed
++ * @2 The actual bitmap pointer
++ * @3 Lower boundary of the bitmap
++ * @4 Upper boundary of the bitmap
++ *
++ * Returns: Newly allocated string containing the offsets
++ */
+ char *bitmap_to_bitstring(char name, unsigned long *bm, unsigned int min_bit, unsigned int max_bit)
+ {
+ char *rv;
+@@ -120,6 +79,15 @@
+ return rv;
+ }
+
++/**
++ * Reverses the bitmap_to_bitstring function.
++ *
++ * @1 Bitstring to be converted
++ * @2 Output bitmap
++ * @3 Size of the whole bitmap
++ *
++ * Returns: void
++ */
+ void string_to_bitmap(char *input, unsigned long *bitmap, int bm_len) {
+ char *token, *ptr;
+ int i = 0;
+@@ -146,6 +114,14 @@
+ } \
+ bitmap = bitmap_to_bitstring(name, bitmap ## _bits, min, mapkey ## _MAX);
+
++/**
++ * Creates an input modalias out of preset environmental variables.
++ *
++ * @1 Pointer to where modalias will be created
++ * @2 Maximum size of the modalias
++ *
++ * Returns: 0 if success, -1 otherwise
++ */
+ int get_input_modalias(char *modalias, int modalias_len) {
+ char *product_env;
+ char *ptr;
+@@ -245,6 +221,14 @@
+ #undef NBITS
+ #undef TEST_INPUT_BIT
+
++/**
++ * Creates a PCI modalias out of preset environmental variables.
++ *
++ * @1 Pointer to where modalias will be created
++ * @2 Maximum size of the modalias
++ *
++ * Returns: 0 if success, -1 otherwise
++ */
+ int get_pci_modalias(char *modalias, int modalias_len) {
+ char *class_env, *id_env, *subsys_env;
+ char *ptr;
+@@ -290,6 +274,15 @@
+ return 0;
+ }
+
++/**
++ * Creates an IEEE1394 (FireWire) modalias out of preset environmental
++ * variables.
++ *
++ * @1 Pointer to where modalias will be created
++ * @2 Maximum size of the modalias
++ *
++ * Returns: 0 if success, -1 otherwise
++ */
+ int get_ieee1394_modalias(char *modalias, int modalias_len) {
+ char *vendor_env, *model_env;
+ char *specifier_env, *version_env;
+@@ -317,6 +310,14 @@
+ return 0;
+ }
+
++/**
++ * Creates a serio modalias out of preset environmental variables.
++ *
++ * @1 Pointer to where modalias will be created
++ * @2 Maximum size of the modalias
++ *
++ * Returns: 0 if success, -1 otherwise
++ */
+ int get_serio_modalias(char *modalias, int modalias_len) {
+ char *serio_type_env, *serio_proto_env;
+ char *serio_id_env, *serio_extra_env;
+@@ -344,6 +345,14 @@
+ return 0;
+ }
+
++/**
++ * Creates an USB modalias out of preset environmental variables.
++ *
++ * @1 Pointer to where modalias will be created
++ * @2 Maximum size of the modalias
++ *
++ * Returns: 0 if success, -1 otherwise
++ */
+ int get_usb_modalias(char *modalias, int modalias_len) {
+ char *product_env, *type_env, *interface_env;
+ char *ptr;
+@@ -409,6 +418,16 @@
+ return 0;
+ }
+
++/**
++ * Distributes modalias generating according to the bus name.
++ *
++ * @1 Bus name
++ * @2 Pointer to where modalias will be created
++ * @3 Maximum size of the modalias
++ *
++ * Returns: The return value of the subsystem modalias function, or -1 if
++ * no match.
++ */
+ int get_modalias(char *bus, char *modalias, int modalias_len) {
+ memset(modalias, 0, modalias_len);
+
+@@ -435,6 +454,16 @@
+ return -1;
+ }
+
++/**
++ * Turns all environmental variables as set when invoked by /proc/sys/hotplug
++ * into an uevent formatted (thus not null-terminated) string.
++ *
++ * @1 All environmental variables
++ * @2 Bus of the event (as read from argv)
++ * @3 Pointer to size of the returned uevent string
++ *
++ * Returns: Not null terminated uevent string.
++ */
+ inline char *get_uevent_string(char **environ, char *bus, unsigned long *uevent_string_len) {
+ char *uevent_string;
+ char *tmp;
+@@ -516,7 +545,7 @@
+ return 1;
+ }
+
+- netlink_socket = init_netlink_socket();
++ netlink_socket = init_netlink_socket(NETLINK_CONNECT);
+ if (netlink_socket == -1) {
+ ERROR("netlink init","Unable to open netlink socket.");
+ goto exit;
+diff -urN -x .svn hotplug2-0.9/hotplug2.h hotplug2/hotplug2.h
+--- hotplug2-0.9/hotplug2.h 2006-10-08 12:21:56.000000000 +0200
++++ hotplug2/hotplug2.h 2007-07-09 01:17:14.865503750 +0200
+@@ -34,7 +34,7 @@
+ #endif
+
+ #ifndef O_NOATIME
+-#define O_NOATIME 01000000
++#define O_NOATIME 01000000
+ #endif
+
+ #define ERROR(action, fmt, arg...) fprintf(stderr, "[%s]: " fmt"\n", action, ##arg);
+@@ -47,7 +47,7 @@
+
+ #define UEVENT_BUFFER_SIZE 2048
+ #define HOTPLUG2_POLL_INTERVAL 20000
+-#define HOTPLUG2_THROTTLE_INTERVAL 10000
++#define HOTPLUG2_THROTTLE_INTERVAL 10000
+ #define HOTPLUG2_RULE_PATH "/etc/hotplug2.rules"
+
+ #define ACTION_ADD 0
+diff -urN -x .svn hotplug2-0.9/hotplug2_utils.c hotplug2/hotplug2_utils.c
+--- hotplug2-0.9/hotplug2_utils.c 1970-01-01 01:00:00.000000000 +0100
++++ hotplug2/hotplug2_utils.c 2007-07-09 01:17:14.869504000 +0200
+@@ -0,0 +1,96 @@
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <fcntl.h>
++#include <stdio.h>
++#include <unistd.h>
++#include <errno.h>
++#include <sys/socket.h>
++#include <sys/types.h>
++#include <sys/un.h>
++#include <sys/wait.h>
++#include <linux/types.h>
++#include <linux/netlink.h>
++
++#include "hotplug2_utils.h"
++
++/**
++ * A trivial function that reads kernel seqnum from sysfs.
++ *
++ * Returns: Seqnum as read from sysfs
++ */
++inline event_seqnum_t get_kernel_seqnum() {
++ FILE *fp;
++
++ char filename[64];
++ char seqnum[64];
++
++ strcpy(filename, sysfs_seqnum_path);
++
++ fp = fopen(filename, "r");
++ if (fp == NULL)
++ return 0;
++
++ fread(seqnum, 1, 64, fp);
++ fclose(fp);
++
++ return strtoull(seqnum, NULL, 0);
++}
++
++/**
++ * Opens a PF_NETLINK socket into the kernel, to read uevents.
++ *
++ * @1 Specifies type of socket (whether we bind or whether we connect)
++ *
++ * Returns: Socket fd if succesful, -1 otherwise.
++ */
++inline int init_netlink_socket(int type) {
++ int netlink_socket;
++ struct sockaddr_nl snl;
++ int buffersize = 16 * 1024 * 1024;
++
++ memset(&snl, 0x00, sizeof(struct sockaddr_nl));
++ snl.nl_family = AF_NETLINK;
++ snl.nl_pid = getpid();
++ snl.nl_groups = 1;
++ netlink_socket = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
++ if (netlink_socket == -1) {
++ ERROR("opening netlink","Failed socket: %s.", strerror(errno));
++ return -1;
++ }
++
++ /*
++ * We're trying to override buffer size. If we fail, we attempt to set a big buffer and pray.
++ */
++ if (setsockopt(netlink_socket, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize))) {
++ ERROR("opening netlink","Failed setsockopt: %s. (non-critical)", strerror(errno));
++
++ /* Somewhat safe default. */
++ buffersize = 106496;
++
++ if (setsockopt(netlink_socket, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize))) {
++ ERROR("opening netlink","Failed setsockopt: %s. (critical)", strerror(errno));
++ }
++ }
++
++ /*
++ * hotplug2-dnode performs connect, while hotplug2 daemon binds
++ */
++ switch (type) {
++ case NETLINK_CONNECT:
++ if (connect(netlink_socket, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl))) {
++ ERROR("opening netlink","Failed connect: %s.", strerror(errno));
++ close(netlink_socket);
++ return -1;
++ }
++
++ default:
++ if (bind(netlink_socket, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl))) {
++ ERROR("opening netlink","Failed bind: %s.", strerror(errno));
++ close(netlink_socket);
++ return -1;
++ }
++ }
++
++ return netlink_socket;
++}
+diff -urN -x .svn hotplug2-0.9/hotplug2_utils.h hotplug2/hotplug2_utils.h
+--- hotplug2-0.9/hotplug2_utils.h 1970-01-01 01:00:00.000000000 +0100
++++ hotplug2/hotplug2_utils.h 2007-07-09 01:17:14.869504000 +0200
+@@ -0,0 +1,21 @@
++/*****************************************************************************\
++* _ _ _ _ ___ *
++* | || | ___ | |_ _ __ | | _ _ __ _ |_ ) *
++* | __ |/ _ \| _|| '_ \| || || |/ _` | / / *
++* |_||_|\___/ \__|| .__/|_| \_,_|\__, |/___| *
++* |_| |___/ *
++\*****************************************************************************/
++
++#ifndef HOTPLUG2_UTILS_H
++#define HOTPLUG2_UTILS_H 1
++
++#include "hotplug2.h"
++
++#define NETLINK_UNDEFINED 0
++#define NETLINK_CONNECT 1
++#define NETLINK_BIND 2
++
++inline event_seqnum_t get_kernel_seqnum();
++inline int init_netlink_socket(int);
++
++#endif
+diff -urN -x .svn hotplug2-0.9/linux24_compat/hotplug2-coldplug-2.4.c hotplug2/linux24_compat/hotplug2-coldplug-2.4.c
+--- hotplug2-0.9/linux24_compat/hotplug2-coldplug-2.4.c 2006-09-25 22:22:47.000000000 +0200
++++ hotplug2/linux24_compat/hotplug2-coldplug-2.4.c 2007-07-09 01:17:14.793499250 +0200
+@@ -28,59 +28,7 @@
+ #include "../mem_utils.h"
+ #include "../parser_utils.h"
+ #include "../filemap_utils.h"
+-
+-inline int init_netlink_socket() {
+- int netlink_socket;
+- struct sockaddr_nl snl;
+- int buffersize = 16 * 1024 * 1024;
+-
+- memset(&snl, 0x00, sizeof(struct sockaddr_nl));
+- snl.nl_family = AF_NETLINK;
+- snl.nl_pid = getpid();
+- snl.nl_groups = 1;
+- netlink_socket = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+- if (netlink_socket == -1) {
+- ERROR("opening netlink","Failed socket: %s.", strerror(errno));
+- return -1;
+- }
+-
+- if (setsockopt(netlink_socket, SOL_SOCKET, SO_SNDBUFFORCE, &buffersize, sizeof(buffersize))) {
+- ERROR("opening netlink","Failed setsockopt: %s. (non-critical)", strerror(errno));
+-
+- /* Somewhat safe default. */
+- buffersize = 106496;
+-
+- if (setsockopt(netlink_socket, SOL_SOCKET, SO_SNDBUF, &buffersize, sizeof(buffersize))) {
+- ERROR("opening netlink","Failed setsockopt: %s. (critical)", strerror(errno));
+- }
+- }
+-
+- if (connect(netlink_socket, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl))) {
+- ERROR("opening netlink","Failed bind: %s.", strerror(errno));
+- close(netlink_socket);
+- return -1;
+- }
+-
+- return netlink_socket;
+-}
+-
+-inline event_seqnum_t get_kernel_seqnum() {
+- FILE *fp;
+-
+- char filename[64];
+- char seqnum[64];
+-
+- strcpy(filename, sysfs_seqnum_path);
+-
+- fp = fopen(filename, "r");
+- if (fp == NULL)
+- return 0;
+-
+- fread(seqnum, 1, 64, fp);
+- fclose(fp);
+-
+- return strtoull(seqnum, NULL, 0);
+-}
++#include "../hotplug2_utils.h"
+
+ inline char *get_uevent_string(char **environ, unsigned long *uevent_string_len) {
+ char *uevent_string;
+@@ -413,7 +361,7 @@
+ int main(int argc, char *argv[], char **environ) {
+ int netlink_socket;
+
+- netlink_socket = init_netlink_socket();
++ netlink_socket = init_netlink_socket(NETLINK_CONNECT);
+ if (netlink_socket == -1) {
+ ERROR("netlink init","Unable to open netlink socket.");
+ return 1;