Finish remerging busybox udhcp and udhcp. Some cleanups as well.
diff --git a/networking/udhcp/AUTHORS b/networking/udhcp/AUTHORS
index 3772aed..bb58de1 100644
--- a/networking/udhcp/AUTHORS
+++ b/networking/udhcp/AUTHORS
@@ -9,6 +9,6 @@
 --------------
 Moreton Bay	(http://www.moretonbay.com/)
 Lineo		(http://opensource.lineo.com)
-Vladimir Oleynik <dzo@simtrea.ru>, optimize and more integrate for busybox
+Vladimir Oleynik <dzo@simtrea.ru> Size optimizations
 
 
diff --git a/networking/udhcp/ChangeLog b/networking/udhcp/ChangeLog
index 9ee9753..f1aac06 100644
--- a/networking/udhcp/ChangeLog
+++ b/networking/udhcp/ChangeLog
@@ -1,8 +1,6 @@
-0.9.10
-  Size optimization (over 3k), more busybox integration
-  (Vladimir Oleynik <dzo@simtreas.ru>
-
 0.9.9 (pending)
++ Various other size optimizations (Vladimir)
++ Change strerror(errno) to %m (Vladimir N. Oleynik <dzo@simtreas.ru>)
 + Fixed a little endian problem in mton (Bastian Blank <waldi@debian.org>)
 + Fixed a arpping alignment problem (Rui He <rhe@3eti.com>)
 + Added sanity check for max_leases (udhcp bug #1285) (me)
@@ -36,7 +34,7 @@
   udhcp bug#1256
 + Fixed reading of client id (David Poole <davep@portsmith.com>)
 + change sys_errlist[] to strerror() as it aparently doesn't exist
-  (Erik Andersen <andersen@codepoet.org>)
+  (Erik Andersen <andersee@codepoet.org>)
 + fixed get_raw_packet so it returns -2 on non fatal errors
   (Ted Lemon <Ted.Lemon@nominum.com>)
 + Improved (hopefully) NAKing behavior (me)
diff --git a/networking/udhcp/Makefile.in b/networking/udhcp/Makefile.in
index d06e809..4d3f270 100644
--- a/networking/udhcp/Makefile.in
+++ b/networking/udhcp/Makefile.in
@@ -33,22 +33,14 @@
 endif
 endif
 
-ifeq ($(CONFIG_UDHCPD), y)
-CONFIG_UDHCP_LEASES_FILE=y
-else
-ifeq ($(CONFIG_UDHCPD), y)
-CONFIG_UDHCP_LEASES_FILE=y
-else
-CONFIG_UDHCP_LEASES_FILE=n
-endif
-endif
-
 UDHCP-y:=
-UDHCP-$(CONFIG_UDHCP_SHARED)    += options.c socket.c packet.c common.c
-UDHCP-$(CONFIG_UDHCPC)		+= dhcpc.c clientpacket.c script.c
-UDHCP-$(CONFIG_UDHCPD)		+= dhcpd.c arpping.c files.c leases.c serverpacket.c
+UDHCP-$(CONFIG_UDHCP_SHARED)    += common.c options.c packet.c pidfile.c \
+				   signalpipe.c socket.c
+UDHCP-$(CONFIG_UDHCPC)		+= dhcpc.c clientpacket.c clientsocket.c \
+				   script.c
+UDHCP-$(CONFIG_UDHCPD)		+= dhcpd.c arpping.c files.c leases.c \
+				   serverpacket.c
 UDHCP-$(CONFIG_DUMPLEASES)	+= dumpleases.c
-UDHCP-$(CONFIG_UDHCP_LEASES_FILE) += leases_file.c
 UDHCP_OBJS=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y))
 
 libraries-y+=$(UDHCP_DIR)$(UDHCP_AR)
diff --git a/networking/udhcp/README b/networking/udhcp/README
index 5f4bb78..eddb24b 100644
--- a/networking/udhcp/README
+++ b/networking/udhcp/README
@@ -11,19 +11,22 @@
 
 The Makefile contains three of the compile time options:
 	
-	DEBUG: If DEBUG is defined, udhcpd will output extra debugging
-	output, compile with -g, and not fork to the background when run.
-	SYSLOG: If SYSLOG is defined, udhcpd will log all its messages
-	syslog, otherwise, it will attempt to log them to stdout.
+	UDHCP_DEBUG: If UDHCP_DEBUG is defined, udhcpd will output extra
+	debugging output, compile with -g, and not fork to the background when
+	run.
+	UDHCP_SYSLOG: If UDHCP_SYSLOG is defined, udhcpd will log all its
+	messages syslog, otherwise, it will attempt to log them to stdout.
 	
 	COMBINED_BINARY: If COMBINED_BINARY is define, one binary, udhcpd,
 	is created. If called as udhcpd, the dhcp server will be started.
 	If called as udhcpc, the dhcp client will be started.
 	
-dhcpd.h contains the other two compile time options:
+dhcpd.h contains the other three compile time options:
 	
 	LEASE_TIME: The default lease time if not specified in the config
 	file.
+
+	LEASES_FILE: The default file for storing leases.
 	
 	DHCPD_CONFIG_FILE: The defualt config file to use.
 	
diff --git a/networking/udhcp/TODO b/networking/udhcp/TODO
index f88694a..6febe5a 100644
--- a/networking/udhcp/TODO
+++ b/networking/udhcp/TODO
@@ -1,5 +1,6 @@
 TODO
 ----
++ Check for valid IP, netmask, hostname, paths, strings, etc
 + Integrade README.*'s with manpages
 + using time(0) breaks if the system clock changes, find a portable solution
 + make failure of reading functions revert to previous value, not the default
@@ -9,6 +10,7 @@
 + make sure packet generation works on a wide varitey of arches
 + Interoperability testing
 + Hooks within the DHCP server
+	* Server notification when a lease is added/removed
 + Additional bootp support in client/server
 + Make serverid option in server configurable
 + Possibly add failure message to DHCP NAK
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c
index e20395a..363408d 100644
--- a/networking/udhcp/arpping.c
+++ b/networking/udhcp/arpping.c
@@ -44,7 +44,11 @@
 
 
 	if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1) {
+#ifdef IN_BUSYBOX
 		LOG(LOG_ERR, bb_msg_can_not_create_raw_socket);
+#else
+		LOG(LOG_ERR, "Could not open raw socket");
+#endif
 		return -1;
 	}
 	
diff --git a/networking/udhcp/clientsocket.c b/networking/udhcp/clientsocket.c
new file mode 100644
index 0000000..7c1b6e8
--- /dev/null
+++ b/networking/udhcp/clientsocket.c
@@ -0,0 +1,62 @@
+/*
+ * clientsocket.c -- DHCP client socket creation
+ *
+ * udhcp client
+ *
+ * Russ Dill <Russ.Dill@asu.edu> July 2001
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <features.h>
+#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
+#include <netpacket/packet.h>
+#include <net/ethernet.h>
+#else
+#include <asm/types.h>
+#include <linux/if_packet.h>
+#include <linux/if_ether.h>
+#endif
+
+#include "clientsocket.h"
+#include "common.h"
+
+
+int raw_socket(int ifindex)
+{
+	int fd;
+	struct sockaddr_ll sock;
+
+	DEBUG(LOG_INFO, "Opening raw socket on ifindex %d", ifindex);
+	if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
+		DEBUG(LOG_ERR, "socket call failed: %m");
+		return -1;
+	}
+
+	sock.sll_family = AF_PACKET;
+	sock.sll_protocol = htons(ETH_P_IP);
+	sock.sll_ifindex = ifindex;
+	if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
+		DEBUG(LOG_ERR, "bind call failed: %m");
+		close(fd);
+		return -1;
+	}
+
+	return fd;
+}
diff --git a/networking/udhcp/clientsocket.h b/networking/udhcp/clientsocket.h
new file mode 100644
index 0000000..17a55c1
--- /dev/null
+++ b/networking/udhcp/clientsocket.h
@@ -0,0 +1,7 @@
+/* clientsocket.h */
+#ifndef _CLIENTSOCKET_H
+#define _CLIENTSOCKET_H
+
+int raw_socket(int ifindex);
+
+#endif
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index babd980..bfdc7ba 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -1,8 +1,9 @@
 /* common.c
  *
- * Functions to assist in the writing and removing of pidfiles.
+ * Functions for debugging and logging as well as some other
+ * simple helper functions.
  *
- * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
+ * Russ Dill <Russ.Dill@asu.edu> 2001-2003
  * Rewrited by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
  *
  * This program is free software; you can redistribute it and/or modify
@@ -26,18 +27,54 @@
 #include <string.h>
 #include <stdlib.h>
 #include <signal.h>
+#include <paths.h>
 #include <sys/socket.h>
+#include <stdarg.h>
 
 #include "common.h"
+#include "pidfile.h"
 
 
 static int daemonized;
 
-#ifdef CONFIG_FEATURE_UDHCP_SYSLOG
 
+/*
+ * This function makes sure our first socket calls
+ * aren't going to fd 1 (printf badness...) and are
+ * not later closed by daemon()
+ */
+static inline void sanitize_fds(void)
+{
+	int zero;
+	if ((zero = open(_PATH_DEVNULL, O_RDWR, 0)) < 0) return;
+	while (zero < 3) zero = dup(zero);
+	close(zero);
+}
+
+
+void background(const char *pidfile)
+{
+#ifdef __uClinux__
+	LOG(LOG_ERR, "Cannot background in uclinux (yet)");	
+#else /* __uClinux__ */
+	int pid_fd;
+
+	if (!pidfile) return;
+
+	pid_fd = pidfile_acquire(pidfile); /* hold lock during fork. */
+	if (daemon(0, 0) == -1) {
+		perror("fork");
+		exit(1);
+	}
+	daemonized++;
+	pidfile_write_release(pid_fd);
+#endif /* __uClinux__ */
+}
+
+
+#ifdef UDHCP_SYSLOG
 void udhcp_logging(int level, const char *fmt, ...)
 {
-	int e = errno;
 	va_list p;
 	va_list p2;
 
@@ -46,21 +83,34 @@
 	if(!daemonized) {
 		vprintf(fmt, p);
 		putchar('\n');
-		fflush(stdout);
-		errno = e;
 	}
 	vsyslog(level, fmt, p2);
 	va_end(p);
 }
 
-void start_log(const char *client_server)
+
+void start_log_and_pid(const char *client_server, const char *pidfile)
 {
-	openlog(bb_applet_name, LOG_PID | LOG_CONS, LOG_LOCAL0);
+	int pid_fd;
+
+	/* Make sure our syslog fd isn't overwritten */
+	sanitize_fds();
+
+	/* do some other misc startup stuff while we are here to save bytes */
+	pid_fd = pidfile_acquire(pidfile);
+	pidfile_write_release(pid_fd);
+
+	/* equivelent of doing a fflush after every \n */
+	setlinebuf(stdout);
+
+	openlog(client_server, LOG_PID | LOG_CONS, LOG_LOCAL0);
 	udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
 }
 
+
 #else
 
+
 static char *syslog_level_msg[] = {
 	[LOG_EMERG]   = "EMERGENCY!",
 	[LOG_ALERT]   = "ALERT!",
@@ -71,86 +121,36 @@
 	[LOG_DEBUG]   = "debug"
 };
 
+
 void udhcp_logging(int level, const char *fmt, ...)
 {
-	int e = errno;
 	va_list p;
 
 	va_start(p, fmt);
 	if(!daemonized) {
 		printf("%s, ", syslog_level_msg[level]);
-		errno = e;
 		vprintf(fmt, p);
 		putchar('\n');
-		fflush(stdout);
 	}
 	va_end(p);
 }
 
-void start_log(const char *client_server)
+
+void start_log_and_pid(const char *client_server, const char *pidfile)
 {
+	int pid_fd;
+
+	/* Make sure our syslog fd isn't overwritten */
+	sanitize_fds();
+
+	/* do some other misc startup stuff while we are here to save bytes */
+	pid_fd = pidfile_acquire(pidfile);
+	pidfile_write_release(pid_fd);
+
+	/* equivelent of doing a fflush after every \n */
+	setlinebuf(stdout);
+
 	udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
 }
 #endif
 
-static const char *saved_pidfile;
-
-static void exit_fun(void)
-{
-	if (saved_pidfile) unlink(saved_pidfile);
-}
-
-void background(const char *pidfile)
-{
-#ifdef __uClinux__
-	LOG(LOG_ERR, "Cannot background in uclinux (yet)");	
-#else /* __uClinux__ */
-	int pid_fd = -1;
-
-	if (pidfile) {
-		pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
-		if (pid_fd < 0) {
-			LOG(LOG_ERR, "Unable to open pidfile %s: %m", pidfile);
-		} else {
-			lockf(pid_fd, F_LOCK, 0);
-			if(!saved_pidfile)
-				atexit(exit_fun);       /* set atexit one only */
-			saved_pidfile = pidfile;        /* but may be rewrite */
-		}
-	}
-	while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */
-	if (daemon(0, 0) == -1) {
-		perror("fork");
-		exit(1);
-	}
-	daemonized++;
-	if (pid_fd >= 0) {
-		FILE *out;
-
-		if ((out = fdopen(pid_fd, "w")) != NULL) {
-			fprintf(out, "%d\n", getpid());
-			fclose(out);
-		}
-		lockf(pid_fd, F_UNLCK, 0);
-		close(pid_fd);
-	}
-#endif /* __uClinux__ */
-}
-
-/* Signal handler */
-int udhcp_signal_pipe[2];
-static void signal_handler(int sig)
-{
-	if (send(udhcp_signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) {
-		LOG(LOG_ERR, "Could not send signal: %m");
-	}
-}
-
-void udhcp_set_signal_pipe(int sig_add)
-{
-	socketpair(AF_UNIX, SOCK_STREAM, 0, udhcp_signal_pipe);
-	signal(SIGUSR1, signal_handler);
-	signal(SIGTERM, signal_handler);
-	if(sig_add)
-		signal(sig_add, signal_handler);
-}
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index 768f551..78eb1c1 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -18,10 +18,14 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include "version.h"
-#include "busybox.h"
+#ifndef _COMMON_H
+#define _COMMON_H
 
-#ifndef CONFIG_FEATURE_UDHCP_SYSLOG
+#include "version.h"
+#include "libbb_udhcp.h"
+
+
+#ifndef UDHCP_SYSLOG
 enum syslog_levels {
 	LOG_EMERG = 0,
 	LOG_ALERT,
@@ -35,18 +39,17 @@
 #include <syslog.h>
 #endif
 
-void start_log(const char *client_server);
+void background(const char *pidfile);
+void start_log_and_pid(const char *client_server, const char *pidfile);
 void background(const char *pidfile);
 void udhcp_logging(int level, const char *fmt, ...);
-
-extern int udhcp_signal_pipe[2];
-void udhcp_set_signal_pipe(int sig_add);
-
-
+                                                                                
 #define LOG(level, str, args...) udhcp_logging(level, str, ## args)
 
-#ifdef CONFIG_FEATURE_UDHCP_DEBUG
-# define DEBUG(level, str, args...) udhcp_logging(level, str, ## args)
+#ifdef UDHCP_DEBUG
+# define DEBUG(level, str, args...) LOG(level, str, ## args)
 #else
 # define DEBUG(level, str, args...) do {;} while(0)
 #endif
+
+#endif
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 55664ab..a180cc5 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -38,9 +38,11 @@
 #include "dhcpc.h"
 #include "options.h"
 #include "clientpacket.h"
+#include "clientsocket.h"
 #include "script.h"
 #include "socket.h"
 #include "common.h"
+#include "signalpipe.h"
 
 static int state;
 static unsigned long requested_ip; /* = 0 */
@@ -54,12 +56,6 @@
 #define LISTEN_RAW 2
 static int listen_mode;
 
-#ifdef CONFIG_INSTALL_NO_USR
-#define DEFAULT_SCRIPT	"/share/udhcpc/default.script"
-#else
-#define DEFAULT_SCRIPT	"/usr/share/udhcpc/default.script"
-#endif
-
 struct client_config_t client_config = {
 	/* Default options. */
 	abort_if_no_lease: 0,
@@ -78,7 +74,7 @@
 #ifndef IN_BUSYBOX
 static void __attribute__ ((noreturn)) show_usage(void)
 {
-        printf(
+	printf(
 "Usage: udhcpc [OPTIONS]\n\n"
 "  -c, --clientid=CLIENTID         Client identifier\n"
 "  -H, --hostname=HOSTNAME         Client hostname\n"
@@ -95,8 +91,8 @@
 "  -s, --script=file               Run file at dhcp events (default:\n"
 "                                  " DEFAULT_SCRIPT ")\n"
 "  -v, --version                   Display version\n"
-        );
-        exit(0);
+	);
+	exit(0);
 }
 #else
 #define show_usage bb_show_usage
@@ -177,7 +173,11 @@
 }
 
 
+#ifdef COMBINED_BINARY
 int udhcpc_main(int argc, char *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
 {
 	unsigned char *temp, *message;
 	unsigned long t1 = 0, t2 = 0, xid = 0;
@@ -258,18 +258,20 @@
 			client_config.script = optarg;
 			break;
 		case 'v':
-			bb_error_msg("version %s\n", VERSION);
-			return(0);
+			printf("udhcpcd, version %s\n\n", VERSION);
+			return 0;
 			break;
 		default:
 			show_usage();
 		}
 	}
 
-	start_log("client");
+	/* Start the log, sanitize fd's, and write a pid file */
+	start_log_and_pid("udhcpc", client_config.pidfile);
+
 	if (read_interface(client_config.interface, &client_config.ifindex, 
 			   NULL, client_config.arp) < 0)
-		return(1);
+		return 1;
 		
 	if (!client_config.clientid) {
 		client_config.clientid = xmalloc(6 + 3);
@@ -279,8 +281,8 @@
 		memcpy(client_config.clientid + 3, client_config.arp, 6);
 	}
 
-	/* setup signal handlers */
-	udhcp_set_signal_pipe(SIGUSR2);
+	/* setup the signal pipe */
+	udhcp_sp_setup();	
 	
 	state = INIT_SELECTING;
 	run_script(NULL, "deconfig");
@@ -290,7 +292,6 @@
 
 		tv.tv_sec = timeout - time(0);
 		tv.tv_usec = 0;
-		FD_ZERO(&rfds);
 
 		if (listen_mode != LISTEN_NONE && fd < 0) {
 			if (listen_mode == LISTEN_KERNEL)
@@ -299,15 +300,13 @@
 				fd = raw_socket(client_config.ifindex);
 			if (fd < 0) {
 				LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m");
-				return(0);
+				return 0;
 			}
 		}
-		if (fd >= 0) FD_SET(fd, &rfds);
-		FD_SET(udhcp_signal_pipe[0], &rfds);
+		max_fd = udhcp_sp_fd_set(&rfds, fd);
 
 		if (tv.tv_sec > 0) {
 			DEBUG(LOG_INFO, "Waiting on select...");
-			max_fd = udhcp_signal_pipe[0] > fd ? udhcp_signal_pipe[0] : fd;
 			retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
 		} else retval = 0; /* If we already timed out, fall through */
 
@@ -332,7 +331,7 @@
 						client_background();
 					} else if (client_config.abort_if_no_lease) {
 						LOG(LOG_INFO, "No lease, failing.");
-						return(1);
+						return 1;
 				  	}
 					/* wait to try again */
 					packet_num = 0;
@@ -474,7 +473,7 @@
 					state = BOUND;
 					change_mode(LISTEN_NONE);
 					if (client_config.quit_after_lease) 
-						return(0);
+						return 0;
 					if (!client_config.foreground)
 						client_background();
 
@@ -494,11 +493,7 @@
 				break;
 			/* case BOUND, RELEASED: - ignore all packets */
 			}	
-		} else if (retval > 0 && FD_ISSET(udhcp_signal_pipe[0], &rfds)) {
-			if (read(udhcp_signal_pipe[0], &sig, sizeof(sig)) < 0) {
-				DEBUG(LOG_ERR, "Could not read signal: %m");
-				continue; /* probably just EINTR */
-			}
+		} else if (retval > 0 && (sig = udhcp_sp_read(&rfds))) {
 			switch (sig) {
 			case SIGUSR1: 
 				perform_renew();
@@ -508,7 +503,7 @@
 				break;
 			case SIGTERM:
 				LOG(LOG_INFO, "Received SIGTERM");
-				return(0);
+				return 0;
 			}
 		} else if (retval == -1 && errno == EINTR) {
 			/* a signal was caught */		
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index e23d9d4..7145cbd 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -2,6 +2,11 @@
 #ifndef _DHCPC_H
 #define _DHCPC_H
 
+#define DEFAULT_SCRIPT  "/usr/share/udhcpc/default.script"
+
+/* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */
+#include "libbb_udhcp.h"
+
 #define INIT_SELECTING	0
 #define REQUESTING	1
 #define BOUND		2
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index c21cb72..aabab38 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -43,6 +43,7 @@
 #include "files.h"
 #include "serverpacket.h"
 #include "common.h"
+#include "signalpipe.h"
 
 
 /* globals */
@@ -50,7 +51,11 @@
 struct server_config_t server_config;
 
 
+#ifdef COMBINED_BINARY	
 int udhcpd_main(int argc, char *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
 {	
 	fd_set rfds;
 	struct timeval tv;
@@ -64,16 +69,13 @@
 	struct option_set *option;
 	struct dhcpOfferedAddr *lease;
 	int max_sock;
-	int sig;
 	unsigned long num_ips;
 	
-	start_log("server");
-
 	memset(&server_config, 0, sizeof(struct server_config_t));
-	
-	if (argc < 2)
-		read_config(DHCPD_CONF_FILE);
-	else read_config(argv[1]);
+	read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);
+
+	/* Start the log, sanitize fd's, and write a pid file */
+	start_log_and_pid("udhcpd", server_config.pidfile);
 
 	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
 		memcpy(&server_config.lease, option->data + 2, 4);
@@ -90,18 +92,19 @@
 		server_config.max_leases = num_ips;
 	}
 
-	leases = xcalloc(sizeof(struct dhcpOfferedAddr), server_config.max_leases);
+	leases = xcalloc(server_config.max_leases, sizeof(struct dhcpOfferedAddr));
 	read_leases(server_config.lease_file);
 
 	if (read_interface(server_config.interface, &server_config.ifindex,
 			   &server_config.server, server_config.arp) < 0)
-		return(1);
+		return 1;
 
-#ifndef CONFIG_FEATURE_UDHCP_DEBUG
-	background(server_config.pidfile);
+#ifndef UDHCP_DEBUG
+	background(server_config.pidfile); /* hold lock during fork. */
 #endif
 
-	udhcp_set_signal_pipe(0);
+	/* Setup the signal pipe */
+	udhcp_sp_setup();
 
 	timeout_end = time(0) + server_config.auto_time;
 	while(1) { /* loop until universe collapses */
@@ -109,18 +112,15 @@
 		if (server_socket < 0)
 			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
 				LOG(LOG_ERR, "FATAL: couldn't create server socket, %m");
-				return(2);
+				return 2;
 			}			
 
-		FD_ZERO(&rfds);
-		FD_SET(server_socket, &rfds);
-		FD_SET(udhcp_signal_pipe[0], &rfds);
+		max_sock = udhcp_sp_fd_set(&rfds, server_socket);
 		if (server_config.auto_time) {
 			tv.tv_sec = timeout_end - time(0);
 			tv.tv_usec = 0;
 		}
 		if (!server_config.auto_time || tv.tv_sec > 0) {
-			max_sock = server_socket > udhcp_signal_pipe[0] ? server_socket : udhcp_signal_pipe[0];
 			retval = select(max_sock + 1, &rfds, NULL, NULL, 
 					server_config.auto_time ? &tv : NULL);
 		} else retval = 0; /* If we already timed out, fall through */
@@ -134,20 +134,18 @@
 			continue;
 		}
 		
