am 1f1ef57e: DHCPDC: Actually we do have a monotonic clock...

* commit '1f1ef57e839d72b24bb2f43b602ecf63e1068010':
  DHCPDC: Actually we do have a monotonic clock...
diff --git a/client.c b/client.c
deleted file mode 100644
index 90657b3..0000000
--- a/client.c
+++ /dev/null
@@ -1,1854 +0,0 @@
-/* 
- * dhcpcd - DHCP client daemon
- * Copyright 2006-2008 Roy Marples <roy@marples.name>
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-
-#ifdef __linux__
-# include <netinet/ether.h>
-#endif
-
-#include <errno.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "common.h"
-#include "client.h"
-#include "configure.h"
-#include "dhcp.h"
-#include "dhcpcd.h"
-#include "net.h"
-#include "logger.h"
-#include "signals.h"
-
-#define IPV4LL_LEASETIME 	2
-
-/* Some platforms don't define INFTIM */
-#ifndef INFTIM
-# define INFTIM                 -1
-#endif
-
-#define STATE_INIT              0
-#define STATE_DISCOVERING	1
-#define STATE_REQUESTING        2
-#define STATE_BOUND             3
-#define STATE_RENEWING          4
-#define STATE_REBINDING         5
-#define STATE_REBOOT            6
-#define STATE_RENEW_REQUESTED   7
-#define STATE_INIT_IPV4LL	8
-#define STATE_PROBING		9
-#define STATE_ANNOUNCING	10
-
-/* Constants taken from RFC 2131. */
-#define T1			0.5
-#define T2			0.875
-#define DHCP_BASE		4
-#define DHCP_MAX		64
-#define DHCP_RAND_MIN		-1
-#define DHCP_RAND_MAX		1
-#define DHCP_ARP_FAIL		10
-
-/* We should define a maximum for the NAK exponential backoff */ 
-#define NAKOFF_MAX              60
-
-#define SOCKET_CLOSED           0
-#define SOCKET_OPEN             1
-
-/* These are for IPV4LL, RFC 3927. */
-#define PROBE_WAIT		 1
-#define PROBE_NUM		 3
-#define PROBE_MIN		 1
-#define PROBE_MAX		 2
-#define ANNOUNCE_WAIT		 2
-/* BSD systems always do a grauitous ARP when assigning an address,
- * so we can do one less announce. */
-#ifdef BSD
-# define ANNOUNCE_NUM		 1
-#else
-# define ANNOUNCE_NUM		 2
-#endif
-#define ANNOUNCE_INTERVAL	 2
-#define MAX_CONFLICTS		10
-#define RATE_LIMIT_INTERVAL	60
-#define DEFEND_INTERVAL		10
-
-
-/* number of usecs in a second. */
-#define USECS_SECOND		1000000
-/* As we use timevals, we should use the usec part for
- * greater randomisation. */
-#define DHCP_RAND_MIN_U		DHCP_RAND_MIN * USECS_SECOND
-#define DHCP_RAND_MAX_U		DHCP_RAND_MAX * USECS_SECOND
-#define PROBE_MIN_U		PROBE_MIN * USECS_SECOND
-#define PROBE_MAX_U		PROBE_MAX * USECS_SECOND
-
-#define timernorm(tvp)						\
-	do {							\
-		while ((tvp)->tv_usec >= 1000000) {		\
-			(tvp)->tv_sec++;			\
-			(tvp)->tv_usec -= 1000000;		\
-		}						\
-	} while (0 /* CONSTCOND */);
-
-#define timerneg(tvp)	((tvp)->tv_sec < 0 || (tvp)->tv_usec < 0)
-
-struct if_state {
-	int options;
-	struct interface *interface;
-	struct dhcp_message *offer;
-	struct dhcp_message *new;
-	struct dhcp_message *old;
-	struct dhcp_lease lease;
-	struct timeval timeout;
-	struct timeval stop;
-	struct timeval exit;
-	int state;
-	int messages;
-	time_t nakoff;
-	uint32_t xid;
-	int socket;
-	int *pid_fd;
-	int signal_fd;
-	int carrier;
-	int probes;
-	int claims;
-	int conflicts;
-	time_t defend;
-	struct in_addr fail;
-};
-
-#define LINK_UP 	1
-#define LINK_UNKNOWN	0
-#define LINK_DOWN 	-1
-
-struct dhcp_op {
-        uint8_t value;
-        const char *name;
-};
-
-static const struct dhcp_op const dhcp_ops[] = {
-	{ DHCP_DISCOVER, "DHCP_DISCOVER" },
-	{ DHCP_OFFER,    "DHCP_OFFER" },
-	{ DHCP_REQUEST,  "DHCP_REQUEST" },
-	{ DHCP_DECLINE,  "DHCP_DECLINE" },
-	{ DHCP_ACK,      "DHCP_ACK" },
-	{ DHCP_NAK,      "DHCP_NAK" },
-	{ DHCP_RELEASE,  "DHCP_RELEASE" },
-	{ DHCP_INFORM,   "DHCP_INFORM" },
-	{ 0, NULL }
-};
-
-static const char *
-get_dhcp_op(uint8_t type)
-{
-	const struct dhcp_op *d;
-
-	for (d = dhcp_ops; d->name; d++)
-		if (d->value == type)
-			return d->name;
-	return NULL;
-}
-
-#ifdef THERE_IS_NO_FORK
-#define daemonise(a,b) 0
-#else
-static int
-daemonise(struct if_state *state, const struct options *options)
-{
-	pid_t pid;
-	sigset_t full;
-	sigset_t old;
-	char buf = '\0';
-	int sidpipe[2];
-
-	if (state->options & DHCPCD_DAEMONISED ||
-	    !(options->options & DHCPCD_DAEMONISE))
-		return 0;
-
-	sigfillset(&full);
-	sigprocmask(SIG_SETMASK, &full, &old);
-
-	/* Setup a signal pipe so parent knows when to exit. */
-	if (pipe(sidpipe) == -1) {
-		logger(LOG_ERR,"pipe: %s", strerror(errno));
-		return -1;
-	}
-
-	logger(LOG_DEBUG, "forking to background");
-	switch (pid = fork()) {
-		case -1:
-			logger(LOG_ERR, "fork: %s", strerror(errno));
-			exit(EXIT_FAILURE);
-			/* NOTREACHED */
-		case 0:
-			setsid();
-			/* Notify parent it's safe to exit as we've detached. */
-			close(sidpipe[0]);
-			if (write(sidpipe[1], &buf, 1) != 1)
-				logger(LOG_ERR, "write: %s", strerror(errno));
-			close(sidpipe[1]);
-			close_fds();
-			break;
-		default:
-			/* Reset signals as we're the parent about to exit. */
-			signal_reset();
-			/* Wait for child to detach */
-			close(sidpipe[1]);
-			if (read(sidpipe[0], &buf, 1) != 1)
-				logger(LOG_ERR, "read: %s", strerror(errno));
-			close(sidpipe[0]);
-			break;
-	}
-
-	/* Done with the fd now */
-	if (pid != 0) {
-		writepid(*state->pid_fd, pid);
-		close(*state->pid_fd);
-		*state->pid_fd = -1;
-	}
-
-	sigprocmask(SIG_SETMASK, &old, NULL);
-	if (pid == 0) {
-		state->options |= DHCPCD_DAEMONISED;
-		timerclear(&state->exit);
-		return 0;
-	}
-	state->options |= DHCPCD_PERSISTENT | DHCPCD_FORKED;
-	return -1;
-}
-#endif
-
-#define THIRTY_YEARS_IN_SECONDS    946707779
-static size_t
-get_duid(unsigned char *duid, const struct interface *iface)
-{
-	FILE *f;
-	uint16_t type = 0;
-	uint16_t hw = 0;
-	uint32_t ul;
-	time_t t;
-	int x = 0;
-	unsigned char *p = duid;
-	size_t len = 0, l = 0;
-	char *buffer = NULL, *line, *option;
-
-	/* If we already have a DUID then use it as it's never supposed
-	 * to change once we have one even if the interfaces do */
-	if ((f = fopen(DUID, "r"))) {
-		while ((get_line(&buffer, &len, f))) {
-			line = buffer;
-			while ((option = strsep(&line, " \t")))
-				if (*option != '\0')
-					break;
-			if (!option || *option == '\0' || *option == '#')
-				continue;
-			l = hwaddr_aton(NULL, option);
-			if (l && l <= DUID_LEN) {
-				hwaddr_aton(duid, option);
-				break;
-			}
-			l = 0;
-		}
-		fclose(f);
-		free(buffer);
-		if (l)
-			return l;
-	} else {
-		if (errno != ENOENT)
-			return 0;
-	}
-
-	/* No file? OK, lets make one based on our interface */
-	if (!(f = fopen(DUID, "w")))
-		return 0;
-	type = htons(1); /* DUI-D-LLT */
-	memcpy(p, &type, 2);
-	p += 2;
-	hw = htons(iface->family);
-	memcpy(p, &hw, 2);
-	p += 2;
-	/* time returns seconds from jan 1 1970, but DUID-LLT is
-	 * seconds from jan 1 2000 modulo 2^32 */
-	t = time(NULL) - THIRTY_YEARS_IN_SECONDS;
-	ul = htonl(t & 0xffffffff);
-	memcpy(p, &ul, 4);
-	p += 4;
-	/* Finally, add the MAC address of the interface */
-	memcpy(p, iface->hwaddr, iface->hwlen);
-	p += iface->hwlen;
-	len = p - duid;
-	x = fprintf(f, "%s\n", hwaddr_ntoa(duid, len));
-	fclose(f);
-	/* Failed to write the duid? scrub it, we cannot use it */
-	if (x < 1) {
-		len = 0;
-		unlink(DUID);
-	}
-	return len;
-}
-
-static struct dhcp_message*
-ipv4ll_get_dhcp(uint32_t old_addr)
-{
-	uint32_t u32;
-	struct dhcp_message *dhcp;
-	uint8_t *p;
-
-	dhcp = xzalloc(sizeof(*dhcp));
-	/* Put some LL options in */
-	p = dhcp->options;
-	*p++ = DHO_SUBNETMASK;
-	*p++ = sizeof(u32);
-	u32 = htonl(LINKLOCAL_MASK);
-	memcpy(p, &u32, sizeof(u32));
-	p += sizeof(u32);
-	*p++ = DHO_BROADCAST;
-	*p++ = sizeof(u32);
-	u32 = htonl(LINKLOCAL_BRDC);
-	memcpy(p, &u32, sizeof(u32));
-	p += sizeof(u32);
-	*p++ = DHO_END;
-
-	for (;;) {
-		dhcp->yiaddr = htonl(LINKLOCAL_ADDR |
-				     (((uint32_t)abs((int)arc4random())
-				       % 0xFD00) + 0x0100));
-		if (dhcp->yiaddr != old_addr &&
-		    IN_LINKLOCAL(ntohl(dhcp->yiaddr)))
-			break;
-	}
-	return dhcp;
-}
-
-static double
-timeval_to_double(struct timeval *tv)
-{
-	return tv->tv_sec * 1.0 + tv->tv_usec * 1.0e-6;
-}
-
-static void
-get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
-{
-	time_t t;
-
-	if (lease->frominfo)
-		return;
-	lease->addr.s_addr = dhcp->yiaddr;
-
-	if (get_option_addr(&lease->net, dhcp, DHO_SUBNETMASK) == -1)
-		lease->net.s_addr = get_netmask(dhcp->yiaddr);
-	if (get_option_uint32(&lease->leasetime, dhcp, DHO_LEASETIME) == 0) {
-		/* Ensure that we can use the lease */
-		t = 0;
-		if (t + (time_t)lease->leasetime < t) {
-			logger(LOG_WARNING, "lease of %u would overflow, "
-			       "treating as infinite", lease->leasetime);
-			lease->leasetime = ~0U; /* Infinite lease */
-		}
-	} else
-		lease->leasetime = DEFAULT_LEASETIME;
-	if (get_option_uint32(&lease->renewaltime, dhcp, DHO_RENEWALTIME) != 0)
-		lease->renewaltime = 0;
-	if (get_option_uint32(&lease->rebindtime, dhcp, DHO_REBINDTIME) != 0)
-		lease->rebindtime = 0;
-}
-
-static int
-get_old_lease(struct if_state *state)
-{
-	struct interface *iface = state->interface;
-	struct dhcp_lease *lease = &state->lease;
-	struct dhcp_message *dhcp = NULL;
-	struct timeval tv;
-	unsigned int offset = 0;
-	struct stat sb;
-
-	if (stat(iface->leasefile, &sb) == -1) {
-		if (errno != ENOENT)
-			logger(LOG_ERR, "stat: %s", strerror(errno));
-		goto eexit;
-	}
-	if (!IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
-		logger(LOG_INFO, "trying to use old lease in `%s'",
-		       iface->leasefile);
-	if ((dhcp = read_lease(iface)) == NULL) {
-		logger(LOG_INFO, "read_lease: %s", strerror(errno));
-		goto eexit;
-	}
-	lease->frominfo = 0;
-	get_lease(&state->lease, dhcp);
-	lease->frominfo = 1;
-	lease->leasedfrom = sb.st_mtime;
-
-	/* Vitaly important we remove the server information here */
-	state->lease.server.s_addr = 0;
-	dhcp->servername[0] = '\0';
-
-	if (!IN_LINKLOCAL(ntohl(dhcp->yiaddr))) {
-		if (!(state->options & DHCPCD_LASTLEASE))
-			goto eexit;
-
-		/* Ensure that we can still use the lease */
-		if (gettimeofday(&tv, NULL) == -1) {
-			logger(LOG_ERR, "gettimeofday: %s", strerror(errno));
-			goto eexit;
-		}
-
-		offset = tv.tv_sec - lease->leasedfrom;
-		if (lease->leasedfrom &&
-		    tv.tv_sec - lease->leasedfrom > (time_t)lease->leasetime)
-		{
-			logger(LOG_ERR, "lease expired %u seconds ago",
-			       offset + lease->leasetime);
-			/* Persistent interfaces should still try and use the
-			 * lease if we can't contact a DHCP server.
-			 * We just set the timeout to 1 second. */
-			if (state->options & DHCPCD_PERSISTENT)
-				offset = lease->renewaltime - 1;
-			else
-				goto eexit;
-		}
-		lease->leasetime -= offset;
-		lease->rebindtime -= offset;
-		lease->renewaltime -= offset;
-	}
-
-	free(state->old);
-	state->old = state->new;
-	state->new = NULL;
-	state->offer = dhcp;
-	return 0;
-
-eexit:
-	lease->addr.s_addr = 0;
-	free(dhcp);
-	return -1;
-}
-
-static int
-client_setup(struct if_state *state, const struct options *options)
-{
-	struct interface *iface = state->interface;
-	struct dhcp_lease *lease = &state->lease;
-	struct in_addr addr;
-	struct timeval tv;
-	size_t len = 0;
-	unsigned char *duid = NULL;
-	uint32_t ul;
-
-	state->state = STATE_INIT;
-	state->nakoff = 1;
-	state->options = options->options;
-	timerclear(&tv);
-
-	if (options->request_address.s_addr == 0 &&
-	    (options->options & DHCPCD_INFORM ||
-	     options->options & DHCPCD_REQUEST ||
-	     (options->options & DHCPCD_DAEMONISED &&
-	      !(options->options & DHCPCD_BACKGROUND))))
-	{
-		if (get_old_lease(state) != 0)
-			return -1;
-		timerclear(&state->timeout);
-
-		if (!(options->options & DHCPCD_DAEMONISED) &&
-		    IN_LINKLOCAL(ntohl(lease->addr.s_addr)))
-		{
-			logger(LOG_ERR, "cannot request a link local address");
-			return -1;
-		}
-	} else {
-		lease->addr.s_addr = options->request_address.s_addr;
-		lease->net.s_addr = options->request_netmask.s_addr;
-	}
-
-	/* If INFORMing, ensure the interface has the address */
-	if (state->options & DHCPCD_INFORM &&
-	    has_address(iface->name, &lease->addr, &lease->net) < 1)
-	{
-		addr.s_addr = lease->addr.s_addr | ~lease->net.s_addr;
-		logger(LOG_DEBUG, "adding IP address %s/%d",
-		       inet_ntoa(lease->addr), inet_ntocidr(lease->net));
-		if (add_address(iface->name, &lease->addr,
-				&lease->net, &addr) == -1)
-		{
-			logger(LOG_ERR, "add_address: %s", strerror(errno));
-			return -1;
-		}
-		iface->addr.s_addr = lease->addr.s_addr;
-		iface->net.s_addr = lease->net.s_addr;
-	}
-
-       /* If we haven't specified a ClientID and our hardware address 
-	* length is greater than DHCP_CHADDR_LEN then we enforce a ClientID 
-	* of the hardware address family and the hardware address. */ 
-	if (!(state->options & DHCPCD_CLIENTID) && iface->hwlen > DHCP_CHADDR_LEN) 
-		state->options |= DHCPCD_CLIENTID; 
- 
-	if (*options->clientid) {
-		iface->clientid = xmalloc(options->clientid[0] + 1);
-		memcpy(iface->clientid,
-		       options->clientid, options->clientid[0] + 1);
-	} else if (state->options & DHCPCD_CLIENTID) {
-		if (state->options & DHCPCD_DUID) {
-			duid = xmalloc(DUID_LEN);
-			if ((len = get_duid(duid, iface)) == 0)
-				logger(LOG_ERR, "get_duid: %s",
-				       strerror(errno));
-		}
-
-		if (len > 0) {
-			logger(LOG_DEBUG, "DUID = %s",
-			       hwaddr_ntoa(duid, len));
-
-			iface->clientid = xmalloc(len + 6);
-			iface->clientid[0] = len + 5;
-			iface->clientid[1] = 255; /* RFC 4361 */
-
-			/* IAID is 4 bytes, so if the iface name is 4 bytes
-			 * or less, use it */
-			ul = strlen(iface->name);
-			if (ul < 5) {
-				memcpy(iface->clientid + 2, iface->name, ul);
-				if (ul < 4)
-					memset(iface->clientid + 2 + ul,
-					       0, 4 - ul);
-			} else {
-				/* Name isn't 4 bytes, so use the index */
-				ul = htonl(if_nametoindex(iface->name));
-				memcpy(iface->clientid + 2, &ul, 4);
-			}
-
-			memcpy(iface->clientid + 6, duid, len);
-			free(duid);
-		}
-		if (len == 0) {
-			len = iface->hwlen + 1;
-			iface->clientid = xmalloc(len + 1);
-			iface->clientid[0] = len;
-			iface->clientid[1] = iface->family;
-			memcpy(iface->clientid + 2, iface->hwaddr, iface->hwlen);
-		}
-	}
-
-	if (state->options & DHCPCD_LINK) {
-		open_link_socket(iface);
-		switch (carrier_status(iface->name)) {
-		case 0:
-			state->carrier = LINK_DOWN;
-			break;
-		case 1:
-			state->carrier = LINK_UP;
-			break;
-		default:
-			state->carrier = LINK_UNKNOWN;
-		}
-	}
-
-	if (options->timeout > 0 &&
-	    !(state->options & DHCPCD_DAEMONISED))
-	{
-		if (state->options & DHCPCD_IPV4LL) {
-			state->stop.tv_sec = options->timeout;
-			if (!(state->options & DHCPCD_BACKGROUND))
-				state->exit.tv_sec = state->stop.tv_sec + 10;
-		} else if (!(state->options & DHCPCD_BACKGROUND))
-			state->exit.tv_sec = options->timeout;
-	}
-	return 0;
-}
-
-static int 
-do_socket(struct if_state *state, int mode)
-{
-	if (state->interface->raw_fd != -1) {
-		close(state->interface->raw_fd);
-		state->interface->raw_fd = -1;
-	}
-	if (mode == SOCKET_CLOSED) {
-		if (state->interface->udp_fd != -1) {
-			close(state->interface->udp_fd);
-			state->interface->udp_fd = -1;
-		}
-		if (state->interface->arp_fd != -1) {
-			close(state->interface->arp_fd);
-			state->interface->arp_fd = -1;
-		}
-	}
-
-	/* Always have the UDP socket open to avoid the kernel sending
-	 * ICMP unreachable messages. */
-	/* For systems without SO_BINDTODEVICE, (ie BSD ones) we may get an
-	 * error or EADDRINUSE when binding to INADDR_ANY as another dhcpcd
-	 * instance could be running.
-	 * Oddly enough, we don't care about this as the socket is there
-	 * just to please the kernel - we don't care for reading from it. */
-	if (mode == SOCKET_OPEN &&
-	    state->interface->udp_fd == -1 &&
-	    open_udp_socket(state->interface) == -1 &&
-	    (errno != EADDRINUSE || state->interface->addr.s_addr != 0))
-		logger(LOG_ERR, "open_udp_socket: %s", strerror(errno));
-
-	if (mode == SOCKET_OPEN) 
-		if (open_socket(state->interface, ETHERTYPE_IP) == -1) {
-			logger(LOG_ERR, "open_socket: %s", strerror(errno));
-			return -1;
-		}
-	state->socket = mode;
-	return 0;
-}
-
-static ssize_t
-send_message(struct if_state *state, int type, const struct options *options)
-{
-	struct dhcp_message *dhcp;
-	uint8_t *udp;
-	ssize_t len, r;
-	struct in_addr from, to;
-	in_addr_t a = 0;
-
-	if (state->carrier == LINK_DOWN)
-		return 0;
-	if (type == DHCP_RELEASE)
-		logger(LOG_DEBUG, "sending %s with xid 0x%x",
-		       get_dhcp_op(type), state->xid);
-	else
-		logger(LOG_DEBUG,
-		       "sending %s with xid 0x%x, next in %0.2f seconds",
-		       get_dhcp_op(type), state->xid,
-		       timeval_to_double(&state->timeout));
-	state->messages++;
-	if (state->messages < 0)
-		state->messages = INT_MAX;
-	/* If we couldn't open a UDP port for our IP address
-	 * then we cannot renew.
-	 * This could happen if our IP was pulled out from underneath us. */
-	if (state->interface->udp_fd == -1) {
-		a = state->interface->addr.s_addr;
-		state->interface->addr.s_addr = 0;
-	}
-	len = make_message(&dhcp, state->interface, &state->lease, state->xid,
-			   type, options);
-	if (state->interface->udp_fd == -1)
-		state->interface->addr.s_addr = a;
-	from.s_addr = dhcp->ciaddr;
-	if (from.s_addr)
-		to.s_addr = state->lease.server.s_addr;
-	else
-		to.s_addr = 0;
-	if (to.s_addr && to.s_addr != INADDR_BROADCAST) {
-		r = send_packet(state->interface, to, (uint8_t *)dhcp, len);
-		if (r == -1)
-			logger(LOG_ERR, "send_packet: %s", strerror(errno));
-	} else {
-		len = make_udp_packet(&udp, (uint8_t *)dhcp, len, from, to);
-		r = send_raw_packet(state->interface, ETHERTYPE_IP, udp, len);
-		free(udp);
-		if (r == -1)
-			logger(LOG_ERR, "send_raw_packet: %s", strerror(errno));
-	}
-	free(dhcp);
-	/* Failed to send the packet? Return to the init state */
-	if (r == -1) {
-		state->state = STATE_INIT;
-		timerclear(&state->timeout);
-		/* We need to set a timeout so we fall through gracefully */
-		state->stop.tv_sec = 1;
-		state->stop.tv_usec = 0;
-		do_socket(state, SOCKET_CLOSED);
-	}
-	return r;
-}
-
-static void
-drop_config(struct if_state *state, const char *reason,
-	    const struct options *options)
-{
-	if (state->new || strcmp(reason, "FAIL") == 0) {
-		configure(state->interface, reason, NULL, state->new,
-			  &state->lease, options, 0);
-		free(state->old);
-		state->old = NULL;
-		free(state->new);
-		state->new = NULL;
-	}
-	state->lease.addr.s_addr = 0;
-}
-
-static void
-reduce_timers(struct if_state *state, const struct timeval *tv)
-{
-	if (timerisset(&state->exit)) {
-		timersub(&state->exit, tv, &state->exit);
-		if (!timerisset(&state->exit))
-			state->exit.tv_sec = -1;
-	}
-	if (timerisset(&state->stop)) {
-		timersub(&state->stop, tv, &state->stop);
-		if (!timerisset(&state->stop))
-			state->stop.tv_sec = -1;
-	}
-	if (timerisset(&state->timeout)) {
-		timersub(&state->timeout, tv, &state->timeout);
-		if (!timerisset(&state->timeout))
-			state->timeout.tv_sec = -1;
-	}
-}
-
-static struct timeval *
-get_lowest_timer(struct if_state *state)
-{
-	struct timeval *ref = NULL;
-	
-	if (timerisset(&state->exit))
-		ref = &state->exit;
-	if (timerisset(&state->stop)) {
-		if (!ref || timercmp(&state->stop, ref, <))
-			ref = &state->stop;
-	}
-	if (timerisset(&state->timeout)) {
-		if (!ref || timercmp(&state->timeout, ref, <))
-			ref = &state->timeout;
-	}
-	return ref;
-}
-
-static int
-wait_for_fd(struct if_state *state, int *fd)
-{
-	struct pollfd fds[4]; /* signal, link, raw, arp */
-	struct interface *iface = state->interface;
-	int i, r, nfds = 0, msecs = -1;
-	struct timeval start, stop, diff, *ref;
-	static int lastinf = 0;
-
-	/* Ensure that we haven't already timed out */
-	ref = get_lowest_timer(state);
-	if (ref && timerneg(ref))
-		return 0;
-
-	/* We always listen to signals */
-	fds[nfds].fd = state->signal_fd;
-	fds[nfds].events = POLLIN;
-	nfds++;
-	/* And links */
-	if (iface->link_fd != -1) {
-		fds[nfds].fd = iface->link_fd;
-		fds[nfds].events = POLLIN;
-		nfds++;
-	}
-
-	if (state->lease.leasetime == ~0U &&
-	    state->state == STATE_BOUND)
-	{
-		if (!lastinf) {
-			logger(LOG_DEBUG, "waiting for infinity");
-			lastinf = 1;
-		}
-		ref = NULL;
-	} else if (state->carrier == LINK_DOWN && !ref) {
-		if (!lastinf) {
-			logger(LOG_DEBUG, "waiting for carrier");
-			lastinf = 1;
-		}
-		if (timerisset(&state->exit))
-			ref = &state->exit;
-		else
-			ref = NULL;
-	} else {
-		if (iface->raw_fd != -1) {
-			fds[nfds].fd = iface->raw_fd;
-			fds[nfds].events = POLLIN;
-			nfds++;
-		}
-		if (iface->arp_fd != -1) {
-			fds[nfds].fd = iface->arp_fd;
-			fds[nfds].events = POLLIN;
-			nfds++;
-		}
-	}
-
-	/* Wait and then reduce the timers.
-	 * If we reduce a timer to zero, set it negative to indicate timeout.
-	 * We cannot reliably use select as there is no guarantee we will
-	 * actually wait the whole time if greater than 31 days according
-	 * to POSIX. So we loop on poll if needed as it's limitation of
-	 * INT_MAX milliseconds is known. */
-	for (;;) {
-		get_monotonic(&start);
-		if (ref) {
-			lastinf = 0;
-			if (ref->tv_sec > INT_MAX / 1000 ||
-			    (ref->tv_sec == INT_MAX / 1000 &&
-			     (ref->tv_usec + 999) / 1000 > INT_MAX % 1000))
-				msecs = INT_MAX;
-			else
-				msecs = ref->tv_sec * 1000 +
-					(ref->tv_usec + 999) / 1000;
-		} else
-			msecs = -1;
-		r = poll(fds, nfds, msecs);
-		get_monotonic(&stop);
-		timersub(&stop, &start, &diff);
-		reduce_timers(state, &diff);
-		if (r == -1) {
-			if (errno != EINTR)
-				logger(LOG_ERR, "poll: %s", strerror(errno));
-			return -1;
-		}
-		if (r)
-			break;
-		/* We should not have an infinite timeout if we get here */
-		if (timerneg(ref))
-			return 0;
-	}
-
-	/* We configured our array in the order we should deal with them */
-	for (i = 0; i < nfds; i++) {
-		if (fds[i].revents & POLLERR) {
-			syslog(LOG_ERR, "poll: POLLERR on fd %d", fds[i].fd);
-			errno = EBADF;
-			return -1;
-		}
-		if (fds[i].revents & POLLNVAL) {
-			syslog(LOG_ERR, "poll: POLLNVAL on fd %d", fds[i].fd);
-			errno = EINVAL;
-			return -1;
-		}
-		if (fds[i].revents & (POLLIN | POLLHUP)) {
-			*fd = fds[i].fd;
-			return r;
-		}
-	}
-	/* We should never get here. */
-	return 0;
-}
-
-static int
-handle_signal(int sig, struct if_state *state,  const struct options *options)
-{
-	struct dhcp_lease *lease = &state->lease;
-
-	switch (sig) {
-	case SIGINT:
-		logger(LOG_INFO, "received SIGINT, stopping");
-		if (!(state->options & DHCPCD_PERSISTENT))
-			drop_config(state, "STOP", options);
-		return -1;
-	case SIGTERM:
-		logger(LOG_INFO, "received SIGTERM, stopping");
-		if (!(state->options & DHCPCD_PERSISTENT))
-			drop_config(state, "STOP", options);
-		return -1;
-	case SIGALRM:
-		logger(LOG_INFO, "received SIGALRM, renewing lease");
-		do_socket(state, SOCKET_CLOSED);
-		state->state = STATE_RENEW_REQUESTED;
-		timerclear(&state->timeout);
-		timerclear(&state->stop);
-		return 1;
-	case SIGHUP:
-		logger(LOG_INFO, "received SIGHUP, releasing lease");
-		if (lease->addr.s_addr &&
-		    !IN_LINKLOCAL(ntohl(lease->addr.s_addr)))
-		{
-			do_socket(state, SOCKET_OPEN);
-			state->xid = arc4random();
-			send_message(state, DHCP_RELEASE, options);
-			do_socket(state, SOCKET_CLOSED);
-		}
-		drop_config(state, "RELEASE", options);
-		return -1;
-	default:
-		logger (LOG_ERR,
-			"received signal %d, but don't know what to do with it",
-			sig);
-	}
-
-	return 0;
-}
-
-static int bind_dhcp(struct if_state *state, const struct options *options)
-{
-	struct interface *iface = state->interface;
-	struct dhcp_lease *lease = &state->lease;
-	const char *reason = NULL;
-	struct timeval start, stop, diff;
-	int retval;
-
-	free(state->old);
-	state->old = state->new;
-	state->new = state->offer;
-	state->offer = NULL;
-	state->messages = 0;
-	state->conflicts = 0;
-	state->defend = 0;
-	timerclear(&state->exit);
-	if (clock_monotonic)
-		get_monotonic(&lease->boundtime);
-
-	if (options->options & DHCPCD_INFORM) {
-		if (options->request_address.s_addr != 0)
-			lease->addr.s_addr = options->request_address.s_addr;
-		else
-			lease->addr.s_addr = iface->addr.s_addr;
-		logger(LOG_INFO, "received approval for %s",
-		       inet_ntoa(lease->addr));
-		state->state = STATE_BOUND;
-		state->lease.leasetime = ~0U;
-		timerclear(&state->stop);
-		reason = "INFORM";
-	} else if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
-		get_lease(lease, state->new);
-		logger(LOG_INFO, "using IPv4LL address %s",
-		       inet_ntoa(lease->addr));
-		state->state = STATE_INIT;
-		timerclear(&state->timeout);
-		reason = "IPV4LL";
-	} else {
-		if (gettimeofday(&start, NULL) == 0)
-			lease->leasedfrom = start.tv_sec;
-
-		get_lease(lease, state->new);
-		if (lease->frominfo)
-			reason = "TIMEOUT";
-
-		if (lease->leasetime == ~0U) {
-			lease->renewaltime = lease->rebindtime = lease->leasetime;
-			logger(LOG_INFO, "leased %s for infinity",
-			       inet_ntoa(lease->addr));
-			state->state = STATE_BOUND;
-			timerclear(&state->stop);
-		} else {
-			if (lease->rebindtime == 0)
-				lease->rebindtime = lease->leasetime * T2;
-			else if (lease->rebindtime >= lease->leasetime) {
-				lease->rebindtime = lease->leasetime * T2;
-				logger(LOG_ERR,
-				       "rebind time greater than lease "
-				       "time, forcing to %u seconds",
-				       lease->rebindtime);
-			}
-			if (lease->renewaltime == 0)
-				lease->renewaltime = lease->leasetime * T1;
-			else if (lease->renewaltime > lease->rebindtime) {
-				lease->renewaltime = lease->leasetime * T1;
-				logger(LOG_ERR,
-				       "renewal time greater than rebind time, "
-				       "forcing to %u seconds",
-				       lease->renewaltime);
-			}
-			logger(LOG_INFO,
-			       "leased %s for %u seconds",
-			       inet_ntoa(lease->addr), lease->leasetime);
-			state->stop.tv_sec = lease->renewaltime;
-			state->stop.tv_usec = 0;
-		}
-		state->state = STATE_BOUND;
-	}
-
-	state->xid = 0;
-	timerclear(&state->timeout);
-	if (!reason) {
-		if (state->old) {
-			if (state->old->yiaddr == state->new->yiaddr &&
-			    lease->server.s_addr)
-				reason = "RENEW";
-			else
-				reason = "REBIND";
-		} else
-			reason = "BOUND";
-	}
-	/* If we have a monotonic clock we can safely substract the
-	 * script execution time from our timers.
-	 * Otherwise we can't as the script may update the real time. */
-	if (clock_monotonic)
-		get_monotonic(&start);
-	retval = configure(iface, reason, state->new, state->old,
-			   &state->lease, options, 1);
-	if (clock_monotonic) {
-		get_monotonic(&stop);
-		timersub(&stop, &start, &diff);
-		reduce_timers(state, &diff);
-	}
-	if (retval != 0)
-		return -1;
-	return daemonise(state, options);
-}
-
-static int
-handle_timeout_fail(struct if_state *state, const struct options *options)
-{
-	struct dhcp_lease *lease = &state->lease;
-	struct interface *iface = state->interface;
-	int gotlease = -1, r;
-	const char *reason = NULL;
-
-	timerclear(&state->stop);
-	timerclear(&state->exit);
-	if (state->state != STATE_DISCOVERING)
-		state->messages = 0;
-
-	switch (state->state) {
-	case STATE_INIT:	/* FALLTHROUGH */
-	case STATE_DISCOVERING: /* FALLTHROUGH */
-	case STATE_REQUESTING:
-		if (IN_LINKLOCAL(ntohl(iface->addr.s_addr))) {
-			if (!(state->options & DHCPCD_DAEMONISED))
-				logger(LOG_ERR, "timed out");
-		} else {
-			if (iface->addr.s_addr != 0 &&
-			    !(state->options & DHCPCD_INFORM))
-				logger(LOG_ERR, "lost lease");
-			else if (state->carrier != LINK_DOWN || 
-				!(state->options & DHCPCD_DAEMONISED)) 
-				logger(LOG_ERR, "timed out");
-		}
-		do_socket(state, SOCKET_CLOSED);
-		if (state->options & DHCPCD_INFORM ||
-		    state->options & DHCPCD_TEST)
-			return -1;
-
-		if (state->carrier != LINK_DOWN &&
-		    (state->options & DHCPCD_IPV4LL ||
-		     state->options & DHCPCD_LASTLEASE))
-			gotlease = get_old_lease(state);
-
-		if (state->carrier != LINK_DOWN &&
-		    state->options & DHCPCD_IPV4LL &&
-		    gotlease != 0)
-		{
-			logger(LOG_INFO, "probing for an IPV4LL address");
-			free(state->offer);
-			lease->frominfo = 0;
-			state->offer = ipv4ll_get_dhcp(0);
-			gotlease = 0;
-		}
-
-		if (gotlease == 0 &&
-		    state->offer->yiaddr != iface->addr.s_addr &&
-		    state->options & DHCPCD_ARP)
-		{
-			state->state = STATE_PROBING;
-			state->claims = 0;
-			state->probes = 0;
-			if (iface->addr.s_addr)
-				state->conflicts = 0;
-			return 1;
-		}
-
-		if (gotlease == 0) {
-			r = bind_dhcp(state, options);
-			logger(LOG_DEBUG, "renew in %ld seconds",
-				(long int)state->stop.tv_sec);
-			return r;
-		}
-		if (iface->addr.s_addr)
-			reason = "EXPIRE";
-		else
-			reason = "FAIL";
-		drop_config(state, reason, options);
-		if (!(state->options & DHCPCD_DAEMONISED) &&
-		    (state->options & DHCPCD_DAEMONISE))
-			return -1;
-		state->state = STATE_RENEW_REQUESTED;
-		return 1;
-	case STATE_BOUND:
-		logger(LOG_INFO, "renewing lease of %s",inet_ntoa(lease->addr));
-		if (state->carrier != LINK_DOWN)
-			do_socket(state, SOCKET_OPEN);
-		state->xid = arc4random();
-		state->state = STATE_RENEWING;
-		state->stop.tv_sec = lease->rebindtime - lease->renewaltime;
-		break;
-	case STATE_RENEWING:
-		logger(LOG_ERR, "failed to renew, attempting to rebind");
-		state->state = STATE_REBINDING;
-		if (lease->server.s_addr == 0)
-			state->stop.tv_sec = options->timeout;
-		else
-			state->stop.tv_sec = lease->rebindtime - \
-					     lease->renewaltime;
-		lease->server.s_addr = 0;
-		break;
-	case STATE_REBINDING:
-		logger(LOG_ERR, "failed to rebind");
-		reason = "EXPIRE";
-		drop_config(state, reason, options);
-		state->state = STATE_INIT;
-		break;
-	case STATE_PROBING:    /* FALLTHROUGH */
-	case STATE_ANNOUNCING:
-		/* We should have lost carrier here and exit timer went */
-		logger(LOG_ERR, "timed out");
-		return -1;
-	default:
-		logger(LOG_DEBUG, "handle_timeout_failed: invalid state %d",
-		       state->state);
-	}
-
-	/* This effectively falls through into the handle_timeout funtion */
-	return 1;
-}
-
-static int
-handle_timeout(struct if_state *state, const struct options *options)
-{
-	struct dhcp_lease *lease = &state->lease;
-	struct interface *iface = state->interface;
-	int i = 0;
-	struct in_addr addr;
-	struct timeval tv;
-
-	timerclear(&state->timeout);
-	if (timerneg(&state->exit))
-		return handle_timeout_fail(state, options);
-
-	if (state->state == STATE_RENEW_REQUESTED &&
-	    IN_LINKLOCAL(ntohl(lease->addr.s_addr)))
-	{
-		state->state = STATE_PROBING;
-		free(state->offer);
-		state->offer = read_lease(state->interface);
-		state->probes = 0;
-		state->claims = 0;
-	}
-	switch (state->state) {
-	case STATE_INIT_IPV4LL:
-		state->state = STATE_PROBING;
-		free(state->offer);
-		state->offer = ipv4ll_get_dhcp(0);
-		state->probes = 0;
-		state->claims = 0;
-		/* FALLTHROUGH */
-	case STATE_PROBING:
-		if (iface->arp_fd == -1)
-			open_socket(iface, ETHERTYPE_ARP);
-		if (state->probes < PROBE_NUM) {
-			if (state->probes == 0) {
-				addr.s_addr = state->offer->yiaddr;
-				logger(LOG_INFO, "checking %s is available"
-				       " on attached networks",
-				       inet_ntoa(addr));
-			}
-			state->probes++;
-			if (state->probes < PROBE_NUM) {
-				state->timeout.tv_sec = PROBE_MIN;
-				state->timeout.tv_usec = arc4random() %
-					(PROBE_MAX_U - PROBE_MIN_U);
-				timernorm(&state->timeout);
-			} else {
-				state->timeout.tv_sec = ANNOUNCE_WAIT;
-				state->timeout.tv_usec = 0;
-			}
-			logger(LOG_DEBUG,
-			       "sending ARP probe (%d of %d), next in %0.2f seconds",
-			       state->probes, PROBE_NUM,
-			       timeval_to_double(&state->timeout));
-			if (send_arp(iface, ARPOP_REQUEST, 0,
-				     state->offer->yiaddr) == -1)
-			{
-				logger(LOG_ERR, "send_arp: %s", strerror(errno));
-				return -1;
-			}
-			return 0;
-		} else {
-			/* We've waited for ANNOUNCE_WAIT after the final probe
-			 * so the address is now ours */
-			i = bind_dhcp(state, options);
-			state->state = STATE_ANNOUNCING;
-			state->timeout.tv_sec = ANNOUNCE_INTERVAL;
-			state->timeout.tv_usec = 0;
-			return i;
-		}
-		break;
-	case STATE_ANNOUNCING:
-		if (iface->arp_fd == -1)
-			open_socket(iface, ETHERTYPE_ARP);
-		if (state->claims < ANNOUNCE_NUM) {
-			state->claims++;
-			if (state->claims < ANNOUNCE_NUM) {
-				state->timeout.tv_sec = ANNOUNCE_INTERVAL;
-				state->timeout.tv_usec = 0;
-				logger(LOG_DEBUG,
-				       "sending ARP announce (%d of %d),"
-				       " next in %0.2f seconds",
-				       state->claims, ANNOUNCE_NUM,
-				       timeval_to_double(&state->timeout));
-			} else
-				logger(LOG_DEBUG,
-				       "sending ARP announce (%d of %d)",
-				       state->claims, ANNOUNCE_NUM);
-			i = send_arp(iface, ARPOP_REQUEST,
-				     state->new->yiaddr, state->new->yiaddr);
-			if (i == -1) {
-				logger(LOG_ERR, "send_arp: %s", strerror(errno));
-				return -1;
-			}
-		}
-		if (state->claims < ANNOUNCE_NUM)
-			return 0;
-		if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
-			/* We should pretend to be at the end
-			 * of the DHCP negotation cycle */
-			state->state = STATE_INIT;
-			state->messages = DHCP_MAX / DHCP_BASE;
-			state->probes = 0;
-			state->claims = 0;
-			timerclear(&state->stop);
-			goto dhcp_timeout;
-		} else {
-			state->state = STATE_BOUND;
-			close(iface->arp_fd);
-			iface->arp_fd = -1;
-			if (lease->leasetime != ~0U) {
-				state->stop.tv_sec = lease->renewaltime;
-				state->stop.tv_usec = 0;
-				if (clock_monotonic) {
-					get_monotonic(&tv);
-					timersub(&tv, &lease->boundtime, &tv);
-					timersub(&state->stop, &tv, &state->stop);
-				} else {
-					state->stop.tv_sec -=
-						(ANNOUNCE_INTERVAL * ANNOUNCE_NUM);
-				}
-				logger(LOG_DEBUG, "renew in %ld seconds",
-				       (long int)state->stop.tv_sec);
-			}
-		}
-		return 0;
-	}
-
-	if (timerneg(&state->stop))
-		return handle_timeout_fail(state, options);
-
-	switch (state->state) {
-	case STATE_BOUND: /* FALLTHROUGH */
-	case STATE_RENEW_REQUESTED:
-		timerclear(&state->stop);
-		/* FALLTHROUGH */
-	case STATE_INIT:
-		if (state->carrier == LINK_DOWN)
-			return 0;
-		do_socket(state, SOCKET_OPEN);
-		state->xid = arc4random();
-		iface->start_uptime = uptime();
-		break;
-	}
-
-	switch(state->state) {
-	case STATE_RENEW_REQUESTED:
-		/* If a renew was requested (ie, didn't timeout) we actually
-		 * enter the REBIND state so that we broadcast to all servers.
-		 * We need to do this for when we change networks. */
-		lease->server.s_addr = 0;
-		state->messages = 0;
-		if (lease->addr.s_addr && !(state->options & DHCPCD_INFORM)) {
-			logger(LOG_INFO, "rebinding lease of %s",
-			       inet_ntoa(lease->addr));
-			state->state = STATE_REBINDING;
-			state->stop.tv_sec = options->timeout;
-			state->stop.tv_usec = 0;
-			break;
-		}
-		/* FALLTHROUGH */
-	case STATE_INIT:
-		if (lease->addr.s_addr == 0 ||
-		    IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
-		{
-			logger(LOG_INFO, "broadcasting for a lease");
-			state->state = STATE_DISCOVERING;
-		} else if (state->options & DHCPCD_INFORM) {
-			logger(LOG_INFO, "broadcasting inform for %s",
-			       inet_ntoa(lease->addr));
-			state->state = STATE_REQUESTING;
-		} else {
-			logger(LOG_INFO, "broadcasting for a lease of %s",
-			       inet_ntoa(lease->addr));
-			state->state = STATE_REQUESTING;
-		}
-		if (!lease->addr.s_addr && !timerisset(&state->stop)) {
-			state->stop.tv_sec = DHCP_MAX + DHCP_RAND_MIN;
-			state->stop.tv_usec = arc4random() % (DHCP_RAND_MAX_U - DHCP_RAND_MIN_U);
-			timernorm(&state->stop);
-		}
-		break;
-	}
-
-dhcp_timeout:
-	if (state->carrier == LINK_DOWN) {
-		timerclear(&state->timeout);
-		return 0;
-	}
-	state->timeout.tv_sec = DHCP_BASE;
-	for (i = 0; i < state->messages; i++) {
-		state->timeout.tv_sec *= 2;
-		if (state->timeout.tv_sec > DHCP_MAX) {
-			state->timeout.tv_sec = DHCP_MAX;
-			break;
-		}
-	}
-	state->timeout.tv_sec += DHCP_RAND_MIN;
-	state->timeout.tv_usec = arc4random() %
-		(DHCP_RAND_MAX_U - DHCP_RAND_MIN_U);
-	timernorm(&state->timeout);
-
-	/* We send the message here so that the timeout is reported */
-	switch (state->state) {
-	case STATE_DISCOVERING:
-		send_message(state, DHCP_DISCOVER, options);
-		break;
-	case STATE_REQUESTING:
-		if (state->options & DHCPCD_INFORM) {
-			send_message(state, DHCP_INFORM, options);
-			break;
-		}
-		/* FALLTHROUGH */
-	case STATE_RENEWING:   /* FALLTHROUGH */
-	case STATE_REBINDING:
-		if (iface->raw_fd == -1)
-			do_socket(state, SOCKET_OPEN);
-		send_message(state, DHCP_REQUEST, options);
-		break;
-	}
-
-	return 0;
-}
-
-static void
-log_dhcp(int lvl, const char *msg, const struct dhcp_message *dhcp)
-{
-	char *a;
-	struct in_addr addr;
-	int r;
-
-	if (strcmp(msg, "NAK:") == 0)
-		a = get_option_string(dhcp, DHO_MESSAGE);
-	else {
-		addr.s_addr = dhcp->yiaddr;
-		a = xstrdup(inet_ntoa(addr));
-	}
-	r = get_option_addr(&addr, dhcp, DHO_SERVERID);
-	if (dhcp->servername[0] && r == 0)
-		logger(lvl, "%s %s from %s `%s'", msg, a,
-		       inet_ntoa(addr), dhcp->servername);
-	else if (r == 0)
-		logger(lvl, "%s %s from %s", msg, a, inet_ntoa(addr));
-	else
-		logger(lvl, "%s %s", msg, a);
-	free(a);
-}
-
-static int
-handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp,
-	    const struct options *options)
-{
-	struct dhcp_message *dhcp = *dhcpp;
-	struct interface *iface = state->interface;
-	struct dhcp_lease *lease = &state->lease;
-	uint8_t type, tmp;
-	struct in_addr addr;
-	size_t i;
-	int r;
-
-	/* reset the message counter */
-	state->messages = 0;
-
-	/* We have to have DHCP type to work */
-	if (get_option_uint8(&type, dhcp, DHO_MESSAGETYPE) == -1) {
-		logger(LOG_ERR, "ignoring message; no DHCP type");
-		return 0;
-	}
-	/* Every DHCP message should include ServerID */
-	if (get_option_addr(&addr, dhcp, DHO_SERVERID) == -1) {
-		logger(LOG_ERR, "ignoring message; no Server ID");
-		return 0;
-	}
-
-	/* Ensure that it's not from a blacklisted server.
-	 * We should expand this to check IP and/or hardware address
-	 * at the packet level. */
-	if (options->blacklist_len != 0 &&
-	    get_option_addr(&addr, dhcp, DHO_SERVERID) == 0)
-	{
-		for (i = 0; i < options->blacklist_len; i++) {
-			if (options->blacklist[i] != addr.s_addr)
-				continue;
-			if (dhcp->servername[0])
-				logger(LOG_WARNING,
-				       "ignoring blacklisted server %s `%s'",
-					inet_ntoa(addr), dhcp->servername);
-			else
-				logger(LOG_WARNING,
-				       "ignoring blacklisted server %s",
-				       inet_ntoa(addr));
-			return 0;
-		}
-	}
-
-	/* We should restart on a NAK */
-	if (type == DHCP_NAK) {
-		log_dhcp(LOG_WARNING, "NAK:", dhcp);
-		drop_config(state, "EXPIRE", options);
-		do_socket(state, SOCKET_CLOSED);
-		state->state = STATE_INIT;
-		/* If we constantly get NAKS then we should slowly back off */
-		if (state->nakoff == 0) {
-			state->nakoff = 1;
-			timerclear(&state->timeout);
-		} else {
-			state->timeout.tv_sec = state->nakoff;
-			state->timeout.tv_usec = 0;
-			state->nakoff *= 2;
-			if (state->nakoff > NAKOFF_MAX)
-				state->nakoff = NAKOFF_MAX;
-		} 
-		return 0;
-	}
-
-	/* No NAK, so reset the backoff */
-	state->nakoff = 1;
-
-	/* Ensure that all required options are present */
-	for (i = 1; i < 255; i++) {
-		if (has_option_mask(options->requiremask, i) &&
-		    get_option_uint8(&tmp, dhcp, i) != 0)
-		{
-			log_dhcp(LOG_WARNING, "reject", dhcp);
-			return 0;
-		}
-	}
-
-	if (type == DHCP_OFFER && state->state == STATE_DISCOVERING) {
-		lease->addr.s_addr = dhcp->yiaddr;
-		get_option_addr(&lease->server, dhcp, DHO_SERVERID);
-		log_dhcp(LOG_INFO, "offered", dhcp);
-		if (state->options & DHCPCD_TEST) {
-			run_script(options, iface->name, "TEST", dhcp, NULL);
-			/* Fake the fact we forked so we return 0 to userland */
-			state->options |= DHCPCD_FORKED;
-			return -1;
-		}
-		free(state->offer);
-		state->offer = dhcp;
-		*dhcpp = NULL;
-		timerclear(&state->timeout);
-		state->state = STATE_REQUESTING;
-		return 1;
-	}
-
-	if (type == DHCP_OFFER) {
-		log_dhcp(LOG_INFO, "ignoring offer of", dhcp);
-		return 0;
-	}
-
-	/* We should only be dealing with acks */
-	if (type != DHCP_ACK) {
-		log_dhcp(LOG_ERR, "not ACK or OFFER", dhcp);
-		return 0;
-	}
-	    
-	switch (state->state) {
-	case STATE_RENEW_REQUESTED:
-	case STATE_REQUESTING:
-	case STATE_RENEWING:
-	case STATE_REBINDING:
-		if (!(state->options & DHCPCD_INFORM)) {
-			get_option_addr(&lease->server,
-					dhcp, DHO_SERVERID);
-			log_dhcp(LOG_INFO, "acknowledged", dhcp);
-		}
-		free(state->offer);
-		state->offer = dhcp;
-		*dhcpp = NULL;
-		break;
-	default:
-		logger(LOG_ERR, "wrong state %d", state->state);
-	}
-
-	lease->frominfo = 0;
-	do_socket(state, SOCKET_CLOSED);
-	if (state->options & DHCPCD_ARP &&
-	    iface->addr.s_addr != state->offer->yiaddr)
-	{
-		/* If the interface already has the address configured
-		 * then we can't ARP for duplicate detection. */
-		addr.s_addr = state->offer->yiaddr;
-		if (!has_address(iface->name, &addr, NULL)) {
-			state->state = STATE_PROBING;
-			state->claims = 0;
-			state->probes = 0;
-			state->conflicts = 0;
-			timerclear(&state->stop);
-			return 1;
-		}
-	}
-
-	r = bind_dhcp(state, options);
-	if (!(state->options & DHCPCD_ARP)) {
-		if (!(state->options & DHCPCD_INFORM))
-			logger(LOG_DEBUG, "renew in %ld seconds",
-			       (long int)state->stop.tv_sec);
-		return r;
-	}
-	state->state = STATE_ANNOUNCING;
-	if (state->options & DHCPCD_FORKED)
-		return r;
-	return 1;
-}
-
-static int
-handle_dhcp_packet(struct if_state *state, const struct options *options)
-{
-	uint8_t *packet;
-	struct interface *iface = state->interface;
-	struct dhcp_message *dhcp = NULL;
-	const uint8_t *pp;
-	ssize_t bytes;
-	int retval = -1;
-
-	/* We loop through until our buffer is empty.
-	 * The benefit is that if we get >1 DHCP packet in our buffer and
-	 * the first one fails for any reason, we can use the next. */
-	packet = xmalloc(udp_dhcp_len);
-	for(;;) {
-		bytes = get_raw_packet(iface, ETHERTYPE_IP,
-				       packet, udp_dhcp_len);
-		if (bytes == 0) {
-			retval = 0;
-			break;
-		}
-		if (bytes == -1)
-			break;
-		if (valid_udp_packet(packet, bytes) == -1)
-			continue;
-		bytes = get_udp_data(&pp, packet);
-		if ((size_t)bytes > sizeof(*dhcp)) {
-			logger(LOG_ERR, "packet greater than DHCP size");
-			continue;
-		}
-		if (!dhcp)
-			dhcp = xzalloc(sizeof(*dhcp));
-		memcpy(dhcp, pp, bytes);
-		if (dhcp->cookie != htonl(MAGIC_COOKIE)) {
-			logger(LOG_DEBUG, "bogus cookie, ignoring");
-			continue;
-		}
-		/* Ensure it's the right transaction */
-		if (state->xid != dhcp->xid) {
-			logger(LOG_DEBUG,
-			       "ignoring packet with xid 0x%x as"
-			       " it's not ours (0x%x)",
-			       dhcp->xid, state->xid);
-			continue;
-		}
-		/* Ensure packet is for us */
-		if (iface->hwlen <= sizeof(dhcp->chaddr) &&
-		    memcmp(dhcp->chaddr, iface->hwaddr, iface->hwlen))
-		{
-			logger(LOG_DEBUG, "xid 0x%x is not for our hwaddr %s",
-			       dhcp->xid,
-			       hwaddr_ntoa(dhcp->chaddr, sizeof(dhcp->chaddr)));
-			continue;
-		}
-		retval = handle_dhcp(state, &dhcp, options);
-		if (retval == 0 && state->options & DHCPCD_TEST)
-			state->options |= DHCPCD_FORKED;
-		break;
-	}
-
-	free(packet);
-	free(dhcp);
-	return retval;
-}
-
-static int
-handle_arp_packet(struct if_state *state)
-{
-	struct arphdr reply;
-	uint32_t reply_s;
-	uint32_t reply_t;
-	uint8_t arp_reply[sizeof(reply) + 2 * sizeof(reply_s) + 2 * HWADDR_LEN];
-	uint8_t *hw_s, *hw_t;
-	ssize_t bytes;
-	struct interface *iface = state->interface;
-
-	state->fail.s_addr = 0;
-	for(;;) {
-		bytes = get_raw_packet(iface, ETHERTYPE_ARP,
-				       arp_reply, sizeof(arp_reply));
-		if (bytes == 0 || bytes == -1)
-			return (int)bytes;
-		/* We must have a full ARP header */
-		if ((size_t)bytes < sizeof(reply))
-			continue;
-		memcpy(&reply, arp_reply, sizeof(reply));
-		/* Protocol must be IP. */
-		if (reply.ar_pro != htons(ETHERTYPE_IP))
-			continue;
-		if (reply.ar_pln != sizeof(reply_s))
-			continue;
-		/* Only these types are recognised */
-		if (reply.ar_op != htons(ARPOP_REPLY) &&
-		    reply.ar_op != htons(ARPOP_REQUEST))
-			continue;
-
-		/* Get pointers to the hardware addreses */
-		hw_s = arp_reply + sizeof(reply);
-		hw_t = hw_s + reply.ar_hln + reply.ar_pln;
-		/* Ensure we got all the data */
-		if ((hw_t + reply.ar_hln + reply.ar_pln) - arp_reply > bytes)
-			continue;
-		/* Ignore messages from ourself */
-		if (reply.ar_hln == iface->hwlen &&
-		    memcmp(hw_s, iface->hwaddr, iface->hwlen) == 0)
-			continue;
-		/* Copy out the IP addresses */
-		memcpy(&reply_s, hw_s + reply.ar_hln, reply.ar_pln);
-		memcpy(&reply_t, hw_t + reply.ar_hln, reply.ar_pln);
-
-		/* Check for conflict */
-		if (state->offer && 
-		    (reply_s == state->offer->yiaddr ||
-		     (reply_s == 0 && reply_t == state->offer->yiaddr)))
-			state->fail.s_addr = state->offer->yiaddr;
-
-		/* Handle IPv4LL conflicts */
-		if (IN_LINKLOCAL(htonl(iface->addr.s_addr)) &&
-		    (reply_s == iface->addr.s_addr ||
-		     (reply_s == 0 && reply_t == iface->addr.s_addr)))
-			state->fail.s_addr = iface->addr.s_addr;
-
-		if (state->fail.s_addr) {
-			logger(LOG_ERR, "hardware address %s claims %s",
-			       hwaddr_ntoa((unsigned char *)hw_s,
-					   (size_t)reply.ar_hln),
-			       inet_ntoa(state->fail));
-			errno = EEXIST;
-			return -1;
-		}
-	}
-}
-
-static int
-handle_arp_fail(struct if_state *state, const struct options *options)
-{
-	time_t up;
-	int cookie = state->offer->cookie;
-
-	if (!IN_LINKLOCAL(htonl(state->fail.s_addr))) {
-		if (cookie) {
-			state->timeout.tv_sec = DHCP_ARP_FAIL;
-			state->timeout.tv_usec = 0;
-			do_socket(state, SOCKET_OPEN);
-			send_message(state, DHCP_DECLINE, options);
-			do_socket(state, SOCKET_CLOSED);
-		}
-		state->state = STATE_INIT;
-		free(state->offer);
-		state->offer = NULL;
-		state->lease.addr.s_addr = 0;
-		if (!cookie)
-			return 1;
-		return 0;
-	}
-
-	if (state->fail.s_addr == state->interface->addr.s_addr) {
-		if (state->state == STATE_PROBING)
-			/* This should only happen when SIGALRM or
-			 * link when down/up and we have a conflict. */
-			drop_config(state, "EXPIRE", options);
-		else {
-			up = uptime();
-			if (state->defend + DEFEND_INTERVAL > up) {
-				drop_config(state, "EXPIRE", options);
-				state->conflicts = -1;
-				/* drop through to set conflicts to 0 */
-			} else {
-				state->defend = up;
-				return 0;
-			}
-		}
-	}
-	do_socket(state, SOCKET_CLOSED);
-	state->conflicts++;
-	timerclear(&state->stop);
-	if (state->conflicts > MAX_CONFLICTS) {
-		logger(LOG_ERR, "failed to obtain an IPv4LL address");
-		state->state = STATE_INIT;
-		timerclear(&state->timeout);
-		if (!(state->options & DHCPCD_DAEMONISED) &&
-		    (state->options & DHCPCD_DAEMONISE))
-			return -1;
-		return 1;
-	}
-	state->state = STATE_INIT_IPV4LL;
-	state->timeout.tv_sec = PROBE_WAIT;
-	state->timeout.tv_usec = 0;
-	return 0;
-}
-
-static int
-handle_link(struct if_state *state)
-{
-	int retval;
-
-	retval = link_changed(state->interface);
-	if (retval == -1) {
-		logger(LOG_ERR, "link_changed: %s", strerror(errno));
-		return -1;
-	}
-	if (retval == 0)
-		return 0;
-
-	switch (carrier_status(state->interface->name)) {
-	case -1:
-		logger(LOG_ERR, "carrier_status: %s", strerror(errno));
-		return -1;
-	case 0:
-		if (state->carrier != LINK_DOWN) {
-			logger(LOG_INFO, "carrier lost");
-			state->carrier = LINK_DOWN;
-			do_socket(state, SOCKET_CLOSED);
-			timerclear(&state->timeout);
-			if (state->state != STATE_BOUND)
-				timerclear(&state->stop);
-		}
-		break;
-	default:
-		if (state->carrier != LINK_UP) {
-			logger(LOG_INFO, "carrier acquired");
-			state->state = STATE_RENEW_REQUESTED;
-			state->carrier = LINK_UP;
-			timerclear(&state->timeout);
-			timerclear(&state->stop);
-			return 1;
-		}
-		break;
-	}
-	return 0;
-}
-
-int
-dhcp_run(const struct options *options, int *pid_fd)
-{
-	struct interface *iface;
-	struct if_state *state = NULL;
-	int fd = -1, r = 0, sig;
-
-	iface = read_interface(options->interface, options->metric);
-	if (!iface) {
-		logger(LOG_ERR, "read_interface: %s", strerror(errno));
-		goto eexit;
-	}
-	logger(LOG_DEBUG, "hardware address = %s",
-	       hwaddr_ntoa(iface->hwaddr, iface->hwlen));
-	state = xzalloc(sizeof(*state));
-	state->pid_fd = pid_fd;
-	state->interface = iface;
-	if (!(options->options & DHCPCD_TEST))
-		run_script(options, iface->name, "PREINIT", NULL, NULL);
-
-	if (client_setup(state, options) == -1)
-		goto eexit;
-	if (signal_init() == -1)
-		goto eexit;
-	if (signal_setup() == -1)
-		goto eexit;
-	state->signal_fd = signal_fd();
-
-	if (state->options & DHCPCD_BACKGROUND &&
-	    !(state->options & DHCPCD_DAEMONISED))
-		if (daemonise(state, options) == -1)
-			goto eexit;
-
-	if (state->carrier == LINK_DOWN)
-		logger(LOG_INFO, "waiting for carrier");
-
-	for (;;) {
-		if (r == 0)
-			r = handle_timeout(state, options);
-		else if (r > 0) {
-			if (fd == state->signal_fd) {
-			    	if ((sig = signal_read()) != -1)
-					r = handle_signal(sig, state, options);
-			} else if (fd == iface->link_fd)
-				r = handle_link(state);
-			else if (fd == iface->raw_fd)
-				r = handle_dhcp_packet(state, options);
-			else if (fd == iface->arp_fd) {
-				if ((r = handle_arp_packet(state)) == -1)
-					r = handle_arp_fail(state, options);
-			} else
-				r = 0;
-		}
-		if (r == -1)
-			break;
-		if (r == 0) {
-			fd = -1;
-			r = wait_for_fd(state, &fd);
-			if (r == -1 && errno == EINTR) {
-				r = 1;
-				fd = state->signal_fd;
-			}
-		} else
-			r = 0;
-	}
-
-eexit:
-	if (iface) {
-		do_socket(state, SOCKET_CLOSED);
-		if (iface->link_fd != -1)
-		    close(iface->link_fd);
-		free_routes(iface->routes);
-		free(iface->clientid);
-		free(iface->buffer);
-		free(iface);
-	}
-
-	if (state) {
-		if (state->options & DHCPCD_FORKED)
-			r = 0;
-		if (state->options & DHCPCD_DAEMONISED)
-			unlink(options->pidfile);
-		free(state->offer);
-		free(state->new);
-		free(state->old);
-		free(state);
-	}
-
-	return r;
-}
diff --git a/client.h b/client.h
deleted file mode 100644
index 35a5e37..0000000
--- a/client.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* 
- * dhcpcd - DHCP client daemon
- * Copyright 2006-2008 Roy Marples <roy@marples.name>
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef CLIENT_H
-#define CLIENT_H
-
-#include "dhcpcd.h"
-
-int dhcp_run(const struct options *, int *);
-
-#endif
diff --git a/if-options.c b/if-options.c
index 4dd907b..9e77f2b 100644
--- a/if-options.c
+++ b/if-options.c
@@ -793,6 +793,7 @@
 		ifo->hostname[0] = '\0';
 
 	platform = hardware_platform();
