f6f89c9
--- dhcp-3.0.5/client/dhclient.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/client/dhclient.c	2007-02-08 21:22:14.000000000 -0500
3c1d581
@@ -78,7 +78,9 @@
3c1d581
 int extended_option_environment = 0;
3c1d581
 #endif
3c1d581
 int bootp_broadcast_always = 0;
3c1d581
-
3c1d581
+#ifdef LIBDHCP
3c1d581
+FILE *leaseFile=0;
3c1d581
+#endif
3c1d581
 static void usage PROTO ((void));
3c1d581
 
3c1d581
 void do_release(struct client_state *);
f6f89c9
@@ -89,10 +91,58 @@
3c1d581
 
3c1d581
 extern u_int32_t default_requested_options[];
3c1d581
 
3c1d581
-int main (argc, argv, envp)
3c1d581
+#ifdef LIBDHCP
3c1d581
+#include "libdhcp_control.h"
3c1d581
+LIBDHCP_Control *libdhcp_control;
3c1d581
+static void libdhcp_dispatch(void)
3c1d581
+{
3c1d581
+    struct timeval tv={0,0}, *tvp;
3c1d581
+    isc_result_t status;
3c1d581
+
3c1d581
+    /* Wait for a packet, or a timeout, or libdhcp being finished */
3c1d581
+    do {
3c1d581
+	tvp = process_outstanding_timeouts (&tv;;	
3c1d581
+	status = omapi_one_dispatch (0, tvp);
3c1d581
+	if ( libdhcp_control 
3c1d581
+	   &&( (status == ISC_R_TIMEDOUT)
3c1d581
+	     ||(libdhcp_control->timeout
3c1d581
+	       &&( time(0L) >= 
3c1d581
+	           ( libdhcp_control->timeout 
3c1d581
+	            +libdhcp_control->now
3c1d581
+	           )
3c1d581
+	         )
3c1d581
+	       )
3c1d581
+	     )
3c1d581
+	   )
3c1d581
+	{
3c1d581
+	    if( libdhcp_control -> callback )
3c1d581
+		libdhcp_control -> callback
3c1d581
+		    ( libdhcp_control, DHC_TIMEDOUT, 0L );
3c1d581
+	    break;
3c1d581
+	}
3c1d581
+    } while 
3c1d581
+      ( (status != ISC_R_TIMEDOUT) 
3c1d581
+      &&( (!libdhcp_control)
3c1d581
+        ||(!(libdhcp_control->finished))
3c1d581
+	)
3c1d581
+      );
3c1d581
+}
3c1d581
+
3c1d581
+extern void omapi_free_all_pointers(void);
f6f89c9
+__attribute__ ((visibility ("default")))
3c1d581
+int dhcpv4_client
3c1d581
+(libdhcp_ctl, argc, argv, envp)
3c1d581
+LIBDHCP_Control *libdhcp_ctl;
3c1d581
+#else
3c1d581
+int main
3c1d581
+(argc, argv, envp)
3c1d581
+#endif
3c1d581
 	int argc;
3c1d581
 	char **argv, **envp;
3c1d581
 {
3c1d581
+#ifdef LIBDHCP
3c1d581
+        libdhcp_control = libdhcp_ctl;
3c1d581
+#endif
3c1d581
 	int i;
3c1d581
 	struct servent *ent;
3c1d581
 	struct interface_info *ip;
f6f89c9
@@ -118,7 +168,7 @@
3c1d581
 	int timeout_arg = 0;
3c1d581
 	char *arg_conf = 0L;
3c1d581
 	int arg_conf_len=0;
3c1d581
-
3c1d581
+#ifndef LIBDHCP
3c1d581
 	/* Make sure we have stdin, stdout and stderr. */
3c1d581
 	i = open ("/dev/null", O_RDWR);
3c1d581
 	if (i == 0)
f6f89c9
@@ -139,7 +189,7 @@
3c1d581
 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
3c1d581
 	setlogmask (LOG_UPTO (LOG_INFO));
3c1d581
 #endif	
3c1d581
-
3c1d581
+#endif
3c1d581
 	/* Set up the OMAPI. */
3c1d581
 	status = omapi_init ();
3c1d581
 	if (status != ISC_R_SUCCESS)
f6f89c9
@@ -468,9 +518,12 @@
3c1d581
 		log_fatal("dhclient(%u) is already running - exiting. ", dhcpid);
3c1d581
 		return(1);
3c1d581
 	    }	    
3c1d581
-	}	
3c1d581
+	}
3c1d581
+#ifdef LIBDHCP
3c1d581
+	if ( libdhcp_control && (libdhcp_control->capability & DHCP_USE_PID_FILE) )
3c1d581
+#endif
3c1d581
 	write_client_pid_file();
3c1d581
-
3c1d581
+#ifndef LIBDHCP
3c1d581
 	if (!quiet) {
3c1d581
 		log_info ("%s %s", message, DHCP_VERSION);
3c1d581
 		log_info (copyright);
f6f89c9
@@ -479,7 +532,7 @@
3c1d581
 		log_info ("%s", "");
3c1d581
 	} else
3c1d581
 		log_perror = 0;
3c1d581
-
3c1d581
+#endif
3c1d581
 	/* If we're given a relay agent address to insert, for testing
3c1d581
 	   purposes, figure out what it is. */
3c1d581
 	if (relay) {
f6f89c9
@@ -766,12 +819,18 @@
3c1d581
 		arg_conf_len = 0L;
3c1d581
 	}
3c1d581
 		
3c1d581
+#ifdef LIBDHCP
3c1d581
+	if ( libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE))
3c1d581
+	{
3c1d581
+#endif
3c1d581
 	/* Parse the lease database. */
3c1d581
 	read_client_leases ();
3c1d581
 
3c1d581
 	/* Rewrite the lease database... */
3c1d581
 	rewrite_client_leases ();
3c1d581
-
3c1d581
+#ifdef LIBDHCP
3c1d581
+	}
3c1d581
+#endif
3c1d581
 	/* XXX */
3c1d581
 /* 	config_counter(&snd_counter, &rcv_counter); */
3c1d581
 
f6f89c9
@@ -789,7 +848,7 @@
3c1d581
 		if (!persist) {
3c1d581
 			/* Nothing more to do. */
3c1d581
 			log_info ("No broadcast interfaces found - exiting.");
3c1d581
-			exit (0);
3c1d581
+			return (0);
3c1d581
 		}
