773a3f
diff -up dhcp-3.1.0/omapip/dispatch.c.libdhcp4client dhcp-3.1.0/omapip/dispatch.c
773a3f
--- dhcp-3.1.0/omapip/dispatch.c.libdhcp4client	2005-03-17 15:15:21.000000000 -0500
773a3f
+++ dhcp-3.1.0/omapip/dispatch.c	2007-10-22 16:00:15.000000000 -0400
773a3f
@@ -34,7 +34,7 @@
773a3f
 
773a3f
 #include <omapip omapip_p.h="">
773a3f
 
773a3f
-static omapi_io_object_t omapi_io_states;
773a3f
+omapi_io_object_t omapi_io_states;
773a3f
 TIME cur_time;
773a3f
 
773a3f
 OMAPI_OBJECT_ALLOC (omapi_io,
773a3f
diff -up dhcp-3.1.0/omapip/errwarn.c.libdhcp4client dhcp-3.1.0/omapip/errwarn.c
773a3f
--- dhcp-3.1.0/omapip/errwarn.c.libdhcp4client	2007-10-22 15:55:40.000000000 -0400
773a3f
+++ dhcp-3.1.0/omapip/errwarn.c	2007-10-22 16:00:30.000000000 -0400
773a3f
@@ -39,6 +39,11 @@ static char copyright[] =
773a3f
 #include <omapip omapip_p.h="">
773a3f
 #include <errno.h>
3b727c
 
3c1d58
+#ifdef LIBDHCP
773a3f
+#include <libdhcp_control.h>
773a3f
+extern LIBDHCP_Control *libdhcp_control;
3c1d58
+#endif
3b727c
+
773a3f
 #ifdef DEBUG
773a3f
 int log_perror = -1;
773a3f
 #else
773a3f
@@ -48,7 +53,9 @@ int log_priority;
773a3f
 void (*log_cleanup) (void);
3b727c
 
773a3f
 #define CVT_BUF_MAX 1023
773a3f
+#ifndef LIBDHCP
773a3f
 static char mbuf [CVT_BUF_MAX + 1];
773a3f
+#endif
773a3f
 static char fbuf [CVT_BUF_MAX + 1];
3c1d58
 
773a3f
 /* Log an error message, then exit... */
773a3f
@@ -58,6 +65,16 @@ void log_fatal (const char * fmt, ... )
773a3f
   va_list list;
3c1d58
 
773a3f
   do_percentm (fbuf, fmt);
773a3f
+  
3c1d58
+#ifdef LIBDHCP
773a3f
+  if (libdhcp_control && (libdhcp_control->eh)) {
773a3f
+      va_start (list, fmt);
773a3f
+      libdhcp_control->eh(libdhcp_control, LOG_FATAL, fbuf, list);
773a3f
+      va_end(list);
773a3f
+      libdhcp_control->finished = 1;
773a3f
+      return;
773a3f
+  }
3c1d58
+#else
3b727c
 
773a3f
   /* %Audit% This is log output. %2004.06.17,Safe%
773a3f
    * If we truncate we hope the user can get a hint from the log.
773a3f
@@ -91,6 +108,7 @@ void log_fatal (const char * fmt, ... )
773a3f
   if (log_cleanup)
773a3f
 	  (*log_cleanup) ();
773a3f
   exit (1);
3c1d58
+#endif
773a3f
 }
3b727c
 
773a3f
 /* Log an error message... */
773a3f
@@ -101,6 +119,13 @@ int log_error (const char * fmt, ...)
773a3f
 
773a3f
   do_percentm (fbuf, fmt);
3b727c
 
3c1d58
+#ifdef LIBDHCP
773a3f
+  if (libdhcp_control && libdhcp_control->eh) {
773a3f
+      va_start (list, fmt);
773a3f
+      libdhcp_control->eh(libdhcp_control, LOG_ERR, fbuf, list);
773a3f
+      va_end(list);
773a3f
+  }
773a3f
+#else
773a3f
   /* %Audit% This is log output. %2004.06.17,Safe%
773a3f
    * If we truncate we hope the user can get a hint from the log.
773a3f
    */
773a3f
@@ -116,7 +141,7 @@ int log_error (const char * fmt, ...)
773a3f
 	  write (STDERR_FILENO, mbuf, strlen (mbuf));
773a3f
 	  write (STDERR_FILENO, "\n", 1);
773a3f
   }
773a3f
-
3c1d58
+#endif
773a3f
   return 0;
773a3f
 }
3b727c
 
773a3f
@@ -128,6 +153,13 @@ int log_info (const char *fmt, ...)
3b727c
 
773a3f
   do_percentm (fbuf, fmt);
3b727c
 
3c1d58
+#ifdef LIBDHCP
773a3f
+  if (libdhcp_control && libdhcp_control->eh) {
773a3f
+      va_start (list, fmt);
773a3f
+      libdhcp_control->eh(libdhcp_control, LOG_INFO, fbuf, list);
773a3f
+      va_end(list);
773a3f
+  }
773a3f
+#else
773a3f
   /* %Audit% This is log output. %2004.06.17,Safe%
773a3f
    * If we truncate we hope the user can get a hint from the log.
773a3f
    */
773a3f
@@ -143,7 +175,7 @@ int log_info (const char *fmt, ...)
773a3f
 	  write (STDERR_FILENO, mbuf, strlen (mbuf));
773a3f
 	  write (STDERR_FILENO, "\n", 1);
773a3f
   }
773a3f
-
3c1d58
+#endif
773a3f
   return 0;
773a3f
 }
3c1d58
 
773a3f
@@ -154,7 +186,13 @@ int log_debug (const char *fmt, ...)
773a3f
   va_list list;
773a3f
 
773a3f
   do_percentm (fbuf, fmt);
773a3f
-
3c1d58
+#ifdef LIBDHCP
773a3f
+  if (libdhcp_control && libdhcp_control->eh) {
773a3f
+      va_start (list, fmt);
773a3f
+      libdhcp_control->eh(libdhcp_control, LOG_DEBUG, fbuf, list);
773a3f
+      va_end(list);
773a3f
+  }
773a3f
+#else
773a3f
   /* %Audit% This is log output. %2004.06.17,Safe%
773a3f
    * If we truncate we hope the user can get a hint from the log.
773a3f
    */
773a3f
@@ -170,7 +208,7 @@ int log_debug (const char *fmt, ...)
773a3f
 	  write (STDERR_FILENO, mbuf, strlen (mbuf));
773a3f
 	  write (STDERR_FILENO, "\n", 1);
773a3f
   }
773a3f
-
3c1d58
+#endif
773a3f
   return 0;
773a3f
 }
3b727c
 