-		if (FD_ISSET(udhcp_signal_pipe[0], &rfds)) {
-			if (read(udhcp_signal_pipe[0], &sig, sizeof(sig)) < 0)
-				continue; /* probably just EINTR */
-			switch (sig) {
-			case SIGUSR1:
-				LOG(LOG_INFO, "Received a SIGUSR1");
-				write_leases();
-				/* why not just reset the timeout, eh */
-				timeout_end = time(0) + server_config.auto_time;
-				continue;
-			case SIGTERM:
-				LOG(LOG_INFO, "Received a SIGTERM");
-				return(0);
-			}
+		switch (udhcp_sp_read(&rfds)) {
+		case SIGUSR1:
+			LOG(LOG_INFO, "Received a SIGUSR1");
+			write_leases();
+			/* why not just reset the timeout, eh */
+			timeout_end = time(0) + server_config.auto_time;
+			continue;
+		case SIGTERM:
+			LOG(LOG_INFO, "Received a SIGTERM");
+			return 0;
+		case 0: break;		/* no signal */
+		default: continue;	/* signal or error (probably EINTR) */
 		}
 
 		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
@@ -251,3 +249,4 @@
 
 	return 0;
 }
+
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index f24f01c..6d72863 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -16,6 +16,13 @@
 #include "options.h"
 #include "common.h"
 
