--- pump-0.8.24.orig/debian/docs
+++ pump-0.8.24/debian/docs
@@ -0,0 +1 @@
+CREDITS
--- pump-0.8.24.orig/debian/watch
+++ pump-0.8.24/debian/watch
@@ -0,0 +1,2 @@
+version=3
+http://download.fedora.redhat.com/pub/fedora/linux/core/development/source/SRPMS/pump-([\d\.]+)-.+.src.rpm debian uupdate
--- pump-0.8.24.orig/debian/compat
+++ pump-0.8.24/debian/compat
@@ -0,0 +1 @@
+5
--- pump-0.8.24.orig/debian/README.source
+++ pump-0.8.24/debian/README.source
@@ -0,0 +1,8 @@
+
+README.Debian-source
+
+The source package uses quilt for the modifications of the upstream source. 
+If you want to change something it is best to use the quilt approach as
+documented in 
+        /usr/share/doc/quilt/README.source
+
--- pump-0.8.24.orig/debian/dirs
+++ pump-0.8.24/debian/dirs
@@ -0,0 +1,3 @@
+sbin
+usr/share/man/man8
+var/run
--- pump-0.8.24.orig/debian/Makefile.build
+++ pump-0.8.24/debian/Makefile.build
@@ -0,0 +1,5 @@
+include $(SHOME)/Makefile
+
+DEB_CFLAGS := -I$(SHOME) -O2 -Ddebian -DUDEB=0 -fno-strict-aliasing
+LOADLIBES := -lpopt -lresolv
+VPATH := $(SHOME)
--- pump-0.8.24.orig/debian/copyright
+++ pump-0.8.24/debian/copyright
@@ -0,0 +1,34 @@
+This package was debianized by Steve Dunham <dunham@cse.msu.edu> on
+Thu, 10 Jun 1999 14:45:00 -0400.
+
+It was then worked on by Herbert Xu <herbert@debian.org> since
+Mon, 24 Dec 2001 12:05:16 +1100.
+
+It is maintained by Anibal Monsalve Salazar <anibal@debian.org>.
+
+The source tar file was extracted from sources available at
+
+http://download.fedora.redhat.com/pub/fedora/linux/core/development/SRPMS/
+
+Upstream Author: Red Hat
+
+Copyright:
+
+ Copyright 1999 Red Hat Software, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 dated June, 1991.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+On Debian GNU/Linux systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL-2'.
+
--- pump-0.8.24.orig/debian/changelog
+++ pump-0.8.24/debian/changelog
@@ -0,0 +1,348 @@
+pump (0.8.24-7.5.201403111729) ucs4-0-0-0; urgency=low
+
+  * UCS auto build. No patches were applied to the original source package
+
+ -- Univention builddaemon <buildd@univention.de>  Tue, 11 Mar 2014 17:29:03 +0100
+
+pump (0.8.24-7) unstable; urgency=low
+
+  * Adopted package (Closes: #506508)
+  * Fix licence : GPL-2
+  * Migrated diff to quilt
+    + Added: 00_00-pump-debian.patch
+    + Merged gentoo's pump-0.8.24-1-patches.tar.bz2 (Closes: #268161)
+    + Fix manpage typo, with  A. Costa's patch (Closes: #383119) 
+
+ -- Philippe Coval <rzr@gna.org>  Sat, 27 Feb 2010 16:12:35 +0100
+
+pump (0.8.24-6) unstable; urgency=low
+
+  * QA upload.
+  * Merge 0.8.24-5ubuntu1 from Ubuntu
+    Closes: 560515
+
+ -- Anibal Monsalve Salazar <anibal@debian.org>  Sun, 27 Dec 2009 20:48:44 +1100
+
+pump (0.8.24-5ubuntu1) karmic; urgency=low
+
+  [ Brian Murray ]
+  * Resolve FTBFS on Jaunty because of -D_FORTIFY_SOURCE=2.
+    Thanks to Cesare Tirabassi for the patch. (LP: #309848) 
+
+  [ Ilya Barygin ]
+  * Build with -fno-strict-aliasing to fix FTBFS with gcc 4.4.
+
+ -- Ilya Barygin <barygin@gmail.com>  Tue, 13 Oct 2009 20:27:40 +0400
+
+pump (0.8.24-5) unstable; urgency=low
+
+  * QA upload.
+  * Maintainer is Debian QA Group
+
+ -- Anibal Monsalve Salazar <anibal@debian.org>  Fri, 21 Nov 2008 19:50:09 +1100
+
+pump (0.8.24-4) unstable; urgency=low
+
+  * pump depends on netbase, not net-tools; closes: #469712
+
+ -- Anibal Monsalve Salazar <anibal@debian.org>  Wed, 06 Aug 2008 08:46:48 +1000
+
+pump (0.8.24-3) unstable; urgency=low
+
+  * pump depends on net-tools; closes: #469712 
+  * Standards-Version is 3.8.0
+  * Fix the following lintian issues:
+    W: pump source: debian-rules-sets-DH_COMPAT line 14
+
+ -- Anibal Monsalve Salazar <anibal@debian.org>  Tue, 05 Aug 2008 21:26:01 +1000
+
+pump (0.8.24-2.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Fix gcc-4.3 FTBFS, patch by brian m. carlson. (Closes: #455419)
+
+ -- Marc 'HE' Brockschmidt <he@debian.org>  Sun, 16 Mar 2008 19:08:03 +0100
+
+pump (0.8.24-2) unstable; urgency=low
+
+  * Set Standards-Version to 3.7.2.
+  * Set DH_COMPAT to 5.
+  * Updated debian/watch file.
+
+ -- Anibal Monsalve Salazar <anibal@debian.org>  Mon, 03 Jul 2006 16:10:21 +1000
+
+pump (0.8.24-1) unstable; urgency=low
+
+  * New upstream release.
+    Fixed "does not take option interface-mtu into account", closes:
+    #333519.
+  * Fixed override disparity in unstable, "Override says admin - optional,
+    .deb says base - optional".
+  * Set Standards-Version to 3.6.2.
+  * Added watch file.
+  * Fixed lintian warning "package-uses-deprecated-debhelper-compat-
+    version 2"
+  * Updated FSF mail address.
+  * Fixed linda error "DH_COMPAT is greater than the major version of
+    debhelper depended on".
+
+ -- Anibal Monsalve Salazar <anibal@debian.org>  Sat, 26 Nov 2005 12:55:08 +1100
+
+pump (0.8.21-2) unstable; urgency=low
+
+  * Fixed "man page regression", closes: #302672.
+    Patch by Thomas Hood <jdthood@aglu.demon.nl>.
+
+ -- Anibal Monsalve Salazar <anibal@debian.org>  Sat, 02 Apr 2005 20:25:52 +1000
+
+pump (0.8.21-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Anibal Monsalve Salazar <anibal@debian.org>  Wed, 23 Feb 2005 21:20:26 +1100
+
+pump (0.8.19-5) unstable; urgency=low
+
+  * pump doesn't run resolvconf in a reliable way (closes: #258598).
+    Patch supplied by Thomas Hood <jdthood@aglu.demon.nl>
+  * Improved man page (closes: #268237).
+    Patch supplied by Thomas Hood <jdthood@yahoo.co.uk>
+
+ -- Anibal Monsalve Salazar <A.Monsalve.Salazar@IEEE.org>  Fri, 10 Sep 2004 19:24:30 +1000
+
+pump (0.8.19-4) unstable; urgency=low
+
+  * New maintainer.
+
+ -- Anibal Monsalve Salazar <A.Monsalve.Salazar@IEEE.org>  Thu, 20 May 2004 10:00:28 +1000
+
+pump (0.8.19-3) unstable; urgency=low
+
+  * Removed pump-udeb (closes: #221227).
+  * Removed prerm script (closes: #224000).
+  * Keep going in case of unexpected TCP connection errors
+    (Magos?nyi ?rp?d, closes: #227693).
+
+ -- Herbert Xu <herbert@debian.org>  Sat, 31 Jan 2004 10:29:10 +1100
+
+pump (0.8.19-2) unstable; urgency=low
+
+  * Do not print search line if domain is NULL (closes: #215467).
+  * Added support for multiple gateways (closes: #216088).
+
+ -- Herbert Xu <herbert@debian.org>  Sat,  1 Nov 2003 11:49:31 +1100
+
+pump (0.8.19-1) unstable; urgency=low
+
+  * New upstream release.
+  * Changed priority of pump-udeb to extra.
+  * Suggest resolvconf (closes: #208090).
+  * Removed obsolete debconf note (closes: #207661, #207665).
+  * Use -falign options.
+
+ -- Herbert Xu <herbert@debian.org>  Sat, 13 Sep 2003 13:11:02 +1000
+
+pump (0.8.15-1) unstable; urgency=low
+
+  * New upstream release.
+  * Added resolvconf support (closes: #194204).
+  * Fixed overrides so that they can be set from clients.
+  * Added --script option (closes: #197285).
+  * Actually use the verbose flag (closes: #200439).
+
+ -- Herbert Xu <herbert@debian.org>  Sat, 19 Jul 2003 21:53:07 +1000
+
+pump (0.8.14-2) unstable; urgency=low
+
+  * Fixed persistent renewal failure bug.
+
+ -- Herbert Xu <herbert@debian.org>  Thu,  6 Mar 2003 19:31:32 +1100
+
+pump (0.8.14-1) unstable; urgency=low
+
+  * New upstream release.
+  * Added Danish debconf template (Michael Kristensen, closes: #174753).
+  * Provide dhcp-client (closes: #178961).
+  * Added nosetup option.
+  * Fixed long standing configuration bug.
+
+ -- Herbert Xu <herbert@debian.org>  Sat,  1 Feb 2003 21:14:04 +1100
+
+pump (0.8.13-4) unstable; urgency=low
+
+  * Hard code ports in network byte order (closes: #169236).
+
+ -- Herbert Xu <herbert@debian.org>  Sat, 16 Nov 2002 08:27:17 +1100
+
+pump (0.8.13-3) unstable; urgency=low
+
+  * Create /var/run in the package (closes: #169109).
+
+ -- Herbert Xu <herbert@debian.org>  Fri, 15 Nov 2002 08:08:00 +1100
+
+pump (0.8.13-2) unstable; urgency=low
+
+  * Hard code bootpc/bootps ports in udeb (closes: #168996).
+
+ -- Herbert Xu <herbert@debian.org>  Thu, 14 Nov 2002 20:27:29 +1100
+
+pump (0.8.13-1) unstable; urgency=low
+
+  * New upstream release.
+  * Made udeb smaller on i386 by reducing alignment.
+  * Retry if write/read to control socket fails.
+
+ -- Herbert Xu <herbert@debian.org>  Sat,  9 Nov 2002 13:21:12 +1100
+
+pump (0.8.11-8) unstable; urgency=low
+
+  * Set connect timeout of backup TCP socket to 1s (closes: #156362).
+
+ -- Herbert Xu <herbert@debian.org>  Sun, 18 Aug 2002 14:10:26 +1000
+
+pump (0.8.11-7) unstable; urgency=low
+
+  * Call setsid(2) when daemonising (closes: #153051).
+  * Always setup interface after DhcpRun (closes: #153749).
+  * Fixed silly DNS search path (closes: #152480).
+  * Fixed benign off-by-one error in vendor debug output (closes: #145978).
+  * Use TCP socket as backup for pump.sock (closes: #148642).
+
+ -- Herbert Xu <herbert@debian.org>  Sun, 11 Aug 2002 18:43:41 +1000
+
+pump (0.8.11-6) unstable; urgency=low
+
+  * Fixed --win-client-ident line in manual page (closes: #141202).
+
+ -- Herbert Xu <herbert@debian.org>  Sun, 28 Apr 2002 13:48:37 +1000
+
+pump (0.8.11-5) unstable; urgency=low
+
+  * Fixed cut-and-paste error in renew.
+
+ -- Herbert Xu <herbert@debian.org>  Wed, 20 Mar 2002 07:35:15 +1100
+
+pump (0.8.11-4) unstable; urgency=low
+
+  * Correction to grammar (Ajay Shah, closes: #131558).
+  * Added Russian debconf translation (Ilgiz Kalmetev, closes: #136603).
+  * Removed oldKernel().
+  * Use AF_PACKET to send discover packets (closes: #137611).
+
+ -- Herbert Xu <herbert@debian.org>  Sun, 17 Mar 2002 12:15:31 +1100
+
+pump (0.8.11-3) unstable; urgency=low
+
+  * New maintainer.
+  * Removed "borken" message.
+  * Make sure gethostname results are null-terminated (closes: #77975).
+  * Kill pump on removal and deconfiguration (closes: #82608).
+  * Fixed file descriptor bugs (closes: #95889).
+  * Removed infinite loop.  The actual bug is fixed in 0.8.11 (closes: #95892).
+  * Added db_go to config script (closes: #121207, #121862, #122432, #122853).
+
+ -- Herbert Xu <herbert@debian.org>  Tue, 25 Dec 2001 19:02:45 +1100
+
+pump (0.8.11-2) testing unstable; urgency=high
+
+  * Merge in patches from RedHat 7.2's pump 0.8.11-7:
+  * Add option to remove dns lookups
+  * Add option to specify lease time in seconds
+  * Add option to disable bootp compatibility
+  * Retry renewal forever
+  * Versioned debhelper depends
+  * fix pump-udeb description
+  * Don't call RedHat postIfup script
+  * Add note that pump has "issues" (addresses #110602, 94222, and others)
+  * Include spanish, dutch, brazillian portuguese, german debconf translations.
+  * Closes: #112342, #92535, #114010, #95355, #102628, #94256, #116946
+
+ -- Steve Dunham <dunham@debian.org>  Mon, 19 Nov 2001 08:48:53 -0800
+
+pump (0.8.11-1) testing unstable; urgency=low
+
+  * New upstream version
+
+ -- Steve Dunham <dunham@debian.org>  Wed, 29 Aug 2001 19:01:28 -0700
+
+pump (0.8.3-3) testing unstable; urgency=low
+
+  * Change section of udeb, add debhelper to source depends. Closes #86480
+  * Upload to testing. (0.8.2 and this fixes severe bugs)
+
+ -- Steve Dunham <dunham@debian.org>  Sun, 18 Feb 2001 10:25:10 -0800
+
+pump (0.8.3-2) woody unstable; urgency=low
+
+  * New standards version and builddeps. Closes #81996
+  * chdir to / in daemon. Closes #63961
+  * Back out fix for broken man. Closes #85836
+  * Tweak description. Closes #85838, #81719, #71963
+  * Add udeb patch. Closes #79841
+  * Add changelog and credits. Closes #60847
+  * Remove init script. Use /etc/network/interfaces.
+  * Make verbose log messages optional. Closes #45211 
+
+ -- Steve Dunham <dunham@debian.org>  Tue, 13 Feb 2001 17:15:41 -0800
+
+pump (0.8.3-1) unstable; urgency=low
+
+  * New upstream version
+
+ -- Steve Dunham <dunham@debian.org>  Sun, 22 Oct 2000 14:27:54 -0700
+
+pump (0.7.3-2) unstable; urgency=low
+
+  * Fix lockup while parsing resolv.conf
+
+ -- Steve Dunham <dunham@debian.org>  Wed,  1 Dec 1999 12:24:22 -0800
+
+pump (0.7.3-1) unstable; urgency=low
+
+  * New upstream source
+  * Run tbl on man page in install because 'man' is broken
+  * 0.7.1 seemed to wedge after setting the address, 0.7.3 appears to work
+  * Remove /etc/default/pump on purge.
+  * Add instructions to postinst script
+
+ -- Steve Dunham <dunham@debian.org>  Tue, 23 Nov 1999 00:24:01 -0800
+
+pump (0.7.1-1) unstable; urgency=low
+
+  * New upstream version
+  * Backed out resolv.pump stuff
+  * Added patch to keep it from forgetting everythin on lease renewal
+  * Changed postinst script to default to running on no interfaces
+
+ -- Steve Dunham <dunham@debian.org>  Fri, 24 Sep 1999 00:38:23 -0400
+
+pump (0.7.0-1) unstable; urgency=low
+
+  * New upstream version (Security fix)
+
+ -- Steve Dunham <dunham@debian.org>  Tue, 17 Aug 1999 14:31:32 -0400
+
+pump (0.6.7-4) unstable; urgency=low
+
+  * Compile with libpopt. Closes #41863
+
+ -- Steve Dunham <dunham@debian.org>  Tue, 27 Jul 1999 14:14:10 -0400
+
+pump (0.6.7-3) unstable; urgency=low
+
+  * Fix interface flags
+
+ -- Steve Dunham <dunham@debian.org>  Thu,  8 Jul 1999 13:55:30 -0400
+
+pump (0.6.7-2) unstable; urgency=low
+
+  * Added Alan Cox's buffer overflow patches
+
+ -- Steve Dunham <dunham@debian.org>  Wed, 23 Jun 1999 00:43:43 -0400
+
+pump (0.6.7-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Steve Dunham <dunham@debian.org>  Thu, 10 Jun 1999 14:45:00 -0400
+
--- pump-0.8.24.orig/debian/TODO
+++ pump-0.8.24/debian/TODO
@@ -0,0 +1,2 @@
+* Make pump-dev
+* Negotiate method to configure network
--- pump-0.8.24.orig/debian/pump.postinst
+++ pump-0.8.24/debian/pump.postinst
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $Id: pump.postinst,v 1.3 2003/09/13 02:58:04 herbert Exp $
+
+set -e
+
+if
+	[ "$1" = configure ] && [ -n "$2" ] &&
+	dpkg --compare-versions "$2" lt 0.8.11-2
+then
+	rm -f /etc/default/pump /etc/init.d/pump /etc/rc?.d/???pump
+fi
+
+#DEBHELPER#
--- pump-0.8.24.orig/debian/control
+++ pump-0.8.24/debian/control
@@ -0,0 +1,29 @@
+Source: pump
+Section: admin
+Priority: optional
+Maintainer: Philippe Coval <rzr@gna.org>
+Standards-Version: 3.8.4
+Build-Depends: libpopt-dev, debhelper (>= 5), quilt
+Vcs-git: git://git.debian.org/git/collab-maint/pump.git
+Vcs-Browser: http://git.debian.org/?p=collab-maint/pump.git
+
+
+Package: pump
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, netbase
+Suggests: resolvconf
+Conflicts: dhcpcd
+Provides: dhcp-client
+Description: BOOTP and DHCP client for automatic IP configuration
+ This is the BOOTP/DHCP client written by RedHat.
+ .
+ DHCP (Dynamic Host Configuration Protocol) and BOOTP (Boot Protocol)
+ are protocols which allow individual devices on an IP network to get
+ their own network configuration information (IP address, subnetmask,
+ broadcast address, etc.) from network servers. The overall purpose of
+ DHCP and BOOTP is to make it easier to administer a large network.
+ .
+ Pump is a combined BOOTP and DHCP client daemon, which allows your
+ machine to retrieve configuration information from a server. You
+ should install this package if you are on a network which uses BOOTP
+ or DHCP.
--- pump-0.8.24.orig/debian/pump-udeb.dirs
+++ pump-0.8.24/debian/pump-udeb.dirs
@@ -0,0 +1,2 @@
+sbin
+var/run
--- pump-0.8.24.orig/debian/rules
+++ pump-0.8.24/debian/rules
@@ -0,0 +1,76 @@
+#!/usr/bin/make -f
+#-*- makefile -*-
+
+default: build
+
+# Made with the aid of dh_make, by Craig Small
+# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess.
+# Some lines taken from debmake, by Christoph Lameter.
+# Copyright 2004-2005 Anibal Monsalve Salazar <anibal@debian.org>
+
+# Uncomment this to turn on verbose mode.
+export DH_VERBOSE=1
+
+DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)
+export DEB_HOST_ARCH
+
+include /usr/share/quilt/quilt.make
+
+
+setup: setup-stamp
+setup-stamp: patch
+	dh_testdir
+
+	rm -rf build
+	mkdir build
+	cp debian/Makefile.build build/Makefile
+
+	sed '1,/^%change/d' < pump.spec > changelog
+
+	touch setup-stamp
+
+build: setup
+	dh_testdir
+	
+	$(MAKE) -C build pump SHOME=$(CURDIR)
+
+clean: unpatch
+	dh_testdir
+	dh_testroot
+
+	rm -rf setup-stamp changelog build
+
+	dh_clean
+
+# Build architecture-independent files here.
+binary-indep: build
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k
+	dh_installdirs
+
+	cp build/pump debian/pump/sbin
+	cp pump.8 debian/pump/usr/share/man/man8/pump.8
+
+	dh_installdocs
+	dh_installchangelogs changelog
+ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+	dh_strip
+endif
+	dh_compress
+	dh_fixperms
+	dh_installdeb
+	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+source diff:                                                                  
+	@echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary
--- pump-0.8.24.orig/debian/patches/series
+++ pump-0.8.24/debian/patches/series
@@ -0,0 +1,6 @@
+00_00_all_debian.patch
+00_all_retvals.patch
+10_all_gentoo.patch
+20_all_redefinition.patch
+30_all_Makefile.patch
+40_all_manpage.patch
--- pump-0.8.24.orig/debian/patches/40_all_manpage.patch
+++ pump-0.8.24/debian/patches/40_all_manpage.patch
@@ -0,0 +1,22 @@
+diff --git a/pump.8 b/pump.8
+index d1dce5c..d976748 100644
+--- a/pump.8
++++ b/pump.8
+@@ -77,7 +77,7 @@ switch	long option	description
+ \-R	\-\-renew	Renew lease immediately
+ \-r	\-\-release	Release interface
+ \-m	\-\-route-metric=\fIMETRIC\fR	Metric to use on routes (normally 0)
+-  	\-\-no\-gateway	Don't configurate a default route for this interface
++  	\-\-no\-gateway	Don't configure a default route for this interface
+   	\-\-no\-resolvconf	Don't use the \fBresolvconf\fR program to update resolv.conf
+   	\-\-no\-ntp	Don't update ntp.conf
+   	\-\-no\-setup	Don't set up anything
+@@ -253,7 +253,7 @@ If the UNIX domain socket (normally \fI/var/run/pump.sock\fR)
+ does not exist,
+ .B pump
+ tries to connect to tcp/127.0.0.1:68.
+-If it is also unreacheable (possibly due to packet filtering),
++If it is also unreachable (possibly due to packet filtering),
+ .B pump
+ will issue a warning to stderr and assume that there is no
+ instance of itself running.
--- pump-0.8.24.orig/debian/patches/00_all_retvals.patch
+++ pump-0.8.24/debian/patches/00_all_retvals.patch
@@ -0,0 +1,38 @@
+--- pump-0.8.24/pump.c	2008-12-20 12:29:28.000000000 +0100
++++ pump.c	2008-12-20 12:28:47.000000000 +0100
+@@ -555,7 +555,11 @@
+   
+ 		listen(sock, 5);
+   
+-		write(conn, &c, 1);
++		if (write(conn, &c, 1) < 0) {
++		    syslog(LOG_ERR, "failed to write to connection: %s\n",
++			   strerror(errno));
++		    exit(1);
++		}
+   
+ out:
+ 		close(conn);
+@@ -731,7 +735,8 @@
+     if (!connect(sock_in, (struct sockaddr *) &addr_in, sizeof(addr_in))) {
+ 	char c;
+ 
+-	read(sock_in, &c, 1);
++	if( read(sock_in, &c, 1) < 0) {}
++
+ 	close(sock_in);
+ 	goto again;
+     }
+@@ -774,7 +779,11 @@
+ 	    exit(1);
+ 	}
+ 
+-	chdir("/");
++	if( chdir("/") < 0 ) {
++	    syslog(LOG_ERR, "couldn't chdir to root: %s\n", strerror(errno));
++	    exit(1);
++	}
++
+ 	umask(077);
+ 	if (bind(sock, (struct sockaddr *) &addr, addrLength)) {
+ 	    syslog(LOG_ERR, "bind to %s failed: %s\n", CONTROLSOCKET,
--- pump-0.8.24.orig/debian/patches/00_00_all_debian.patch
+++ pump-0.8.24/debian/patches/00_00_all_debian.patch
@@ -0,0 +1,2160 @@
+diff --git a/Makefile b/Makefile
+index e8b885d..f9eff0b 100644
+--- a/Makefile
++++ b/Makefile
+@@ -6,7 +6,7 @@ USRSBINPATH = $(sbindir)
+ USRLIBPATH = $(libdir)
+ INCPATH = $(includedir)
+ MAN8PATH = $(mandir)/man8
+-CFLAGS = -fPIC -I. -Wall -Werror -g $(RPM_OPT_FLAGS) -D__STANDALONE__ -DVERSION=\"$(VERSION)\"
++CFLAGS = $(DEB_CFLAGS) -I. -Wall -Werror -g $(RPM_OPT_FLAGS) -D__STANDALONE__ -DVERSION=\"$(VERSION)\" -D_GNU_SOURCE
+ CVSROOT = $(shell cat CVS/Root 2>/dev/null)
+ 
+ ARCH := $(patsubst i%86,i386,$(shell uname -m))
+diff --git a/config.c b/config.c
+index 4d2518b..323366d 100644
+--- a/config.c
++++ b/config.c
+@@ -101,8 +101,9 @@ static int readStanza(char ** cfg, struct pumpOverrideInfo * overrideList,
+  	    }
+ 	
+ 	    *nextO = *override;
+-	    strcpy(nextO->intf.device, rest);
+-	    nextO->script = override->script ? strdup(override->script) : NULL;
++	    strcpy(nextO->device, rest);
++	    if (override->script[0])
++		strcpy(nextO->script, override->script);
+ 
+ 	    (*lineNum)++;
+ 	    if (readStanza(&next, overrideList, nextO, lineNum)) return 1;
+@@ -155,6 +156,8 @@ static int readStanza(char ** cfg, struct pumpOverrideInfo * overrideList,
+ 
+ 	    override->numRetries = num;
+ 	} else if (!strcmp(start, "domainsearch")) {
++	    size_t len;
++
+ 	    if (overrideList != override) {
+ 		parseError(*lineNum, "domainsearch directive may not occur "
+ 			   "inside of device specification");
+@@ -169,12 +172,18 @@ static int readStanza(char ** cfg, struct pumpOverrideInfo * overrideList,
+ 		return 1;
+ 	    }
+ 
++	    len = strlen(argv[0]);
++	    if (len >= sizeof(override->searchPath)) {
++		parseError(*lineNum, "domainsearch directive is too long");
++		return 1;
++	    }
++
+ 	    /*
+ 		We don't free this as other configurations may have inherited 
+ 		it. This could be the wrong decision, but leak would be tiny
+ 		so why worry?
+ 	    */
+-	    override->searchPath = strdup(argv[0]);
++	    memcpy(override->searchPath, argv[0], len + 1);
+ 	    free(argv);
+ 	} else if (!strcmp(start, "nodns")) {
+ 	    if (*rest) {
+@@ -200,7 +209,25 @@ static int readStanza(char ** cfg, struct pumpOverrideInfo * overrideList,
+ 		return 1;
+ 	    }
+ 	    override->flags |= OVERRIDE_FLAG_NONISDOMAIN;
++	} else if (!strcmp(start, "nosetup")) {
++	    if (*rest) {
++		parseError(*lineNum, "unexpected argument to nosetup directive");
++		return 1;
++	    }
++	    override->flags |=
++		OVERRIDE_FLAG_NOSETUP |
++		OVERRIDE_FLAG_NODNS |
++		OVERRIDE_FLAG_NOGATEWAY |
++		OVERRIDE_FLAG_NONISDOMAIN;
++	} else if (!strcmp(start, "noresolvconf")) {
++	    if (*rest) {
++		parseError(*lineNum, "unexpected argument to noresolvconf directive");
++		return 1;
++	    }
++	    override->flags |= OVERRIDE_FLAG_NORESOLVCONF;
+ 	} else if (!strcmp(start, "script")) {
++	    size_t len;
++
+ 	    if (overrideList != override) {
+ 		parseError(*lineNum, "script directive may not occur "
+ 			   "inside of device specification");
+@@ -214,7 +241,14 @@ static int readStanza(char ** cfg, struct pumpOverrideInfo * overrideList,
+ 			   "single argument");
+ 		return 1;
+ 	    }
+-	    override->script = strdup(argv[0]);
++
++	    len = strlen(argv[0]);
++	    if (len >= sizeof(override->script)) {
++		parseError(*lineNum, "script directive is too long");
++		return 1;
++	    }
++
++	    memcpy(override->script, argv[0], len + 1);
+ 	    free(argv);
+         } else {
+ 	    char * error;
+@@ -245,7 +279,6 @@ int readPumpConfig(char * configFile, struct pumpOverrideInfo ** overrides) {
+     if ((fd = open(configFile, O_RDONLY)) < 0) {
+ 	*overrides = calloc(sizeof(**overrides), 2);
+ 	pumpInitOverride(*overrides);
+-	close(fd);
+ 	return 0;
+     }
+ 
+diff --git a/dhcp.c b/dhcp.c
+index 852c28f..4794af8 100644
+--- a/dhcp.c
++++ b/dhcp.c
+@@ -31,9 +31,11 @@
+ #include <netinet/in.h>
+ #include <netinet/ip.h>
+ #include <netinet/udp.h>
++#include <netpacket/packet.h>
+ #include <popt.h>
+ #include <resolv.h>
+ #include <signal.h>
++#include <stdint.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -82,9 +84,6 @@ typedef short bp_int16;
+ #define DHCP_OPTION_CLASS_IDENTIFIER    60
+ #define DHCP_OPTION_CLIENT_IDENTIFIER	61
+ 
+-#define BOOTP_CLIENT_PORT	68
+-#define BOOTP_SERVER_PORT	67
+-
+ #define BOOTP_OPCODE_REQUEST	1
+ #define BOOTP_OPCODE_REPLY	2
+ 
+@@ -126,6 +125,12 @@ struct psuedohUdpHeader {
+     bp_int16 len;
+ };
+ 
++struct ippkt {
++    struct ip ip;
++    struct udphdr udp;
++    char payload[sizeof(struct bootpRequest)];
++} __attribute__ ((packed));
++
+ static void parseReply(struct bootpRequest * breq, struct pumpNetIntf * intf);
+ static char * prepareRequest(struct bootpRequest * breq,
+ 			     int sock, char * device, time_t startTime);
+@@ -134,36 +139,24 @@ static void initVendorCodes(struct bootpRequest * breq);
+ static char * handleTransaction(int s, struct pumpOverrideInfo * override, 
+ 				struct bootpRequest * breq,
+ 			        struct bootpRequest * bresp, 
+-			        struct sockaddr_in * serverAddr,
++				struct sockaddr * serverAddr,
++				socklen_t serverAddrLen,
+ 				struct sockaddr_in * respondant,
+-				int useBootpPacket, 
++				int useBootpPacket, int raw,
+ 				time_t startTime, int dhcpResponseType);
+ static int dhcpMessageType(struct bootpRequest * response);
+-static int oldKernel(void);
+ static char * getInterfaceInfo(struct pumpNetIntf * intf, int s);
+ static char * perrorstr(char * msg);
+ static void addClientIdentifier(int flags, struct bootpRequest * req);
+ static void buildRequest(struct bootpRequest * req, int flags, int type,
+ 		         char * reqHostname, char *class, int lease);
+ static void updateSecCount(struct bootpRequest * breq, time_t startTime);
++static void makeraw(struct ippkt *buf, const void *payload, size_t len);
++static uint32_t checksum(const void *, size_t, uint32_t);
++static uint32_t wrapsum(uint32_t);
+ 
+ static const char vendCookie[] = { 99, 130, 83, 99, 255 };
+ 
+-static int oldKernel(void) {
+-    struct utsname ubuf;
+-    int major1, major2;
+-
+-    uname(&ubuf);
+-    if (!strcasecmp(ubuf.sysname, "linux")) {
+-	if (sscanf(ubuf.release, "%d.%d", &major1, &major2) != 2 ||
+-		(major1 < 2) || (major1 == 2 && major2 == 0)) {
+-	    return 1;
+-	}
+-    }
+-
+-    return 0;
+-}
+-
+ static char * getInterfaceInfo(struct pumpNetIntf * intf, int s) {
+     struct ifreq req;
+     struct sockaddr_in * addrp;
+@@ -177,6 +170,10 @@ static char * getInterfaceInfo(struct pumpNetIntf * intf, int s) {
+     intf->broadcast = addrp->sin_addr;
+     intf->set = PUMP_INTFINFO_HAS_BROADCAST;
+ 
++    if (ioctl(s, SIOCGIFINDEX, &req))
++	return perrorstr("SIOCGIFINDEX");
++    intf->ifindex = req.ifr_ifindex;
++
+     return NULL;
+ }
+ 
+@@ -205,15 +202,18 @@ static char * perrorstr(char * msg) {
+ }
+ 
+ 
+-char * pumpDisableInterface(char * device) {
++char * pumpDisableInterface(struct pumpNetIntf * intf) {
+     struct ifreq req;
+     int s;
+ 
++    if (intf->flags & PUMP_FLAG_NOSETUP)
++	return NULL;
++
+     s = socket(AF_INET, SOCK_DGRAM, 0);
+ 	
+     memset(&req,0,sizeof(req));
+ 
+-    strcpy(req.ifr_name, device);
++    strcpy(req.ifr_name, intf->device);
+     if (ioctl(s, SIOCGIFFLAGS, &req)) {
+ 	close(s);
+ 	return perrorstr("SIOCGIFFLAGS");
+@@ -235,6 +235,12 @@ char * pumpSetupInterface(struct pumpNetIntf * intf) {
+     struct ifreq req;
+     struct rtentry route;
+     int s;
++    char * rc;
++
++    if (intf->flags & PUMP_FLAG_NOSETUP)
++	return NULL;
++
++    if ((rc = pumpDisableInterface(intf))) return rc;
+ 
+     s = socket(AF_INET, SOCK_DGRAM, 0);
+ 	
+@@ -246,34 +252,46 @@ char * pumpSetupInterface(struct pumpNetIntf * intf) {
+     strcpy(req.ifr_name, intf->device);
+    
+     addrp->sin_addr = intf->ip;
+-    if (ioctl(s, SIOCSIFADDR, &req))
+-	return perrorstr("SIOCSIFADDR");
++    if (ioctl(s, SIOCSIFADDR, &req)) {
++	rc = perrorstr("SIOCSIFADDR");
++	goto out;
++    }
+ 
+     addrp->sin_addr = intf->netmask;
+-    if (ioctl(s, SIOCSIFNETMASK, &req))
+-	return perrorstr("SIOCSIFNETMASK");
++    if (ioctl(s, SIOCSIFNETMASK, &req)) {
++	rc = perrorstr("SIOCSIFNETMASK");
++	goto out;
++    }
+ 
+     addrp->sin_addr = intf->broadcast;
+-    if (ioctl(s, SIOCSIFBRDADDR, &req))
+-	return perrorstr("SIOCSIFBRDADDR");
++    if (ioctl(s, SIOCSIFBRDADDR, &req)) {
++	rc = perrorstr("SIOCSIFBRDADDR");
++	goto out;
++    }
+ 
+     if (intf->set & PUMP_INTFINFO_HAS_MTU) {
+-        req.ifr_mtu = intf->mtu;
+-        if (ioctl(s, SIOCSIFMTU, &req))
+-            return perrorstr("SIOCSIFMTU");
++	req.ifr_mtu = intf->mtu;
++	if (ioctl(s, SIOCSIFMTU, &req)) {
++	    rc = perrorstr("SIOCSIFMTU");
++	    goto out;
++	}
+     }
+ 
+     /* Bring up the device, and specifically allow broadcasts through it.
+        Don't mess with flags we don't understand though. */
+-    if (ioctl(s, SIOCGIFFLAGS, &req))
+-	return perrorstr("SIOCGIFFLAGS");
++    if (ioctl(s, SIOCGIFFLAGS, &req)) {
++	rc = perrorstr("SIOCGIFFLAGS");
++	goto out;
++    }
+ 
+     req.ifr_flags |= IFF_UP | IFF_RUNNING | IFF_BROADCAST;
+ 
+-    if (ioctl(s, SIOCSIFFLAGS, &req))
+-	return perrorstr("SIOCSIFFLAGS");
++    if (ioctl(s, SIOCSIFFLAGS, &req)) {
++	rc = perrorstr("SIOCSIFFLAGS");
++	goto out;
++    }
+ 
+-    if (!strcmp(intf->device, "lo") || oldKernel()) {
++    if (!strcmp(intf->device, "lo")) {
+ 	/* add a route for this network */
+ 	route.rt_dev = intf->device;
+ 	route.rt_flags = RTF_UP;
+@@ -288,11 +306,14 @@ char * pumpSetupInterface(struct pumpNetIntf * intf) {
+ 
+ 	if (ioctl(s, SIOCADDRT, &route)) {
+ 	    /* the route cannot already exist, as we've taken the device down */
+-	    return perrorstr("SIOCADDRT 1");
++	    rc = perrorstr("SIOCADDRT 1");
++	    goto out;
+ 	}
+     }
+ 
+-    return NULL;
++out:
++    close(s);
++    return rc;
+ }
+ 
+ int pumpSetupDefaultGateway(struct in_addr * gw) {
+@@ -317,23 +338,30 @@ int pumpSetupDefaultGateway(struct in_addr * gw) {
+     route.rt_dev = NULL;
+ 
+     if (ioctl(s, SIOCADDRT, &route)) {
++	close(s);
+ 	syslog(LOG_ERR, "failed to set default route: %s", strerror(errno));
+ 	return -1;
+     }
+ 
++    close(s);
+     return 0;
+ }
+ 
+ char * pumpPrepareInterface(struct pumpNetIntf * intf, int s) {
+     struct sockaddr_in * addrp;
+     struct ifreq req;
+-    struct rtentry route;
+ 
+     memset(&req,0,sizeof(req));
++    strcpy(req.ifr_name, intf->device);
+ 
+-    addrp = (struct sockaddr_in *) &req.ifr_addr;
++    if (ioctl(s, SIOCGIFINDEX, &req))
++	return perrorstr("SIOCGIFINDEX");
++    intf->ifindex = req.ifr_ifindex;
+ 
+-    strcpy(req.ifr_name, intf->device);
++    if (intf->flags & PUMP_FLAG_NOSETUP)
++	return NULL;
++
++    addrp = (struct sockaddr_in *) &req.ifr_addr;
+     addrp->sin_family = AF_INET;
+     addrp->sin_port = 0;
+     memset(&addrp->sin_addr, 0, sizeof(addrp->sin_addr));
+@@ -344,48 +372,19 @@ char * pumpPrepareInterface(struct pumpNetIntf * intf, int s) {
+     if (ioctl(s, SIOCSIFADDR, &req))
+ 	return perrorstr("SIOCSIFADDR");
+ 
+-    if (oldKernel()) {
+-	if (ioctl(s, SIOCSIFNETMASK, &req))
+-	    return perrorstr("SIOCSIFNETMASK");
+-
+-	/* the broadcast address is 255.255.255.255 */
+-	memset(&addrp->sin_addr, 255, sizeof(addrp->sin_addr));
+-	if (ioctl(s, SIOCSIFBRDADDR, &req))
+-	    return perrorstr("SIOCSIFBRDADDR");
+-    }
+-
+     if (ioctl(s, SIOCGIFFLAGS, &req))
+ 	return perrorstr("SIOCGIFFLAGS");
+     req.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
+     if (ioctl(s, SIOCSIFFLAGS, &req))
+ 	return perrorstr("SIOCSIFFLAGS");
+ 
+-    memset(&route, 0, sizeof(route));
+-    memcpy(&route.rt_gateway, addrp, sizeof(*addrp));
+-
+-    addrp->sin_family = AF_INET;
+-    addrp->sin_port = 0;
+-    addrp->sin_addr.s_addr = INADDR_ANY;
+-    memcpy(&route.rt_dst, addrp, sizeof(*addrp));
+-    memcpy(&route.rt_genmask, addrp, sizeof(*addrp));
+-
+-    route.rt_dev = intf->device;
+-    route.rt_flags = RTF_UP;
+-    route.rt_metric = 0;
+-
+-    if (ioctl(s, SIOCADDRT, &route)) {
+-	if (errno != EEXIST) {
+-	    close(s);
+-	    return perrorstr("SIOCADDRT 3");
+-	}
+-    }
+-
+     return NULL;
+ }
+ 
+ static int dhcpMessageType(struct bootpRequest * response) {
+     unsigned char * chptr;
+     unsigned char option, length;
++
+    
+     chptr = response->vendor;
+ 
+@@ -516,9 +515,17 @@ static void parseReply(struct bootpRequest * breq, struct pumpNetIntf * intf) {
+ 		break;
+ 
+ 	    case BOOTP_OPTION_GATEWAY:
+-		memcpy(&intf->gateway, chptr, 4);
++		intf->numGateways = 0;
++		for (i = 0; i < length; i += 4) {
++		    if (intf->numGateways < MAX_GATEWAYS) {
++			memcpy(&intf->gateways[intf->numGateways++], chptr + i,
++			       4);
++			syslog(LOG_DEBUG, "intf: gateways[%i]: %s", 
++			       i/4, inet_ntoa (intf->gateways[i/4]));
++		    }
++		}
+ 		intf->set |= PUMP_NETINFO_HAS_GATEWAY;
+-		syslog (LOG_DEBUG, "intf: gateway: %s", inet_ntoa (intf->gateway));
++		syslog (LOG_DEBUG, "intf: numGateways: %i", intf->numGateways);
+ 		break;
+ 
+ 	    case BOOTP_OPTION_HOSTNAME:
+@@ -692,6 +699,9 @@ void debugbootpRequest(char *name, struct bootpRequest *breq)  {
+     struct in_addr address;
+     unsigned char *vndptr;
+     unsigned char option, length;
++
++    if (!verbose)
++	return;
+     
+     memset(&address,0,sizeof(address));
+ 	
+@@ -744,12 +754,12 @@ void debugbootpRequest(char *name, struct bootpRequest *breq)  {
+ 	    sprintf (vendor, "%3u %3u", option, length);
+ 	    for (i = 0; i < length; i++)
+ 	      {
+-		if (strlen (vendor) > 22)
++		if (strlen (vendor) > sizeof(vendor2) - 6)
+ 		  {
+ 		    syslog (LOG_DEBUG, "%s: vendor: %s", name, vendor);
+ 		    strcpy (vendor, "++++++");
+ 		  }
+-		snprintf (vendor2, 27, "%s 0x%02x", vendor, *vndptr++);
++		snprintf (vendor2, sizeof(vendor2), "%s 0x%02x", vendor, *vndptr++);
+ 		strcpy (vendor, vendor2);
+ 		
+ 	      }
+@@ -763,11 +773,12 @@ void debugbootpRequest(char *name, struct bootpRequest *breq)  {
+ }
+ 
+ static char * handleTransaction(int s, struct pumpOverrideInfo * override, 
+-				struct bootpRequest * breq,
++			        struct bootpRequest * breq,
+ 			        struct bootpRequest * bresp, 
+-			        struct sockaddr_in * serverAddr,
++			        struct sockaddr * serverAddr,
++			        socklen_t serverAddrLen,
+ 				struct sockaddr_in * respondant,
+-				int useBootpPacket, 
++				const int useBootpPacket, const int raw,
+ 				time_t startTime, int dhcpResponseType) {
+     struct timeval tv;
+     fd_set readfs;
+@@ -786,6 +797,9 @@ static char * handleTransaction(int s, struct pumpOverrideInfo * override,
+     struct udphdr * udpHdr = NULL;
+     struct psuedohUdpHeader pHdr;
+     time_t start = pumpUptime();
++    struct ippkt buf;
++    void * pkt;
++    size_t pktlen, breqlen;
+     
+     memset(&pHdr,0,sizeof(pHdr));
+     debugbootpRequest("breq", breq);
+@@ -802,17 +816,26 @@ static char * handleTransaction(int s, struct pumpOverrideInfo * override,
+ 	return strerror(errno);
+     }
+ 
+-    while (!gotit && tries) {
+-	i = sizeof(*breq);
+-	if (useBootpPacket)
+-	    i -= (DHCP_VENDOR_LENGTH - BOOTP_VENDOR_LENGTH);
++    pkt = breq;
++    breqlen = sizeof(*breq);
++    if (useBootpPacket)
++	breqlen -= (DHCP_VENDOR_LENGTH - BOOTP_VENDOR_LENGTH);
++    pktlen = breqlen;
++    if (raw) {
++	pkt = &buf;
++	pktlen += sizeof(struct ip) + sizeof(struct udphdr);
++    }
+ 
++    while (!gotit && tries) {
+ 	if (resend) {
+ 	    if (startTime != -1)
+ 		updateSecCount(breq, startTime);
+ 
+-	    if (sendto(s, breq, i, 0, (struct sockaddr *) serverAddr, 
+-		       sizeof(*serverAddr)) != i) {
++	    if (raw)
++		makeraw(&buf, breq, breqlen);
++
++	    if (sendto(s, pkt, pktlen, 0, (struct sockaddr *) serverAddr, 
++		       serverAddrLen) != pktlen) {
+ 		close(sin);
+ 		return perrorstr("sendto");
+ 	    }
+@@ -890,9 +913,9 @@ static char * handleTransaction(int s, struct pumpOverrideInfo * override,
+ 	    continue;
+ */
+ 
+-	    if (ntohs(udpHdr->source) != BOOTP_SERVER_PORT)
++	    if (udpHdr->source != bootp_server_port)
+ 		continue;
+-	    if (ntohs(udpHdr->dest) != BOOTP_CLIENT_PORT) 
++	    if (udpHdr->dest != bootp_client_port) 
+ 		continue;
+ 	    /* Go on with this packet; it looks sane */
+ 
+@@ -1022,12 +1045,12 @@ static int createSocket(const char * device) {
+     }
+ 
+     if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1)) {
+-	syslog(LOG_ERR, "SO_BINDTODEVICE %s (%zd) failed: %s", device, strlen(device), strerror(errno));
++	syslog(LOG_ERR, "SO_BINDTODEVICE %s (%zu) failed: %s", device, strlen(device), strerror(errno));
+     }
+ 
+     memset(&clientAddr.sin_addr, 0, sizeof(&clientAddr.sin_addr));
+     clientAddr.sin_family = AF_INET;
+-    clientAddr.sin_port = htons(BOOTP_CLIENT_PORT);	/* bootp client */
++    clientAddr.sin_port = bootp_client_port;  /* bootp client */
+ 
+     if (bind(s, (struct sockaddr *) &clientAddr, sizeof(clientAddr))) {
+ 	close(s); 
+@@ -1046,7 +1069,7 @@ int pumpDhcpRelease(struct pumpNetIntf * intf) {
+     char hostname[1024];
+ 
+     if (!(intf->set & PUMP_INTFINFO_HAS_LEASE)) {
+-	pumpDisableInterface(intf->device);
++	pumpDisableInterface(intf);
+ 	syslog(LOG_INFO, "disabling interface %s", intf->device);
+ 
+ 	return 0;
+@@ -1057,7 +1080,7 @@ int pumpDhcpRelease(struct pumpNetIntf * intf) {
+     if ((chptr = prepareRequest(&breq, s, intf->device, pumpUptime()))) {
+ 	close(s);
+ 	while (1) {
+-	    pumpDisableInterface(intf->device);
++	    pumpDisableInterface(intf);
+ 	    return 0;
+ 	}
+     }
+@@ -1072,6 +1095,7 @@ int pumpDhcpRelease(struct pumpNetIntf * intf) {
+ 		      strlen(intf->hostname) + 1, intf->hostname);
+     } else {
+ 	gethostname(hostname, sizeof(hostname));
++	hostname[sizeof(hostname) - 1] = 0;
+ 	if (strcmp(hostname, "localhost") && 
+ 	    strcmp(hostname, "localhost.localdomain")) {
+ 	    addVendorCode(&breq, BOOTP_OPTION_HOSTNAME, 
+@@ -1080,13 +1104,13 @@ int pumpDhcpRelease(struct pumpNetIntf * intf) {
+     }
+ 
+     serverAddr.sin_family = AF_INET;
+-    serverAddr.sin_port = htons(BOOTP_SERVER_PORT);	/* bootp server */
++    serverAddr.sin_port = bootp_server_port;	/* bootp server */
+     serverAddr.sin_addr = intf->bootServer;
+ 
+-    handleTransaction(s, NULL, &breq, &bresp, &serverAddr, NULL, 0, 
+-		      -1, NORESPONSE);
++    handleTransaction(s, NULL, &breq, &bresp, (struct sockaddr *) &serverAddr,
++		      sizeof(serverAddr), NULL, 0, 0, -1, NORESPONSE);
+ 
+-    pumpDisableInterface(intf->device);
++    pumpDisableInterface(intf);
+     close(s);
+ 
+     if (intf->set & PUMP_NETINFO_HAS_HOSTNAME)
+@@ -1116,7 +1140,7 @@ int pumpDhcpRenew(struct pumpNetIntf * intf) {
+ 
+     if ((chptr = prepareRequest(&breq, s, intf->device, pumpUptime()))) {
+ 	close(s);
+-	while (1);	/* problem */
++	return 1;
+     }
+ 
+     messageType = DHCP_TYPE_REQUEST;
+@@ -1132,6 +1156,7 @@ int pumpDhcpRenew(struct pumpNetIntf * intf) {
+ 		      intf->hostname);
+     } else {
+ 	gethostname(hostname, sizeof(hostname));
++	hostname[sizeof(hostname) - 1] = 0;
+ 	if (strcmp(hostname, "localhost") && 
+ 	    strcmp(hostname, "localhost.localdomain")) {
+ 	    addVendorCode(&breq, BOOTP_OPTION_HOSTNAME, 
+@@ -1143,11 +1168,12 @@ int pumpDhcpRenew(struct pumpNetIntf * intf) {
+     addVendorCode(&breq, DHCP_OPTION_LEASE, 4, &i);
+ 
+     serverAddr.sin_family = AF_INET;
+-    serverAddr.sin_port = htons(BOOTP_SERVER_PORT);	/* bootp server */
++    serverAddr.sin_port = bootp_server_port;	/* bootp server */
+     serverAddr.sin_addr = intf->bootServer;
+ 
+-    if (handleTransaction(s, NULL, &breq, &bresp, &serverAddr, NULL, 0,
+-			   startTime, DHCP_TYPE_ACK)) {
++    if (handleTransaction(s, NULL, &breq, &bresp,
++			  (struct sockaddr *) &serverAddr, sizeof(serverAddr),
++			  NULL, 0, 0, startTime, DHCP_TYPE_ACK)) {
+ 	close(s);
+ 	return 1;
+     }
+@@ -1232,6 +1258,7 @@ static void buildRequest(struct bootpRequest * req, int flags, int type,
+     if (!reqHostname) {
+ 	reqHostname = alloca(200);
+ 	gethostname(reqHostname, 200);
++	reqHostname[199] = 0;
+ 	if (!strcmp(reqHostname, "localhost") ||
+ 	    !strcmp(reqHostname, "localhost.localdomain"))
+ 	    reqHostname = NULL;
+@@ -1254,15 +1281,13 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+ 		  struct pumpOverrideInfo * override) {
+     int s;
+     struct sockaddr_in serverAddr;
+-    struct sockaddr_in clientAddr;
+-    struct sockaddr_in broadcastAddr;
++    struct sockaddr_ll broadcastAddr;
+     struct bootpRequest breq, bresp;
+     char * chptr;
+     time_t startTime = pumpUptime();
+-    int true = 1;
+-    int ttl = 16;
+     char * saveDeviceName;
+     unsigned char messageType;
++    struct pumpOverrideInfo saveOverride;
+ 
+     /* If device is the same as intf->device, don't let the memset()
+        blow away the device name */
+@@ -1270,25 +1295,25 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+     strcpy(saveDeviceName, device);
+     device = saveDeviceName;
+ 
++    memcpy(&saveOverride, override, sizeof(*override));
++    override = &saveOverride;
++
+     memset(intf, 0, sizeof(*intf));
+     strcpy(intf->device, device);
+     intf->reqLease = reqLease;
+     intf->set |= PUMP_INTFINFO_HAS_REQLEASE;
++    memcpy(&intf->override, override, sizeof(*override));
+ 
+-    s = socket(AF_INET, SOCK_DGRAM, 0);
++    /* Save these for later */
++    intf->flags = flags & PUMP_FLAG_WINCLIENTID;
++    if (override && (override->flags & OVERRIDE_FLAG_NOSETUP))
++	intf->flags |= PUMP_FLAG_NOSETUP;
++
++    s = socket(AF_PACKET, SOCK_DGRAM, ntohs(ETH_P_IP));
+     if (s < 0) {
+ 	return perrorstr("socket");
+     }
+ 
+-    if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &true, sizeof(true))) {
+-	close(s);
+-	return perrorstr("setsockopt");
+-    }
+-    if (setsockopt(s, SOL_IP, IP_TTL, &ttl, sizeof(ttl))) {
+-	close(s);
+-	return perrorstr("setsockopt");
+-    }
+-
+     if (flags & PUMP_FLAG_NOCONFIG) {
+ 	if ((chptr = getInterfaceInfo(intf, s))) {
+ 	    close(s);
+@@ -1301,7 +1326,7 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+ 
+     if ((chptr = prepareRequest(&breq, s, intf->device, startTime))) {
+ 	close(s);
+-	pumpDisableInterface(intf->device);
++	pumpDisableInterface(intf);
+ 	return chptr;
+     }
+ 
+@@ -1318,19 +1343,10 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+         addVendorCode(&breq, DHCP_OPTION_CLASS_IDENTIFIER,
+                       strlen(class) + 1, class);
+     }
+-    memset(&clientAddr.sin_addr, 0, sizeof(&clientAddr.sin_addr));
+-    clientAddr.sin_family = AF_INET;
+-    clientAddr.sin_port = htons(BOOTP_CLIENT_PORT);	/* bootp client */
+-
+-    if (bind(s, (struct sockaddr *) &clientAddr, sizeof(clientAddr))) {
+-	pumpDisableInterface(intf->device);
+-	close(s);
+-	return perrorstr("bind");
+-    }
+ 
+     memset(&serverAddr,0,sizeof(serverAddr));
+     serverAddr.sin_family = AF_INET;
+-    serverAddr.sin_port = htons(BOOTP_SERVER_PORT);	/* bootp server */
++    serverAddr.sin_port = bootp_server_port;   /* bootp server */
+ 
+ #if 0
+     /* seems like a good idea?? */
+@@ -1339,27 +1355,21 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+ #endif 
+ 
+     memset(&broadcastAddr,0,sizeof(broadcastAddr));
+-    broadcastAddr.sin_family = AF_INET;
+-    broadcastAddr.sin_port = htons(BOOTP_SERVER_PORT);
+-
+-#if 0
+-    /* this too! */
+-    if (intf->set & PUMP_INTFINFO_HAS_BROADCAST)
+-	broadcastAddr.sin_addr = intf->broadcast;
+-#endif
+-
+-    memset(&broadcastAddr.sin_addr, 0xff, 
+-	   sizeof(broadcastAddr.sin_addr));  /* all 1's broadcast */
++    memset(&broadcastAddr.sll_addr, ~0, ETH_ALEN);
++    broadcastAddr.sll_halen = ETH_ALEN;
++    broadcastAddr.sll_ifindex = intf->ifindex;
++    broadcastAddr.sll_protocol = htons(ETH_P_IP);
+ 
+     syslog (LOG_DEBUG, "PUMP: sending discover\n");
+ 
+     if (override && (override->flags & OVERRIDE_FLAG_NOBOOTP))
+       syslog (LOG_DEBUG, "PUMP: Ignoring non-DHCP BOOTP responses\n");
+  
+-    if ((chptr = handleTransaction(s, override, &breq, &bresp, &broadcastAddr,
+-				   NULL, (override && (override->flags & OVERRIDE_FLAG_NOBOOTP))?0:1, startTime, DHCP_TYPE_OFFER))) {
++    if ((chptr = handleTransaction(s, override, &breq, &bresp,
++				   (struct sockaddr *) &broadcastAddr,
++				   sizeof(broadcastAddr), NULL, (override && (override->flags & OVERRIDE_FLAG_NOBOOTP))?0:1, 1, startTime, DHCP_TYPE_OFFER))) {
+ 	close(s);
+-	pumpDisableInterface(intf->device);
++	pumpDisableInterface(intf);
+ 	return chptr;
+     }
+ 
+@@ -1378,17 +1388,19 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+ 
+ 	/* Send another DHCP_DISCOVER with the proper option list */
+ 	if ((chptr = handleTransaction(s, override, &breq, &bresp, 
+-				       &broadcastAddr, NULL, 0, 
++				       (struct sockaddr *) &broadcastAddr,
++				       sizeof(broadcastAddr),
++				       NULL, 0, 1,
+ 				       startTime, DHCP_TYPE_OFFER))) {
+ 	    close(s);
+-	    pumpDisableInterface(intf->device);
++	    pumpDisableInterface(intf);
+ 	    return chptr;
+ 	}
+ 
+ 
+ 	if (dhcpMessageType(&bresp) != DHCP_TYPE_OFFER) {
+ 	    close(s);
+-	    pumpDisableInterface(intf->device);
++	    pumpDisableInterface(intf);
+ 	    return "dhcp offer expected";
+ 	}
+ 
+@@ -1396,7 +1408,7 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+ 
+ 	if (getVendorCode(&bresp, DHCP_OPTION_SERVER, &serverAddr.sin_addr, sizeof(struct in_addr))) {
+ 	    syslog (LOG_DEBUG, "DHCPOFFER didn't include server address");
+-	    intf->bootServer = broadcastAddr.sin_addr;
++	    intf->bootServer.s_addr = INADDR_BROADCAST;
+ 	}
+ 
+ 	initVendorCodes(&breq);
+@@ -1409,10 +1421,12 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+ 	/* why do we need to use the broadcast address here? better reread the
+ 	   spec! */
+ 	if ((chptr = handleTransaction(s, override, &breq, &bresp, 
+-				       &broadcastAddr, NULL, 0, 
++				       (struct sockaddr *) &broadcastAddr,
++				       sizeof(broadcastAddr),
++				       NULL, 0, 1,
+ 				       startTime, DHCP_TYPE_ACK))) {
+ 	    close(s);
+-	    pumpDisableInterface(intf->device);
++	    pumpDisableInterface(intf);
+ 	    return chptr;
+ 	}
+ 
+@@ -1422,7 +1436,7 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+ 
+ 	if (getVendorCode(&bresp, DHCP_OPTION_SERVER, &intf->bootServer, sizeof(struct in_addr))) {
+ 	    syslog (LOG_DEBUG, "DHCPACK didn't include server address");
+-	    intf->bootServer = broadcastAddr.sin_addr;
++	    intf->bootServer.s_addr = INADDR_BROADCAST;
+ 	}
+ 
+ 	intf->set |= PUMP_INTFINFO_HAS_BOOTSERVER;
+@@ -1434,9 +1448,6 @@ char * pumpDhcpClassRun(char * device, int flags, int reqLease,
+     if (flags & PUMP_FLAG_FORCEHNLOOKUP)
+ 	intf->set &= ~(PUMP_NETINFO_HAS_DOMAIN | PUMP_NETINFO_HAS_HOSTNAME);
+ 
+-    /* Save these for later */
+-    intf->flags = flags & PUMP_FLAG_WINCLIENTID;
+-
+     return NULL;
+ }
+ 
+@@ -1448,10 +1459,9 @@ char * pumpDhcpRun(char * device, int flags, int reqLease,
+ }
+ 
+ void pumpInitOverride(struct pumpOverrideInfo * override) {
+-    strcpy(override->intf.device, "MASTER");
++    strcpy(override->device, "MASTER");
+     override->timeout = DEFAULT_TIMEOUT;
+     override->numRetries = DEFAULT_NUM_RETRIES;
+-    override->script = NULL;
+ }
+ 
+ /*
+@@ -1487,3 +1497,68 @@ time_t pumpUptime() {
+     return (time_t)secs;
+ }
+ 
++static void makeraw(struct ippkt *buf, const void *payload, size_t len) {
++	size_t total = sizeof(struct ip) + sizeof(struct udphdr) + len;
++
++	buf->ip.ip_v = 4;
++	buf->ip.ip_hl = 5;
++	buf->ip.ip_tos = IPTOS_LOWDELAY;
++	buf->ip.ip_len = htons(total);
++	buf->ip.ip_id = 0;
++	buf->ip.ip_off = 0;
++	buf->ip.ip_ttl = 16;
++	buf->ip.ip_p = IPPROTO_UDP;
++	buf->ip.ip_sum = 0;
++	buf->ip.ip_src.s_addr = INADDR_ANY;
++	buf->ip.ip_dst.s_addr = INADDR_BROADCAST;
++
++	buf->ip.ip_sum = wrapsum(checksum(&buf->ip, sizeof(buf->ip), 0));
++
++	buf->udp.source = bootp_client_port;
++	buf->udp.dest = bootp_server_port;
++	buf->udp.len = htons(sizeof(struct udphdr) + len);
++	buf->udp.check = 0;
++
++	buf->udp.check =
++		wrapsum(
++			checksum(
++				&buf->udp, sizeof(buf->udp),
++				checksum(
++					payload, len, 
++					checksum(
++						&buf->ip.ip_src,
++						2 * sizeof(buf->ip.ip_src),
++						IPPROTO_UDP +
++							(uint32_t) 
++							ntohs(buf->udp.len)
++					)
++				)
++			)
++		);
++
++	memcpy(buf->payload, payload, len);
++}
++
++uint32_t checksum(const void *buf, size_t len, uint32_t sum) {
++	const char *p = buf;
++	size_t i;
++
++	for (i = 0; i < (len & ~1); i += 2) {
++		sum += ntohs(*(uint16_t *)(p + i));
++		if (sum > 0xffff)
++			sum -= 0xffff;
++	}
++
++	if (i < len) {
++		sum += p[i] << 8;
++		if (sum > 0xffff)
++			sum -= 0xffff;
++	}
++
++	return sum;
++}
++
++uint32_t wrapsum(uint32_t sum) {
++	sum = ~sum & 0xffff;
++	return htons(sum);
++}
+diff --git a/pump.8 b/pump.8
+index fc68ba4..04deffd 100644
+--- a/pump.8
++++ b/pump.8
+@@ -1,4 +1,5 @@
+ .\" Copyright 1999 Red Hat Software, Inc.
++.\" August 2004: Updated by Thomas Hood <jdthood@yahoo.co.uk>
+ .\"
+ .\" This man page is free documentation; you can redistribute it and/or modify
+ .\" it under the terms of the GNU General Public License as published by
+@@ -14,69 +15,120 @@
+ .\" along with this man page; if not, write to the Free Software
+ .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+-.TH PUMP 8 "December 07, 1999" "Linux" "Linux Administrator's Manual"
++.TH PUMP 8 "26 August 2004" "Linux" "Linux Administrator's Manual"
+ .SH NAME
+ pump \- configure network interface via BOOTP or DHCP protocol
+ .SH SYNOPSIS
+-/sbin/pump [-krRsd?] [-c \fIARG\fP] [-h \fIhostname\fP] [-i \fIiface\fP] [-l \fIhours\fP] [--lookup-hostname] [--usage]
++.B pump
++.BR "" [ \-krRsd ]
++.BR "" [ \-c | \-\-config\-file
++.IR FILE ]
++.BR "" [ \-h | \-\-hostname
++.IR HOSTNAME ]
++.BR "" [ \-i | \-\-interface
++.IR IFACE ]
++.BR "" [ \-l | \-\-lease
++.IR HOURS ]
++.BR "" [ \-\-lookup\-hostname ]
++.BR "" [ \-\-no\-dns "] [" \-\-no\-gateway "] [" \-\-no\-setup "] [" \-\-no\-resolvconf ]
++.BR "" [ \-\-release "] [" \-\-renew "] [" \-\-script =
++.IR ISCRIPT ]
++.BR "" [ \-\-status ]
++.BR "" [ \-\-win\-client\-ident ]
++.P
++.B pump
++.BR "" [ \-? | \-\-help "] [" \-\-usage ]
+ .SH DESCRIPTION
+-pump is a daemon that manages network interfaces that are
+-controlled by either the DHCP or BOOTP protocol.
++.B pump
++is a daemon that manages network interfaces that are controlled
++by either the DHCP or BOOTP protocol.
+ 
+-While pump may be started manually, it is normally started
+-automatically by the /sbin/ifup script for devices configured
+-via BOOTP or DHCP.
++While
++.B pump
++may be started manually, it is normally started automatically by
++.BR ifup (8)
++for devices configured via BOOTP or DHCP.
+ 
+-Once pump is managing an interface, you can run pump to query
++If
++.B pump
++is managing an interface, you can run it again to query
+ the status of that interface.  For example,
+ .br
+-\f(CW/sbin/pump -i eth0 --status \fR
++    \f(CWpump \-i eth0 \-\-status\fR
+ .br
+ will print the current status of device eth0.
+-.SH "COMMAND-LINE OPTIONS"
++.SH "COMMAND LINE OPTIONS"
+ .TS
+ lB lB lB
+ lfCW lfCW l.
+ switch	long option	description
+-.TH
+--c	--config-file=ARG	Configuration file to use instead of 
+-		/etc/pump.conf
+--h	--hostname=hostname	Hostname to request
+--i	--interface=iface	Interface to configure (normally eth0)
+--k	--kill	Kill daemon (and disable all interfaces)
+--l	--lease=hours	Lease time to request (in hours)
+-	--lookup-hostname	Always look up hostname and domain in DNS
+--r	--release	Release interface
+--R	--renew	Force immediate lease renewal
+--s	--status	Display interface status
+--d	--no-dns	Don't update resolv.conf
+-  	--no-gateway	Don't configurate a default route for this interface
+-	--win-client-id	Specify a Windows-like client identifier
+--?	--help	Show this help message
+-	--usage	Display brief usage message
++\-?	\-\-help	Show this help message
++\-c	\-\-config\-file=\fIFILE\fR	Get configuration from \fIFILE\fR instead of /etc/pump.conf
++\-d	\-\-no\-dns	Don't update DNS resolver configuration
++\-h	\-\-hostname=\fIHOSTNAME\fR	Request \fIHOSTNAME\fR
++\-i	\-\-interface=\fIIFACE\fR	Manage \fIIFACE\fR rather than eth0
++\-k	\-\-kill	Kill daemon (and disable all interfaces)
++\-l	\-\-lease=\fIHOURS\fR	Request least time of \fIHOURS\fR
++	\-\-lookup\-hostname	Look up hostname in DNS
++\-R	\-\-renew	Renew lease immediately
++\-r	\-\-release	Release interface
++  	\-\-no\-gateway	Don't configurate a default route for this interface
++  	\-\-no\-resolvconf	Don't use the \fBresolvconf\fR program to update resolv.conf
++  	\-\-no\-setup	Don't set up anything
++  	\-\-script=\fISCRIPT\fR	Call \fISCRIPT\fR (or null string to disable)
++\-s	\-\-status	Display interface status
++	\-\-usage	Display a brief usage message
++	\-\-win\-client\-ident	Specify a Windows(tm)-like client identifier
+ .TE
+-.SH LOGGING
+-Pump logs a good deal of information to syslog, much of it at the DEBUG
+-level. If you're having trouble, it's a good idea to turn up syslog's logging
+-level.
+-
+-.SH CONFIG FILE
+-Pump supports a simple configuration file which lets you tune its behavior.
+-By default, it looks at \fI/etc/pump.conf\fR, though the \fB-c\fR option
+-lets you override that.
+-
+-The configuration file is line oriented, and most line contains a
+-directive followed by zero or more arguments. Arguments are handled
+-similar to how shells handle command arguments, allowing the use of
+-quotes and backslash escapes. Comments are allowed, and must begin with
+-a # character, and spaces and tabs are ignored.
+-
+-Directives may be specified at two levels, global and specific. Global 
+-directives change pump's behavior for all of the devices which it manages,
+-while specific directives change pump's behavior for a single device. 
++.SH "OPTION NOTES"
++The
++.B \-\-lookup\-hostname
++option causes
++.B pump
++to ignore the host and domain names returned by the server
++and instead
++to look these up in DNS using the IP address of the interface.
++The name that is looked up is used in forming the
++.B search
++line in the resolv.conf file.
++Thus, if either the
++.B \-\-no\-dns
++or
++.B domainsearch
++option is used then
++.B \-\-lookup\-hostname
++has no effect.
++.P
++Note that
++.B pump
++itself never sets the computer's hostname.
++
++.SH "CONFIGURATION FILE"
++You can tune the behavior of
++.B pump
++using a configuration file.
++By default
++.B pump
++reads \fI/etc/pump.conf\fR but you can change this using the
++\fB\-\-config\-file\fR option.
++
++The configuration file is line-oriented.
++Most lines contain a directive followed by zero or more arguments.
++Arguments are handled similarly to how shells handle command arguments,
++allowing the use of quotes and backslash escapes.
++Comments are allowed, and must begin with a # character.
++Spaces and tabs are ignored.
++
++Directives may be specified at two levels: global and specific.
++Global directives change
++.BR pump 's
++behavior for all of the devices that it manages
++whereas specific directives change
++.BR pump 's
++behavior for a single device. 
+ Later directives always override earlier ones.
+ 
+-Here is an example /etc/pump.conf:
++Here is an example configuration file:
+ 
+ .nf
+ .ta +3i
+@@ -91,71 +143,108 @@ device eth1 {
+ .fi
+ 
+ .pp
+-This configuration file tells pump to use a specific DNS search path rather
+-deriving one from the DHCP or BOOTP server response, to retry each request
+-3 times (for a total of 4 tries), and not to change any DNS configuration
++This configuration file tells
++.B pump
++to use a specific DNS search path rather
++than deriving one from the DHCP or BOOTP server response, to retry each request
++3 times (for a total of 4 tries), and not to change the DNS configuration file
+ when it's configuring the eth1 device.
+ 
+ Here is a complete list of directives:
+ 
+ .TP
+-\fBdevice\fR \fIdevice\fR
+-Specify specific directives for the indicated device. This directive must
++\fBdevice\fR \fIDEVICE\fR
++Specify specific directives for \fIDEVICE\fR. This directive must
+ be followed by a {, and the list of specific directives must end with a }
+-on its own line. These directives may not be nested.
++on its own line.
++These directives may not be nested.
+ 
+ .TP
+-\fBdomainsearch\fR \fIsearchpath\fR
+-Rather then deriving the DNS search path (for /etc/resolv.conf), use the
+-one which is given. As a machine only has a single DNS search path, this
+-directive may only be used globally. 
++\fBdomainsearch\fR \fISEARCHPATH\fR
++Use \fISEARCHPATH\fR as the DNS search path instead of the domain
++name returned by the server or the domain part of the fully
++qualified hostname.
++As a machine only has a single DNS search path, this directive may
++only be used globally. 
+ 
+ .TP
+ \fBnonisdomain\fR
+-Don't set a new NIS domain. Normally \fBpump\fR sets the system's NIS domain
+-if an NIS domain is specified by the dhcp server and the current NIS domain 
+-is empty or \fBlocaldomain\fR.
++Don't set the NIS domain.
++Normally \fBpump\fR sets the system's NIS domain
++if an NIS domain is specified by the DHCP server
++and the current NIS domain is empty or \fBlocaldomain\fR.
+ This directive may only be used within a \fBdevice\fR directive.
+ 
+ .TP
+ \fBnodns\fR
+-Don't create a new /etc/resolv.conf when this interface is configured. This
+-directive may only be used within a \fBdevice\fR directive.
++Don't update /etc/resolv.conf when the interface is configured.
++This directive may only be used within a \fBdevice\fR directive.
+ 
+ .TP
+ \fBnogateway\fR
+-Ignore any default gateway suggested by the DHCP server for this device. This
+-can be usefull on machines with multiple ethernet cards.
++Ignore any default gateway suggested by the DHCP server for this device.
++This can be useful on machines with multiple Ethernet cards.
++
++.TP
++\fBnosetup\fR
++Don't set up anything on the local machine as a result of DHCP operations.
++This implies \fBnodns\fR, \fBnonisdomain\fR and \fBnogateway\fR.
++This option is useful, for example,
++if you want to perform setup in customised scripts.
+ 
+ .TP
+-\fBretries\fR \fIcount\fR
+-Retry each phase of the DHCP process \fIcount\fR times.
++\fBnoresolvconf\fR
++Don't use the resolvconf program to update /etc/resolv.conf;
++instead, update /etc/resolv.conf directly.
++(This option is only relevant if
++.B \-\-nodns
++is not used.)
+ 
+ .TP
+-\fBtimeout\fR \fIcount\fR
+-Don't let any one step of the DHCP process take more then \fIcount\fR seconds.
++\fBretries\fR \fICOUNT\fR
++Retry each phase of the DHCP process \fICOUNT\fR times.
+ 
+ .TP
+-\fBscript\fR \fIexecutable-filename\fR
++\fBtimeout\fR \fICOUNT\fR
++Don't let any one step of the DHCP process take more then \fICOUNT\fR seconds.
++
++.TP
++\fBscript\fR \fIFILE\fR
+ 
+ .TS
+ lB lB lB lB
+ lB lfCW lfCW lfCW.
+-.TH
+ Condition	arg1	arg2	arg3
+ lease	up	eth0	1.2.3.4
+ renewal	renewal	eth0	2.3.4.5
+ release	down	eth0
+ .TE
+ 
+-When events occur in negotiation with the server, calls the given
+-executable or script.  Scripts are called when a lease is granted,
+-when a renewal is negotiated, and when the interface is brought
+-down and the address released.  The scripts are called with two
+-or three arguments, depending on the condition, as documented in
+-the table above.
++When events occur in negotiation with the server, call the executable \fIFILE\fR.
++Scripts are called when a lease is granted, when a renewal is negotiated,
++and when the interface is brought down and the address released.
++The script is called with two or three arguments, depending on the condition,
++as documented in the table above.
++
++.SH LOGGING
++The program logs a good deal of information to syslog,
++much of it at the DEBUG level.
++If you're having trouble, it's a good idea to turn up syslog's logging level.
+ 
+ .SH BUGS
++
++At startup
++.B pump
++tries to detect whether another instance of itself is running.
++If the UNIX domain socket (normally \fI/var/run/pump.sock\fR)
++does not exist,
++.B pump
++tries to connect to tcp/127.0.0.1:68.
++If it is also unreacheable (possibly due to packet filtering),
++.B pump
++will issue a warning to stderr and assume that there is no
++instance of itself running.
++
+ Probably limited to Ethernet, might work on PLIP, probably not 
+ ARCnet and Token Ring. The configuration file should let you do more
+ things.
+@@ -163,5 +252,5 @@ things.
+ Submit bug reports at the Bug Track link at
+ http://developer.redhat.com/
+ .SH QUIBBLE
+-A pump, like a boot[p], is something you wear on your foot. Some of us
+-like the name (I know, hard to believe)!
++A pump, like a boot[p], is something you wear on your foot.
++Some of us like the name (I know, hard to believe)!
+diff --git a/pump.c b/pump.c
+index 0bd3ff2..83641d2 100644
+--- a/pump.c
++++ b/pump.c
+@@ -52,6 +52,12 @@
+ #include "config.h"
+ #include "pump.h"
+ 
++int verbose = 0;
++#if !UDEB
++int bootp_client_port;
++int bootp_server_port;
++#endif
++
+ #define N_(foo) (foo)
+ 
+ #define PROGNAME "pump"
+@@ -69,6 +75,7 @@ struct command {
+ 	    int flags;
+ 	    int reqLease;			/* in seconds */
+ 	    char reqHostname[200];
++	    struct pumpOverrideInfo override;
+ 	} start;
+ 	int result;				/* 0 for success */
+ 	struct {
+@@ -90,8 +97,6 @@ struct command {
+     } u;
+ };
+ 
+-static int openControlSocket(char * configFile, struct pumpOverrideInfo * override);
+-
+ char * readSearchPath(void) {
+     int fd;
+     struct stat sb;
+@@ -132,14 +137,15 @@ char * readSearchPath(void) {
+     return NULL;
+ }
+ 
+-static void createResolvConf(struct pumpNetIntf * intf, char * domain,
+-			     int isSearchPath) {
++static void createResolvConf(struct pumpNetIntf * intf, struct pumpOverrideInfo * override, char * domain) {
+     FILE * f;
+     int i;
+     char * chptr;
++    int resolvconf;
+ 
+     /* force a reread of /etc/resolv.conf if we need it again */
+     res_close();
++    endhostent();
+ 
+     if (!domain) {
+ 	domain = readSearchPath();
+@@ -148,63 +154,56 @@ static void createResolvConf(struct pumpNetIntf * intf, char * domain,
+ 	    strcpy(chptr, domain);
+ 	    free(domain);
+ 	    domain = chptr;
+-	    isSearchPath = 1;
+ 	}
+     }
+ 
+-    f = fopen("/etc/resolv.conf", "w");
+-    if (!f) {
+-	syslog(LOG_ERR, "cannot create /etc/resolv.conf: %s\n",
+-	       strerror(errno));
+-	return;
++    resolvconf = !(override->flags & OVERRIDE_FLAG_NORESOLVCONF);
++    if (resolvconf) {
++	struct stat buf;
++
++	if (stat("/sbin/resolvconf", &buf) < 0)
++	    resolvconf = 0;
+     }
+ 
+-    if (domain && isSearchPath) {
+-	fprintf(f, "search %s\n", domain);
+-    } else if (domain && !strchr(domain, '.')) {
+-	fprintf(f, "search %s\n", domain);
+-    } else if (domain) {
+-	fprintf(f, "search");
+-	chptr = domain;
+-	do {
+-	    /* If there is a single . in the search path, write it out
+-	     * only if the toplevel domain is com, edu, gov, mil, org,
+-	     * net 
+-	     */
+-	    /* Don't do that! It breaks virtually all installations
+-	     * in Europe.
+-	     * Besides, what's wrong with some company assigning hostnames
+-	     * in the ".internal" TLD?
+-	     * What exactly was this supposed to accomplish?
+-	     * Commented out --bero
+-	     */
+-/*	    if (!strchr(strchr(chptr, '.') + 1, '.')) {
+-		char * tail = strchr(chptr, '.');
+-		if (strcmp(tail, ".com") && strcmp(tail, ".edu") &&
+-		    strcmp(tail, ".gov") && strcmp(tail, ".mil") &&
+-		    strcmp(tail, ".net") && 
+-		    strcmp(tail, ".org") && strcmp(tail, ".int")) break;
+-	    } */
+-
+-	    fprintf(f, " %s", chptr);
+-	    chptr = strchr(chptr, '.');
+-	    if (chptr) {
+-		chptr++;
+-		if (!strchr(chptr, '.'))
+-		    chptr = NULL;
+-	    }
+-	} while (chptr);
++    if (resolvconf) {
++	char *arg;
+ 
+-	fprintf(f, "\n");
++	f = NULL;
++	if (asprintf(&arg, "/sbin/resolvconf -a %s >/dev/null 2>&1", intf->device) >= 0) {
++	    f = popen(arg, "w");
++	    free(arg);
++	}
++	if (!f) {
++	    syslog(LOG_ERR, "error starting resolvconf: %s\n", strerror(errno));
++	    return;
++	}
++    } else {
++	f = fopen("/etc/resolv.conf", "w");
++	if (!f) {
++	    syslog(LOG_ERR, "error opening resolv.conf: %s\n", strerror(errno));
++	    return;
++	}
+     }
+ 
++
++    errno = 0;
++
++    if (domain)
++	if(fprintf(f, "search %s\n", domain) < 0)
++	    syslog(LOG_ERR, "failed to write resolver configuration data\n");
++
+     for (i = 0; i < intf->numDns; i++)
+-	fprintf(f, "nameserver %s\n", inet_ntoa(intf->dnsServers[i]));
++	if(fprintf(f, "nameserver %s\n", inet_ntoa(intf->dnsServers[i])) < 0)
++	    syslog(LOG_ERR, "failed to write resolver configuration data\n");
+ 
+-    fclose(f);
++    if (resolvconf) {
++	if(pclose(f) != 0) /* errno not useful on pclose failure */
++	    syslog(LOG_ERR, "error running resolvconf\n");
++    } else {
++	if(fclose(f) != 0)
++	    syslog(LOG_ERR, "error closing resolv.conf: %s\n", strerror(errno));
++    }
+ 
+-    /* force a reread of /etc/resolv.conf */
+-    endhostent();
+ }
+ 
+ void setupDomain(struct pumpNetIntf * intf, 
+@@ -248,8 +247,8 @@ void setupDns(struct pumpNetIntf * intf, struct pumpOverrideInfo * override) {
+ 	return;
+     }
+ 
+-    if (override->searchPath) {
+-	createResolvConf(intf, override->searchPath, 1);
++    if (override->searchPath[0]) {
++	createResolvConf(intf, override, override->searchPath);
+ 	return;
+     }
+ 
+@@ -258,7 +257,7 @@ void setupDns(struct pumpNetIntf * intf, struct pumpOverrideInfo * override) {
+ 	    if (intf->set & PUMP_NETINFO_HAS_HOSTNAME) {
+ 		hn = intf->hostname;
+ 	    } else {
+-		createResolvConf(intf, NULL, 0);
++		createResolvConf(intf, override, NULL);
+ 
+ 		he = gethostbyaddr((char *) &intf->ip, sizeof(intf->ip),
+ 				   AF_INET);
+@@ -278,11 +277,35 @@ void setupDns(struct pumpNetIntf * intf, struct pumpOverrideInfo * override) {
+ 	    dn = intf->domain;
+ 	}
+ 
+-	createResolvConf(intf, dn, 0);
++	createResolvConf(intf, override, dn);
+     }
+ }
+ 
++void unsetupDns(struct pumpNetIntf * intf, struct pumpOverrideInfo * override) {
++    struct stat buf;
++    char *arg;
++
++    if (override->flags & OVERRIDE_FLAG_NODNS)
++	return;
++    if (override->flags & OVERRIDE_FLAG_NORESOLVCONF)
++	return;
++    if (stat("/sbin/resolvconf", &buf) < 0)
++	return;
++    if (asprintf(&arg, "/sbin/resolvconf -d %s", intf->device) < 0) {
++	syslog(LOG_ERR, "failed to release resolvconf: %s", strerror(errno));
++	return;
++    }
++
++    if (system(arg) != 0)
++	syslog(LOG_ERR, "resolvconf -d %s failed", intf->device);
++    free(arg);
++}
++
+ static void callIfupPost(struct pumpNetIntf* intf) {
++#ifdef debian
++    /* can/should we call a debian one? */
++    return;
++#else
+     pid_t child;
+     char * argv[3];
+     char arg[64];
+@@ -304,6 +327,7 @@ static void callIfupPost(struct pumpNetIntf* intf) {
+     }
+ 
+     waitpid(child, NULL, 0);
++#endif
+ }
+ 
+ static void callScript(char* script,int msg,struct pumpNetIntf* intf) {
+@@ -312,13 +336,17 @@ static void callScript(char* script,int msg,struct pumpNetIntf* intf) {
+     char ** nextArg;
+     char * class = NULL, * chptr;
+ 
+-    if (!script) return;
++    if (!*script) return;
+ 
+     argv[0] = script;
+     argv[2] = intf->device;
+     nextArg = argv + 3;
+ 
+     switch (msg) {
++	default:
++#ifdef DEBUG
++		abort();
++#endif
+ 	case PUMP_SCRIPT_NEWLEASE:
+ 	    class = "up";
+ 	    chptr = inet_ntoa(intf->ip);
+@@ -357,35 +385,58 @@ static void callScript(char* script,int msg,struct pumpNetIntf* intf) {
+     waitpid(child, NULL, 0);
+ }
+ 
+-static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * overrides) {
++static void gotNewLease(struct pumpNetIntf *intf) {
++    struct pumpOverrideInfo *o = &intf->override;
++
++    pumpSetupInterface(intf);
++
++    syslog(LOG_INFO, "configured interface %s", intf->device);
++
++    if (!(o->flags & OVERRIDE_FLAG_NOGATEWAY)) {
++	int i;
++
++	for (i = intf->numGateways - 1; i >= 0; i--)
++	    pumpSetupDefaultGateway(&intf->gateways[i]);
++    }
++
++    setupDns(intf, o);
++    setupDomain(intf, o);
++
++    callScript(o->script, PUMP_SCRIPT_NEWLEASE, intf);
++}
++
++static void killLease(struct pumpNetIntf *intf) {
++    struct pumpOverrideInfo *o = &intf->override;
++
++    unsetupDns(intf, o);
++    callScript(o->script, PUMP_SCRIPT_DOWN, intf);
++}
++
++static void runDaemon(int sock, int sock_in) {
+     int conn;
+     struct sockaddr_un addr;
+     socklen_t addrLength = sizeof(struct sockaddr_un);
+     struct command cmd;
+     struct pumpNetIntf intf[20];
++    const int maxIntf = sizeof(intf) / sizeof(intf[0]);
+     int numInterfaces = 0;
+     int i;
+     int closest;
+     struct timeval tv;
+     fd_set fds;
+-    struct pumpOverrideInfo emptyOverride, * o = NULL;
+-
+-    if (!overrides)
+-        readPumpConfig(configFile, &overrides);
+-
+-    if (!overrides) {
+-	overrides = &emptyOverride;
+-	overrides->intf.device[0] = '\0';
+-    }
+ 
+     while (1) {
+ 	FD_ZERO(&fds);
+ 	FD_SET(sock, &fds);
++	FD_SET(sock_in, &fds);
+ 
+ 	tv.tv_sec = tv.tv_usec = 0;
+ 	closest = -1;
+ 	if (numInterfaces) {
+-	    for (i = 0; i < numInterfaces; i++)
++	    for (i = 0; i < numInterfaces; i++) {
++		if (!(intf[i].set &
++		   (PUMP_INTFINFO_NEEDS_NEWLEASE | PUMP_INTFINFO_HAS_LEASE)))
++		    continue;
+ 		/* if this interface has an expired lease due to
+ 		 * renewal failures and it's time to try again to
+ 		 * get a new lease, then try again
+@@ -402,7 +453,7 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 			  intf[i].reqLease,
+ 			  intf[i].set & PUMP_NETINFO_HAS_HOSTNAME
+ 			    ? intf[i].hostname : NULL,
+-			  intf + i, overrides)) {
++			  intf + i, &intf[i].override)) {
+ 
+ 			    /* failed to get a new lease, so try
+ 			     * again in 30 seconds
+@@ -411,14 +462,12 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 
+ 		    } else {
+ 			intf[i].set &= ~PUMP_INTFINFO_NEEDS_NEWLEASE;
+-			callScript(overrides->script, PUMP_SCRIPT_NEWLEASE,
+-				   &intf[i]);
++			gotNewLease(intf + i);
+                     }
+ 		}
+-		else if ((intf[i].set & PUMP_INTFINFO_HAS_LEASE) && 
+-			(closest == -1 || 
+-			       (intf[closest].renewAt > intf[i].renewAt)))
++		if (closest == -1 || (intf[closest].renewAt > intf[i].renewAt))
+ 		    closest = i;
++	    }
+ 	    if (closest != -1) {
+ 		tv.tv_sec = intf[closest].renewAt - pumpUptime();
+ 		if (tv.tv_sec <= 0) {
+@@ -434,13 +483,6 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 			 */
+ 			if ((intf[closest].renewAt = pumpUptime() + 30) >
+ 			    intf[closest].leaseExpiration) {
+-			    o = overrides;
+-			    while (*o->intf.device &&
+-				   strcmp(o->intf.device,cmd.u.start.device)) 
+-				o++;
+-			    
+-			    if (!*o->intf.device) o = overrides;
+-
+ 			    intf[closest].set &= ~PUMP_INTFINFO_HAS_LEASE;
+ 			    intf[closest].set |= PUMP_INTFINFO_NEEDS_NEWLEASE;
+ 
+@@ -450,39 +492,23 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 				  intf[closest].reqLease,
+ 				  intf[closest].set & PUMP_NETINFO_HAS_HOSTNAME
+ 				    ? intf[closest].hostname : NULL,
+-				  intf + closest, o)) {
+- 
+- 				    /* failed to get a new lease, so try
+-				     * again in 30 seconds
+-                                      */
+-				    intf[closest].renewAt = pumpUptime() + 30;
+-#if 0
+- 	/* ifdef this out since we now try more than once to get
+- 	 * a new lease and don't, therefore, want to remove the interface
+- 	 */
++				  intf + closest, &intf[closest].override)) {
+  
+-				if (numInterfaces == 1) {
+-				    callScript(o->script, PUMP_SCRIPT_DOWN,
+-					       &intf[closest]);
+-				    syslog(LOG_INFO,
+-					    "terminating as there are no "
+-					    "more devices under management");
+-					    exit(0);
+-				}
+-
+-				intf[i] = intf[numInterfaces - 1];
+-				numInterfaces--;
+-#endif
++ 				/* failed to get a new lease, so try
++				 * again in 30 seconds
++				 */
++				intf[closest].renewAt = pumpUptime() + 30;
++				killLease(intf + closest);
+ 			    } else {
++				killLease(intf + closest);
+ 				intf[closest].set &=
+ 					~PUMP_INTFINFO_NEEDS_NEWLEASE;
+-				callScript(o->script, PUMP_SCRIPT_NEWLEASE,
+-					   &intf[closest]);
++				gotNewLease(intf + closest);
+                             }
+ 			}
+ 		    } else {
+-			callScript(o->script, PUMP_SCRIPT_RENEWAL,
+-				   &intf[closest]);
++			callScript(intf[closest].override.script,
++				   PUMP_SCRIPT_RENEWAL, &intf[closest]);
+ 			callIfupPost(&intf[closest]);
+ 		    }
+ 
+@@ -493,6 +519,48 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 
+ 	if (select(sock + 1, &fds, NULL, NULL, 
+ 		   closest != -1 ? &tv : NULL) > 0) {
++	    if (!FD_ISSET(sock, &fds)) {
++		char c = 0;
++		struct sockaddr_in addr_in;
++		socklen_t len;
++		struct stat buf;
++  
++		if (!FD_ISSET(sock_in, &fds))
++		    continue;
++  
++		conn = accept(sock_in, (struct sockaddr *) &addr_in, &len);
++  
++		if (!stat(CONTROLSOCKET, &buf))
++		    goto out;
++  
++		close(sock);
++  
++		addr.sun_family = AF_UNIX;
++		strcpy(addr.sun_path, CONTROLSOCKET);
++		addrLength = sizeof(addr.sun_family) + strlen(addr.sun_path);
++  
++		if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
++		    syslog(LOG_ERR, "failed to create socket: %s\n",
++			   strerror(errno));
++		    exit(1);
++		}
++  
++		umask(077);
++		if (bind(sock, (struct sockaddr *) &addr, addrLength)) {
++		    syslog(LOG_ERR, "bind to %s failed: %s\n", CONTROLSOCKET,
++			   strerror(errno));
++		    exit(1);
++		}
++		umask(033);
++  
++		listen(sock, 5);
++  
++		write(conn, &c, 1);
++  
++out:
++		close(conn);
++		continue;
++	    }
+ 	    conn = accept(sock, (struct sockaddr *) &addr, &addrLength);
+ 
+ 	    if (read(conn, &cmd, sizeof(cmd)) != sizeof(cmd)) {
+@@ -504,7 +572,7 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 	      case CMD_DIE:
+ 		for (i = 0; i < numInterfaces; i++) {
+ 		    pumpDhcpRelease(intf + i);
+-		    callScript(o->script, PUMP_SCRIPT_DOWN, &intf[i]);
++		    killLease(intf + i);
+ 		}
+ 
+ 		syslog(LOG_INFO, "terminating at root's request");
+@@ -515,35 +583,20 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 		exit(0);
+ 
+ 	      case CMD_STARTIFACE:
+-		o = overrides; 
+-		while (*o->intf.device && 
+-			strcmp(o->intf.device, cmd.u.start.device)) {
+-		    o++;
++		if (numInterfaces >= maxIntf) {
++		    syslog(LOG_INFO, "too many interfaces");
++		    cmd.u.result = 1;
++		    break;
+ 		}
+-		if (!*o->intf.device) o = overrides;
+ 
+ 		if (pumpDhcpRun(cmd.u.start.device,
+ 			        cmd.u.start.flags, cmd.u.start.reqLease, 
+ 			        cmd.u.start.reqHostname[0] ? 
+ 			            cmd.u.start.reqHostname : NULL,
+-			        intf + numInterfaces, o)) {
++			        intf + numInterfaces, &cmd.u.start.override)) {
+ 		    cmd.u.result = 1;
+ 		} else {
+-		    pumpSetupInterface(intf + numInterfaces);
+-		    i = numInterfaces;
+-
+-		    syslog(LOG_INFO, "configured interface %s", intf[i].device);
+-
+-		    if ((intf[i].set & PUMP_NETINFO_HAS_GATEWAY) &&
+-			 !(o->flags & OVERRIDE_FLAG_NOGATEWAY))
+-			pumpSetupDefaultGateway(&intf[i].gateway);
+-
+-		    setupDns(intf + i, o);
+-		    setupDomain(intf + i, o);
+-
+-		    callScript(o->script, PUMP_SCRIPT_NEWLEASE, 
+-			       intf + numInterfaces);
+-
++		    gotNewLease(intf + numInterfaces);
+ 		    cmd.u.result = 0;
+ 		    numInterfaces++;
+ 		}
+@@ -557,7 +610,8 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 		else {
+ 		    cmd.u.result = pumpDhcpRenew(intf + i);
+ 		    if (!cmd.u.result) {
+-			callScript(o->script, PUMP_SCRIPT_RENEWAL, intf + i);
++			callScript(intf[i].override.script,
++				   PUMP_SCRIPT_RENEWAL, intf + i);
+ 			callIfupPost(intf + i);
+ 		    }
+ 		}
+@@ -570,7 +624,7 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 		    cmd.u.result = RESULT_UNKNOWNIFACE;
+ 		else {
+ 		    cmd.u.result = pumpDhcpRelease(intf + i);
+-		    callScript(o->script, PUMP_SCRIPT_DOWN, intf + i);
++		    killLease(intf + i);
+ 		    if (numInterfaces == 1) {
+                         int j;
+ 			cmd.type = CMD_RESULT;
+@@ -598,7 +652,7 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+ 		    if (intf[i].set & PUMP_NETINFO_HAS_HOSTNAME)
+ 			strncpy(cmd.u.status.hostname,
+ 			    intf->hostname, sizeof(cmd.u.status.hostname));
+-		    cmd.u.status.hostname[sizeof(cmd.u.status.hostname)] = '\0';
++		    cmd.u.status.hostname[sizeof(cmd.u.status.hostname) - 1] = '\0';
+ 
+ 		    if (intf[i].set & PUMP_NETINFO_HAS_DOMAIN)
+ 			strncpy(cmd.u.status.domain,
+@@ -633,12 +687,16 @@ static void runDaemon(int sock, char * configFile, struct pumpOverrideInfo * ove
+     exit(0);
+ }
+ 
+-static int openControlSocket(char * configFile, struct pumpOverrideInfo * override) {
++static int openControlSocket(void) {
+     struct sockaddr_un addr;
++    struct sockaddr_in addr_in;
+     int sock;
++    int sock_in;
+     size_t addrLength;
+     pid_t child;
+     int status;
++    int error;
++    struct timeval timeout;
+ 
+     if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
+ 	return -1;
+@@ -650,13 +708,44 @@ static int openControlSocket(char * configFile, struct pumpOverrideInfo * overri
+     if (!connect(sock, (struct sockaddr *) &addr, addrLength)) 
+ 	return sock;
+ 
+-    if (errno != ENOENT && errno != ECONNREFUSED) {
++    error = errno;
++    if (error != ENOENT && error != ECONNREFUSED) {
+ 	fprintf(stderr, "failed to connect to %s: %s\n", CONTROLSOCKET,
+-		strerror(errno));
+-	close(sock);
+-	return -1;
++		strerror(error));
++	goto err;
+     }
+ 
++    unlink(CONTROLSOCKET);
++
++    if ((sock_in = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
++	goto err;
++    }
++
++    addr_in.sin_family = AF_INET;
++    addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
++    addr_in.sin_port = bootp_client_port;
++
++    timeout.tv_sec = 1;
++    timeout.tv_usec = 0;
++    setsockopt(sock_in, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
++    if (!connect(sock_in, (struct sockaddr *) &addr_in, sizeof(addr_in))) {
++	char c;
++
++	read(sock_in, &c, 1);
++	close(sock_in);
++	goto again;
++    }
++
++    error = errno;
++    close(sock_in);
++    if (error != ECONNREFUSED && error != ETIMEDOUT) {
++	fprintf(stderr, "failed to connect to localhost:bootpc: %s\n",
++		strerror(error));
++	fprintf(stderr, "There might be another pump running!\n");
++    }
++
++    addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
++
+     if (!(child = fork())) {
+ 	close(sock);
+ 
+@@ -664,12 +753,28 @@ static int openControlSocket(char * configFile, struct pumpOverrideInfo * overri
+ 	close(1);
+ 	close(2);
+ 
+-	if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
++	openlog("pumpd", LOG_PID, LOG_DAEMON);
++
++	if ((sock_in = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
++	    syslog(LOG_ERR, "failed to create IP socket: %s\n",
++		   strerror(errno));
++	    exit(1);
++	}
++
++	if (bind(sock_in, (struct sockaddr *) &addr_in, sizeof(addr_in))) {
++	    syslog(LOG_ERR, "bind to bootpc/tcp failed: %s\n",
++		   strerror(errno));
++	    exit(1);
++	}
++
++	listen(sock_in, 5);
++
++	if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ 	    syslog(LOG_ERR, "failed to create socket: %s\n", strerror(errno));
+ 	    exit(1);
+ 	}
+ 
+-	unlink(CONTROLSOCKET);
++	chdir("/");
+ 	umask(077);
+ 	if (bind(sock, (struct sockaddr *) &addr, addrLength)) {
+ 	    syslog(LOG_ERR, "bind to %s failed: %s\n", CONTROLSOCKET,
+@@ -682,7 +787,8 @@ static int openControlSocket(char * configFile, struct pumpOverrideInfo * overri
+ 
+ 	if (fork()) _exit(0);
+ 
+-	openlog("pumpd", LOG_PID, LOG_DAEMON);
++	setsid();
++
+ 	{
+ 	    time_t now,upt;
+ 	    int updays,uphours,upmins,upsecs;
+@@ -700,20 +806,25 @@ static int openControlSocket(char * configFile, struct pumpOverrideInfo * overri
+ 	    }
+ 	}
+ 
+-	runDaemon(sock, configFile, override);
++	runDaemon(sock, sock_in);
+     }
+ 
++    close(sock_in);
++
+     waitpid(child, &status, 0);
+     if (!WIFEXITED(status) || WEXITSTATUS(status))
+ 	return -1;
+ 
++again:
+     if (!connect(sock, (struct sockaddr *) &addr, addrLength)) 
+ 	return sock;
+ 
+-    fprintf(stderr, "failed to connect to %s: %s\n", CONTROLSOCKET,
++    fprintf(stderr, "failed to connect to localhost:bootpc: %s\n",
+ 	    strerror(errno));
+ 
+-    return 0;
++err:
++    close(sock);
++    return -1;
+ }
+ 
+ void printStatus(struct pumpNetIntf i, char * hostname, char * domain,
+@@ -729,8 +840,13 @@ void printStatus(struct pumpNetIntf i, char * hostname, char * domain,
+     printf("\tBoot server %s\n", inet_ntoa(i.bootServer));
+     printf("\tNext server %s\n", inet_ntoa(i.nextServer));
+ 
+-    if (i.set & PUMP_NETINFO_HAS_GATEWAY)
+-	printf("\tGateway: %s\n", inet_ntoa(i.gateway));
++    if (i.numGateways) {
++	printf("\tGateway: %s\n", inet_ntoa(i.gateways[0]));
++	printf("\tGateways:");
++	for (j = 0; j < i.numGateways; j++)
++	    printf(" %s", inet_ntoa(i.gateways[j]));
++	printf("\n");
++    }
+ 
+     if (i.set & PUMP_INTFINFO_HAS_BOOTFILE)
+ 	printf("\tBoot file: %s\n", bootFile);
+@@ -802,7 +918,6 @@ int main (int argc, const char ** argv) {
+     char * hostname = "";
+     poptContext optCon;
+     int rc;
+-    int ret;
+     int test = 0;
+     int flags = 0;
+     int lease_hrs = 0;
+@@ -811,8 +926,11 @@ int main (int argc, const char ** argv) {
+     int winId = 0;
+     int release = 0, renew = 0, status = 0, lookupHostname = 0, nodns = 0;
+     int nogateway = 0, nobootp = 0;
++    int nosetup = 0;
++    int noresolvconf = 0;
+     struct command cmd, response;
+     char * configFile = "/etc/pump.conf";
++    char * script = NULL;
+     struct pumpOverrideInfo * overrides;
+     int cont;
+     struct poptOption options[] = {
+@@ -836,14 +954,22 @@ int main (int argc, const char ** argv) {
+ 			N_("Release interface"), NULL },
+ 	    { "renew", 'R', POPT_ARG_NONE, &renew, 0,
+ 			N_("Force immediate lease renewal"), NULL },
++            { "verbose", 'v', POPT_ARG_NONE, &verbose, 0,
++                        N_("Log verbose debug info"), NULL },
+ 	    { "status", 's', POPT_ARG_NONE, &status, 0,
+ 			N_("Display interface status"), NULL },
+ 	    { "no-dns", 'd', POPT_ARG_NONE, &nodns, 0,
+ 			N_("Don't update resolv.conf"), NULL },
+ 	    { "no-gateway", '\0', POPT_ARG_NONE, &nogateway, 0,
+ 			N_("Don't set a gateway for this interface"), NULL },
++	    { "no-setup", '\0', POPT_ARG_NONE, &nosetup, 0,
++			N_("Don't set up anything"), NULL },
++	    { "no-resolvconf", '\0', POPT_ARG_NONE, &noresolvconf, 0,
++			N_("Don't set up resolvconf"), NULL },
+ 	    { "no-bootp", '\0', POPT_ARG_NONE, &nobootp, 0,
+ 	                N_("Ignore non-DHCP BOOTP responses"), NULL },
++	    { "script", '\0', POPT_ARG_STRING, &script, 0,
++			N_("Script to use") },
+ 	    { "win-client-ident", '\0', POPT_ARG_NONE, &winId, 0,
+ 			N_("Set the client identifier to match Window's") },
+ 	    /*{ "test", 't', POPT_ARG_NONE, &test, 0,
+@@ -852,6 +978,23 @@ int main (int argc, const char ** argv) {
+ 	    POPT_AUTOHELP
+ 	    { NULL, '\0', 0, NULL, 0 }
+         };
++#if !UDEB
++    struct servent *servent;
++
++    servent = getservbyname("bootpc", "udp");
++    if (!servent) {
++	perror("Cannot resolve bootpc/udp service");
++	return 1;
++    }
++    bootp_client_port = servent->s_port;
++
++    servent = getservbyname("bootps", "udp");
++    if (!servent) {
++	perror("Cannot resolve bootps/udp service");
++	return 1;
++    }
++    bootp_server_port = servent->s_port;
++#endif
+ 
+     memset(&cmd, 0, sizeof(cmd));
+     memset(&response, 0, sizeof(response));
+@@ -871,6 +1014,11 @@ int main (int argc, const char ** argv) {
+ 	return 1;
+     }
+ 
++    if (script && strlen(script) > sizeof(overrides->script)) {
++	fprintf(stderr, _("%s: --script argument is too long\n"), PROGNAME);
++	return 1;
++    }
++
+     /* make sure the config file is parseable before going on any further */
+     if (readPumpConfig(configFile, &overrides)) return 1;
+ 
+@@ -885,16 +1033,6 @@ int main (int argc, const char ** argv) {
+ 	flags |= PUMP_FLAG_WINCLIENTID;
+     if (lookupHostname)
+ 	flags |= PUMP_FLAG_FORCEHNLOOKUP;
+-    if (nodns)
+-	overrides->flags |= OVERRIDE_FLAG_NODNS;
+-    if (nobootp)
+-	overrides->flags |= OVERRIDE_FLAG_NOBOOTP;
+-    if (nogateway)
+-	overrides->flags |= OVERRIDE_FLAG_NOGATEWAY;
+-
+-    cont = openControlSocket(configFile, overrides);
+-    if (cont < 0) 
+-	exit(1);
+ 
+     if (killDaemon) {
+ 	cmd.type = CMD_DIE;
+@@ -908,6 +1046,8 @@ int main (int argc, const char ** argv) {
+ 	cmd.type = CMD_STOPIFACE;
+ 	strcpy(cmd.u.stop.device, device);
+     } else {
++	struct pumpOverrideInfo * o;
++
+ 	cmd.type = CMD_STARTIFACE;
+ 	strcpy(cmd.u.start.device, device);
+ 	cmd.u.start.flags = flags;
+@@ -916,19 +1056,47 @@ int main (int argc, const char ** argv) {
+ 	else
+ 		cmd.u.start.reqLease = lease;
+ 	strcpy(cmd.u.start.reqHostname, hostname);
++ 
++        o = overrides + 1;
++	while (*o->device && strcmp(o->device, device))
++	    o++;
++	if (!*o->device)
++	    o = overrides;
++ 
++	if (nodns)
++	    o->flags |= OVERRIDE_FLAG_NODNS;
++	if (nobootp)
++	    o->flags |= OVERRIDE_FLAG_NOBOOTP;
++	if (nogateway)
++	    o->flags |= OVERRIDE_FLAG_NOGATEWAY;
++	if (nosetup)
++	    o->flags |=
++		OVERRIDE_FLAG_NOSETUP |
++		OVERRIDE_FLAG_NODNS |
++		OVERRIDE_FLAG_NOGATEWAY |
++		OVERRIDE_FLAG_NONISDOMAIN;
++	if (noresolvconf)
++	    o->flags |= OVERRIDE_FLAG_NORESOLVCONF;
++	if (script)
++	    strcpy(o->script, script);
++ 
++	memcpy(&cmd.u.start.override, o, sizeof(*o));
+     }
+ 
+-    ret = write(cont, &cmd, sizeof(cmd));
+-    ret = read(cont, &response, sizeof(response));
++    free(overrides);
+ 
+-    if (response.type == CMD_RESULT && response.u.result &&
+-	    cmd.type == CMD_STARTIFACE) {
+-	cont = openControlSocket(configFile, overrides);
+-	if (cont < 0) 
+-	    exit(1);
+-	ret = write(cont, &cmd, sizeof(cmd));
+-	ret = read(cont, &response, sizeof(response));
++again:
++    cont = openControlSocket();
++    if (cont < 0)
++	exit(1);
++ 
++    if (write(cont, &cmd, sizeof(cmd)) < 0) {
++retry:
++	close(cont);
++	goto again;
+     }
++    if (read(cont, &response, sizeof(response)) <= 0)
++	goto retry;
+ 
+     if (response.type == CMD_RESULT) {
+ 	if (response.u.result) {
+diff --git a/pump.h b/pump.h
+index 50263bc..6c2be0e 100644
+--- a/pump.h
++++ b/pump.h
+@@ -6,6 +6,7 @@
+ #include <arpa/inet.h>
+ #include <sys/time.h>
+ 
++#define MAX_GATEWAYS		3
+ #define MAX_DNS_SERVERS		3
+ #define MAX_LOG_SERVERS		3
+ #define MAX_LPR_SERVERS		3
+@@ -42,14 +43,32 @@
+ #define PUMP_FLAG_NOCONFIG	(1 << 1)
+ #define PUMP_FLAG_FORCEHNLOOKUP	(1 << 2)
+ #define PUMP_FLAG_WINCLIENTID	(1 << 3)
++#define PUMP_FLAG_NOSETUP	(1 << 4)
+ 
+ #define PUMP_SCRIPT_NEWLEASE	1
+ #define PUMP_SCRIPT_RENEWAL	2
+ #define PUMP_SCRIPT_DOWN	3
+ 
++#define OVERRIDE_FLAG_NODNS		(1 << 0)
++#define OVERRIDE_FLAG_NONISDOMAIN	(1 << 1)
++#define OVERRIDE_FLAG_NOGATEWAY		(1 << 2)
++#define OVERRIDE_FLAG_NOBOOTP           (1 << 3)
++#define OVERRIDE_FLAG_NOSETUP		(1 << 4)
++#define OVERRIDE_FLAG_NORESOLVCONF	(1 << 5)
++
++struct pumpOverrideInfo {
++    char device[10];
++    char searchPath[1024];
++    int flags;
++    int numRetries;
++    int timeout;
++    char script[1024];
++};
++
+ /* all of these in_addr things are in network byte order! */
+ struct pumpNetIntf {
+     char device[10];
++    int ifindex;
+     int set;
+     struct in_addr ip, netmask, broadcast, network;
+     struct in_addr bootServer, nextServer;
+@@ -58,13 +77,14 @@ struct pumpNetIntf {
+     int reqLease;		/* in seconds */
+     char * hostname, * domain;		/* dynamically allocated */
+     char * nisDomain;			/* dynamically allocated */
+-    struct in_addr gateway;
++    struct in_addr gateways[MAX_GATEWAYS];
+     struct in_addr logServers[MAX_LOG_SERVERS];
+     struct in_addr lprServers[MAX_LPR_SERVERS];
+     struct in_addr ntpServers[MAX_NTP_SERVERS];
+     struct in_addr xfntServers[MAX_XFS_SERVERS];
+     struct in_addr xdmServers[MAX_XDM_SERVERS];
+     struct in_addr dnsServers[MAX_DNS_SERVERS];
++    int numGateways;
+     int numLog;
+     int numLpr;
+     int numNtp;
+@@ -72,6 +92,7 @@ struct pumpNetIntf {
+     int numXdm;
+     int numDns;
+     int flags;
++    struct pumpOverrideInfo override;
+ 
+     /* these don't really belong here, but anaconda's about the only thing 
+      * that uses pump and this stuff is needed for the loader on s390 */
+@@ -79,20 +100,6 @@ struct pumpNetIntf {
+     struct in_addr ptpaddr;             /* ptp address for ptp devs like ctc */
+ };
+ 
+-#define OVERRIDE_FLAG_NODNS		(1 << 0)
+-#define OVERRIDE_FLAG_NONISDOMAIN	(1 << 1)
+-#define OVERRIDE_FLAG_NOGATEWAY		(1 << 2)
+-#define OVERRIDE_FLAG_NOBOOTP           (1 << 3)
+-
+-struct pumpOverrideInfo {
+-    struct pumpNetIntf intf;
+-    char * searchPath;
+-    int flags;
+-    int numRetries;
+-    int timeout;
+-    char * script;
+-};
+-
+ void pumpInitOverride(struct pumpOverrideInfo * override);
+ char * pumpDhcpClassRun(char * device, int flags, int lease,
+                     char * reqHostname, char * class, struct pumpNetIntf * intf,
+@@ -103,7 +110,7 @@ char * pumpDhcpRun(char * device, int flags, int lease,
+ char * pumpSetupInterface(struct pumpNetIntf * intf);
+ /* setup an interface for sending a broadcast -- uses all 0's address */
+ char * pumpPrepareInterface(struct pumpNetIntf * intf, int s);
+-char * pumpDisableInterface(char * device);
++char * pumpDisableInterface(struct pumpNetIntf * intf);
+ int pumpDhcpRenew(struct pumpNetIntf * intf);
+ int pumpDhcpRelease(struct pumpNetIntf * intf);
+ int pumpSetupDefaultGateway(struct in_addr * gw);
+@@ -113,5 +120,14 @@ time_t pumpUptime(void);
+ #define RESULT_FAILED		1
+ #define RESULT_UNKNOWNIFACE	2
+ 
++extern int verbose;
++#if UDEB
++#define bootp_client_port htons(68)
++#define bootp_server_port htons(67)
++#else
++extern int bootp_client_port;
++extern int bootp_server_port;
++#endif
++
+ 
+ #endif
--- pump-0.8.24.orig/debian/patches/30_all_Makefile.patch
+++ pump-0.8.24/debian/patches/30_all_Makefile.patch
@@ -0,0 +1,20 @@
+diff -Nru pump-0.8.24.vanilla/Makefile pump-0.8.24/Makefile
+--- pump-0.8.24.vanilla/Makefile	2009-03-07 15:55:01.000000000 +0000
++++ pump-0.8.24/Makefile	2009-03-07 15:56:21.000000000 +0000
+@@ -6,14 +6,13 @@
+ USRLIBPATH = $(libdir)
+ INCPATH = $(includedir)
+ MAN8PATH = $(mandir)/man8
+-CFLAGS = $(DEB_CFLAGS) -I. -Wall -Werror -g $(RPM_OPT_FLAGS) -D__STANDALONE__ -DVERSION=\"$(VERSION)\" -D_GNU_SOURCE
++CFLAGS = $(DEB_CFLAGS) -I. -Wall $(RPM_OPT_FLAGS) -D__STANDALONE__ -DVERSION=\"$(VERSION)\" -D_GNU_SOURCE
+ CVSROOT = $(shell cat CVS/Root 2>/dev/null)
+ 
+ ARCH := $(patsubst i%86,i386,$(shell uname -m))
+ ARCH := $(patsubst sparc%,sparc,$(ARCH))
+ 
+-LOADLIBES = -Wl,-Bstatic -lpopt -Wl,-Bdynamic -lresolv
+-LDFLAGS = -g
++LOADLIBES = -lpopt -lresolv
+ 
+ CVSTAG = r$(subst .,-,$(VERSION))
+ 
--- pump-0.8.24.orig/debian/patches/20_all_redefinition.patch
+++ pump-0.8.24/debian/patches/20_all_redefinition.patch
@@ -0,0 +1,13 @@
+diff -Nru pump-0.8.24.orig/pump.c pump-0.8.24/pump.c
+--- pump-0.8.24.orig/pump.c	2009-02-11 10:48:34.000000000 +0100
++++ pump-0.8.24/pump.c	2009-02-11 10:48:54.000000000 +0100
+@@ -58,7 +58,9 @@
+ int bootp_server_port;
+ #endif
+ 
++#if !defined(N_)
+ #define N_(foo) (foo)
++#endif
+ 
+ #define PROGNAME "pump"
+ #define CONTROLSOCKET "/var/run/pump.sock"
--- pump-0.8.24.orig/debian/patches/10_all_gentoo.patch
+++ pump-0.8.24/debian/patches/10_all_gentoo.patch
@@ -0,0 +1,557 @@
+diff -Nru pump-0.8.24.orig/config.c pump-0.8.24/config.c
+--- pump-0.8.24.orig/config.c	2009-02-11 10:47:07.000000000 +0100
++++ pump-0.8.24/config.c	2009-02-11 10:47:33.000000000 +0100
+@@ -155,15 +155,26 @@
+ 	    }
+ 
+ 	    override->numRetries = num;
+-	} else if (!strcmp(start, "domainsearch")) {
+-	    size_t len;
++	} else if (!strcmp(start, "routemetric")) {
++	    poptParseArgvString(rest, &argc, &argv);
+ 
+-	    if (overrideList != override) {
+-		parseError(*lineNum, "domainsearch directive may not occur "
+-			   "inside of device specification");
++	    if (argc != 1) {
++		parseError(*lineNum, "routemetric directive expects a "
++			   "single argument");
+ 		return 1;
+ 	    }
+ 
++	    num = strtol(argv[0], &chptr, 0);
++	    if (*chptr) {
++		parseError(*lineNum, "routemetric requires a numeric "
++			   "argument");
++		return 1;
++	    }
++
++	    override->routeMetric = num;
++	} else if (!strcmp(start, "domainsearch")) {
++	    size_t len;
++
+ 	    poptParseArgvString(rest, &argc, &argv);
+ 
+ 	    if (argc != 1) {
+@@ -209,6 +220,12 @@
+ 		return 1;
+ 	    }
+ 	    override->flags |= OVERRIDE_FLAG_NONISDOMAIN;
++	} else if (!strcmp(start, "nontp")) {
++	    if (*rest) {
++		parseError(*lineNum, "unexpected argument to nontp directive");
++		return 1;
++	    }
++	    override->flags |= OVERRIDE_FLAG_NONTP;
+ 	} else if (!strcmp(start, "nosetup")) {
+ 	    if (*rest) {
+ 		parseError(*lineNum, "unexpected argument to nosetup directive");
+@@ -228,12 +245,6 @@
+ 	} else if (!strcmp(start, "script")) {
+ 	    size_t len;
+ 
+-	    if (overrideList != override) {
+-		parseError(*lineNum, "script directive may not occur "
+-			   "inside of device specification");
+-		return 1;
+-	    }
+-
+ 	    poptParseArgvString(rest, &argc, &argv);
+ 
+ 	    if (argc != 1) {
+diff -Nru pump-0.8.24.orig/dhcp.c pump-0.8.24/dhcp.c
+--- pump-0.8.24.orig/dhcp.c	2009-02-11 10:47:07.000000000 +0100
++++ pump-0.8.24/dhcp.c	2009-02-11 10:47:33.000000000 +0100
+@@ -204,16 +204,30 @@
+ 
+ char * pumpDisableInterface(struct pumpNetIntf * intf) {
+     struct ifreq req;
++    struct sockaddr_in * addrp;
+     int s;
+ 
+     if (intf->flags & PUMP_FLAG_NOSETUP)
+ 	return NULL;
+ 
+     s = socket(AF_INET, SOCK_DGRAM, 0);
+-	
+-    memset(&req,0,sizeof(req));
+ 
++    memset(&req,0,sizeof(req));
+     strcpy(req.ifr_name, intf->device);
++
++    addrp = (struct sockaddr_in *) &req.ifr_addr;
++    addrp->sin_family = AF_INET;
++    addrp->sin_addr.s_addr = 0;
++    if (ioctl(s, SIOCSIFADDR, &req)) {
++	close(s);
++	return perrorstr("SIOCSIFADDR");
++    }
++
++    if (intf->override.flags & OVERRIDE_FLAG_KEEPUP) {
++	close(s);
++	return NULL;
++    }
++    
+     if (ioctl(s, SIOCGIFFLAGS, &req)) {
+ 	close(s);
+ 	return perrorstr("SIOCGIFFLAGS");
+@@ -291,18 +305,27 @@
+ 	goto out;
+     }
+ 
+-    if (!strcmp(intf->device, "lo")) {
+-	/* add a route for this network */
+-	route.rt_dev = intf->device;
+-	route.rt_flags = RTF_UP;
+-	route.rt_metric = 0;
++    route.rt_dev = intf->device;
++    route.rt_flags = RTF_UP;
++    route.rt_metric = 0;
++
++    addrp->sin_family = AF_INET;
++    addrp->sin_port = 0;
++    addrp->sin_addr = intf->network;
++    memcpy(&route.rt_dst, addrp, sizeof(*addrp));
++    addrp->sin_addr = intf->netmask;
++    memcpy(&route.rt_genmask, addrp, sizeof(*addrp));
++    
++    if (strcmp(intf->device,"lo") && intf->override.routeMetric) {
++	if (ioctl(s, SIOCDELRT, &route)) {
++	    rc = perrorstr("SIOCDELRT");
++	    goto out;
++	}
++    }
+ 
+-	addrp->sin_family = AF_INET;
+-	addrp->sin_port = 0;
+-	addrp->sin_addr = intf->network;
+-	memcpy(&route.rt_dst, addrp, sizeof(*addrp));
+-	addrp->sin_addr = intf->netmask;
+-	memcpy(&route.rt_genmask, addrp, sizeof(*addrp));
++    if (!strcmp(intf->device, "lo") || intf->override.routeMetric) {
++	if (intf->override.routeMetric)
++	    route.rt_metric = intf->override.routeMetric + 1;
+ 
+ 	if (ioctl(s, SIOCADDRT, &route)) {
+ 	    /* the route cannot already exist, as we've taken the device down */
+@@ -316,31 +339,37 @@
+     return rc;
+ }
+ 
+-int pumpSetupDefaultGateway(struct in_addr * gw) {
++int pumpSetupDefaultGateway(struct pumpNetIntf * intf) {
+     struct sockaddr_in addr;
+     struct rtentry route;
+     int s;
++    int i;
+ 
+     s = socket(AF_INET, SOCK_DGRAM, 0);
+-	
+-    memset(&addr,0,sizeof(addr));
+-    memset(&route,0,sizeof(route));
+-    addr.sin_family = AF_INET;
+-    addr.sin_port = 0;
+-    addr.sin_addr.s_addr = INADDR_ANY;
+-    memcpy(&route.rt_dst, &addr, sizeof(addr));
+-    memcpy(&route.rt_genmask, &addr, sizeof(addr));
+-    addr.sin_addr = *gw;
+-    memcpy(&route.rt_gateway, &addr, sizeof(addr));
+-    
+-    route.rt_flags = RTF_UP | RTF_GATEWAY;
+-    route.rt_metric = 0;
+-    route.rt_dev = NULL;
+ 
+-    if (ioctl(s, SIOCADDRT, &route)) {
+-	close(s);
+-	syslog(LOG_ERR, "failed to set default route: %s", strerror(errno));
+-	return -1;
++    for (i = intf->numGateways - 1; i >= 0; i--) {
++	memset(&addr,0,sizeof(addr));
++	memset(&route,0,sizeof(route));
++	addr.sin_family = AF_INET;
++	addr.sin_port = 0;
++	addr.sin_addr.s_addr = INADDR_ANY;
++	memcpy(&route.rt_dst, &addr, sizeof(addr));
++	memcpy(&route.rt_genmask, &addr, sizeof(addr));
++	addr.sin_addr = intf->gateways[i];
++	memcpy(&route.rt_gateway, &addr, sizeof(addr));
++
++	route.rt_flags = RTF_UP | RTF_GATEWAY;
++	route.rt_dev = intf->device;
++	if (intf->override.routeMetric)
++	    route.rt_metric = intf->override.routeMetric + 1;
++	else
++	    route.rt_metric = 0;
++
++	if (ioctl(s, SIOCADDRT, &route)) {
++	    close(s);
++	    syslog(LOG_ERR, "failed to set default route: %s", strerror(errno));
++	    return -1;
++	}
+     }
+ 
+     close(s);
+@@ -386,7 +415,7 @@
+     unsigned char option, length;
+ 
+    
+-    chptr = response->vendor;
++    chptr = (unsigned char *) response->vendor;
+ 
+     chptr += 4;
+     while (*chptr != 0xFF) {
+@@ -463,7 +492,7 @@
+     intf->set |= PUMP_INTFINFO_HAS_NEXTSERVER;
+     syslog (LOG_DEBUG, "intf: next server: %s", inet_ntoa (intf->nextServer));
+ 
+-    chptr = breq->vendor;
++    chptr = (unsigned char *) breq->vendor;
+     chptr += 4;
+     while (*chptr != 0xFF && (void *) chptr < (void *) breq->vendor + DHCP_VENDOR_LENGTH) {
+ 	option = *chptr++;
+@@ -729,7 +758,7 @@
+     syslog (LOG_DEBUG, "%s: servername: %s", name, breq->servername);
+     syslog (LOG_DEBUG, "%s: bootfile: %s", name, breq->bootfile);
+     
+-    vndptr = breq->vendor;
++    vndptr = (unsigned char *) breq->vendor;
+     sprintf (vendor, "0x%02x 0x%02x 0x%02x 0x%02x", vndptr[0], vndptr[1], vndptr[2], vndptr[3]);
+     vndptr += 4;
+     syslog (LOG_DEBUG, "%s: vendor: %s", name, vendor);
+@@ -741,7 +770,7 @@
+ 	if (option == 0xFF)
+ 	  {
+ 	    sprintf (vendor, "0x%02x", option);
+-	    vndptr = breq->vendor + DHCP_VENDOR_LENGTH;
++	    vndptr = (unsigned char *)breq->vendor + DHCP_VENDOR_LENGTH;
+ 	  }
+ 	else if (option == 0x00)
+ 	  {
+@@ -990,7 +1019,7 @@
+     unsigned char * chptr;
+     int theOption, theLength;
+ 
+-    chptr = breq->vendor;
++    chptr = (unsigned char *) breq->vendor;
+     chptr += 4;
+     while (*chptr != 0xFF && *chptr != option) {
+ 	theOption = *chptr++;
+@@ -1010,7 +1039,7 @@
+     unsigned char * chptr;
+     unsigned int length, theOption;
+ 
+-    chptr = bresp->vendor;
++    chptr = (unsigned char *) bresp->vendor;
+     chptr += 4;
+     while (*chptr != 0xFF && *chptr != option) {
+ 	theOption = *chptr++;
+diff -Nru pump-0.8.24.orig/pump.8 pump-0.8.24/pump.8
+--- pump-0.8.24.orig/pump.8	2009-02-11 10:47:07.000000000 +0100
++++ pump-0.8.24/pump.8	2009-02-11 10:47:33.000000000 +0100
+@@ -1,5 +1,6 @@
+ .\" Copyright 1999 Red Hat Software, Inc.
+ .\" August 2004: Updated by Thomas Hood <jdthood@yahoo.co.uk>
++.\" July 2005: Updated by Roy Marples <uberlord@gentoo.org>
+ .\"
+ .\" This man page is free documentation; you can redistribute it and/or modify
+ .\" it under the terms of the GNU General Public License as published by
+@@ -29,8 +30,10 @@
+ .IR IFACE ]
+ .BR "" [ \-l | \-\-lease
+ .IR HOURS ]
++.BR "" [ \-m | \-\-route\-metric
++.IR METRIC ]
+ .BR "" [ \-\-lookup\-hostname ]
+-.BR "" [ \-\-no\-dns "] [" \-\-no\-gateway "] [" \-\-no\-setup "] [" \-\-no\-resolvconf ]
++.BR "" [ \-\-no\-dns "] [" \-\-no\-gateway "] [" \-\- no\-ntp "] [" \-\-no\-setup "]
+ .BR "" [ \-\-release "] [" \-\-renew "] [" \-\-script =
+ .IR ISCRIPT ]
+ .BR "" [ \-\-status ]
+@@ -67,13 +70,16 @@
+ \-d	\-\-no\-dns	Don't update DNS resolver configuration
+ \-h	\-\-hostname=\fIHOSTNAME\fR	Request \fIHOSTNAME\fR
+ \-i	\-\-interface=\fIIFACE\fR	Manage \fIIFACE\fR rather than eth0
++	\-\-keep\-up	Keep the interface up when released
+ \-k	\-\-kill	Kill daemon (and disable all interfaces)
+ \-l	\-\-lease=\fIHOURS\fR	Request least time of \fIHOURS\fR
+ 	\-\-lookup\-hostname	Look up hostname in DNS
+ \-R	\-\-renew	Renew lease immediately
+ \-r	\-\-release	Release interface
++\-m	\-\-route-metric=\fIMETRIC\fR	Metric to use on routes (normally 0)
+   	\-\-no\-gateway	Don't configurate a default route for this interface
+   	\-\-no\-resolvconf	Don't use the \fBresolvconf\fR program to update resolv.conf
++  	\-\-no\-ntp	Don't update ntp.conf
+   	\-\-no\-setup	Don't set up anything
+   	\-\-script=\fISCRIPT\fR	Call \fISCRIPT\fR (or null string to disable)
+ \-s	\-\-status	Display interface status
+@@ -164,8 +170,13 @@
+ Use \fISEARCHPATH\fR as the DNS search path instead of the domain
+ name returned by the server or the domain part of the fully
+ qualified hostname.
+-As a machine only has a single DNS search path, this directive may
+-only be used globally. 
++
++.TP
++\fBkeepup\fR
++Keep the interface up when released.
++Normally \fBpump\fR brings the interface down when it releases its
++lease, but some daemons such as ifplugd or wpa_supplicant still need the
++interface to be up so that they can still work.
+ 
+ .TP
+ \fBnonisdomain\fR
+@@ -173,22 +184,24 @@
+ Normally \fBpump\fR sets the system's NIS domain
+ if an NIS domain is specified by the DHCP server
+ and the current NIS domain is empty or \fBlocaldomain\fR.
+-This directive may only be used within a \fBdevice\fR directive.
+ 
+ .TP
+ \fBnodns\fR
+ Don't update /etc/resolv.conf when the interface is configured.
+-This directive may only be used within a \fBdevice\fR directive.
+ 
+ .TP
+ \fBnogateway\fR
+ Ignore any default gateway suggested by the DHCP server for this device.
+-This can be useful on machines with multiple Ethernet cards.
++This can be useful on machines with multiple devices.
++
++.TP
++\fBnontp\fR
++Don't update /etc/ntp.conf when the interface is configured.
+ 
+ .TP
+ \fBnosetup\fR
+ Don't set up anything on the local machine as a result of DHCP operations.
+-This implies \fBnodns\fR, \fBnonisdomain\fR and \fBnogateway\fR.
++This implies \fBnodns\fR, \fBnonisdomain\fR, \fBnogateway\fR and \fBnontp\fR.
+ This option is useful, for example,
+ if you want to perform setup in customised scripts.
+ 
+diff -Nru pump-0.8.24.orig/pump.c pump-0.8.24/pump.c
+--- pump-0.8.24.orig/pump.c	2009-02-11 10:47:07.000000000 +0100
++++ pump-0.8.24/pump.c	2009-02-11 10:47:33.000000000 +0100
+@@ -188,9 +188,17 @@
+ 
+     errno = 0;
+ 
+-    if (domain)
+-	if(fprintf(f, "search %s\n", domain) < 0)
+-	    syslog(LOG_ERR, "failed to write resolver configuration data\n");
++    fprintf(f, "# Generated by pump for interface %s\n", intf->device);
++    
++    if (domain) {
++	if (strchr(domain, ' ')) {
++	    if(fprintf(f, "search %s\n", domain) < 0)
++		syslog(LOG_ERR, "failed to write resolver configuration data\n");
++	} else {
++	    if(fprintf(f, "search %s\n", domain) < 0)
++		syslog(LOG_ERR, "failed to write resolver configuration data\n");
++	}
++    }
+ 
+     for (i = 0; i < intf->numDns; i++)
+ 	if(fprintf(f, "nameserver %s\n", inet_ntoa(intf->dnsServers[i])) < 0)
+@@ -301,35 +309,6 @@
+     free(arg);
+ }
+ 
+-static void callIfupPost(struct pumpNetIntf* intf) {
+-#ifdef debian
+-    /* can/should we call a debian one? */
+-    return;
+-#else
+-    pid_t child;
+-    char * argv[3];
+-    char arg[64];
+-
+-    argv[0] = "/etc/sysconfig/network-scripts/ifup-post";
+-    snprintf(arg,64,"ifcfg-%s",intf->device);
+-    argv[1] = arg;
+-    argv[2] = NULL;
+-
+-    if (!(child = fork())) {
+-	/* send the script to init */
+-	if (fork()) _exit(0);
+-
+-	execvp(argv[0], argv);
+-
+-	syslog(LOG_ERR,"failed to run %s: %s", argv[0], strerror(errno));
+-
+-	_exit(0);
+-    }
+-
+-    waitpid(child, NULL, 0);
+-#endif
+-}
+-
+ static void callScript(char* script,int msg,struct pumpNetIntf* intf) {
+     pid_t child;
+     char * argv[20];
+@@ -392,12 +371,8 @@
+ 
+     syslog(LOG_INFO, "configured interface %s", intf->device);
+ 
+-    if (!(o->flags & OVERRIDE_FLAG_NOGATEWAY)) {
+-	int i;
+-
+-	for (i = intf->numGateways - 1; i >= 0; i--)
+-	    pumpSetupDefaultGateway(&intf->gateways[i]);
+-    }
++    if (!(o->flags & OVERRIDE_FLAG_NOGATEWAY))
++	pumpSetupDefaultGateway(intf);
+ 
+     setupDns(intf, o);
+     setupDomain(intf, o);
+@@ -509,7 +484,6 @@
+ 		    } else {
+ 			callScript(intf[closest].override.script,
+ 				   PUMP_SCRIPT_RENEWAL, &intf[closest]);
+-			callIfupPost(&intf[closest]);
+ 		    }
+ 
+ 		    continue;	    /* recheck timeouts */
+@@ -616,7 +590,6 @@
+ 		    if (!cmd.u.result) {
+ 			callScript(intf[i].override.script,
+ 				   PUMP_SCRIPT_RENEWAL, intf + i);
+-			callIfupPost(intf + i);
+ 		    }
+ 		}
+ 		break;
+@@ -850,7 +823,6 @@
+     printf("\tNext server %s\n", inet_ntoa(i.nextServer));
+ 
+     if (i.numGateways) {
+-	printf("\tGateway: %s\n", inet_ntoa(i.gateways[0]));
+ 	printf("\tGateways:");
+ 	for (j = 0; j < i.numGateways; j++)
+ 	    printf(" %s", inet_ntoa(i.gateways[j]));
+@@ -934,12 +906,15 @@
+     int killDaemon = 0;
+     int winId = 0;
+     int release = 0, renew = 0, status = 0, lookupHostname = 0, nodns = 0;
+-    int nogateway = 0, nobootp = 0;
++    int nogateway = 0, nobootp = 0, nontp = 0;
+     int nosetup = 0;
+     int noresolvconf = 0;
++    int routeMetric = 0;
++    int keepUp = 0;
+     struct command cmd, response;
+     char * configFile = "/etc/pump.conf";
+     char * script = NULL;
++    char * searchPath = NULL;
+     struct pumpOverrideInfo * overrides;
+     int cont;
+     struct poptOption options[] = {
+@@ -951,6 +926,8 @@
+             { "interface", 'i', POPT_ARG_STRING, &device, 0, 
+ 			N_("Interface to configure (normally eth0)"), 
+ 			N_("iface") },
++	    { "keep-up", 'u', POPT_ARG_NONE, &keepUp, 0,
++			N_("Keep the interface up when releasing it") },
+ 	    { "kill", 'k', POPT_ARG_NONE, &killDaemon, 0,
+ 			N_("Kill daemon (and disable all interfaces)"), NULL },
+ 	    { "lease", 'l', POPT_ARG_INT, &lease_hrs, 0,
+@@ -963,7 +940,9 @@
+ 			N_("Release interface"), NULL },
+ 	    { "renew", 'R', POPT_ARG_NONE, &renew, 0,
+ 			N_("Force immediate lease renewal"), NULL },
+-            { "verbose", 'v', POPT_ARG_NONE, &verbose, 0,
++	    { "route-metric", 'm', POPT_ARG_INT, &routeMetric, 0,
++			N_("Metric applied to routes (normally 0)"), N_("(metric)") },
++	    { "verbose", 'v', POPT_ARG_NONE, &verbose, 0,
+                         N_("Log verbose debug info"), NULL },
+ 	    { "status", 's', POPT_ARG_NONE, &status, 0,
+ 			N_("Display interface status"), NULL },
+@@ -971,12 +950,16 @@
+ 			N_("Don't update resolv.conf"), NULL },
+ 	    { "no-gateway", '\0', POPT_ARG_NONE, &nogateway, 0,
+ 			N_("Don't set a gateway for this interface"), NULL },
++	    { "no-ntp", '\0', POPT_ARG_NONE, &nontp, 0,
++			N_("Don't update ntp.conf"), NULL },
+ 	    { "no-setup", '\0', POPT_ARG_NONE, &nosetup, 0,
+ 			N_("Don't set up anything"), NULL },
+ 	    { "no-resolvconf", '\0', POPT_ARG_NONE, &noresolvconf, 0,
+ 			N_("Don't set up resolvconf"), NULL },
+ 	    { "no-bootp", '\0', POPT_ARG_NONE, &nobootp, 0,
+ 	                N_("Ignore non-DHCP BOOTP responses"), NULL },
++	    { "search-path", 'p', POPT_ARG_STRING, &searchPath, 0,
++			N_("Use this DNS search path instead of the supplied one"), NULL },
+ 	    { "script", '\0', POPT_ARG_STRING, &script, 0,
+ 			N_("Script to use") },
+ 	    { "win-client-ident", '\0', POPT_ARG_NONE, &winId, 0,
+@@ -1023,6 +1006,11 @@
+ 	return 1;
+     }
+ 
++    if (searchPath && strlen(searchPath) > sizeof(overrides->searchPath)) {
++	fprintf(stderr, _("%s: --search-path argument is to long\n"), PROGNAME);
++	return 1;
++    }
++    
+     if (script && strlen(script) > sizeof(overrides->script)) {
+ 	fprintf(stderr, _("%s: --script argument is too long\n"), PROGNAME);
+ 	return 1;
+@@ -1042,7 +1030,7 @@
+ 	flags |= PUMP_FLAG_WINCLIENTID;
+     if (lookupHostname)
+ 	flags |= PUMP_FLAG_FORCEHNLOOKUP;
+-
++    
+     if (killDaemon) {
+ 	cmd.type = CMD_DIE;
+     } else if (status) {
+@@ -1078,14 +1066,22 @@
+ 	    o->flags |= OVERRIDE_FLAG_NOBOOTP;
+ 	if (nogateway)
+ 	    o->flags |= OVERRIDE_FLAG_NOGATEWAY;
++	if (nontp)
++	    o->flags |= OVERRIDE_FLAG_NONTP;
+ 	if (nosetup)
+ 	    o->flags |=
+ 		OVERRIDE_FLAG_NOSETUP |
+ 		OVERRIDE_FLAG_NODNS |
+ 		OVERRIDE_FLAG_NOGATEWAY |
++		OVERRIDE_FLAG_NONTP |
+ 		OVERRIDE_FLAG_NONISDOMAIN;
+ 	if (noresolvconf)
+ 	    o->flags |= OVERRIDE_FLAG_NORESOLVCONF;
++	if (keepUp)
++	    o->flags |= OVERRIDE_FLAG_KEEPUP;
++	o->routeMetric = routeMetric;
++	if (searchPath)
++	    strcpy(o->searchPath, searchPath);
+ 	if (script)
+ 	    strcpy(o->script, script);
+  
+diff -Nru pump-0.8.24.orig/pump.h pump-0.8.24/pump.h
+--- pump-0.8.24.orig/pump.h	2009-02-11 10:47:07.000000000 +0100
++++ pump-0.8.24/pump.h	2009-02-11 10:47:33.000000000 +0100
+@@ -55,6 +55,8 @@
+ #define OVERRIDE_FLAG_NOBOOTP           (1 << 3)
+ #define OVERRIDE_FLAG_NOSETUP		(1 << 4)
+ #define OVERRIDE_FLAG_NORESOLVCONF	(1 << 5)
++#define OVERRIDE_FLAG_NONTP		(1 << 6)
++#define OVERRIDE_FLAG_KEEPUP		(1 << 7)
+ 
+ struct pumpOverrideInfo {
+     char device[10];
+@@ -63,6 +65,7 @@
+     int numRetries;
+     int timeout;
+     char script[1024];
++    int routeMetric;
+ };
+ 
+ /* all of these in_addr things are in network byte order! */
+@@ -113,7 +116,7 @@
+ char * pumpDisableInterface(struct pumpNetIntf * intf);
+ int pumpDhcpRenew(struct pumpNetIntf * intf);
+ int pumpDhcpRelease(struct pumpNetIntf * intf);
+-int pumpSetupDefaultGateway(struct in_addr * gw);
++int pumpSetupDefaultGateway(struct pumpNetIntf * intf);
+ time_t pumpUptime(void);
+ 
+ #define RESULT_OKAY		0