773a3f
diff -up dhcp-3.1.0/omapip/alloc.c.libdhcp4client dhcp-3.1.0/omapip/alloc.c
773a3f
--- dhcp-3.1.0/omapip/alloc.c.libdhcp4client	2006-02-24 18:16:30.000000000 -0500
773a3f
+++ dhcp-3.1.0/omapip/alloc.c	2007-10-22 16:00:03.000000000 -0400
773a3f
@@ -40,6 +40,33 @@ static char copyright[] =
3b727c
 
773a3f
 #include <omapip omapip_p.h="">
3c1d58
 
773a3f
+#ifdef LIBDHCP
773a3f
+/* OK, we need a quick and dirty way of freeing all memory used by libdhcp. 
773a3f
+   All pointers will be stored in a glibc tree on alloc, and removed on free.
773a3f
+   This is not too expensive for light single-call library use.
773a3f
+*/
773a3f
+#include <search.h>  
773a3f
+extern void tdestroy (void *root, void (*free_node)(void *nodep));
773a3f
+static void *all_pointers=0L;
773a3f
+static int ptr_comparator(const void *p1, const void *p2) {
773a3f
+    return ((p1 == p2) ? 0 : ((p1 > p2) ? 1 : -1));
773a3f
+}
3b727c
+
773a3f
+static void record_pointer(void *ptr) {
773a3f
+    tsearch(ptr, &(all_pointers), ptr_comparator);
773a3f
+}
3b727c
+
773a3f
+static void forget_pointer(void *ptr) {
773a3f
+    tdelete(ptr, &(all_pointers), ptr_comparator);
773a3f
+}
86a07e
+
773a3f
+void omapi_free_all_pointers(void) {
773a3f
+    if (all_pointers != NULL)
773a3f
+		tdestroy(all_pointers, free);
773a3f
+    all_pointers = NULL;
773a3f
+}
773a3f
+#endif
3b727c
+
773a3f
 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
773a3f
 		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
773a3f
 struct dmalloc_preamble *dmalloc_list;
773a3f
@@ -78,7 +105,9 @@ VOIDPTR dmalloc (size, file, line)
773a3f
 		return (VOIDPTR)0;
773a3f
 
773a3f
 	foo = malloc(len);
773a3f
-
773a3f
+#ifdef LIBDHCP
773a3f
+	record_pointer(foo);
773a3f
+#endif
773a3f
 	if (!foo)
773a3f
 		return (VOIDPTR)0;
773a3f
 	bar = (VOIDPTR)(foo + DMDOFFSET);
773a3f
@@ -200,6 +229,9 @@ void dfree (ptr, file, line)
773a3f
 		     0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);
773a3f
 #endif
773a3f
 	free (ptr);
773a3f
+#ifdef LIBDHCP
773a3f
+	forget_pointer(ptr);
773a3f
+#endif
773a3f
 }
773a3f
 
773a3f
 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
773a3f
diff -up dhcp-3.1.0/configure.libdhcp4client dhcp-3.1.0/configure
773a3f
--- dhcp-3.1.0/configure.libdhcp4client	2005-03-17 15:14:55.000000000 -0500
773a3f
+++ dhcp-3.1.0/configure	2007-10-22 15:59:07.000000000 -0400
773a3f
@@ -246,7 +246,7 @@ if [ ! -d $workname ]; then
773a3f
 fi
773a3f
 
773a3f
 if [ x"$dirs" = x ]; then
773a3f
-  dirs=". client server relay common omapip dhcpctl minires dst"
773a3f
+  dirs=". client server relay common omapip dhcpctl minires dst libdhcp4client"
773a3f
 fi
773a3f
 
773a3f
 for foo in $dirs; do
773a3f
diff -up dhcp-3.1.0/dst/hmac_link.c.libdhcp4client dhcp-3.1.0/dst/hmac_link.c
773a3f
--- dhcp-3.1.0/dst/hmac_link.c.libdhcp4client	2001-02-22 02:22:08.000000000 -0500
773a3f
+++ dhcp-3.1.0/dst/hmac_link.c	2007-10-22 15:59:24.000000000 -0400
773a3f
@@ -38,6 +38,10 @@ static const char rcsid[] = "$Header: /p
773a3f
 
773a3f
 #include "dst_internal.h"
773a3f
 
773a3f
+#ifdef LIBDHCP
773a3f
+extern void* dmalloc(size_t,char *,int);
773a3f
+#endif
3b727c
+
773a3f
 #ifdef USE_MD5
773a3f
 # include "md5.h"
773a3f
 # ifndef _MD5_H_