+/* 
+ * Domain names may have 254 chars, and string options can be 254
+ * chars long. However, 80 bytes will be enough for most, and won't
+ * hog up memory. If you have a special application, change it
+ */
+#define READ_CONFIG_BUF_SIZE 80
+
 /* on these functions, make sure you datatype matches */
 static int read_ip(const char *line, void *arg)
 {
@@ -66,23 +73,23 @@
 	return retval;
 }
 
-#define READ_CONFIG_BUF_SIZE 512        /* domainname may have 254 chars */
 
 /* read a dhcp option and add it to opt_list */
 static int read_opt(const char *const_line, void *arg)
 {
-	char line[READ_CONFIG_BUF_SIZE];
 	struct option_set **opt_list = arg;
 	char *opt, *val, *endptr;
 	struct dhcp_option *option;
 	int retval = 0, length;
-	char buffer[256];                       /* max opt length */
-	u_int16_t result_u16;
-	u_int32_t result_u32;
-	void *valptr;
+	char buffer[8];
+	char *line;
+	u_int16_t *result_u16 = (u_int16_t *) buffer;
+	u_int32_t *result_u32 = (u_int32_t *) buffer;
+
+	/* Cheat, the only const line we'll actually get is "" */
+	line = (char *) const_line;
+	if (!(opt = strtok(line, " \t="))) return 0;
 	
-	if (!(opt = strtok(strcpy(line, const_line), " \t="))) return 0;
-		
 	for (option = dhcp_options; option->code; option++)
 		if (!strcasecmp(option->name, opt))
 			break;
@@ -90,11 +97,10 @@
 	if (!option->code) return 0;
 
 	do {
-		val = strtok(NULL, ", \t");
-		if(!val)
-			break;
+		if (!(val = strtok(NULL, ", \t"))) break;
 		length = option_lengths[option->flags & TYPE_MASK];
-		valptr = NULL;
+		retval = 0;
+		opt = buffer; /* new meaning for variable opt */
 		switch (option->flags & TYPE_MASK) {
 		case OPTION_IP:
 			retval = read_ip(val, buffer);
@@ -108,9 +114,8 @@
 			length = strlen(val);
 			if (length > 0) {
 				if (length > 254) length = 254;
-				endptr = buffer + length;
-				endptr[0] = 0;
-				valptr = val;
+				opt = val;
+				retval = 1;
 			}
 			break;
 		case OPTION_BOOLEAN:
@@ -118,43 +123,36 @@
 			break;
 		case OPTION_U8:
 			buffer[0] = strtoul(val, &endptr, 0);
-			valptr = buffer;
+			retval = (endptr[0] == '\0');
 			break;
 		case OPTION_U16:
-			result_u16 = htons(strtoul(val, &endptr, 0));
-			valptr = &result_u16;
+			*result_u16 = htons(strtoul(val, &endptr, 0));
+			retval = (endptr[0] == '\0');
 			break;
 		case OPTION_S16:
-			result_u16 = htons(strtol(val, &endptr, 0));
-			valptr = &result_u16;
+			*result_u16 = htons(strtol(val, &endptr, 0));
+			retval = (endptr[0] == '\0');
 			break;
 		case OPTION_U32:
-			result_u32 = htonl(strtoul(val, &endptr, 0));
-			valptr = &result_u32;
+			*result_u32 = htonl(strtoul(val, &endptr, 0));	
+			retval = (endptr[0] == '\0');
 			break;
 		case OPTION_S32:
-			result_u32 = htonl(strtol(val, &endptr, 0));	
-			valptr = &result_u32;
+			*result_u32 = htonl(strtol(val, &endptr, 0));	
+			retval = (endptr[0] == '\0');
 			break;
 		default:
-			retval = 0;
 			break;
 		}
-		if (valptr) {
-			memcpy(buffer, valptr, length);
-			retval = (endptr[0] == '\0');
-		}
 		if (retval) 
-			attach_option(opt_list, option, buffer, length);
-		else
-			break;
-	} while (option->flags & OPTION_LIST);
+			attach_option(opt_list, option, opt, length);
+	} while (retval && option->flags & OPTION_LIST);
 	return retval;
 }
 
 
 static const struct config_keyword keywords[] = {
-	/* keyword      handler   variable address              default     */
+	/* keyword	handler   variable address		default */
 	{"start",	read_ip,  &(server_config.start),	"192.168.0.20"},
 	{"end",		read_ip,  &(server_config.end),		"192.168.0.254"},
 	{"interface",	read_str, &(server_config.interface),	"eth0"},
@@ -167,7 +165,7 @@
 	{"conflict_time",read_u32,&(server_config.conflict_time),"3600"},
 	{"offer_time",	read_u32, &(server_config.offer_time),	"60"},
 	{"min_lease",	read_u32, &(server_config.min_lease),	"60"},
-	{"lease_file",  read_str, &(server_config.lease_file),	LEASES_FILE},
+	{"lease_file",	read_str, &(server_config.lease_file),	LEASES_FILE},
 	{"pidfile",	read_str, &(server_config.pidfile),	"/var/run/udhcpd.pid"},
 	{"notify_file", read_str, &(server_config.notify_file),	""},
 	{"siaddr",	read_ip,  &(server_config.siaddr),	"0.0.0.0"},
@@ -181,9 +179,11 @@
 int read_config(const char *file)
 {
 	FILE *in;
-	char buffer[READ_CONFIG_BUF_SIZE], orig[READ_CONFIG_BUF_SIZE];
-	char *token, *line;
-	int i;
+	char buffer[READ_CONFIG_BUF_SIZE], *token, *line;
+#ifdef UDHCP_DEBUG
+	char orig[READ_CONFIG_BUF_SIZE];
+#endif
+	int i, lm = 0;
 
 	for (i = 0; keywords[i].keyword[0]; i++)
 		if (keywords[i].def[0])
@@ -195,27 +195,27 @@
 	}
 	
 	while (fgets(buffer, READ_CONFIG_BUF_SIZE, in)) {
+		lm++;
 		if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0';
+#ifdef UDHCP_DEBUG
 		strcpy(orig, buffer);
+#endif
 		if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0';
-		token = strtok(buffer, " \t");
-		if(!token)
-			continue;
-		line = strtok(NULL, "");
-		if(!line)
-			continue;
-		while(*line == '=' || isspace(*line))
-		line++;
+
+		if (!(token = strtok(buffer, " \t"))) continue;
+		if (!(line = strtok(NULL, ""))) continue;		
+		
+		/* eat leading whitespace */
+		line = line + strspn(line, " \t=");
 		/* eat trailing whitespace */
 		for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--);
 		line[i] = '\0';
-		if (*line == '\0')
-			continue;
 		
 		for (i = 0; keywords[i].keyword[0]; i++)
 			if (!strcasecmp(token, keywords[i].keyword))
 				if (!keywords[i].handler(line, keywords[i].var)) {
-					LOG(LOG_ERR, "unable to parse '%s'", orig);
+					LOG(LOG_ERR, "Failure parsing line %d of %s", lm, file);
+					DEBUG(LOG_ERR, "unable to parse '%s'", orig);
 					/* reset back to the default value */
 					keywords[i].handler(keywords[i].def, keywords[i].var);
 				}
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c
index 341abab..add114f 100644
--- a/networking/udhcp/leases.c
+++ b/networking/udhcp/leases.c
@@ -117,6 +117,7 @@
 	} else return 0;
 }
 