3c1d581
 	} else if (!release_mode) {
3c1d581
 		/* Call the script with the list of interfaces. */
f6f89c9
@@ -884,7 +943,7 @@
3c1d581
 	dmalloc_longterm = dmalloc_outstanding;
3c1d581
 	dmalloc_outstanding = 0;
3c1d581
 #endif
3c1d581
-
3c1d581
+#ifndef LIBDHCP
3c1d581
 	/* If we're not supposed to wait before getting the address,
3c1d581
 	   don't. */
3c1d581
 	if (nowait)
f6f89c9
@@ -897,7 +956,125 @@
3c1d581
 
3c1d581
 	/* Start dispatching packets and timeouts... */
3c1d581
 	dispatch ();
3c1d581
+#else
3c1d581
+	if (  libdhcp_control )
3c1d581
+	{
3c1d581
+	   if ( libdhcp_control->timeout ) 
3c1d581
+	       libdhcp_control->now = time(0L);
3c1d581
+	   else
3c1d581
+	       libdhcp_control->now = 0;
3c1d581
+	}
3c1d581
+	libdhcp_dispatch();
1270fb8
 
3c1d581
+	/* libdhcp is finished with us. */
86a07e1
+
3c1d581
+	/* close all file descriptors:  */
3c1d581
+	for (ip = interfaces; ip; ip = ip -> next) {
3c1d581
+	    shutdown( ip -> wfdesc, SHUT_RDWR );
3c1d581
+	    close(ip -> wfdesc);
3c1d581
+	    if( ip -> rfdesc != ip -> wfdesc )
3c1d581
+		close(ip -> rfdesc);
3c1d581
+	}
3c1d581
+	if( fallback_interface != 0 )
3c1d581
+	{
3c1d581
+	    ip = fallback_interface;
3c1d581
+	    shutdown( ip -> wfdesc, SHUT_RDWR );
3c1d581
+	    close(ip -> wfdesc);
3c1d581
+	    if( ip -> rfdesc != ip -> wfdesc )
3c1d581
+		close(ip -> rfdesc);
3c1d581
+	}
3c1d581
+	if (leaseFile)
3c1d581
+	    fclose (leaseFile);
3c1d581
+	closelog();
3c1d581
+	
3c1d581
+	char *current_pid_file = _PATH_DHCLIENT_PID;
3c1d581
+
3c1d581
+	/* Free ALL allocated memory: */
3c1d581
+	omapi_free_all_pointers();
1270fb8
+
3c1d581
+	/* Re-Initialize globals: */
3c1d581
+	client_env = 0;
3c1d581
+	client_env_count = 0;
3c1d581
+	default_lease_time = 43200;
3c1d581
+
3c1d581
+	dhcp_max_agent_option_packet_length = 0;
3c1d581
+	extended_option_environment = 0;
3c1d581
+	iaddr_any.len = 4;
3c1d581
+	memset(&(iaddr_any.iabuf[0]),'\0',4);
3c1d581
+	iaddr_broadcast.len = 4;
3c1d581
+	memset(&(iaddr_broadcast.iabuf[0]),0xff,4);
3c1d581
+	interfaces_requested = 0;
3c1d581
+	leaseFile = 0;
3c1d581
+
3c1d581
+	libdhcp_control = 0;
3c1d581
+	
3c1d581
+	local_port = 0;
3c1d581
+	no_daemon=0;
3c1d581
+	nowait=0;
3c1d581
+	onetry=0;
3c1d581
+	quiet=0;
3c1d581
+	max_lease_time = 86400;
3c1d581
+	path_dhclient_conf = _PATH_DHCLIENT_CONF;
3c1d581
+	path_dhclient_db = _PATH_DHCLIENT_DB;	
3c1d581
+	path_dhclient_pid = _PATH_DHCLIENT_PID;
3c1d581
+	strcpy(&(path_dhclient_script_array[0]), _PATH_DHCLIENT_SCRIPT);
3c1d581
+	path_dhclient_script = path_dhclient_script_array;
3c1d581
+	remote_port = 0;
3c1d581
+	resolver_inited = 0;
3c1d581
+	new_option_info_tree = 0;
3c1d581
+	log_isc_blurb = 0;
3c1d581
+	log_perror = 1;
3c1d581
+	global_scope = 0L;
3c1d581
+	root_group = 0L;
3c1d581
+	group_name_hash = 0L;
3c1d581
+	interfaces = 0L;
3c1d581
+	dummy_interfaces = 0L;
3c1d581
+	fallback_interface = 0L;
3c1d581
+extern int have_setup_fallback;
3c1d581
+        have_setup_fallback=0;
3c1d581
+	quiet_interface_discovery=1;
86a07e1
+#ifndef LIBDHCP
3c1d581
+	timeouts = 0L;
86a07e1
+#endif
3c1d581
+	dhcp_type_interface=0L;
3c1d581
+	interface_vector = 0L;
3c1d581
+	interface_count =0;
3c1d581
+	interface_max = 0;
3c1d581
+	name_servers = 0;
3c1d581
+	domains = 0;
3c1d581
+	dhcp_type_interface=0L;
3c1d581
+	dhcp_type_group=0L;
3c1d581
+	dhcp_type_shared_network=0L;
3c1d581
+	dhcp_type_control=0L;
3c1d581
+	memset(&dhcp_universe, '\0', sizeof(struct universe));
3c1d581
+	memset(&nwip_universe, '\0', sizeof(struct universe));
3c1d581
+	memset(&fqdn_universe, '\0', sizeof(struct universe));
3c1d581
+	universe_hash = 0;
3c1d581
+	universes=0;
3c1d581
+	universe_count=0;
3c1d581
+	universe_max=0;
3c1d581
+	config_universe = 0;	
3c1d581
+extern struct hash_bucket *free_hash_buckets;
3c1d581
+	free_hash_buckets=0L;
3c1d581
+extern struct dhcp_packet *dhcp_free_list;
3c1d581
+	dhcp_free_list = 0L;
3c1d581
+extern struct packet *packet_free_list;
3c1d581
+	packet_free_list = 0L;
3c1d581
+extern struct binding_value *free_binding_values;
3c1d581
+	free_binding_values=0L;
3c1d581
+extern struct expression *free_expressions;
3c1d581
+	free_expressions=0L;
3c1d581
+extern struct option_cache *free_option_caches;
3c1d581
+	free_option_caches=0L;
3c1d581
+extern  struct packet *free_packets;
3c1d581
+	free_packets=0L;
3c1d581
+extern  pair free_pairs;
3c1d581
+	free_pairs=0L;
3c1d581
+extern omapi_io_object_t omapi_io_states;
3c1d581
+        memset(&omapi_io_states, '\0', sizeof(omapi_io_states));
3c1d581
+	dhcp_control_object=0L;
3c1d581
+	unlink(current_pid_file);
3c1d581
+#endif
3c1d581
 	/*NOTREACHED*/
3c1d581
 	return 0;
3c1d581
 }
f6f89c9
@@ -1292,7 +1469,20 @@
3c1d581
 	if (client -> new -> rebind < cur_time)
3c1d581
 		client -> new -> rebind = TIME_MAX;
1270fb8
 
3c1d581
+#ifdef LIBDHCP
1270fb8
+    /* We need the server's siaddr for the 'bootServer'
1270fb8
+     * pump option 
1270fb8
+     */
1270fb8
+    u_int32_t set_siaddr = 0;  
1270fb8
+    set_siaddr = client -> packet.siaddr.s_addr;
1270fb8
+    client->packet.siaddr.s_addr = packet->raw->siaddr.s_addr;
3c1d581
+#endif
3c1d581
+
1270fb8
 	bind_lease (client);
3c1d581
+
3c1d581
+#ifdef LIBDHCP
1270fb8
+    client->packet.siaddr.s_addr = set_siaddr;
3c1d581
+#endif
3c1d581
 }
3c1d581
 
3c1d581
 void bind_lease (client)
f6f89c9
@@ -1328,6 +1518,9 @@
3c1d581
 		return;
3c1d581
 	}
3c1d581
 
3c1d581
+#ifdef LIBDHCP
3c1d581
+	if ( libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE))
3c1d581
+#endif
3c1d581
 	/* Write out the new lease. */
3c1d581
 	write_client_lease (client, client -> new, 0, 0);
3c1d581
 
f6f89c9
@@ -1427,13 +1620,13 @@
3c1d581
 {
3c1d581
 	return 0;
3c1d581
 }