773a3f
@@ -86,7 +90,11 @@ dst_hmac_md5_sign(const int mode, DST_KE
773a3f
 	MD5_CTX *ctx = NULL;
1270fb
 
773a3f
 	if (mode & SIG_MODE_INIT) 
3c1d58
+#ifdef LIBDHCP
773a3f
+		ctx = (MD5_CTX *) dmalloc(sizeof(*ctx),__FILE__,__LINE__);
773a3f
+#else
773a3f
 		ctx = (MD5_CTX *) malloc(sizeof(*ctx));
3c1d58
+#endif
773a3f
 	else if (context)
773a3f
 		ctx = (MD5_CTX *) *context;
773a3f
 	if (ctx == NULL) 
773a3f
@@ -153,7 +161,11 @@ dst_hmac_md5_verify(const int mode, DST_
773a3f
 	MD5_CTX *ctx = NULL;
773a3f
 
773a3f
 	if (mode & SIG_MODE_INIT) 
3c1d58
+#ifdef LIBDHCP
773a3f
+		ctx = (MD5_CTX *) dmalloc(sizeof(*ctx),__FILE__,__LINE__);
773a3f
+#else
773a3f
 		ctx = (MD5_CTX *) malloc(sizeof(*ctx));
3c1d58
+#endif
773a3f
 	else if (context)
773a3f
 		ctx = (MD5_CTX *) *context;
773a3f
 	if (ctx == NULL) 
773a3f
@@ -217,8 +229,11 @@ dst_buffer_to_hmac_md5(DST_KEY *dkey, co
3c1d58
 
773a3f
 	if (dkey == NULL || key == NULL || keylen < 0)
773a3f
 		return (-1);
773a3f
-
773a3f
+#ifdef  LIBDHCP
773a3f
+	if ((hkey = (HMAC_Key *) dmalloc(sizeof(HMAC_Key),__FILE__,__LINE__)) == NULL)
773a3f
+#else
773a3f
 	if ((hkey = (HMAC_Key *) malloc(sizeof(HMAC_Key))) == NULL)
773a3f
+#endif
773a3f
 		  return (-2);
3c1d58
 
773a3f
 	memset(hkey->hk_ipad, 0, sizeof(hkey->hk_ipad));
773a3f
@@ -347,7 +362,11 @@ dst_hmac_md5_key_from_file_format(DST_KE
773a3f
 	if (eol == NULL)
773a3f
 		return (-4);
773a3f
 	len = eol - p;
3c1d58
+#ifdef LIBDHCP
773a3f
+	tmp = dmalloc(len + 2,__FILE__,__LINE__);
773a3f
+#else
773a3f
 	tmp = malloc(len + 2);
3c1d58
+#endif
773a3f
 	memcpy(tmp, p, len);
773a3f
 	*(tmp + len) = 0x0;
773a3f
 	key_len = b64_pton((char *)tmp, key, HMAC_LEN+1);	/* see above */
773a3f
@@ -439,8 +458,11 @@ dst_hmac_md5_generate_key(DST_KEY *key, 
773a3f
 		return(0);
773a3f
 	
773a3f
 	len = size > 64 ? 64 : size;
773a3f
+#ifdef LIBDHCP
773a3f
+	buff = dmalloc(len+8,__FILE__,__LINE__);
773a3f
+#else
773a3f
 	buff = malloc(len+8);
773a3f
-
773a3f
+#endif
773a3f
 	n = dst_random(DST_RAND_SEMI, len, buff);
773a3f
 	n += dst_random(DST_RAND_KEY, len, buff);
773a3f
 	if (n <= len) {	/* failed getting anything */
773a3f
@@ -463,7 +485,11 @@ dst_hmac_md5_init()
3c1d58
 {
773a3f
 	if (dst_t_func[KEY_HMAC_MD5] != NULL)
773a3f
 		return (1);
773a3f
+#ifdef LIBDHCP
773a3f
+	dst_t_func[KEY_HMAC_MD5] = dmalloc(sizeof(struct dst_func),__FILE__,__LINE__);
773a3f
+#else
773a3f
 	dst_t_func[KEY_HMAC_MD5] = malloc(sizeof(struct dst_func));
3c1d58
+#endif
773a3f
 	if (dst_t_func[KEY_HMAC_MD5] == NULL)
773a3f
 		return (0);
773a3f
 	memset(dst_t_func[KEY_HMAC_MD5], 0, sizeof(struct dst_func));
773a3f
diff -up dhcp-3.1.0/common/discover.c.libdhcp4client dhcp-3.1.0/common/discover.c
773a3f
--- dhcp-3.1.0/common/discover.c.libdhcp4client	2006-11-07 18:41:39.000000000 -0500
773a3f
+++ dhcp-3.1.0/common/discover.c	2007-10-22 15:58:09.000000000 -0400
773a3f
@@ -121,6 +121,10 @@ isc_result_t interface_initialize (omapi
773a3f
    register that interface with the network I/O software, figure out what
773a3f
    subnet it's on, and add it to the list of interfaces. */
3b727c
 
3c1d58
+#ifdef LIBDHCP
773a3f
+int have_setup_fallback = 0;
3c1d58
+#endif
773a3f
+
773a3f
 void discover_interfaces (state)
773a3f
 	int state;
773a3f
 {
773a3f
@@ -141,7 +145,9 @@ void discover_interfaces (state)
773a3f
 	char *s;
773a3f
 #endif
773a3f
 	isc_result_t status;
3c1d58
+#ifndef LIBDHCP
773a3f
 	static int setup_fallback = 0;
3c1d58
+#endif
773a3f
 	int wifcount = 0;
773a3f
 
773a3f
 	/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
773a3f
@@ -695,10 +701,17 @@ void discover_interfaces (state)
773a3f
 		log_fatal ("Not configured to listen on any interfaces!");
773a3f
 	}
3c1d58
 
1270fb
+#ifdef LIBDHCP
773a3f
+	if (!have_setup_fallback) {
773a3f
+		have_setup_fallback = 1;
773a3f
+		maybe_setup_fallback ();
3b727c
+	}
3c1d58
+#else
773a3f
 	if (!setup_fallback) {
773a3f
 		setup_fallback = 1;
773a3f
 		maybe_setup_fallback ();
773a3f
 	}
3c1d58
+#endif
773a3f
 
773a3f
 #if defined (HAVE_SETFD)
773a3f
 	if (fallback_interface) {
773a3f
diff -up dhcp-3.1.0/common/tree.c.libdhcp4client dhcp-3.1.0/common/tree.c
773a3f
--- dhcp-3.1.0/common/tree.c.libdhcp4client	2007-02-14 17:41:22.000000000 -0500
773a3f
+++ dhcp-3.1.0/common/tree.c	2007-10-22 15:58:54.000000000 -0400
773a3f
@@ -41,7 +41,7 @@ static char copyright[] =
773a3f
 #include <omapip omapip_p.h="">
773a3f
 #include <ctype.h>
773a3f
 
773a3f
-struct binding_scope *global_scope;
773a3f
+struct binding_scope __attribute__ ((visibility ("default"))) *global_scope;
773a3f
 
773a3f
 static int do_host_lookup PROTO ((struct data_string *,
773a3f
 				  struct dns_host_entry *));
773a3f
@@ -2761,6 +2761,7 @@ int evaluate_numeric_expression (result,
773a3f
    result of that evaluation.   There should never be both an expression
773a3f
    and a valid data_string. */
773a3f
 
773a3f
+__attribute__ ((visibility ("default")))
773a3f
 int evaluate_option_cache (result, packet, lease, client_state,
773a3f
 			   in_options, cfg_options, scope, oc, file, line)
773a3f
 	struct data_string *result;
773a3f
diff -up dhcp-3.1.0/common/options.c.libdhcp4client dhcp-3.1.0/common/options.c
773a3f
--- dhcp-3.1.0/common/options.c.libdhcp4client	2007-05-23 15:26:22.000000000 -0400
773a3f
+++ dhcp-3.1.0/common/options.c	2007-10-22 15:58:39.000000000 -0400
773a3f
@@ -2501,6 +2501,7 @@ int fqdn_option_space_encapsulate (resul
773a3f
 	return 1;
3c1d58
 }
3c1d58
 
773a3f
+__attribute__ ((visibility ("default")))
773a3f
 void option_space_foreach (struct packet *packet, struct lease *lease,
773a3f
 			   struct client_state *client_state,
773a3f
 			   struct option_state *in_options,
773a3f
diff -up dhcp-3.1.0/common/dispatch.c.libdhcp4client dhcp-3.1.0/common/dispatch.c
773a3f
--- dhcp-3.1.0/common/dispatch.c.libdhcp4client	2007-10-22 15:55:40.000000000 -0400
773a3f
+++ dhcp-3.1.0/common/dispatch.c	2007-10-22 15:58:24.000000000 -0400
773a3f
@@ -39,8 +39,24 @@ static char copyright[] =
3c1d58
 
773a3f
 #include "dhcpd.h"
3b727c
 
773a3f
-struct timeout *timeouts;
773a3f
-static struct timeout *free_timeouts;
773a3f
+struct timeout {
773a3f
+#ifndef LIBDHCP
773a3f
+	struct timeout *next;
3c1d58
+#endif
773a3f
+	TIME when;
773a3f
+	void (*func) PROTO ((void *));
773a3f
+	void *what;
773a3f
+	tvref_t ref;
773a3f
+	tvunref_t unref;
773a3f
+};
3b727c
+
773a3f
+#ifdef LIBDHCP
773a3f
+static struct timeout *timeouts = NULL;
773a3f
+static int ntimeouts = 0;
773a3f
+#else
773a3f
+static struct timeout *timeouts = NULL;
773a3f
+static struct timeout *free_timeouts = NULL;
773a3f
+#endif
c637bc
 
773a3f
 void set_time(TIME t)
773a3f
 {
773a3f
@@ -53,9 +69,41 @@ void set_time(TIME t)
c637bc
 
773a3f
 struct timeval *process_outstanding_timeouts (struct timeval *tvp)
773a3f
 {
c637bc
+#ifdef LIBDHCP
773a3f
+	int i;
773a3f
+	struct timeout t = { 0 };
773a3f
+#endif
773a3f
 	/* Call any expired timeouts, and then if there's
773a3f
 	   still a timeout registered, time out the select
773a3f
 	   call then. */
773a3f
+#ifdef LIBDHCP
773a3f
+	if (!ntimeouts)
773a3f
+		return NULL;
c637bc
+
773a3f
+	for (i = 0; i < ntimeouts && timeouts[i].when <= cur_time;) {
773a3f
+		struct timeout *new_timeouts;
773a3f
+		size_t n;
c637bc
+
773a3f
+		memmove(&t, &timeouts[i], sizeof (t));
c637bc
+
773a3f
+		n = (ntimeouts - i - 1) * sizeof (t);
773a3f
+		memmove(&timeouts[i+1], &timeouts[i], n);
c637bc
+
773a3f
+		n = --ntimeouts * sizeof (t);
773a3f
+		new_timeouts = realloc(timeouts, n);
773a3f
+		/* XXX broken API, no way to return error here */
773a3f
+		if (new_timeouts || !n)
773a3f
+			timeouts = new_timeouts;
773a3f
+
773a3f
+		if (t.func)
773a3f
+			t.func(t.what);
773a3f
+		if (t.unref)
773a3f
+			t.unref(t.what, MDL);
773a3f
+	}
773a3f
+	if (tvp && ntimeouts) {
773a3f
+		tvp->tv_sec = timeouts[0].when;
773a3f
+		tvp->tv_usec = 0;
773a3f
+#else
773a3f
       another:
773a3f
 	if (timeouts) {
773a3f
 		struct timeout *t;
773a3f
@@ -73,9 +121,15 @@ struct timeval *process_outstanding_time
773a3f
 			tvp -> tv_sec = timeouts -> when;
773a3f
 			tvp -> tv_usec = 0;
773a3f
 		}
c637bc
+#endif
773a3f
 		return tvp;
c637bc
+#ifdef LIBDHCP
773a3f
+	}
773a3f
+	return NULL;
773a3f
+#else
773a3f
 	} else
773a3f
 		return (struct timeval *)0;
c637bc
+#endif
c637bc
 }
c637bc
 
773a3f
 /* Wait for packets to come in using select().   When one does, call
773a3f
@@ -104,13 +158,28 @@ void add_timeout (when, where, what, ref
773a3f
 	tvref_t ref;
773a3f
 	tvunref_t unref;
773a3f
 {
c637bc
+#ifdef LIBDHCP
773a3f
+	struct timeout t = {
773a3f
+		.when = when,
773a3f
+		.func = where,
773a3f
+		.what = what,
773a3f
+		.ref = ref,
773a3f
+		.unref = unref
773a3f
+	};
773a3f
+	struct timeout *new_timeouts;
773a3f
+	int i, pos = 0;
773a3f
+#else
773a3f
 	struct timeout *t, *q;
c637bc
+#endif
c637bc
 
773a3f
 	/* See if this timeout supersedes an existing timeout. */
c637bc
+#ifdef LIBDHCP
773a3f
+	for (i = 0; i < ntimeouts; i++) {
773a3f
+		struct timeout *q = &timeouts[i];
c637bc
+#else
773a3f
 	t = (struct timeout *)0;
773a3f
 	for (q = timeouts; q; q = q -> next) {
773a3f
-		if ((where == NULL || q -> func == where) &&
773a3f
-		    q -> what == what) {
773a3f
+		if ((where == NULL || q -> func == where) && q -> what == what) {
773a3f
 			if (t)
773a3f
 				t -> next = q -> next;
773a3f
 			else
773a3f
@@ -119,7 +188,29 @@ void add_timeout (when, where, what, ref
773a3f
 		}
773a3f
 		t = q;
773a3f
 	}
773a3f
+#endif
c637bc
 
773a3f
+#ifdef LIBDHCP
773a3f
+		/* If this one is already in the list with a different time,
773a3f
+		 * remove it and re-add */
773a3f
+		if ((where == NULL || q->func == where) &&
773a3f
+				q->what == what) {
773a3f
+			size_t n = (--ntimeouts - i) * sizeof (*q);
773a3f
+			memmove(&t, q, sizeof (t));
773a3f
+
773a3f
+			if (n)
773a3f
+				memmove(&timeouts[i], &timeouts[i+1], n);
773a3f
+
773a3f
+			if (ntimeouts) {
773a3f
+				new_timeouts = realloc(timeouts, ntimeouts * sizeof (*q));
773a3f
+				/* XXX broken API, no way to return error here */
773a3f
+				if (new_timeouts)
773a3f
+					timeouts = new_timeouts;
773a3f
+			} else {
773a3f
+				timeouts = NULL;
773a3f
+			}
773a3f
+			add_timeout(when, where, what, ref, unref);
773a3f
+#else
773a3f
 	/* If we didn't supersede a timeout, allocate a timeout
773a3f
 	   structure now. */
773a3f
 	if (!q) {
773a3f
@@ -128,7 +219,7 @@ void add_timeout (when, where, what, ref
773a3f
 			free_timeouts = q -> next;
773a3f
 		} else {
773a3f
 			q = ((struct timeout *)
773a3f
-			     dmalloc (sizeof (struct timeout), MDL));
773a3f
+				dmalloc (sizeof (struct timeout), MDL));
773a3f
 			if (!q)
773a3f
 				log_fatal ("add_timeout: no memory!");
773a3f
 		}
773a3f
@@ -158,22 +249,76 @@ void add_timeout (when, where, what, ref
773a3f
 		if (t -> next -> when > q -> when) {
773a3f
 			q -> next = t -> next;
773a3f
 			t -> next = q;
c637bc
+#endif
773a3f
 			return;
773a3f
+#ifdef LIBDHCP
773a3f
+		} else if (timeouts[i].when > when) {
773a3f
+			pos = i;
773a3f
+#endif
773a3f
 		}
773a3f
 	}
c637bc
 
c637bc
+#ifdef LIBDHCP
773a3f
+	/* If we didn't supersede an existing timeout, then pos is set
773a3f
+	 * to the timeout which will post after this one.  Insert this
773a3f
+	 * one before it. */
773a3f
+
773a3f
+	new_timeouts = realloc(timeouts, sizeof (t) * (ntimeouts+1));
773a3f
+	/* XXX broken API, no way to return error here */
773a3f
+	if (new_timeouts) {
773a3f
+		/* ntimeouts = 10
773a3f
+		 * pos = 3;
773a3f
+		 * n = 10-3 * sizeof (t) = 7 * sizeof (t) 
773a3f
+		 */
773a3f
+		size_t n = (ntimeouts - pos) * sizeof (t);
773a3f
+
773a3f
+		timeouts = new_timeouts;
773a3f
+		memmove(&timeouts[pos+1], &timeouts[pos], n);
773a3f
+		memmove(&timeouts[pos], &t, sizeof (t));
773a3f
+		ntimeouts++;
773a3f
+	}
c637bc
+#else
773a3f
 	/* End of list. */
773a3f
 	t -> next = q;
773a3f
 	q -> next = (struct timeout *)0;
c637bc
+#endif
c637bc
 }
c637bc
 
773a3f
 void cancel_timeout (where, what)
773a3f
 	void (*where) PROTO ((void *));
773a3f
 	void *what;
773a3f
 {
773a3f
+#ifdef LIBDHCP
773a3f
+	struct timeout t;
773a3f
+	int i = 0;
773a3f
+#else
773a3f
 	struct timeout *t, *q;
773a3f
+#endif
c637bc
 
773a3f
 	/* Look for this timeout on the list, and unlink it if we find it. */
c637bc
+#ifdef LIBDHCP
773a3f
+	for (i = 0; i < ntimeouts; i++) {
773a3f
+		struct timeout *new_timeouts, *q = &timeouts[i];
773a3f
+
773a3f
+		if (q->func == where && q->what == what) {
773a3f
+			size_t n;
773a3f
+
773a3f
+			memmove(&t, q, sizeof (t));
773a3f
+
773a3f
+			n = (ntimeouts - i - 1) * sizeof (t);
773a3f
+			memmove(&timeouts[i+1], &timeouts[i], n);
773a3f
+
773a3f
+			n = --ntimeouts * sizeof (t);
773a3f
+			new_timeouts = realloc(timeouts, n);
773a3f
+			/* XXX broken API, no way to return error here */
773a3f
+			if (new_timeouts || !n)
773a3f
+				timeouts = new_timeouts;
773a3f
+
773a3f
+			if (t.unref)
773a3f
+				t.unref(t.what, MDL);
773a3f
+		}
773a3f
+	}
c637bc
+#else
773a3f
 	t = (struct timeout *)0;
773a3f
 	for (q = timeouts; q; q = q -> next) {
773a3f
 		if (q -> func == where && q -> what == what) {
773a3f
@@ -193,10 +338,15 @@ void cancel_timeout (where, what)
773a3f
 		q -> next = free_timeouts;
773a3f
 		free_timeouts = q;
773a3f
 	}
c637bc
+#endif
c637bc
 }
c637bc
 
773a3f
 void cancel_all_timeouts ()
773a3f
 {
773a3f
+#ifdef LIBDHCP
773a3f
+	cur_time = TIME_MAX;
773a3f
+	process_outstanding_timeouts(NULL);
773a3f
+#else
773a3f
 	struct timeout *t, *n;
773a3f
 	for (t = timeouts; t; t = n) {
773a3f
 		n = t -> next;
773a3f
@@ -205,13 +355,20 @@ void cancel_all_timeouts ()
773a3f
 		t -> next = free_timeouts;
773a3f
 		free_timeouts = t;
773a3f
 	}
773a3f
+#endif
773a3f
 }
c637bc
 
773a3f
+__attribute__ ((visibility ("default")))
773a3f
 void relinquish_timeouts ()
773a3f
 {
c637bc
+#ifdef LIBDHCP
773a3f
+	while (ntimeouts)
773a3f
+		cancel_timeout(timeouts[0].func, timeouts[0].what);
c637bc
+#else
773a3f
 	struct timeout *t, *n;
773a3f
 	for (t = free_timeouts; t; t = n) {
773a3f
 		n = t -> next;
773a3f
 		dfree (t, MDL);
773a3f
 	}
c637bc
+#endif
c637bc
 }
773a3f
diff -up dhcp-3.1.0/common/alloc.c.libdhcp4client dhcp-3.1.0/common/alloc.c
773a3f
--- dhcp-3.1.0/common/alloc.c.libdhcp4client	2006-06-01 16:23:17.000000000 -0400
773a3f
+++ dhcp-3.1.0/common/alloc.c	2007-10-22 15:57:53.000000000 -0400
773a3f
@@ -1013,7 +1013,11 @@ int executable_statement_reference (ptr,
773a3f
 	return 1;
773a3f
 }
773a3f
 
773a3f
+#ifdef LIBDHCP
773a3f
+struct packet *free_packets;
773a3f
+#else
773a3f
 static struct packet *free_packets;
773a3f
+#endif
c637bc
 
773a3f
 #if defined (DEBUG_MEMORY_LEAKAGE) || \
773a3f
 		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
773a3f
diff -up dhcp-3.1.0/includes/dhcpd.h.libdhcp4client dhcp-3.1.0/includes/dhcpd.h
773a3f
--- dhcp-3.1.0/includes/dhcpd.h.libdhcp4client	2007-10-22 15:55:40.000000000 -0400
773a3f
+++ dhcp-3.1.0/includes/dhcpd.h	2007-10-22 15:59:51.000000000 -0400
773a3f
@@ -1000,14 +1000,6 @@ struct hardware_link {
c637bc
 
c637bc
 typedef void (*tvref_t)(void *, void *, const char *, int);
c637bc
 typedef void (*tvunref_t)(void *, const char *, int);
c637bc
-struct timeout {
c637bc
-	struct timeout *next;
c637bc
-	TIME when;
c637bc
-	void (*func) PROTO ((void *));
c637bc
-	void *what;
c637bc
-	tvref_t ref;
c637bc
-	tvunref_t unref;
c637bc
-};
c637bc
 
c637bc
 struct protocol {
c637bc
 	struct protocol *next;
773a3f
@@ -1960,7 +1952,6 @@ extern void (*bootp_packet_handler) PROT
c637bc
 					    struct dhcp_packet *, unsigned,
c637bc
 					    unsigned int,
c637bc
 					    struct iaddr, struct hardware *));
c637bc
-extern struct timeout *timeouts;
c637bc
 extern omapi_object_type_t *dhcp_type_interface;
c637bc
 #if defined (TRACING)
c637bc
 trace_type_t *interface_trace;
773a3f
diff -up dhcp-3.1.0/client/dhclient.c.libdhcp4client dhcp-3.1.0/client/dhclient.c
773a3f
--- dhcp-3.1.0/client/dhclient.c.libdhcp4client	2007-10-22 15:55:40.000000000 -0400
773a3f
+++ dhcp-3.1.0/client/dhclient.c	2007-10-22 16:08:09.000000000 -0400
773a3f
@@ -82,14 +82,50 @@ int quiet=0;
773a3f
 int nowait=0;
773a3f
 int bootp_broadcast_always = 0;
1270fb
 
3c1d58
+#ifdef LIBDHCP
773a3f
+FILE *leaseFile = NULL;
3c1d58
+#endif
1270fb
+
773a3f
 extern u_int32_t default_requested_options[];
3c1d58
 
773a3f
 static void usage PROTO ((void));
3b727c
 
3c1d58
+#ifdef LIBDHCP
773a3f
+#include "libdhcp_control.h"
773a3f
+LIBDHCP_Control *libdhcp_control;
773a3f
+static void libdhcp_dispatch(void)
773a3f
+{
773a3f
+	struct timeval tv = { 0, 0 }, *tvp;
773a3f
+	isc_result_t status;
773a3f
+
773a3f
+	/* Wait for a packet, or a timeout, or libdhcp being finished */
773a3f
+	do {
773a3f
+		tvp = process_outstanding_timeouts(&tv);
773a3f
+		status = omapi_one_dispatch(0, tvp);
773a3f
+
773a3f
+		if (libdhcp_control && ((status == ISC_R_TIMEDOUT) || (libdhcp_control->timeout && (time(NULL) >= (libdhcp_control->timeout + libdhcp_control->now))))) {
773a3f
+			if (libdhcp_control->callback)
773a3f
+				libdhcp_control->callback(libdhcp_control, DHC_TIMEDOUT, NULL);
773a3f
+
773a3f
+			break;
773a3f
+		}
773a3f
+	} while ((status != ISC_R_TIMEDOUT) && ((!libdhcp_control) || (!(libdhcp_control->finished))));
773a3f
+}
773a3f
+
773a3f
+extern void omapi_free_all_pointers(void);
773a3f
+
773a3f
+__attribute__ ((visibility ("default")))
773a3f
+int dhcpv4_client (libdhcp_ctl, argc, argv, envp)
773a3f
+	LIBDHCP_Control *libdhcp_ctl;
3c1d58
+#else
773a3f
 int main (argc, argv, envp)
3c1d58
+#endif
773a3f
 	int argc;
773a3f
 	char **argv, **envp;
773a3f
 {
1270fb
+#ifdef LIBDHCP
773a3f
+	libdhcp_control = libdhcp_ctl;
1270fb
+#endif
773a3f
 	int fd;
773a3f
 	int i;
773a3f
 	struct servent *ent;
773a3f
@@ -120,6 +156,7 @@ int main (argc, argv, envp)
773a3f
 	char *arg_conf = NULL;
773a3f
 	int arg_conf_len = 0;
50e357
 
3b727c
+#ifndef LIBDHCP
773a3f
         /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
773a3f
            2 (stderr) are open. To do this, we assume that when we
773a3f
            open a file the lowest available file decriptor is used. */
773a3f
@@ -143,6 +180,7 @@ int main (argc, argv, envp)
773a3f
 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
773a3f
 	setlogmask (LOG_UPTO (LOG_INFO));
773a3f
 #endif	
3b727c
+#endif
3b727c
 
773a3f
 	/* Set up the OMAPI. */
773a3f
 	status = omapi_init ();
773a3f
@@ -439,8 +477,12 @@ int main (argc, argv, envp)
3b727c
 		}
773a3f
 	}
773a3f
 
3b727c
+#ifdef LIBDHCP
773a3f
+	if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_PID_FILE))
3b727c
+#endif
773a3f
 	write_client_pid_file();
3b727c
 
773a3f
+#ifndef LIBDHCP
773a3f
 	if (!quiet) {
773a3f
 		log_info ("%s %s", message, DHCP_VERSION);
773a3f
 		log_info (copyright);
773a3f
@@ -449,6 +491,7 @@ int main (argc, argv, envp)
773a3f
 		log_info ("%s", "");
773a3f
 	} else
773a3f
 		log_perror = 0;
3b727c
+#endif
3b727c
 
773a3f
 	/* If we're given a relay agent address to insert, for testing
773a3f
 	   purposes, figure out what it is. */
773a3f
@@ -680,11 +723,17 @@ int main (argc, argv, envp)
773a3f
 		arg_conf_len = 0;
3b727c
 	}
3b727c
 
3b727c
+#ifdef LIBDHCP
773a3f
+	if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE)) {
3b727c
+#endif
773a3f
 	/* Parse the lease database. */
773a3f
 	read_client_leases ();
773a3f
 
773a3f
 	/* Rewrite the lease database... */
773a3f
 	rewrite_client_leases ();
3b727c
+#ifdef LIBDHCP
773a3f
+	}
3b727c
+#endif
773a3f
 
773a3f
 	/* XXX */
773a3f
 /* 	config_counter(&snd_counter, &rcv_counter); */
773a3f
@@ -703,7 +752,7 @@ int main (argc, argv, envp)
773a3f
 		if (!persist) {
773a3f
 			/* Nothing more to do. */
773a3f
 			log_info ("No broadcast interfaces found - exiting.");
773a3f
-			exit (0);
773a3f
+			return (0);
3b727c
 		}
773a3f
 	} else if (!release_mode && !exit_mode) {
773a3f
 		/* Call the script with the list of interfaces. */
773a3f
@@ -799,6 +848,7 @@ int main (argc, argv, envp)
773a3f
 	dmalloc_outstanding = 0;
773a3f
 #endif
3b727c
 
773a3f
+#ifndef LIBDHCP
773a3f
 	/* If we're not supposed to wait before getting the address,
773a3f
 	   don't. */
773a3f
 	if (nowait)
773a3f
@@ -811,6 +861,126 @@ int main (argc, argv, envp)
773a3f
 
773a3f
 	/* Start dispatching packets and timeouts... */
773a3f
 	dispatch ();
773a3f
+#else
773a3f
+	if (libdhcp_control) {
773a3f
+		if (libdhcp_control->timeout)
773a3f
+			libdhcp_control->now = time(NULL);
773a3f
+		else
773a3f
+			libdhcp_control->now = 0;
773a3f
+	}
3b727c
+
773a3f
+	libdhcp_dispatch();
3b727c
+
773a3f
+	/* libdhcp is finished with us. */
773a3f
+
773a3f
+	/* close all file descriptors:  */
773a3f
+	for (ip = interfaces; ip; ip = ip->next) {
773a3f
+		shutdown(ip->wfdesc, SHUT_RDWR);
773a3f
+		close(ip->wfdesc);
773a3f
+
773a3f
+		if (ip->rfdesc != ip->wfdesc)
773a3f
+			close(ip->rfdesc);
3b727c
+	}
773a3f
+
773a3f
+	if (fallback_interface != 0) {
773a3f
+		ip = fallback_interface;
773a3f
+		shutdown(ip->wfdesc, SHUT_RDWR);
773a3f
+		close(ip->wfdesc);
773a3f
+
773a3f
+		if (ip->rfdesc != ip->wfdesc)
773a3f
+			close(ip->rfdesc);
773a3f
+	}
773a3f
+
773a3f
+	if (leaseFile)
773a3f
+		fclose (leaseFile);
773a3f
+
773a3f
+	closelog();
773a3f
+
773a3f
+	char *current_pid_file = _PATH_DHCLIENT_PID;
773a3f
+
773a3f
+	/* Free ALL allocated memory: */
773a3f
+	omapi_free_all_pointers();
773a3f
+
773a3f
+	/* Re-Initialize globals: */
773a3f
+	client_env = 0;
773a3f
+	client_env_count = 0;
773a3f
+	default_lease_time = 43200;
773a3f
+
773a3f
+	dhcp_max_agent_option_packet_length = 0;
773a3f
+	iaddr_any.len = 4;
773a3f
+	memset(&(iaddr_any.iabuf[0]), '\0', 4);
773a3f
+	iaddr_broadcast.len = 4;
773a3f
+	memset(&(iaddr_broadcast.iabuf[0]), 0xff, 4);
773a3f
+	interfaces_requested = 0;
773a3f
+	leaseFile = 0;
773a3f
+
773a3f
+	libdhcp_control = 0;
773a3f
+
773a3f
+	local_port = 0;
773a3f
+	no_daemon = 0;
773a3f
+	nowait = 0;
773a3f
+	onetry = 0;
773a3f
+	quiet = 0;
773a3f
+	max_lease_time = 86400;
773a3f
+	path_dhclient_conf = _PATH_DHCLIENT_CONF;
773a3f
+	path_dhclient_db = _PATH_DHCLIENT_DB;
773a3f
+	path_dhclient_pid = _PATH_DHCLIENT_PID;
773a3f
+	strcpy(&(path_dhclient_script_array[0]), _PATH_DHCLIENT_SCRIPT);
773a3f
+	path_dhclient_script = path_dhclient_script_array;
773a3f
+	remote_port = 0;
773a3f
+	resolver_inited = 0;
773a3f
+	log_perror = 1;
773a3f
+	global_scope = NULL;
773a3f
+	root_group = NULL;
773a3f
+	group_name_hash = NULL;
773a3f
+	interfaces = NULL;
773a3f
+	dummy_interfaces = NULL;
773a3f
+	fallback_interface = NULL;
773a3f
+	extern int have_setup_fallback;
773a3f
+	have_setup_fallback = 0;
773a3f
+	quiet_interface_discovery = 1;
773a3f
+#ifndef LIBDHCP
773a3f
+	timeouts = NULL;
773a3f
+#endif
773a3f
+	dhcp_type_interface = NULL;
773a3f
+	interface_vector = NULL;
773a3f
+	interface_count = 0;
773a3f
+	interface_max = 0;
773a3f
+	name_servers = 0;
773a3f
+	domains = 0;
773a3f
+	dhcp_type_interface = NULL;
773a3f
+	dhcp_type_group = NULL;
773a3f
+	dhcp_type_shared_network = NULL;
773a3f
+	dhcp_type_control = NULL;
773a3f
+	memset(&dhcp_universe, '\0', sizeof(struct universe));
773a3f
+	memset(&nwip_universe, '\0', sizeof(struct universe));
773a3f
+	memset(&fqdn_universe, '\0', sizeof(struct universe));
773a3f
+	universe_hash = 0;
773a3f
+	universes = 0;
773a3f
+	universe_count = 0;
773a3f
+	universe_max = 0;
773a3f
+	config_universe = 0; 
773a3f
+	extern struct hash_bucket *free_hash_buckets;
773a3f
+	free_hash_buckets = NULL;
773a3f
+	extern struct dhcp_packet *dhcp_free_list;
773a3f
+	dhcp_free_list = NULL;
773a3f
+	extern struct packet *packet_free_list;
773a3f
+	packet_free_list = NULL;
773a3f
+	extern struct binding_value *free_binding_values;
773a3f
+	free_binding_values = NULL;
773a3f
+	extern struct expression *free_expressions;
773a3f
+	free_expressions = NULL;
773a3f
+	extern struct option_cache *free_option_caches;
773a3f
+	free_option_caches = NULL;
773a3f
+	extern  struct packet *free_packets;
773a3f
+	free_packets = NULL;
773a3f
+	extern  pair free_pairs;
773a3f
+	free_pairs = NULL;
773a3f
+	extern omapi_io_object_t omapi_io_states;
773a3f
+	memset(&omapi_io_states, '\0', sizeof(omapi_io_states));
773a3f
+	dhcp_control_object = NULL;
773a3f
+	unlink(current_pid_file);
3b727c
+#endif
3b727c
 
773a3f
 	/*NOTREACHED*/
773a3f
 	return 0;
773a3f
@@ -1203,7 +1373,20 @@ void dhcpack (packet)
773a3f
 	if (client -> new -> rebind < cur_time)
773a3f
 		client -> new -> rebind = TIME_MAX;
3b727c
 
3b727c
+#ifdef LIBDHCP
773a3f
+	/* We need the server's siaddr for the 'bootServer'
773a3f
+	 * pump option
773a3f
+	 */
773a3f
+	u_int32_t set_siaddr = 0;
773a3f
+	set_siaddr = client->packet.siaddr.s_addr;
773a3f
+	client->packet.siaddr.s_addr = packet->raw->siaddr.s_addr;
773a3f
+#endif
3b727c
+
773a3f
 	bind_lease (client);
3b727c
+
773a3f
+#ifdef LIBDHCP
773a3f
+	client->packet.siaddr.s_addr = set_siaddr;
3b727c
+#endif
3b727c
 }
3b727c
 
773a3f
 void bind_lease (client)
773a3f
@@ -1241,6 +1424,9 @@ void bind_lease (client)
773a3f
 		return;
3b727c
 	}
f6f89c
 
3b727c
+#ifdef LIBDHCP
773a3f
+	if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE))
3b727c
+#endif
773a3f
 	/* Write out the new lease. */
773a3f
 	write_client_lease (client, client -> new, 0, 0);
773a3f
 
773a3f
@@ -1343,11 +1529,13 @@ int commit_leases ()
773a3f
 	return 0;
3b727c
 }
3c1d58
 
773a3f
+#ifndef LIBDHCP
773a3f
 int write_lease (lease)
773a3f
 	struct lease *lease;
773a3f
 {
773a3f
 	return 0;
773a3f
 }
773a3f
+#endif
3c1d58
 
773a3f
 int write_host (host)
773a3f
 	struct host_decl *host;
773a3f
@@ -1957,6 +2145,10 @@ void state_panic (cpp)
773a3f
 	   tell the shell script that we failed to allocate an address,
773a3f
 	   and try again later. */
773a3f
 	if (onetry) {
3c1d58
+#ifdef LIBDHCP
773a3f
+		script_init (client, "FAIL", (struct string_list *)0);
773a3f
+		return;
3c1d58
+#endif
773a3f
 		if (!quiet)
773a3f
 			log_info ("Unable to obtain a lease on first try.%s",
773a3f
 				  "  Exiting.");
773a3f
@@ -2579,7 +2771,9 @@ void destroy_client_lease (lease)
773a3f
 	free_client_lease (lease, MDL);
773a3f
 }
3c1d58
 
773a3f
+#ifndef LIBDHCP
773a3f
 FILE *leaseFile;
3c1d58
+#endif
3c1d58
 
773a3f
 void rewrite_client_leases ()
773a3f
 {
773a3f
@@ -2960,6 +3154,54 @@ void script_write_params (client, prefix
773a3f
 int script_go (client)
773a3f
 	struct client_state *client;
773a3f
 {
3c1d58
+#ifdef LIBDHCP
773a3f
+	struct string_list *sp;
773a3f
+
773a3f
+	if (libdhcp_control && libdhcp_control->callback) {
773a3f
+		int dhcmsg;
773a3f
+		char *reason="";
773a3f
+
773a3f
+		for (sp = client->env; sp; sp = sp->next)
773a3f
+			if (strncmp(sp->string, "reason=", 7) == 0) {
773a3f
+				reason = sp->string + 7;
773a3f
+				break;
773a3f
+			}
773a3f
+
773a3f
+		if (strcmp(reason,"NBI") == 0)
773a3f
+			dhcmsg = DHC4_NBI;
773a3f
+		else if (strcmp(reason,"PREINIT") == 0)
773a3f
+			dhcmsg = DHC4_PREINIT;
773a3f
+		else if (strcmp(reason,"BOUND") == 0)
773a3f
+			dhcmsg = DHC4_BOUND;
773a3f
+		else if (strcmp(reason,"RENEW") == 0)
773a3f
+			dhcmsg = DHC4_RENEW;
773a3f
+		else if (strcmp(reason,"REBOOT") == 0)
773a3f
+			dhcmsg = DHC4_REBOOT;
773a3f
+		else if (strcmp(reason,"REBIND") == 0)
773a3f
+			dhcmsg = DHC4_REBIND;
773a3f
+		else if (strcmp(reason,"STOP") == 0)
773a3f
+			dhcmsg = DHC4_STOP;
773a3f
+		else if (strcmp(reason,"MEDIUM") == 0)
773a3f
+			dhcmsg = DHC4_MEDIUM;
773a3f
+		else if (strcmp(reason,"TIMEOUT") == 0)
773a3f
+			dhcmsg = DHC4_TIMEOUT;
773a3f
+		else if (strcmp(reason,"FAIL") == 0)
773a3f
+			dhcmsg = DHC4_FAIL;
773a3f
+		else if (strcmp(reason,"EXPIRE") == 0)
773a3f
+			dhcmsg = DHC4_EXPIRE;
773a3f
+		else if (strcmp(reason,"RELEASE") == 0)
773a3f
+			dhcmsg = DHC4_RELEASE;
773a3f
+		else
773a3f
+			dhcmsg = DHC4_NBI;
773a3f
+
773a3f
+		(*libdhcp_control->callback) (libdhcp_control, dhcmsg, client);
773a3f
+
773a3f
+		if (libdhcp_control->decline)
773a3f
+			return 1;
773a3f
+	}
773a3f
+
773a3f
+	return 0;
3c1d58
+#else
773a3f
 	int rval;
773a3f
 	char *scriptName;
773a3f
 	char *argv [2];
773a3f
@@ -3038,6 +3280,7 @@ int script_go (client)
773a3f
 	GET_TIME (&cur_time);
773a3f
 	return (WIFEXITED (wstatus) ?
773a3f
 		WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
3c1d58
+#endif
773a3f
 }
3c1d58
 
773a3f
 void client_envadd (struct client_state *client,
773a3f
@@ -3120,6 +3363,9 @@ void go_daemon ()
3c1d58
 
773a3f
 	/* Don't become a daemon if the user requested otherwise. */
773a3f
 	if (no_daemon) {
3c1d58
+#ifdef LIBDHCP
773a3f
+		if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_PID_FILE ))
3c1d58
+#endif
773a3f
 		write_client_pid_file ();
773a3f
 		return;
773a3f
 	}
773a3f
@@ -3129,6 +3375,10 @@ void go_daemon ()
773a3f
 		return;
773a3f
 	state = 1;
773a3f
 
3c1d58
+#ifdef LIBDHCP
773a3f
+	return;
3c1d58
+#endif
773a3f
+
773a3f
 	/* Stop logging to stderr... */
773a3f
 	log_perror = 0;
773a3f
 
773a3f
diff -up dhcp-3.1.0/Makefile.dist.libdhcp4client dhcp-3.1.0/Makefile.dist
773a3f
--- dhcp-3.1.0/Makefile.dist.libdhcp4client	2005-03-17 15:14:54.000000000 -0500
773a3f
+++ dhcp-3.1.0/Makefile.dist	2007-10-22 15:57:26.000000000 -0400
3c1d58
@@ -22,7 +22,7 @@
3c1d58
 #   http://www.isc.org/
3c1d58
 
3c1d58
 
3c1d58
-SUBDIRS=	common $(MINIRES) dst omapip server client relay dhcpctl
3c1d58
+SUBDIRS=	common $(MINIRES) dst omapip server client relay dhcpctl libdhcp4client
3c1d58
 
3c1d58
 all:
3c1d58
 	@for dir in ${SUBDIRS}; do \