+
 /* find an assignable address, it check_expired is true, we check all the expired leases as well.
  * Maybe this should try expired leases by age... */
 u_int32_t find_address(int check_expired) 
diff --git a/networking/udhcp/leases.h b/networking/udhcp/leases.h
index d54cd11..24d8608 100644
--- a/networking/udhcp/leases.h
+++ b/networking/udhcp/leases.h
@@ -9,8 +9,6 @@
 	u_int32_t expires;	/* host order */
 };
 
-extern const char leases_file[];
-
 extern unsigned char blank_chaddr[];
 
 void clear_lease(u_int8_t *chaddr, u_int32_t yiaddr);
diff --git a/networking/udhcp/leases_file.c b/networking/udhcp/leases_file.c
deleted file mode 100644
index 96e2f2d..0000000
--- a/networking/udhcp/leases_file.c
+++ /dev/null
@@ -1 +0,0 @@
-const char leases_file[] = "/var/lib/misc/udhcpd.leases";
diff --git a/networking/udhcp/libbb_udhcp.h b/networking/udhcp/libbb_udhcp.h
index 73e2146..9b5d5a8 100644
--- a/networking/udhcp/libbb_udhcp.h
+++ b/networking/udhcp/libbb_udhcp.h
@@ -1,5 +1,13 @@
 /* libbb_udhcp.h - busybox compatability wrapper */
 