3c1d581
-
3c1d581
+#ifndef LIBDHCP
3c1d581
 int write_lease (lease)
3c1d581
 	struct lease *lease;
3c1d581
 {
3c1d581
 	return 0;
3c1d581
 }
3c1d581
-
3c1d581
+#endif
3c1d581
 int write_host (host)
3c1d581
 	struct host_decl *host;
3c1d581
 {
f6f89c9
@@ -2004,6 +2197,10 @@
3c1d581
 	   tell the shell script that we failed to allocate an address,
3c1d581
 	   and try again later. */
3c1d581
 	if (onetry) {
3c1d581
+#ifdef LIBDHCP
3c1d581
+	    script_init (client, "FAIL", (struct string_list *)0);
3c1d581
+	    return;
3c1d581
+#endif
3c1d581
 		if (!quiet)
3c1d581
 			log_info ("Unable to obtain a lease on first try.%s",
3c1d581
 				  "  Exiting.");
f6f89c9
@@ -2607,7 +2804,9 @@
3c1d581
 	free_client_lease (lease, MDL);
3c1d581
 }
3c1d581
 
3c1d581
+#ifndef LIBDHCP
3c1d581
 FILE *leaseFile;
3c1d581
+#endif
3c1d581
 
3c1d581
 void rewrite_client_leases ()
3c1d581
 {
f6f89c9
@@ -3048,6 +3247,54 @@
3c1d581
 int script_go (client)
3c1d581
 	struct client_state *client;
3c1d581
 {
1270fb8
+#ifdef LIBDHCP
3c1d581
+    struct string_list *sp;
3c1d581
+
1270fb8
+    if (libdhcp_control && libdhcp_control->callback) {
1270fb8
+        int dhcmsg;
1270fb8
+        char *reason="";
1270fb8
+
1270fb8
+        for (sp = client->env; sp; sp = sp->next) 
1270fb8
+            if (strncmp(sp->string, "reason=", 7) == 0) {
1270fb8
+                reason = sp->string + 7;
1270fb8
+                break;
1270fb8
+            }
1270fb8
+
1270fb8
+       if (strcmp(reason,"NBI") == 0)
1270fb8
+            dhcmsg = DHC4_NBI;
1270fb8
+       else if (strcmp(reason,"PREINIT") == 0)
1270fb8
+            dhcmsg = DHC4_PREINIT;
1270fb8
+       else if (strcmp(reason,"BOUND") == 0)
1270fb8
+            dhcmsg = DHC4_BOUND;
1270fb8
+       else if (strcmp(reason,"RENEW") == 0)
1270fb8
+            dhcmsg = DHC4_RENEW;
1270fb8
+       else if (strcmp(reason,"REBOOT") == 0)
1270fb8
+            dhcmsg = DHC4_REBOOT;
1270fb8
+       else if (strcmp(reason,"REBIND") == 0)
1270fb8
+            dhcmsg = DHC4_REBIND;
1270fb8
+       else if (strcmp(reason,"STOP") == 0)
1270fb8
+            dhcmsg = DHC4_STOP;
1270fb8
+       else if (strcmp(reason,"MEDIUM") == 0)
1270fb8
+            dhcmsg = DHC4_MEDIUM;
1270fb8
+       else if (strcmp(reason,"TIMEOUT") == 0)
1270fb8
+            dhcmsg = DHC4_TIMEOUT;
1270fb8
+       else if (strcmp(reason,"FAIL") == 0)
1270fb8
+            dhcmsg = DHC4_FAIL;
1270fb8
+       else if (strcmp(reason,"EXPIRE") == 0)
1270fb8
+            dhcmsg = DHC4_EXPIRE;
1270fb8
+       else if (strcmp(reason,"RELEASE") == 0)
1270fb8
+            dhcmsg = DHC4_RELEASE;
1270fb8
+       else
1270fb8
+            dhcmsg = DHC4_NBI;
1270fb8
+
1270fb8
+       (*libdhcp_control->callback) (libdhcp_control, dhcmsg, client);
1270fb8
+
1270fb8
+       if (libdhcp_control->decline)
1270fb8
+           return 1;
3c1d581
+    }
1270fb8
+
3c1d581
+    return 0;
3c1d581
+#else
3c1d581
 	char *scriptName;
3c1d581
 	char *argv [2];
3c1d581
 	char **envp;
f6f89c9
@@ -3121,6 +3368,7 @@
3c1d581
 	GET_TIME (&cur_time);
3c1d581
 	return (WIFEXITED (wstatus) ?
3c1d581
 		WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
3c1d581
+#endif
3c1d581
 }
3c1d581
 
3c1d581
 void client_envadd (struct client_state *client,
f6f89c9
@@ -3211,6 +3459,9 @@
3c1d581
 
3c1d581
 	/* Don't become a daemon if the user requested otherwise. */
3c1d581
 	if (no_daemon) {
3c1d581
+#ifdef LIBDHCP
3c1d581
+	    if ( libdhcp_control && (libdhcp_control->capability & DHCP_USE_PID_FILE ) )
3c1d581
+#endif
3c1d581
 		write_client_pid_file ();
3c1d581
 		return;
3c1d581
 	}
f6f89c9
@@ -3219,7 +3470,9 @@
3c1d581
 	if (state)
3c1d581
 		return;
3c1d581
 	state = 1;
3c1d581
-
3c1d581
+#ifdef LIBDHCP
3c1d581
+	return;
3c1d581
+#endif
3c1d581
 	/* Stop logging to stderr... */
3c1d581
 	log_perror = 0;
3c1d581
 
f6f89c9
--- dhcp-3.0.5/common/discover.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/common/discover.c	2007-02-08 21:01:16.000000000 -0500
1270fb8
@@ -121,6 +121,10 @@
3c1d581
    register that interface with the network I/O software, figure out what
3c1d581
    subnet it's on, and add it to the list of interfaces. */
1270fb8
 
3c1d581
+#ifdef LIBDHCP
3c1d581
+int have_setup_fallback = 0;
3c1d581
+#endif
1270fb8
+
3c1d581
 void discover_interfaces (state)
3c1d581
 	int state;
3c1d581
 {
1270fb8
@@ -139,7 +143,9 @@
3c1d581
 	char *s;
3c1d581
 #endif
1270fb8
 	isc_result_t status;
3c1d581
+#ifndef LIBDHCP
3c1d581
 	static int setup_fallback = 0;
3c1d581
+#endif
3c1d581
 	int wifcount = 0;
3c1d581
 
3c1d581
 	/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
1270fb8
@@ -691,12 +697,17 @@
3c1d581
 		log_info ("%s", "");
3c1d581
 		log_fatal ("Not configured to listen on any interfaces!");
3c1d581
 	}
3c1d581
-
3c1d581
+#ifdef LIBDHCP
3c1d581
+	if (!have_setup_fallback) {
3c1d581
+		have_setup_fallback = 1;
3c1d581
+		maybe_setup_fallback ();
3c1d581
+	}
3c1d581
+#else
3c1d581
 	if (!setup_fallback) {
3c1d581
 		setup_fallback = 1;
3c1d581
 		maybe_setup_fallback ();
3c1d581
 	}
3c1d581
-
3c1d581
+#endif
3c1d581
 #if defined (HAVE_SETFD)
3c1d581
 	if (fallback_interface) {
3c1d581
 	    if (fcntl (fallback_interface -> rfdesc, F_SETFD, 1) < 0)
1270fb8
@@ -811,7 +822,7 @@
1270fb8
 					omapi_typed_data_t *value)
86a07e1
 {
86a07e1
 	struct interface_info *interface;
86a07e1
-	isc_result_t status;
1270fb8
+    isc_result_t status;
86a07e1
 
86a07e1
 	if (h -> type != dhcp_type_interface)
86a07e1
 		return ISC_R_INVALIDARG;
f6f89c9
--- dhcp-3.0.5/common/lpf.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/common/lpf.c	2007-02-08 21:01:16.000000000 -0500
1270fb8
@@ -246,6 +246,7 @@
3c1d581
 	struct interface_info *info;
3c1d581
 {
3c1d581
 	struct sock_fprog p;
3c1d581
+	memset(&p,'\0', sizeof(struct sock_fprog));
3c1d581
 
3c1d581
 	/* Set up the bpf filter program structure.    This is defined in
3c1d581
 	   bpf.c */
f6f89c9
--- dhcp-3.0.5/common/alloc.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/common/alloc.c	2007-02-08 21:01:16.000000000 -0500
1270fb8
@@ -1009,7 +1009,11 @@
50e3571
 	return 1;
50e3571
 }
50e3571
 
1270fb8
+#ifdef LIBDHCP
1270fb8
+struct packet *free_packets;
1270fb8
+#else
1270fb8
 static struct packet *free_packets;
1270fb8
+#endif
50e3571
 
1270fb8
 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1270fb8
 		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
f6f89c9
--- dhcp-3.0.5/common/tree.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/common/tree.c	2007-02-08 21:24:40.000000000 -0500
f6f89c9
@@ -40,7 +40,7 @@
f6f89c9
 #include "dhcpd.h"
f6f89c9
 #include <omapip/omapip_p.h>
f6f89c9
 
f6f89c9
-struct binding_scope *global_scope;
f6f89c9
+struct binding_scope __attribute__ ((visibility ("default"))) *global_scope;
f6f89c9
 
f6f89c9
 static int do_host_lookup PROTO ((struct data_string *,
f6f89c9
 				  struct dns_host_entry *));
f6f89c9
@@ -2615,6 +2615,7 @@
f6f89c9
    result of that evaluation.   There should never be both an expression
f6f89c9
    and a valid data_string. */
f6f89c9
 
f6f89c9
+__attribute__ ((visibility ("default")))
f6f89c9
 int evaluate_option_cache (result, packet, lease, client_state,
f6f89c9
 			   in_options, cfg_options, scope, oc, file, line)
f6f89c9
 	struct data_string *result;
f6f89c9
--- dhcp-3.0.5/common/options.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/common/options.c	2007-02-08 21:23:37.000000000 -0500
f6f89c9
@@ -2153,6 +2153,7 @@
f6f89c9
 	return 1;
f6f89c9
 }
f6f89c9
 
f6f89c9
+__attribute__ ((visibility ("default")))
f6f89c9
 void option_space_foreach (struct packet *packet, struct lease *lease,
f6f89c9
 			   struct client_state *client_state,
f6f89c9
 			   struct option_state *in_options,
f6f89c9
--- dhcp-3.0.5/common/dispatch.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/common/dispatch.c	2007-02-08 21:24:08.000000000 -0500
f6f89c9
@@ -358,6 +358,7 @@
f6f89c9
 #endif
f6f89c9
 }
f6f89c9
 
f6f89c9
+__attribute__ ((visibility ("default")))
f6f89c9
 void relinquish_timeouts ()
f6f89c9
 {
f6f89c9
 #ifdef LIBDHCP
f6f89c9
--- dhcp-3.0.5/dst/hmac_link.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/dst/hmac_link.c	2007-02-08 21:01:16.000000000 -0500
3c1d581
@@ -38,6 +38,10 @@
3c1d581
 
3c1d581
 #include "dst_internal.h"
3c1d581
 
3c1d581
+#ifdef LIBDHCP
3c1d581
+extern void* dmalloc(size_t,char *,int);
3c1d581
+#endif
3c1d581
+
3c1d581
 #ifdef USE_MD5
3c1d581
 # include "md5.h"
3c1d581
 # ifndef _MD5_H_
3c1d581
@@ -86,7 +90,11 @@
3c1d581
 	MD5_CTX *ctx = NULL;
3c1d581
 
3c1d581
 	if (mode & SIG_MODE_INIT) 
3c1d581
+#ifdef LIBDHCP
3c1d581
+		ctx = (MD5_CTX *) dmalloc(sizeof(*ctx),__FILE__,__LINE__);
3c1d581
+#else
3c1d581
 		ctx = (MD5_CTX *) malloc(sizeof(*ctx));
3c1d581
+#endif
3c1d581
 	else if (context)
3c1d581
 		ctx = (MD5_CTX *) *context;
3c1d581
 	if (ctx == NULL) 
3c1d581
@@ -153,7 +161,11 @@
3c1d581
 	MD5_CTX *ctx = NULL;
3c1d581
 
3c1d581
 	if (mode & SIG_MODE_INIT) 
3c1d581
-		ctx = (MD5_CTX *) malloc(sizeof(*ctx));
3c1d581
+#ifdef LIBDHCP
3c1d581
+		ctx = (MD5_CTX *) dmalloc(sizeof(*ctx),__FILE__,__LINE__);
3c1d581
+#else
3c1d581
+	        ctx = (MD5_CTX *) malloc(sizeof(*ctx));
3c1d581
+#endif
3c1d581
 	else if (context)
3c1d581
 		ctx = (MD5_CTX *) *context;
3c1d581
 	if (ctx == NULL) 
3c1d581
@@ -217,8 +229,11 @@
3c1d581
 
3c1d581
 	if (dkey == NULL || key == NULL || keylen < 0)
3c1d581
 		return (-1);
3c1d581
-
3c1d581
+#ifdef  LIBDHCP
3c1d581
+	if ((hkey = (HMAC_Key *) dmalloc(sizeof(HMAC_Key),__FILE__,__LINE__)) == NULL)
3c1d581
+#else
3c1d581
 	if ((hkey = (HMAC_Key *) malloc(sizeof(HMAC_Key))) == NULL)
3c1d581
+#endif
3c1d581
 		  return (-2);
3c1d581
 
3c1d581
 	memset(hkey->hk_ipad, 0, sizeof(hkey->hk_ipad));
3c1d581
@@ -347,7 +362,11 @@
3c1d581
 	if (eol == NULL)
3c1d581
 		return (-4);
3c1d581
 	len = eol - p;
3c1d581
+#ifdef LIBDHCP
3c1d581
+	tmp = dmalloc(len + 2,__FILE__,__LINE__);
3c1d581
+#else
3c1d581
 	tmp = malloc(len + 2);
3c1d581
+#endif
3c1d581
 	memcpy(tmp, p, len);
3c1d581
 	*(tmp + len) = 0x0;
3c1d581
 	key_len = b64_pton((char *)tmp, key, HMAC_LEN+1);	/* see above */
3c1d581
@@ -439,8 +458,11 @@
3c1d581
 		return(0);
3c1d581
 	
3c1d581
 	len = size > 64 ? 64 : size;
3c1d581
+#ifdef LIBDHCP
3c1d581
+	buff = dmalloc(len+8,__FILE__,__LINE__);
3c1d581
+#else
3c1d581
 	buff = malloc(len+8);
3c1d581
-
3c1d581
+#endif
3c1d581
 	n = dst_random(DST_RAND_SEMI, len, buff);
3c1d581
 	n += dst_random(DST_RAND_KEY, len, buff);
3c1d581
 	if (n <= len) {	/* failed getting anything */
3c1d581
@@ -463,7 +485,11 @@
3c1d581
 {
3c1d581
 	if (dst_t_func[KEY_HMAC_MD5] != NULL)
3c1d581
 		return (1);
3c1d581
+#ifdef LIBDHCP
3c1d581
+	dst_t_func[KEY_HMAC_MD5] = dmalloc(sizeof(struct dst_func),__FILE__,__LINE__);
3c1d581
+#else
3c1d581
 	dst_t_func[KEY_HMAC_MD5] = malloc(sizeof(struct dst_func));
3c1d581
+#endif
3c1d581
 	if (dst_t_func[KEY_HMAC_MD5] == NULL)
3c1d581
 		return (0);
3c1d581
 	memset(dst_t_func[KEY_HMAC_MD5], 0, sizeof(struct dst_func));
fc985ec
--- dhcp-3.0.5/dst/md5_dgst.c.libdhcp4client	2004-06-14 14:50:06.000000000 -0400
f6f89c9
+++ dhcp-3.0.5/dst/md5_dgst.c	2007-02-08 21:05:27.000000000 -0500
fc985ec
@@ -65,7 +65,7 @@
fc985ec
 
fc985ec
 #ifdef USE_MD5 /* Added by ogud@tis.com 1998/1/26 */
fc985ec
 
fc985ec
-const char *MD5_version="MD5 part of SSLeay 0.8.1 19-Jul-1997";
f6f89c9
+const char *MD5_version ="MD5 part of SSLeay 0.8.1 19-Jul-1997";
fc985ec
 
fc985ec
 /* Implemented from RFC1321 The MD5 Message-Digest Algorithm
fc985ec
  */
f6f89c9
--- dhcp-3.0.5/omapip/alloc.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/omapip/alloc.c	2007-02-08 21:01:16.000000000 -0500
3c1d581
@@ -40,6 +40,41 @@
3c1d581
 
3c1d581
 #include <omapip/omapip_p.h>
3c1d581
 
3c1d581
+#ifdef LIBDHCP
3c1d581
+/* OK, we need a quick and dirty way of freeing all memory used by libdhcp. 
3c1d581
+   All pointers will be stored in a glibc tree on alloc, and removed on free.
3c1d581
+   This is not too expensive for light single-call library use.
3c1d581
+*/
3c1d581
+#include <search.h>  
3c1d581
+extern void tdestroy (void *root, void (*free_node)(void *nodep));
3c1d581
+static void *all_pointers=0L;
3c1d581
+static int ptr_comparator( const void *p1, const void *p2 )
3c1d581
+{
3c1d581
+    return
3c1d581
+	(  (p1 == p2) 
3c1d581
+	   ? 0
3c1d581
+	   :( (p1 > p2)
3c1d581
+	      ? 1
3c1d581
+	      : -1
3c1d581
+	    )
3c1d581
+	);
3c1d581
+}
3c1d581
+static void record_pointer( void *ptr )
3c1d581
+{
3c1d581
+    tsearch(ptr, &(all_pointers), ptr_comparator);
3c1d581
+}
3c1d581
+static void forget_pointer( void *ptr )
3c1d581
+{
3c1d581
+    tdelete(ptr, &(all_pointers), ptr_comparator);
3c1d581
+}
3c1d581
+void omapi_free_all_pointers(void)
3c1d581
+{
3c1d581
+    if( all_pointers != 0L )
3c1d581
+	tdestroy(all_pointers, free);
3c1d581
+    all_pointers = 0L;
3c1d581
+}
3c1d581
+#endif
3c1d581
+
3c1d581
 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
3c1d581
 		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
3c1d581
 struct dmalloc_preamble *dmalloc_list;
1270fb8
@@ -77,7 +112,9 @@
3c1d581
 		return (VOIDPTR)0;
3c1d581
 
3c1d581
 	foo = malloc(len);
3c1d581
-
3c1d581
+#ifdef LIBDHCP
3c1d581
+	record_pointer(foo);
3c1d581
+#endif
3c1d581
 	if (!foo)
3c1d581
 		return (VOIDPTR)0;
3c1d581
 	bar = (VOIDPTR)(foo + DMDOFFSET);
1270fb8
@@ -199,6 +236,9 @@
3c1d581
 		     0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);
3c1d581
 #endif
3c1d581
 	free (ptr);
3c1d581
+#ifdef LIBDHCP
3c1d581
+	forget_pointer(ptr);
3c1d581
+#endif
3c1d581
 }
3c1d581
 
3c1d581
 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
f6f89c9
--- dhcp-3.0.5/omapip/dispatch.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/omapip/dispatch.c	2007-02-08 21:01:16.000000000 -0500
3c1d581
@@ -34,7 +34,7 @@
3c1d581
 
3c1d581
 #include <omapip/omapip_p.h>
3c1d581
 
3c1d581
-static omapi_io_object_t omapi_io_states;
3c1d581
+omapi_io_object_t omapi_io_states;
3c1d581
 TIME cur_time;
3c1d581
 
3c1d581
 OMAPI_OBJECT_ALLOC (omapi_io,
f6f89c9
--- dhcp-3.0.5/omapip/errwarn.c.libdhcp4client	2007-02-08 21:01:16.000000000 -0500
f6f89c9
+++ dhcp-3.0.5/omapip/errwarn.c	2007-02-08 21:01:16.000000000 -0500
3c1d581
@@ -39,6 +39,11 @@
3c1d581
 #include <omapip/omapip_p.h>
3c1d581
 #include <errno.h>
3c1d581
 
3c1d581
+#ifdef LIBDHCP
3c1d581
+#include <libdhcp_control.h>
3c1d581
+extern LIBDHCP_Control *libdhcp_control;
3c1d581
+#endif
3c1d581
+
3c1d581
 #ifdef DEBUG
3c1d581
 int log_perror = -1;
3c1d581
 #else
3c1d581
@@ -50,7 +55,9 @@
3c1d581
 void (*log_cleanup) (void);
3c1d581
 
3c1d581
 #define CVT_BUF_MAX 1023
3c1d581
+#ifndef LIBDHCP
3c1d581
 static char mbuf [CVT_BUF_MAX + 1];
3c1d581
+#endif
3c1d581
 static char fbuf [CVT_BUF_MAX + 1];
3c1d581
 
3c1d581
 /* Log an error message, then exit... */
3c1d581
@@ -60,6 +67,17 @@
3c1d581
   va_list list;
3c1d581
 
3c1d581
   do_percentm (fbuf, fmt);
3c1d581
+  
3c1d581
+#ifdef LIBDHCP
3c1d581
+  if ( libdhcp_control && (libdhcp_control->eh) )
3c1d581
+  {
3c1d581
+      va_start (list, fmt);
3c1d581
+      libdhcp_control->eh(libdhcp_control, LOG_FATAL, fbuf, list);
3c1d581
+      va_end(list);
3c1d581
+      libdhcp_control->finished = 1;
3c1d581
+      return;
3c1d581
+  }
3c1d581
+#else
3c1d581
 
3c1d581
   /* %Audit% This is log output. %2004.06.17,Safe%
3c1d581
    * If we truncate we hope the user can get a hint from the log.
3c1d581
@@ -108,6 +126,7 @@
3c1d581
   if (log_cleanup)
3c1d581
 	  (*log_cleanup) ();
3c1d581
   exit (1);
3c1d581
+#endif
3c1d581
 }
3c1d581
 
3c1d581
 /* Log an error message... */
3c1d581
@@ -118,6 +137,14 @@
3c1d581
 
3c1d581
   do_percentm (fbuf, fmt);
3c1d581
 
3c1d581
+#ifdef LIBDHCP
3c1d581
+  if ( libdhcp_control && libdhcp_control->eh )
3c1d581
+  {
3c1d581
+      va_start (list, fmt);
3c1d581
+      libdhcp_control->eh(libdhcp_control, LOG_ERR, fbuf, list);
3c1d581
+      va_end(list);
3c1d581
+  }
3c1d581
+#else
3c1d581
   /* %Audit% This is log output. %2004.06.17,Safe%
3c1d581
    * If we truncate we hope the user can get a hint from the log.
3c1d581
    */
3c1d581
@@ -134,7 +161,7 @@
3c1d581
 	  r=write (STDERR_FILENO, mbuf, strlen (mbuf));
3c1d581
 	  r=write (STDERR_FILENO, "\n", 1);
3c1d581
   }
3c1d581
-
3c1d581
+#endif
3c1d581
   return 0;
3c1d581
 }
3c1d581
 
3c1d581
@@ -146,6 +173,14 @@
3c1d581
 
3c1d581
   do_percentm (fbuf, fmt);
3c1d581
 
3c1d581
+#ifdef LIBDHCP
3c1d581
+  if ( libdhcp_control && libdhcp_control->eh )
3c1d581
+  {
3c1d581
+      va_start (list, fmt);
3c1d581
+      libdhcp_control->eh(libdhcp_control, LOG_INFO, fbuf, list);
3c1d581
+      va_end(list);
3c1d581
+  }
3c1d581
+#else
3c1d581
   /* %Audit% This is log output. %2004.06.17,Safe%
3c1d581
    * If we truncate we hope the user can get a hint from the log.
3c1d581
    */
3c1d581
@@ -162,7 +197,7 @@
3c1d581
 	  r=write (STDERR_FILENO, mbuf, strlen (mbuf));
3c1d581
 	  r=write (STDERR_FILENO, "\n", 1);
3c1d581
   }
3c1d581
-
3c1d581
+#endif
3c1d581
   return 0;
3c1d581
 }
3c1d581
 
3c1d581
@@ -173,7 +208,14 @@
3c1d581
   va_list list;
3c1d581
 
3c1d581
   do_percentm (fbuf, fmt);
3c1d581
-
3c1d581
+#ifdef LIBDHCP
3c1d581
+  if ( libdhcp_control && libdhcp_control->eh )
3c1d581
+  {
3c1d581
+      va_start (list, fmt);
3c1d581
+      libdhcp_control->eh(libdhcp_control, LOG_DEBUG, fbuf, list);
3c1d581
+      va_end(list);
3c1d581
+  }
3c1d581
+#else
3c1d581
   /* %Audit% This is log output. %2004.06.17,Safe%
3c1d581
    * If we truncate we hope the user can get a hint from the log.
3c1d581
    */
3c1d581
@@ -190,7 +232,7 @@
3c1d581
 	  r=write (STDERR_FILENO, mbuf, strlen (mbuf));
3c1d581
 	  r=write (STDERR_FILENO, "\n", 1);
3c1d581
   }
3c1d581
-
3c1d581
+#endif
3c1d581
   return 0;
3c1d581
 }