+#ifndef ANDROID
 	if (uname(&utn) == 0)
 		ifo->vendorclassid[0] = snprintf((char *)ifo->vendorclassid + 1,
 		    VENDORCLASSID_MAX_LEN,
@@ -800,6 +801,7 @@
 		    utn.sysname, utn.release, utn.machine,
 		    platform ? ":" : "", platform ? platform : "");
 	else
+#endif
 		ifo->vendorclassid[0] = snprintf((char *)ifo->vendorclassid + 1,
 		    VENDORCLASSID_MAX_LEN, "%s-%s", PACKAGE, VERSION);
 
diff --git a/logger.c b/logger.c
deleted file mode 100644
index 1ef423c..0000000
--- a/logger.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* 
- * dhcpcd - DHCP client daemon
- * Copyright 2006-2008 Roy Marples <roy@marples.name>
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-
-#include "common.h"
-#include "logger.h"
-
-#ifdef ANDROID
-#include <android/log.h>
-#endif
-
-static int loglevel = LOG_INFO;
-static char logprefix[12] = {0};
-
-void
-setloglevel(int level)
-{
-	loglevel = level;
-}
-
-void
-setlogprefix(const char *prefix)
-{
-	strlcpy(logprefix, prefix, sizeof(logprefix));
-}
-
-void
-logger(int level, const char *fmt, ...)
-{
-	va_list p, p2;
-	FILE *f = stderr;
-	size_t len, fmt2len;
-	char *fmt2, *pf;
-
-	va_start(p, fmt);
-#ifdef ANDROID
-	if (level <= loglevel) {
-		if (level <= LOG_ERR) {
-			level = ANDROID_LOG_ERROR;
-		} else {
-			level = ANDROID_LOG_DEBUG;
-		}
-		__android_log_vprint(level, "dhcpcd", fmt, p);
-	}
-#else
-	va_copy(p2, p);
-
-	if (level <= LOG_ERR || level <= loglevel) {
-		fprintf(f, "%s", logprefix);
-		vfprintf(f, fmt, p);
-		fputc('\n', f);
-	}
-
-	if (level < LOG_DEBUG || level <= loglevel) {
-		len = strlen(logprefix);
-		fmt2len = strlen(fmt) + len + 1;
-		fmt2 = pf = malloc(sizeof(char) * fmt2len);
-		if (fmt2) {
-			strlcpy(pf, logprefix, fmt2len);
-			pf += len;
-			strlcpy(pf, fmt, fmt2len - len);
-			vsyslog(level, fmt2, p2);
-			free(fmt2);
-		} else {
-			vsyslog(level, fmt, p2);
-			syslog(LOG_ERR, "logger: memory exhausted");
-			exit(EXIT_FAILURE);
-		}
-	}
-
-	va_end(p2);
-#endif
-	va_end(p);
-}
diff --git a/logger.h b/logger.h
deleted file mode 100644
index 8ac76b6..0000000
--- a/logger.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 
- * dhcpcd - DHCP client daemon
- * Copyright 2006-2008 Roy Marples <roy@marples.name>
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef LOGGER_H
-#define LOGGER_H
-
-#if defined(__GNUC__)
-#  define _PRINTF_LIKE(_one, _two)  __attribute__ ((__format__ (__printf__, _one, _two)))
-#else
-#  define _PRINTF_LIKE(_one, _two)
-#endif
-
-#include <syslog.h>
-
-void setloglevel(int);
-void setlogprefix(const char *);
-void logger(int, const char *, ...) _PRINTF_LIKE (2, 3);
-
-#endif