+/* bit of a hack, do this no matter what the order of the includes.
+ * (for busybox) */
+
+#ifdef CONFIG_INSTALL_NO_USR
+#undef DEFUALT_SCRIPT
+#define DEFAULT_SCRIPT  "/share/udhcpc/default.script"
+#endif
+
 #ifndef _LIBBB_UDHCP_H
 #define _LIBBB_UDHCP_H
 
@@ -7,22 +15,16 @@
 #include "busybox.h"
 
 #ifdef CONFIG_FEATURE_UDHCP_SYSLOG
-#define SYSLOG
+#define UDHCP_SYSLOG
 #endif
 
 #ifdef CONFIG_FEATURE_UDHCP_DEBUG
-#define DEBUG
+#define UDHCP_DEBUG
 #endif
 
 #define COMBINED_BINARY
 #include "version.h"
 
-#ifdef CONFIG_INSTALL_NO_USR
-#define DEFAULT_SCRIPT  "/share/udhcpc/default.script"
-#else
-#define DEFAULT_SCRIPT  "/usr/share/udhcpc/default.script"
-#endif
-
 #define xfopen bb_xfopen
 
 #else /* ! BB_VER */
@@ -36,8 +38,6 @@
 #define xmalloc malloc
 #define xcalloc calloc
 