3c1d581
 
3c1d581
--- dhcp-3.0.5/configure.libdhcp4client	2004-09-10 17:02:30.000000000 -0400
f6f89c9
+++ dhcp-3.0.5/configure	2007-02-08 21:01:16.000000000 -0500
3c1d581
@@ -246,7 +246,7 @@
3c1d581
 fi
3c1d581
 
3c1d581
 if [ x"$dirs" = x ]; then
3c1d581
-  dirs=". client server relay common omapip dhcpctl minires dst"
3c1d581
+  dirs=". client server relay common omapip dhcpctl minires dst libdhcp4client"
3c1d581
 fi
3c1d581
 
3c1d581
 for foo in $dirs; do
f6f89c9
--- /dev/null	2007-02-06 10:40:24.955607220 -0500
f6f89c9
+++ dhcp-3.0.5/libdhcp4client/Makefile.dist	2007-02-08 21:12:41.000000000 -0500
1270fb8
@@ -0,0 +1,127 @@
3c1d581
+# Makefile.dist for libdhcp4client
3c1d581
+#
3c1d581
+# We get the libdhcp4client library from the patched ISC source code.  We
3c1d581
+# rebuild key C files with -DLIBDHCP to turn on the library features we
3c1d581
+# need.  Normal build results in standard ISC code (i.e., not LIBDHCP
3c1d581
+# stuff enabled).  We then link together a static library and a shared
3c1d581
+# library with the new resulting objects.
3c1d581
+#
3c1d581
+# David Cantrell <dcantrell@redhat.com>
3c1d581
+
fc985ec
+# What version of ISC DHCP is this?
fc985ec
+VER   = $(shell grep DHCP_VERSION ../../includes/version.h | head -1 | cut -d '"' -f 2 | cut -d 'V' -f 2 | cut -d '-' -f 1)
fc985ec
+
fc985ec
+PROGS = libdhcp4client.a libdhcp4client-$(VER).so.0
fc985ec
+
fc985ec
+# NOTE: The ordering of these file lists is important!  We are using the
fc985ec
+# whole program optimization features of gcc, so the order matters here.
fc985ec
+
fc985ec
+# Source files shared by all objects
fc985ec
+COMMON_SRCS = client_clparse.c client_dhclient.c common_alloc.c common_bpf.c \
fc985ec
+              common_comapi.c common_conflex.c common_discover.c \
fc985ec
+              common_dispatch.c common_dns.c common_ethernet.c \
fc985ec
+              common_execute.c common_inet.c common_lpf.c common_memory.c \
fc985ec
+              common_options.c common_packet.c common_parse.c common_print.c \
fc985ec
+              common_socket.c common_tables.c common_tr.c common_tree.c \
fc985ec
+              dst_dst_api.c dst_base64.c dst_hmac_link.c dst_md5_dgst.c \
fc985ec
+              omapip_alloc.c omapip_array.c omapip_auth.c omapip_buffer.c \
fc985ec
+              omapip_connection.c omapip_convert.c omapip_dispatch.c \
fc985ec
+              omapip_errwarn.c omapip_handle.c omapip_hash.c \
fc985ec
+              omapip_listener.c omapip_mrtrace.c omapip_result.c \
fc985ec
+              omapip_support.c omapip_toisc.c omapip_trace.c
fc985ec
+
fc985ec
+# Source files for libdhcp4client.o
fc985ec
+CLIENT_SRCS = common_ctrace.c common_dlpi.c common_nit.c common_upf.c \
fc985ec
+              dst_dst_support.c dst_prandom.c omapip_generic.c \
fc985ec
+              omapip_message.c omapip_protocol.c
fc985ec
+
fc985ec
+# Source files for libres.o (minires)
fc985ec
+MINIRES_SRCS = minires_ns_date.c minires_ns_name.c minires_ns_parse.c \
fc985ec
+               minires_ns_samedomain.c minires_ns_sign.c minires_ns_verify.c \
fc985ec
+               minires_res_comp.c minires_res_findzonecut.c \
fc985ec
+               minires_res_init.c minires_res_mkquery.c \
fc985ec
+               minires_res_mkupdate.c minires_res_query.c minires_res_send.c \
fc985ec
+               minires_res_sendsigned.c minires_res_update.c
fc985ec
+
fc985ec
+HDRS = dhcp4client.h libdhcp_control.h
fc985ec
+SRCS = $(COMMON_SRCS) $(CLIENT_SRCS)
fc985ec
+OBJS = $(SRCS:.c=.o)
3c1d581
+
86a07e1
+INCLUDES = -I$(TOP) -I$(TOP)/includes -I$(TOP)/dst -I.
3c1d581
+CFLAGS   = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS) \
1270fb8
+           -DCLIENT_PATH=${CLIENT_PATH} -DLIBDHCP -DUSE_MD5
3c1d581
+
3c1d581
+all: $(PROGS)
3c1d581
+
3c1d581
+install: all
fc985ec
+	install -p -m 0755 -D libdhcp4client-$(VER).so.0 $(DESTDIR)$(LIBDIR)/libdhcp4client-$(VER).so.0
fc985ec
+	ln -sf libdhcp4client-$(VER).so.0 $(DESTDIR)/$(LIBDIR)/libdhcp4client.so
3c1d581
+	install -p -m 0644 -D libdhcp4client.a $(DESTDIR)$(LIBDIR)/libdhcp4client.a
3c1d581
+	install -p -m 0644 -D dhcp4client.h $(DESTDIR)$(INCDIR)/dhcp4client/dhcp4client.h
3c1d581
+	install -p -m 0644 -D libdhcp_control.h $(DESTDIR)$(INCDIR)/dhcp4client/libdhcp_control.h
3c1d581
+	( cd $(TOP)/includes ; \
3c1d581
+	  find . -name "*.h" -type f | while read h ; do \
3c1d581
+	      install -p -m 0644 -D $$h $(DESTDIR)$(INCDIR)/dhcp4client/isc_dhcp/$$h ; \
3c1d581
+	  done ; \
3c1d581
+	)
3c1d581
+
3c1d581
+depend:
3c1d581
+	$(MKDEP) $(INCLUDES) $(PREDEFINES) $(SRCS)
3c1d581
+
3c1d581
+clean:
3c1d581
+	-rm -f $(OBJS)
3c1d581
+
3c1d581
+realclean: clean
3c1d581
+	-rm -f $(PROG) *~ #*
3c1d581
+
3c1d581
+distclean: realclean
3c1d581
+	-rm -f Makefile
3c1d581
+
3c1d581
+# This isn't the cleanest way to set up links, but I prefer this so I don't
3c1d581
+# need object targets for each subdirectory.  The idea is simple.  Since
3c1d581
+# libdhcp4client is a linked together wad of objects from across the source
3c1d581
+# tree, we change / to _ when linking source files here.  Follow this example:
3c1d581
+#
3c1d581
+# We need to use client/dhclient.c, so we make this link:
3c1d581
+#     rm -f client_dhclient.c
3c1d581
+#     ln -s $(TOP)/client/dhclient.c client_dhclient.c
3c1d581
+#
3c1d581
+# Simple.  Given the way the ISC build system works, this is the easiest to
3c1d581
+# maintain and least invasive.
3c1d581
+#
3c1d581
+# David Cantrell <dcantrell@redhat.com>
3c1d581
+links:
3c1d581
+	@for target in $(SRCS); do \
3c1d581
+		source="`echo $$target | sed -e 's|_|/|'`"; \
3c1d581
+		if [ ! -b $$target ]; then \
3c1d581
+			rm -f $$target; \
3c1d581
+		fi; \
3c1d581
+		ln -s $(TOP)/$$source $$target; \
3c1d581
+	done; \
3c1d581
+	for hdr in $(HDRS); do \
3c1d581
+		if [ ! -b $$hdr ]; then \
3c1d581
+			rm -f $$hdr; \
3c1d581
+		fi; \
3c1d581
+		ln -s $(TOP)/libdhcp4client/$$hdr $$hdr; \
3c1d581
+	done
3c1d581
+
86a07e1
+# minires is difficult to build because it overrides things in common and dst,
86a07e1
+# so we just link with the already built libres.a since we need it all anyway
86a07e1
+libres.a:
86a07e1
+	if [ ! -f ../minires/$@ ]; then \
86a07e1
+		$(MAKE) -C ../minires; \
86a07e1
+	fi; \
86a07e1
+	ln ../minires/libres.a .; \
86a07e1
+	$(AR) x libres.a
86a07e1
+
fc985ec
+# Create the libraries
3c1d581
+# minires/res_query.o contains an undefined symbol __h_errno_set, is not
3c1d581
+# used by any dhcp code, and is optimized out by the linker when producing
3c1d581
+# the dhclient executable or a shared library
86a07e1
+libdhcp4client.a: $(OBJS) libres.a
a914f34
+	$(AR) crus $@ $(OBJS) `$(AR) t libres.a | grep -v res_query.o`
3c1d581
+
fc985ec
+libdhcp4client-$(VER).so.0: $(OBJS) libres.a
a914f34
+	$(CC) -shared -o $@ -Wl,-soname,$@ $(OBJS) `$(AR) t libres.a | grep -v res_query.o`
3c1d581
+
3c1d581
+# Dependencies (semi-automatically-generated)
f6f89c9
--- /dev/null	2007-02-06 10:40:24.955607220 -0500
f6f89c9
+++ dhcp-3.0.5/libdhcp4client/dhcp4client.h	2007-02-08 21:01:16.000000000 -0500
3c1d581
@@ -0,0 +1,24 @@
3c1d581
+/* dhcp4client.h
3c1d581
+ *
3c1d581
+ *  Interface to the ISC dhcp IPv4 client libdhcp4client library.
3c1d581
+ *
3c1d581
+ *
3c1d581
+ *  Copyright(C) Jason Vas Dias <jvdias@redhat.com> Red Hat Inc. May 2006
3c1d581
+ *
3c1d581
+ *  This program is free software; you can redistribute it and/or modify
3c1d581
+ *  it under the terms of the GNU General Public License as published by
3c1d581
+ *  the Free Software Foundation at 
3c1d581
+ *           http://www.fsf.org/licensing/licenses/gpl.txt
3c1d581
+ *  and included in this software distribution as the "LICENSE" file.
3c1d581
+ *
3c1d581
+ *  This program is distributed in the hope that it will be useful,
3c1d581
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
3c1d581
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3c1d581
+ *  GNU General Public License for more details.
3c1d581
+ */
3c1d581
+
3c1d581
+struct libdhcp_control_s;  /* include libdhcp_control.h or libdhcp.h for this */
3c1d581
+
3c1d581
+extern int dhcpv4_client( struct libdhcp_control_s *dhc_ctl, int argc, char **argv, char **envp);
3c1d581
+    /* The ISC IPv4 DHCP client main() function .
3c1d581
+     */
f6f89c9
--- /dev/null	2007-02-06 10:40:24.955607220 -0500
f6f89c9
+++ dhcp-3.0.5/libdhcp4client/libdhcp_control.h	2007-02-08 21:01:16.000000000 -0500
3c1d581
@@ -0,0 +1,102 @@
3c1d581
+/* libdhcp_control.h
3c1d581
+ *
3c1d581
+ *  DHCP client control API for libdhcp, a minimal interface to the
3c1d581
+ *  ISC dhcp IPv4 client libdhcp4client library,
3c1d581
+ *  and to the dhcpv6 DHCPv6 client libdhcp6client library.
3c1d581
+ *
3c1d581
+ *  Each DHCP client library must include this file to be controlled
3c1d581
+ *  by libdhcp.
3c1d581
+ *
3c1d581
+ *  Copyright(C) Jason Vas Dias <jvdias@redhat.com> Red Hat Inc. May 2006
3c1d581
+ *
3c1d581
+ *  This program is free software; you can redistribute it and/or modify
3c1d581
+ *  it under the terms of the GNU General Public License as published by
3c1d581
+ *  the Free Software Foundation at 
3c1d581
+ *           http://www.fsf.org/licensing/licenses/gpl.txt
3c1d581
+ *  and included in this software distribution as the "LICENSE" file.
3c1d581
+ *
3c1d581
+ *  This program is distributed in the hope that it will be useful,
3c1d581
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
3c1d581
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3c1d581
+ *  GNU General Public License for more details.
3c1d581
+ */
3c1d581
+#ifndef LIBDHCP_CONTROL_H
3c1d581
+#define LIBDHCP_CONTROL_H
3c1d581
+
3c1d581
+#include <stdint.h>
3c1d581
+
3c1d581
+#define  LOG_FATAL 8
3c1d581
+
3c1d581
+typedef enum dhcp_state_e
3c1d581
+{
3c1d581
+
3c1d581
+    /* DHCPv4 client states - third callback arg will be a 'struct client_state *'    */
3c1d581
+    DHC4_NBI,         		/* failed: no broadcast interfaces found              */
3c1d581
+    DHC4_PREINIT, 		/* configuration started - bring the interface "UP"   */
3c1d581
+    DHC4_BOUND, 		/* lease obtained                                     */
3c1d581
+    DHC4_RENEW, 		/* lease renewed                                      */
3c1d581
+    DHC4_REBOOT,	        /* have valid lease, but now obtained a different one */
3c1d581
+    DHC4_REBIND, 		/* new, different lease                               */
3c1d581
+    DHC4_STOP,  		/* remove old lease                                   */
3c1d581
+    DHC4_MEDIUM, 		/* media selection begun                              */
3c1d581
+    DHC4_TIMEOUT, 		/* timed out contacting DHCP server                   */
3c1d581
+    DHC4_FAIL, 			/* all attempts to contact server timed out, sleeping */
3c1d581
+    DHC4_EXPIRE, 		/* lease has expired, renewing                        */
3c1d581
+    DHC4_RELEASE, 		/* releasing lease                                    */
3c1d581
+    /* This state raised by both clients: */
3c1d581
+    DHC_TIMEDOUT,               /* libdhcp_control timeout has been exceeded          */
3c1d581
+    /* DHCPv6 client states:    */
3c1d581
+    DHC6_BOUND,                 /* new lease obtained             - arg is optinfo *  */
3c1d581
+    DHC6_REBIND,                /* existing expired lease rebound - arg is optinfo *  */
3c1d581
+    DHC6_RELEASE                /* existing lease expired         - arg is dhcp6_iaidaddr*/
3c1d581
+} DHCP_State;
3c1d581
+
3c1d581
+struct libdhcp_control_s;
3c1d581
+
3c1d581
+typedef
3c1d581
+int ( *LIBDHCP_Error_Handler )
3c1d581
+    ( struct libdhcp_control_s *ctl,
3c1d581
+      int priority,  /* ala syslog(3): LOG_EMERG=0 - LOG_DEBUG=7 (+ LOG_FATAL=8 : finished -> 1)   */
3c1d581
+      const char *fmt,
3c1d581
+      va_list ap
3c1d581
+    );
3c1d581
+
3c1d581
+typedef 
3c1d581
+int ( *LIBDHCP_Callback ) ( struct libdhcp_control_s *control, enum dhcp_state_e, void* );
3c1d581
+    /* The DHCP clients will call the users' callback on important state change events,
3c1d581
+     * with the second arg set to the client DHCP_State, and the third arg set to
3c1d581
+     * a client specific pointer as described below.
3c1d581
+     */
3c1d581
+
3c1d581
+typedef 
3c1d581
+struct libdhcp_control_s
3c1d581
+{
3c1d581
+    LIBDHCP_Callback    callback;    	/* the DHCP clients' main loop calls this on state changes */
3c1d581
+    uint16_t            capability;     /* LIBDHCP_Capability bits to enable                       */
3c1d581
+    uint8_t             finished;       /* set to one to make clients exit their main loop         */
3c1d581
+    uint8_t             decline;        /* set to one to decline the lease (DHCPv4 only)           */
3c1d581
+    time_t              timeout;        /* (timeout+now) == time after which clients MUST return   */
3c1d581
+    time_t              now;            /* clients set this to time(0) on entering main loop       */
3c1d581
+    void               *arg;            /* user data pointer                                       */
3c1d581
+    LIBDHCP_Error_Handler eh;
3c1d581
+} LIBDHCP_Control;
3c1d581
+
3c1d581
+typedef enum libdhcp_capability_e
3c1d581
+{/* DHCP client "capabilities" */ 
3c1d581
+    DHCP_USE_LEASE_DATABASE   = 1,  	/* use / do not use persistent lease database files */
3c1d581
+    DHCP_USE_PID_FILE         = 2,  	/* use / do not use pid file                        */
3c1d581
+ /*
3c1d581
+  * DHCPv6 supports these capabilities in process, 
3c1d581
+  * while the DHCPv4 client will fork and exec the dhclient-script to implement them if these
3c1d581
+  * bits are set - otherwise, if no bits are set, the callback is called and the script is 
3c1d581
+  * not run.
3c1d581
+  */
3c1d581
+    DHCP_CONFIGURE_INTERFACES = 4,  	/* configure interfaces UP/DOWN as required         */
3c1d581
+    DHCP_CONFIGURE_ADDRESSES  = 8,  	/* configure interface addresses as required        */
3c1d581
+    DHCP_CONFIGURE_ROUTES     =16,  	/* configure routes as required                     */
3c1d581
+    DHCP_CONFIGURE_RESOLVER   =32,  	/* configure resolv.conf as required                */
3c1d581
+    /* DHCPv6 only: */
3c1d581
+    DHCP_CONFIGURE_RADVD      =64,  	/* configure radvd.conf & restart radvd as required */
3c1d581
+} LIBDHCP_Capability;
3c1d581
+
3c1d581
+#endif
3c1d581
--- dhcp-3.0.5/Makefile.dist.libdhcp4client	2004-06-10 13:59:10.000000000 -0400
f6f89c9
+++ dhcp-3.0.5/Makefile.dist	2007-02-08 21:01:16.000000000 -0500
3c1d581
@@ -22,7 +22,7 @@
3c1d581
 #   http://www.isc.org/
3c1d581
 
3c1d581
 
3c1d581
-SUBDIRS=	common $(MINIRES) dst omapip server client relay dhcpctl
3c1d581
+SUBDIRS=	common $(MINIRES) dst omapip server client relay dhcpctl libdhcp4client
3c1d581
 
3c1d581
 all:
3c1d581
 	@for dir in ${SUBDIRS}; do \