-#define DEFAULT_SCRIPT  "/usr/share/udhcpc/default.script"
-
 static inline FILE *xfopen(const char *file, const char *mode)
 {
 	FILE *fp;
diff --git a/networking/udhcp/pidfile.c b/networking/udhcp/pidfile.c
new file mode 100644
index 0000000..d656c7a
--- /dev/null
+++ b/networking/udhcp/pidfile.c
@@ -0,0 +1,75 @@
+/* pidfile.c
+ *
+ * Functions to assist in the writing and removing of pidfiles.
+ *
+ * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pidfile.h"
+#include "common.h"
+
+static char *saved_pidfile;
+
+static void pidfile_delete(void)
+{
+	if (saved_pidfile) unlink(saved_pidfile);
+}
+
+
+int pidfile_acquire(const char *pidfile)
+{
+	int pid_fd;
+	if (!pidfile) return -1;
+
+	pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
+	if (pid_fd < 0) {
+		LOG(LOG_ERR, "Unable to open pidfile %s: %m\n", pidfile);
+	} else {
+		lockf(pid_fd, F_LOCK, 0);
+		if (!saved_pidfile)
+			atexit(pidfile_delete);
+		saved_pidfile = (char *) pidfile;
+	}
+
+	return pid_fd;
+}
+
+
+void pidfile_write_release(int pid_fd)
+{
+	FILE *out;
+
+	if (pid_fd < 0) return;
+
+	if ((out = fdopen(pid_fd, "w")) != NULL) {
+		fprintf(out, "%d\n", getpid());
+		fclose(out);
+	}
+	lockf(pid_fd, F_UNLCK, 0);
+	close(pid_fd);
+}
+
+
+
+
diff --git a/networking/udhcp/pidfile.h b/networking/udhcp/pidfile.h
new file mode 100644
index 0000000..7f8e8ae
--- /dev/null
+++ b/networking/udhcp/pidfile.h
@@ -0,0 +1,25 @@
+/* pidfile.h
+ *
+ * Functions to assist in the writing and removing of pidfiles.
+ *
+ * Russ Dill <Russ.Dill@asu.edu> Soptember 2001
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+int pidfile_acquire(const char *pidfile);
+void pidfile_write_release(int pid_fd);
+
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c
index 9c766a2..dcd2cad 100644
--- a/networking/udhcp/script.c
+++ b/networking/udhcp/script.c
@@ -32,7 +32,6 @@
 #include "options.h"
 #include "dhcpd.h"
 #include "dhcpc.h"
-#include "script.h"
 #include "common.h"
 
 /* get a rough idea of how long an option will be (rounding up...) */
@@ -56,14 +55,9 @@
 }
 
 
-static int sprintip(char *dest, unsigned char *ip)
+static int sprintip(char *dest, char *pre, unsigned char *ip)
 {
-	return sprintf(dest, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
-}
-
-static void asprintip(char **dest, char *pre, unsigned char *ip)
-{
-	asprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]);
+	return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]);
 }
 
 
@@ -96,12 +90,12 @@
 	for(;;) {
 		switch (type) {
 		case OPTION_IP_PAIR:
-			dest += sprintip(dest, option);
+			dest += sprintip(dest, "", option);
 			*(dest++) = '/';
 			option += 4;
 			optlen = 4;
 		case OPTION_IP:	/* Works regardless of host byte order. */
-			dest += sprintip(dest, option);
+			dest += sprintip(dest, "", option);
  			break;
 		case OPTION_BOOLEAN:
 			dest += sprintf(dest, *option ? "yes" : "no");
@@ -138,15 +132,6 @@
 }
 
 
-static char *find_env(const char *prefix, char *defaultstr)
-{
-	char *ptr;
-
-	ptr = getenv(prefix);
-	return ptr ? ptr : defaultstr;
-}
-
-
 /* put all the paramaters into an environment */
 static char **fill_envp(struct dhcpMessage *packet)
 {
@@ -167,21 +152,20 @@
 		if ((temp = get_option(packet, DHCP_OPTION_OVER)))
 			over = *temp;
 		if (!(over & FILE_FIELD) && packet->file[0]) num_options++;
-		if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++;		
+		if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++;
 	}
 	
-	envp = xmalloc((num_options + 5) * sizeof(char *));
+	envp = xcalloc(sizeof(char *), num_options + 5);
 	j = 0;
 	asprintf(&envp[j++], "interface=%s", client_config.interface);
-	envp[j++] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin");
-	envp[j++] = find_env("HOME", "HOME=/");
+	asprintf(&envp[j++], "%s=%s", "PATH",
+		getenv("PATH") ? : "/bin:/usr/bin:/sbin:/usr/sbin");
+	asprintf(&envp[j++], "%s=%s", "HOME", getenv("HOME") ? : "/");
 
-	if (packet == NULL) {
-		envp[j++] = NULL;
-		return envp;
-	}
+	if (packet == NULL) return envp;
 
-	asprintip(&envp[j++], "ip=", (unsigned char *) &packet->yiaddr);
+	envp[j] = xmalloc(sizeof("ip=255.255.255.255"));
+	sprintip(envp[j++], "ip=", (unsigned char *) &packet->yiaddr);
 
 
 	for (i = 0; dhcp_options[i].code; i++) {
@@ -198,7 +182,8 @@
 		}
 	}
 	if (packet->siaddr) {
-		asprintip(&envp[j++], "siaddr=", (unsigned char *) &packet->siaddr);
+		envp[j] = xmalloc(sizeof("siaddr=255.255.255.255"));
+		sprintip(envp[j++], "siaddr=", (unsigned char *) &packet->siaddr);
 	}
 	if (!(over & FILE_FIELD) && packet->file[0]) {
 		/* watch out for invalid packets */
@@ -210,7 +195,6 @@
 		packet->sname[sizeof(packet->sname) - 1] = '\0';
 		asprintf(&envp[j++], "sname=%s", packet->sname);
 	}	
-	envp[j] = NULL;
 	return envp;
 }
 
diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c
new file mode 100644
index 0000000..4f3292b
--- /dev/null
+++ b/networking/udhcp/signalpipe.c
@@ -0,0 +1,78 @@
+/* signalpipe.c
+ *
+ * Signal pipe infastructure. A reliable way of delivering signals.
+ *
+ * Russ Dill <Russ.Dill@asu.edu> Decemeber 2003
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <unistd.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+
+
+#include "signalpipe.h"
+#include "common.h"
+
+static int signal_pipe[2];
+
+static void signal_handler(int sig)
+{
+	if (send(signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0)
+		DEBUG(LOG_ERR, "Could not send signal: %m");
+}
+
+
+/* Call this before doing anything else. Sets up the socket pair
+ * and installs the signal handler */
+void udhcp_sp_setup(void)
+{
+	socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
+	signal(SIGUSR1, signal_handler);
+	signal(SIGUSR2, signal_handler);
+	signal(SIGTERM, signal_handler);
+}
+
+
+/* Quick little function to setup the rfds. Will return the
+ * max_fd for use with select. Limited in that you can only pass
+ * one extra fd */
+int udhcp_sp_fd_set(fd_set *rfds, int extra_fd)
+{
+	FD_ZERO(rfds);
+	FD_SET(signal_pipe[0], rfds);
+	if (extra_fd >= 0) FD_SET(extra_fd, rfds);
+	return signal_pipe[0] > extra_fd ? signal_pipe[0] : extra_fd;
+}
+
+
+/* Read a signal from the signal pipe. Returns 0 if there is
+ * no signal, -1 on error (and sets errno appropriately), and
+ * your signal on success */
+int udhcp_sp_read(fd_set *rfds)
+{
+	int sig;
+
+	if (!FD_ISSET(signal_pipe[0], rfds))
+		return 0;
+
+	if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
+		return -1;
+
+	return sig;
+}
diff --git a/networking/udhcp/signalpipe.h b/networking/udhcp/signalpipe.h
new file mode 100644
index 0000000..70c1e57
--- /dev/null
+++ b/networking/udhcp/signalpipe.h
@@ -0,0 +1,22 @@
+/* signalpipe.h
+ *
+ * Russ Dill <Russ.Dill@asu.edu> December 2003
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+void udhcp_sp_setup(void);
+int udhcp_sp_fd_set(fd_set *rfds, int extra_fd);
+int udhcp_sp_read(fd_set *rfds);
diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c
index 60190a0..c19838a 100644
--- a/networking/udhcp/socket.c
+++ b/networking/udhcp/socket.c
@@ -130,29 +130,3 @@
 	
 	return fd;
 }
-
-
-int raw_socket(int ifindex)
-{
-	int fd;
-	struct sockaddr_ll sock;
-
-	DEBUG(LOG_INFO, "Opening raw socket on ifindex %d", ifindex);
-	if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
-		DEBUG(LOG_ERR, "socket call failed: %m");
-		return -1;
-	}
-
-	while (fd >= 0 && fd < 3) fd = dup(fd); /* don't let daemon close fds on us */
-	
-	sock.sll_family = AF_PACKET;
-	sock.sll_protocol = htons(ETH_P_IP);
-	sock.sll_ifindex = ifindex;
-	if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
-		DEBUG(LOG_ERR, "bind call failed: %m");
-		close(fd);
-		return -1;
-	}
-
-	return fd;
-}
diff --git a/networking/udhcp/socket.h b/networking/udhcp/socket.h
index 333994b..d259ef7 100644
--- a/networking/udhcp/socket.h
+++ b/networking/udhcp/socket.h
@@ -4,6 +4,5 @@
 
 int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp);
 int listen_socket(unsigned int ip, int port, char *inf);
-int raw_socket(int ifindex);
 
 #endif