--- proftpd-1.2.9.orig/config.guess
+++ proftpd-1.2.9/config.guess
@@ -0,0 +1,1432 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2004-01-05'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pegasos:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha*:OpenVMS:*:*)
+	echo alpha-hp-vms
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	# Determine whether the default compiler uses glibc.
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#if __GLIBC__ >= 2
+	LIBC=gnu
+	#else
+	LIBC=
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	# GNU/KFreeBSD systems have a "k" prefix to indicate we are using
+	# FreeBSD's kernel, but not the complete OS.
+	case ${LIBC} in gnu) kernel_only='k' ;; esac
+	echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+	i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	case `uname -p` in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    powerpc) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
+    *:DRAGONFLY:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly${UNAME_RELEASE}
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- proftpd-1.2.9.orig/debian/CVS/Root
+++ proftpd-1.2.9/debian/CVS/Root
@@ -0,0 +1 @@
+:ext:frankie@cvs.alioth.debian.org:/cvsroot/pkg-proftpd
--- proftpd-1.2.9.orig/debian/CVS/Repository
+++ proftpd-1.2.9/debian/CVS/Repository
@@ -0,0 +1 @@
+debian
--- proftpd-1.2.9.orig/debian/CVS/Entries
+++ proftpd-1.2.9/debian/CVS/Entries
@@ -0,0 +1,33 @@
+/NEWS.Debian/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/TODO.texi/1.1.1.1/Sun Sep 14 10:55:39 2003//
+/conffiles.notused/1.1.1.1/Sun Sep 14 10:55:39 2003//
+/copyright/1.3/Mon Nov  3 14:52:48 2003//
+/default/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/dirs/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/examples/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/ftpasswd.8/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/ftpusers/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/ftpusers.5/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/html2man.pl/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/mod_mysql.texi/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/mod_mysql.txt/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/mod_pgsql.texi/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/mod_pgsql.txt/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/proftpd.config/1.2/Mon Nov  3 14:52:48 2003//
+/proftpd.cron.monthly/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/proftpd.init/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/proftpd.pam/1.1.1.1/Sun Sep 14 10:55:40 2003//
+/proftpd.preinst/1.2/Mon Nov  3 14:52:48 2003//
+/proftpd.prerm/1.1.1.1/Sun Sep 14 10:55:39 2003//
+/proftpd.templates/1.1.1.1/Sun Sep 14 10:55:39 2003//
+/rules/1.4/Mon Nov  3 14:52:48 2003//
+/welcome.msg/1.1.1.1/Sun Sep 14 10:55:40 2003//
+D/patches////
+D/po////
+D/scripts////
+/control/1.6/Result of merge+Wed Mar 24 19:04:16 2004//
+/ftpstats.8/1.2/Wed Mar 24 19:04:16 2004//
+/proftpd.postrm/1.2/Result of merge+Wed Mar 24 19:04:16 2004//
+/basic.conf/1.4/Sun Apr  4 10:47:07 2004//
+/changelog/1.10/Result of merge+Sun Apr  4 10:47:08 2004//
+/proftpd.postinst/1.6/Result of merge//
--- proftpd-1.2.9.orig/debian/patches/CVS/Root
+++ proftpd-1.2.9/debian/patches/CVS/Root
@@ -0,0 +1 @@
+:ext:frankie@cvs.alioth.debian.org:/cvsroot/pkg-proftpd
--- proftpd-1.2.9.orig/debian/patches/CVS/Repository
+++ proftpd-1.2.9/debian/patches/CVS/Repository
@@ -0,0 +1 @@
+debian/patches
--- proftpd-1.2.9.orig/debian/patches/CVS/Entries
+++ proftpd-1.2.9/debian/patches/CVS/Entries
@@ -0,0 +1,16 @@
+/02.mod_pam.c.change.pam.name.diff/1.1/Mon Nov  3 14:52:48 2003//
+/03.mod_ldap.c.diff/1.1/Mon Nov  3 14:52:48 2003//
+/04.mod_sql_postgres.c.diff/1.1/Mon Nov  3 14:52:48 2003//
+/06.man.diff/1.1/Mon Nov  3 14:52:48 2003//
+/07.autoconf.diff/1.1/Mon Nov  3 14:52:48 2003//
+/08.misc.diff/1.1/Mon Nov  3 14:52:48 2003//
+/09.mod_xfer.c.diff/1.1/Mon Nov  3 14:52:48 2003//
+/10.mod_unixpw.c.ldap.fix.diff/1.1/Mon Nov  3 14:52:48 2003//
+/11.mod_auth.c.shell.null.segfault.diff/1.1/Mon Nov  3 14:52:48 2003//
+/12.ftpasswd.cracklib.location.diff/1.1/Mon Nov  3 14:52:48 2003//
+/13.mod_sql_mysql.c.diff/1.1/Mon Nov  3 14:52:48 2003//
+/14.quotatab_modules.diff/1.4/Mon Nov 17 15:30:12 2003//
+/15.mod_quotatab_sql.c.diff/1.1/Tue Mar  9 10:18:09 2004//
+/01.contrib.mod_ldap.c.diff/1.8/Result of merge+Sun Apr  4 10:47:08 2004//
+/16.dirtree,c.diff/1.1/Mon Mar 29 20:50:59 2004//
+D
--- proftpd-1.2.9.orig/debian/patches/17.netio.c.diff
+++ proftpd-1.2.9/debian/patches/17.netio.c.diff
@@ -0,0 +1,12 @@
+diff -ruN proftpd-1.2.9-old/src/netio.c proftpd-1.2.9/src/netio.c
+--- proftpd-1.2.9-old/src/netio.c	2003-10-17 08:15:38.000000000 +0200
++++ proftpd-1.2.9/src/netio.c	2004-04-12 09:37:55.000000000 +0200
+@@ -682,7 +682,7 @@
+           }
+ 
+ #ifdef EAGAIN
+-	  if (errno == EAGAIN)
++	  if (bread == -1 && errno == EAGAIN)
+             goto polling;
+ #endif
+ 
--- proftpd-1.2.9.orig/debian/patches/01.contrib.mod_ldap.c.diff
+++ proftpd-1.2.9/debian/patches/01.contrib.mod_ldap.c.diff
@@ -0,0 +1,329 @@
+diff -ruN proftpd-1.2.8+cvs20030805-old/contrib/mod_ldap.c proftpd-1.2.8+cvs20030805/contrib/mod_ldap.c
+--- proftpd-1.2.8+cvs20030805-old/contrib/mod_ldap.c	2003-07-16 21:06:36.000000000 +0200
++++ proftpd-1.2.8+cvs20030805/contrib/mod_ldap.c	2003-08-05 11:08:42.000000000 +0200
+@@ -40,13 +40,16 @@
+  *                                         - LDAPForceHomedirOnDemand support
+  * Andreas Strodl (andreas at strodl dot org) - multiple group support
+  * Ross Thomas (ross at grinfinity dot com) - Non-AuthBinds auth fix
+- * Ivo Timmermans (ivo at debian dot org) - TLS support
++ * Ivo Timmermans (ivo at debian dot org) - LDAPCheckAllow,LDAPCheckDeny,
++ *                                         LDAPHomedirOnDemandScript,
++ *                                         TLS support
+  * Bert Vermeulen (bert at be dot easynet dot net) - LDAPHomedirOnDemand,
+  *                                                   LDAPDefaultAuthScheme
+  *
+  *
+  * $Id: mod_ldap.c,v 1.30 2003/07/10 16:09:23 jwm Exp $
+  * $Libraries: -lldap -llber$
++ * $Libraries: -lldap -llber -lcrypto$
+  */
+ 
+ /* You can override the attribute names that mod_ldap uses here. */
+@@ -89,7 +92,7 @@
+  * TLS after connecting to the LDAP server. If TLS cannot be enabled, the
+  * LDAP connection will fail.
+  */
+-/* #define USE_LDAPV3_TLS */
++#define USE_LDAPV3_TLS 
+ 
+ /* Uncomment this if you have OpenSSL and wish to verify non-crypt()
+  * password hashes locally with OpenSSL. You'll also need to edit
+@@ -97,7 +100,7 @@
+  * (-I/path/to/include-dir) and link again OpenSSL's crypto library
+  * (-L/path/to/lib-dir -lcrypto).
+  */
+-/* #define HAVE_OPENSSL */
++#define HAVE_OPENSSL
+ 
+ /*
+  * If you have to edit anything below this line, it's a bug. Report it
+@@ -164,8 +167,11 @@
+             *ldap_auth_basedn, *ldap_uid_basedn, *ldap_gid_basedn,
+             *ldap_quota_basedn,
+             *ldap_defaultauthscheme, *ldap_authbind_dn,
++            *ldap_check_allow = NULL, *ldap_check_deny = NULL,
++            *ldap_hdod_script = NULL,
+             *ldap_hdod_prefix, **ldap_hdod_suffix,
+             *ldap_default_quota;
++static array_header *ldap_check_allow_result = NULL, *ldap_check_deny_result = NULL;
+ static int ldap_doauth = 0, ldap_douid = 0, ldap_dogid = 0, ldap_doquota = 0,
+            ldap_authbinds = 1, ldap_negcache = 1,
+            ldap_querytimeout = 0, ldap_hdod = 0, ldap_hdod_prefix_nouname = 0,
+@@ -419,15 +425,72 @@
+   return filter;
+ }
+ 
++void ldap_array_add_attrs(char **ldap_attrs, char *attr)
++{
++  int i;
++
++  if(attr == NULL)
++    return;
++  if(ldap_attrs == NULL)
++    return;
++  for(i = 0; ldap_attrs[i]; i++)
++    ;
++ ldap_attrs[i] = attr;
++ ldap_attrs[i+1] = NULL;
++}
++
++/* Duplicate the array of char*'s, and reserve space for two extra
++   elements */
++char **ldap_array_duplicate(char **ldap_attrs, pool *p)
++{
++  int i;
++  char **r;
++
++  for(i = 0; ldap_attrs[i]; i++)
++    ;
++  r = pcalloc(p, (i + 3) * sizeof(char *));
++  for(i = 0; ldap_attrs[i]; i++)
++    r[i] = ldap_attrs[i];
++  r[i] = NULL;
++  return r;
++}
++
++/* Execute script when a new homedir is to be created.  The script
++   will have the homedir as its first and only argument. */
++static int execute_hdod_script(const char *script, const char *dir)
++{
++  pid_t pid;
++  int status;
++
++  if(!(pid = fork()))
++    { /* child */
++      if(execl(script, script, dir, NULL) < 0)
++       return -1;
++    }
++  else
++    { /* parent */
++      if(wait4(pid, &status, WUNTRACED, NULL) < 0)
++       return -1;
++    }
++
++  return 0;
++}
++
++
++
++
+ static struct passwd *
+ pr_ldap_user_lookup(pool *p,
+                     char *filter_template, const char *replace,
+-                    char *basedn, char *ldap_attrs[],
++                    char *basedn, char *orig_ldap_attrs[],
+                     char **user_dn)
+ {
+   char *filter, **values, *dn;
+   int i = 0, ret;
+   LDAPMessage *result, *e;
++  unsigned short int homedirisnew = 0;
++  char **ldap_attrs;
++
+ 
+   if (! basedn) {
+     log_pri(PR_LOG_ERR, "mod_ldap: no LDAP base DN specified for auth/UID lookups, declining request.");
+@@ -445,6 +508,15 @@
+ 
+   filter = pr_ldap_generate_filter(p, filter_template, replace);
+ 
++  /* Copy the array */
++  ldap_attrs = ldap_array_duplicate(orig_ldap_attrs, p);
++
++  /* Add two extra attributes if we want user based access control */
++  if(ldap_check_allow)
++    ldap_array_add_attrs(ldap_attrs, ldap_check_allow);
++  if(ldap_check_deny)
++    ldap_array_add_attrs(ldap_attrs, ldap_check_deny);
++
+   if ((ret = ldap_search_st(ld, basedn, ldap_search_scope, filter, ldap_attrs, 0, &ldap_querytimeout_tp, &result)) != LDAP_SUCCESS) {
+     if (ret == LDAP_SERVER_DOWN) {
+       log_pri(PR_LOG_ERR, "mod_ldap: pr_ldap_user_lookup(): LDAP server went away, trying to reconnect");
+@@ -545,6 +617,20 @@
+         continue;
+       }
+ 
++      /* Don't worry if either of these isn't found in the tree */
++      if(ldap_check_allow)
++       if (strcasecmp(ldap_attrs[i], ldap_check_allow) == 0) {
++         /* value of ldap_check_allow has been found */
++         ++i;
++         continue;
++       }
++      if(ldap_check_deny)
++       if (strcasecmp(ldap_attrs[i], ldap_check_deny) == 0) {
++         /* value of ldap_check_deny has been found */
++         ++i;
++         continue;
++       }
++
+       /* We only restart the while loop above if we can fill in alternate
+        * values for certain attributes. If something odd has happened, we
+        * fall through to here and will complain about not being able to find
+@@ -1764,6 +1850,45 @@
+ #endif /* USE_LDAPV3_TLS */
+ }
+ 
++MODRET set_ldap_allow(cmd_rec *cmd)
++{
++  config_rec *c;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd,CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  c = add_config_param_str("LDAPCheckAllow", 1, cmd->argv[1]);
++  c->flags |= CF_MERGEDOWN;
++
++  return(HANDLED(cmd));
++}
++
++MODRET set_ldap_deny(cmd_rec *cmd)
++{
++  config_rec *c;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd,CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  c = add_config_param_str("LDAPCheckDeny", 1, cmd->argv[1]);
++  c->flags |= CF_MERGEDOWN;
++
++  return(HANDLED(cmd));
++}
++
++MODRET set_ldap_hdod_script(cmd_rec *cmd)
++{
++  config_rec *c;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd,CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  c = add_config_param_str("LDAPHomedirOnDemandScript", 1, cmd->argv[1]);
++  c->flags |= CF_MERGEDOWN;
++
++  return(HANDLED(cmd));
++}
++
+ static int
+ ldap_getconf(void)
+ {
+@@ -1893,6 +2018,8 @@
+     ldap_hdod_suffix[i] = NULL;
+   }
+ 
++  ldap_hdod_script  = (char *)get_param_ptr(main_server->conf,"LDAPHomedirOnDemandScript", FALSE);
++
+   /* If ldap_defaultauthscheme is NULL, ldap_check() will assume crypt. */
+   ldap_defaultauthscheme = (char *)get_param_ptr(main_server->conf, "LDAPDefaultAuthScheme", FALSE);
+ 
+@@ -1900,9 +2027,94 @@
+   ldap_use_tls = (int)get_param_int(main_server->conf, "LDAPUseTLS", FALSE);
+ #endif
+ 
++  ldap_check_allow = (char *)get_param_ptr(main_server->conf, "LDAPCheckAllow", FALSE);
++  ldap_check_deny  = (char *)get_param_ptr(main_server->conf, "LDAPCheckDeny",  FALSE);
++
+   return 0;
+ }
+ 
++/* Check any allow/deny IP address ranges to see if this user is
++   allowed to connect.  This function uses the result of
++   ldap_lookup_user(), so it can only be called after the USER command
++   has been handled completely.
++*/
++int ldap_check_ip_match(cmd_rec *cmd, const char *name)
++{
++  char *arg;
++  int argc;
++  int negate = 0;
++  array_header *res;
++
++  if(strcasecmp(name, "Allow") == 0) {
++    res = ldap_check_allow_result;
++  } else {
++    res = ldap_check_deny_result;
++  }
++
++  if(res != (array_header*)(NULL)) {
++    for(argc = 0; (arg = (char*)((char**)res->elts)[argc]) && argc < res->nelts; argc++) {
++      if(*arg == '!') {
++       negate++;
++       arg++;
++      } else negate = 0;
++
++      /* match_ip() is in dirtree.c */
++      switch(match_ip(session.c->remote_addr,session.c->remote_name,arg)) {
++      case 1:
++       /* If in logical negate mode, we specifically did NOT find what we
++        * were looking for.
++        */
++       if(negate) break;
++
++       /* otherwise, we did */
++       return TRUE;
++
++      case -1:
++       /* -1 is only returned on an explicit mismatch, which can only
++        * happen for "NONE".  Negate is not valid in this case, and is
++        * disallowed by mod_core's _add_allow_deny().
++        */
++       return FALSE;
++
++      default:
++       /* No match, but if we are in negate mode, that means it IS
++        * a match.
++        */
++       if(negate) return FALSE;
++       break;
++      }
++    }
++  }
++  return FALSE;
++}
++
++
++/* When we get a PASS command, first check if the user is allowed to
++   log in; check with any allow/deny values that we acquired from LDAP
++   earlier.
++   The user must exist in the LDAP directory.
++*/
++MODRET ldap_cmd_pass(cmd_rec *cmd)
++{
++  if(ldap_check_allow)
++    /* Check allow rules */
++    if(ldap_check_ip_match(cmd, "Allow") == TRUE)
++      return DECLINED(cmd);  /* No change, continue the command chain */
++
++  if(ldap_check_deny)
++    /* Check deny rules */
++    if(ldap_check_ip_match(cmd, "Deny") == TRUE)
++      {
++       log_pri(LOG_NOTICE, "User denied access based on the value of %s\n",
++               ldap_check_deny);
++       /* User is not allowed to log in, based on his IP address. */
++       return ERROR_MSG(cmd,R_530,"Login incorrect.");
++      }
++
++  return DECLINED(cmd);  /* No change, continue the command chain */
++}
++
++
+ static conftable ldap_config[] = {
+   { "LDAPServer",                          set_ldap_server,            NULL },
+   { "LDAPDNInfo",                          set_ldap_dninfo,            NULL },
+@@ -1923,12 +2135,16 @@
+   { "LDAPHomedirOnDemandPrefixNoUsername", set_ldap_hdodprefixnouname, NULL },
+   { "LDAPHomedirOnDemandSuffix",           set_ldap_hdodsuffix,        NULL },
+   { "LDAPForceHomedirOnDemand",            set_ldap_forcehdod,         NULL },
++  { "LDAPHomedirOnDemandScript",           set_ldap_hdod_script,       NULL },
+   { "LDAPDefaultAuthScheme",               set_ldap_defaultauthscheme, NULL },
+   { "LDAPUseTLS",                          set_ldap_usetls,            NULL },
++  { "LDAPCheckAllow",                      set_ldap_allow,             NULL },
++  { "LDAPCheckDeny",                       set_ldap_deny,              NULL },
+   { NULL,                                  NULL,                       NULL }
+ };
+ 
+ static cmdtable ldap_cmdtab[] = {
++  {CMD, C_PASS, G_NONE, ldap_cmd_pass, FALSE, FALSE },
+   {CMD, "ldap_quota_lookup", G_NONE, handle_ldap_quota_lookup, FALSE, FALSE},
+   {0, NULL}
+ };
--- proftpd-1.2.9.orig/debian/patches/02.mod_pam.c.change.pam.name.diff
+++ proftpd-1.2.9/debian/patches/02.mod_pam.c.change.pam.name.diff
@@ -0,0 +1,12 @@
+diff -urN proftpd-1.2.8/modules/mod_auth_pam.c proftpd-1.2.8-debian/modules/mod_auth_pam.c
+--- proftpd-1.2.8/modules/mod_auth_pam.c	2003-01-02 19:25:20.000000000 +0100
++++ proftpd-1.2.8-debian/modules/mod_auth_pam.c	2003-03-17 15:09:28.000000000 +0100
+@@ -57,7 +57,7 @@
+ #endif /* HAVE_PAM_PAM_APPL_H */
+ 
+ static pam_handle_t *	pamh			= NULL;
+-static char *		pamconfig		= "ftp";
++static char *		pamconfig		= "proftpd";
+ static char *		pam_user 		= NULL;
+ static char *		pam_pass 		= NULL;
+ static size_t		pam_user_len		= 0;
--- proftpd-1.2.9.orig/debian/patches/03.mod_ldap.c.diff
+++ proftpd-1.2.9/debian/patches/03.mod_ldap.c.diff
@@ -0,0 +1,12 @@
+diff -ruN proftpd-1.2.8+cvs20030805-old/contrib/mod_ldap.c proftpd-1.2.8+cvs20030805/contrib/mod_ldap.c
+--- proftpd-1.2.8+cvs20030805-old/contrib/mod_ldap.c	2003-08-07 13:54:18.000000000 +0200
++++ proftpd-1.2.8+cvs20030805/contrib/mod_ldap.c	2003-08-07 13:56:15.000000000 +0200
+@@ -1956,7 +1956,7 @@
+         ldap_group_gid_filter = "(&(" GIDNUMBER_ATTR "=%v)(objectclass=posixGroup))";
+ 
+       if (c->argc > 4)
+-        ldap_group_member_filter = pstrdup(session.pool, c->argv[3]);
++        ldap_group_member_filter = pstrdup(session.pool, c->argv[4]);
+       else
+         ldap_group_member_filter = "(&(" MEMBERUID_ATTR "=%v)(objectclass=posixGroup))";
+     }
--- proftpd-1.2.9.orig/debian/patches/04.mod_sql_postgres.c.diff
+++ proftpd-1.2.9/debian/patches/04.mod_sql_postgres.c.diff
@@ -0,0 +1,12 @@
+diff -urN proftpd-1.2.8+cvs20030620/contrib/mod_sql_postgres.c proftpd-1.2.8+cvs20030620-debian/contrib/mod_sql_postgres.c
+--- proftpd-1.2.8+cvs20030620/contrib/mod_sql_postgres.c	2003-06-19 09:34:54.000000000 +0200
++++ proftpd-1.2.8+cvs20030620-debian/contrib/mod_sql_postgres.c	2003-06-21 12:51:53.000000000 +0200
+@@ -37,7 +37,7 @@
+ 
+ #define _POSTGRES_PORT "5432"
+ 
+-#include <libpq-fe.h>
++#include <postgresql/libpq-fe.h>
+ #include "conf.h"
+ #include "../contrib/mod_sql.h"
+ 
--- proftpd-1.2.9.orig/debian/patches/06.man.diff
+++ proftpd-1.2.9/debian/patches/06.man.diff
@@ -0,0 +1,22 @@
+diff -urN proftpd-1.2.8/Makefile.in proftpd-1.2.8-debian/Makefile.in
+--- proftpd-1.2.8/Makefile.in	2003-01-30 02:25:40.000000000 +0100
++++ proftpd-1.2.8-debian/Makefile.in	2003-03-17 15:17:46.000000000 +0100
+@@ -94,7 +94,8 @@
+ 	       	           $(DESTDIR)$(sysconfdir)/proftpd.conf ; \
+ 	fi
+ 
+-install-man: $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir)/man5 $(DESTDIR)$(mandir)/man8
++install-man-proftpd: $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man8
++install-man-utils: $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir)/man5 $(DESTDIR)$(mandir)/man8
+ 	$(INSTALL_MAN) $(top_srcdir)/src/proftpd.8    $(DESTDIR)$(mandir)/man8
+ 	$(INSTALL_MAN) $(top_srcdir)/utils/ftpshut.8  $(DESTDIR)$(mandir)/man8
+ 	$(INSTALL_MAN) $(top_srcdir)/utils/ftpcount.1 $(DESTDIR)$(mandir)/man1
+@@ -102,6 +103,8 @@
+ 	$(INSTALL_MAN) $(top_srcdir)/utils/ftpwho.1   $(DESTDIR)$(mandir)/man1
+ 	$(INSTALL_MAN) $(top_srcdir)/src/xferlog.5    $(DESTDIR)$(mandir)/man5
+ 
++install-man: install-man-proftpd install-man-utils
++
+ install-all: install-proftpd install-utils install-conf install-man
+ 
+ install: install-all
--- proftpd-1.2.9.orig/debian/patches/07.autoconf.diff
+++ proftpd-1.2.9/debian/patches/07.autoconf.diff
@@ -0,0 +1,2685 @@
+diff -ruN proftpd-1.2.8+cvs20031020-old/configure.ac proftpd-1.2.8+cvs20031020/configure.ac
+--- proftpd-1.2.8+cvs20031020-old/configure.ac	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.8+cvs20031020/configure.ac	2003-10-15 22:37:53.000000000 +0200
+@@ -0,0 +1,1328 @@
++dnl ProFTPD - FTP server daemon
++dnl Copyright (c) 1997, 1998 Public Flood Software
++dnl Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net>
++dnl Copyright (c) 2001, 2002, 2003 The ProFTPD Project team
++dnl
++dnl This program is free software; you can redistribute it and/or modify
++dnl it under the terms of the GNU General Public License as published by
++dnl the Free Software Foundation; either version 2 of the License, or
++dnl (at your option) any later version.
++dnl
++dnl This program is distributed in the hope that it will be useful,
++dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
++dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++dnl GNU General Public License for more details.
++dnl
++dnl You should have received a copy of the GNU General Public License
++dnl along with this program; if not, write to the Free Software
++dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
++dnl
++dnl Process this file with autoconf to produce a configure script.
++
++AC_INIT(include/conf.h)
++
++ac_core_modules="mod_core.o mod_xfer.o mod_auth_unix.o mod_auth_file.o mod_auth.o mod_ls.o mod_log.o mod_site.o"
++ac_build_core_modules="modules/mod_core.o modules/mod_xfer.o modules/mod_auth_unix.o modules/mod_auth_file.o modules/mod_auth.o modules/mod_ls.o modules/mod_log.o modules/mod_site.o"
++
++dnl Get the OS type
++AC_CONFIG_AUX_DIR(./)
++AC_CANONICAL_SYSTEM
++
++dnl Create symlinks in modules/ and contrib/
++olddir=`pwd`
++cd contrib
++test -f README.mod_sql || ln -s ../README.mod_sql README.mod_sql
++cd $olddir
++
++OSTYPE=-D`echo $build_os | sed 's/\..*$//g' | sed 's/-.*//g' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
++OSREL=-D`echo $build_os | sed 's/-.*//g' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | tr '.' '_'`
++
++if test "$OSTYPE" = "$OSREL" ; then
++  OSTYPE=""
++fi
++AC_SUBST(OSREL)
++AC_SUBST(OSTYPE)
++
++dnl MacOS X requires -traditional-cpp; autodetecting it isn't impossible
++dnl AFAIK, since assuming the need for -traditional-cpp breaks the build
++dnl on other OSes. -jwm, 30 Jan 2001
++if test "$OSTYPE" = "-DRHAPSODY5"; then
++  CFLAGS="$CFLAGS -traditional-cpp -D__OT__"
++fi
++
++dnl Checks for programs.
++AC_PROG_CC
++AC_PROG_MAKE_SET
++AC_PROG_INSTALL
++AC_PROG_RANLIB
++
++dnl This test must come as early as possible after the compiler
++dnl configuration tests, because the choice of the file model can (in
++dnl principle) affect whether functions and headers are available,
++dnl whether they work, etc.
++AC_SYS_LARGEFILE  
++
++# The native HP-UX 10 compiler needs -Ae to enable Extended ANSI compliance
++# (-Ae is the default in the native compiler under HP-UX 11).
++if test $ac_cv_prog_gcc = no -a "$OSTYPE" = "-DHPUX10"; then
++  CFLAGS="$CFLAGS -Ae"
++fi
++
++LDFLAGS="-Llib $LDFLAGS"
++
++if test $ac_cv_prog_gcc = yes; then
++  if test x"$CFLAGS" = "x-g -O2"; then
++    fullCFLAGS="-O2"
++  else
++    fullCFLAGS="$CFLAGS"
++  fi
++
++  dnl Compilation tests
++
++  dnl test for -malign-jumps=2 -malign-loops=2 -malign-functions=2
++  if echo $ac_cv_build_cpu | egrep "^i[[34567]]86$" > /dev/null 2>&1; then
++    AC_MSG_CHECKING([whether the C compiler accepts -malign-jumps -malign-loops -malign-functions])
++    CFLAGS="-malign-jumps=2 -malign-loops=2 -malign-functions=2"
++    AC_TRY_COMPILE(,,
++      AC_MSG_RESULT(yes); fullCFLAGS="$fullCFLAGS $CFLAGS",
++      AC_MSG_RESULT(no))
++  fi
++
++  dnl test for -Wall
++  AC_MSG_CHECKING([whether the C compiler accepts -Wall])
++  CFLAGS="-Wall"
++  AC_TRY_COMPILE(,,
++    AC_MSG_RESULT(yes); fullCFLAGS="$fullCFLAGS $CFLAGS",
++    AC_MSG_RESULT(no))
++
++  CFLAGS="$fullCFLAGS"
++fi
++
++dnl We substitute these in the man page templates.
++if test x$exec_prefix = xNONE; then
++  exec_prefix=$prefix
++fi
++
++BINDIR=`eval echo $bindir`
++AC_SUBST(BINDIR)
++LOCALSTATEDIR=`eval echo $localstatedir`
++AC_SUBST(LOCALSTATEDIR)
++SBINDIR=`eval echo $sbindir`
++AC_SUBST(SBINDIR)
++SYSCONFDIR=`eval echo $sysconfdir`
++AC_SUBST(SYSCONFDIR)
++
++AC_ARG_VAR(LIBS, [linker flags, e.g. -l<lib>.{a,so} if you have nonstandard libraries to link])
++
++dnl configure command line options...
++
++dnl --with options.
++
++dnl ProFTPD comes bundled with GNU's implementation of getopt, to be used
++dnl in case the host system doesn't have getopt.  However, this causes
++dnl problems for certain builds of proftpd, e.g. ProFTPD and MySQL (which
++dnl itself similarly bundles a getopt implementation).  Thus, we need to
++dnl support/handle --without-getopt, to disable use of ProFTPD's getopt.
++dnl I don't know if MySQL supports any similar option.
++LIB_OBJS="pr_fnmatch.o sstrncpy.o strsep.o vsnprintf.o glibc-glob.o glibc-hstrerror.o glibc-mkstemp.o pr-syslog.o pwgrent.o"
++ac_pr_check_getopt="yes"
++
++AC_ARG_WITH(getopt,
++  [AC_HELP_STRING(
++      [--without-getopt],
++      [prevent proftpd from using its bundled getopt implementation.  This is done automatically if the host supports getopt, but may need to be explicitly used when combining proftpd with other applications, such as MySQL])
++  ],
++  [
++    if test "$withval" != "no" ; then
++      LIB_OBJS="$LIB_OBJS getopt.o getopt1.o"
++      AC_CHECK_FUNCS(getopt)
++    fi
++  ],
++  [
++    LIB_OBJS="$LIB_OBJS getopt.o getopt1.o"
++    AC_CHECK_FUNCS(getopt)
++  ])
++
++dnl Modules...'nuff said.
++AC_ARG_WITH(includes,
++  [AC_HELP_STRING(
++    [--with-includes=LIST],
++    [add additional include paths to proftpd. LIST is a colon-separated list of include paths to add e.g. --with-includes=/some/mysql/include:/my/include])
++  ],
++  [ ac_addl_includes=`echo "$withval" | sed -e 's/:/ /g'` ;
++    for ainclude in $ac_addl_includes; do
++      if test x"$ac_build_addl_includes" = x ; then
++        ac_build_addl_includes="-I$ainclude"
++      else
++        ac_build_addl_includes="-I$ainclude $ac_build_addl_includes"
++      fi
++    done ])
++
++AC_ARG_WITH(libraries,
++  [AC_HELP_STRING(
++    [--with-libraries=LIST],
++    [add additional library paths to proftpd. LIST is a colon-separated list of include paths to add e.g. --with-libraries=/some/mysql/libdir:/my/libs])
++  ],
++  [ ac_addl_libraries=`echo "$withval" | sed -e 's/:/ /g'` ;
++    for ainclude in $ac_addl_libraries; do
++      if test x"$ac_build_addl_libraries" = x ; then
++        ac_build_addl_libraries="-L$ainclude"
++      else
++        ac_build_addl_libraries="-L$ainclude $ac_build_addl_libraries"
++      fi
++    done ])
++
++AC_ARG_WITH(modules,
++  [AC_HELP_STRING(
++    [--with-modules=LIST],
++    [add additional modules to proftpd. LIST is a colon-separated list of modules to add e.g. --with-modules=mod_auth_pam:mod_readme])
++  ],
++  [ ac_addl_modules=`echo "$withval" | sed -e 's/:/.o /g'`.o ;
++    for amodule in $ac_addl_modules; do
++      ac_build_addl_modules="modules/$amodule $ac_build_addl_modules"
++    done ])
++
++dnl --enable/--disable options.
++
++AC_ARG_ENABLE(auth-unix,
++  [AC_HELP_STRING(
++    [--disable-auth-unix],
++    [omit mod_auth_unix from core modules])
++  ],
++  [
++    if test "$enableval" = "no"; then
++      ac_core_modules=`echo "$ac_core_modules" | sed -e 's/mod_auth_unix\.o//'`
++      ac_build_core_modules=`echo "$ac_build_core_modules" | sed -e 's/modules\/mod_auth_unix\.o//'`
++    fi
++  ])
++
++AC_ARG_ENABLE(auth-file,
++  [AC_HELP_STRING(
++    [--disable-auth-file],
++    [omit mod_auth_file from core modules])
++  ],
++  [
++    if test "$enableval" = "no"; then
++      ac_core_modules=`echo "$ac_core_modules" | sed -e 's/mod_auth_file\.o//'`
++      ac_build_core_modules=`echo "$ac_build_core_modules" | sed -e 's/modules\/mod_auth_file\.o//'`
++    fi
++  ])
++ 
++dnl Auto-detection of shadow passwords.
++AC_ARG_ENABLE(autoshadow,
++  [AC_HELP_STRING(
++    [--enable-autoshadow],
++    [enable run-time auto-detection of shadowed passwords (requires shadow)])
++  ],
++  [
++    dnl AIX does not have shadow file/library support.  Try to prevent a
++    dnl bad build if the admin, configuring on an AIX box, uses this option.
++    if test "$enableval" = "yes" && test "$OSTYPE" = "-DAIX4"; then
++      AC_MSG_WARN(AIX does not support traditional shadowed passwords)
++      enableval="no"
++    fi
++
++    if test "$enableval" != "no" ; then
++      AC_DEFINE(USE_SHADOW, 1, [Define if using /etc/shadow files.])
++      AC_DEFINE(USE_AUTO_SHADOW, 1,
++      [Define if auto-detection of shadow passwords is wanted.])
++      force_shadow="yes"
++    fi ])
++
++dnl PAM support.
++AC_ARG_ENABLE(auth-pam,
++  [AC_HELP_STRING(
++    [--enable-auth-pam],
++    [enable PAM support (default=yes)])
++  ],
++  [ if test "$enableval" = "no" && \
++       test `echo $ac_addl_modules | grep -c mod_auth_pam` != "0"; then
++      AC_MSG_ERROR([You cannot run configure with --disable-auth-pam and include mod_auth_pam in --with-modules at the same time])
++    fi ])
++
++dnl Workaround for broken getaddrinfo on some systems
++AC_ARG_ENABLE(builtin-getaddrinfo,
++  [AC_HELP_STRING(
++    [--enable-builtin-getaddrinfo],
++    [force use of builtin getaddrinfo (default=no)])
++  ],
++  [
++    if test x"$enableval" = xyes; then
++      AC_DEFINE(USE_GETADDRINFO, 1, [Define if using builtin getaddrinfo()])
++    fi
++  ])
++
++dnl Workaround for borken getnameinfo on some systems
++AC_ARG_ENABLE(builtin-getnameinfo,
++  [AC_HELP_STRING(
++    [--enable-builtin-getnameinfo],
++    [force use of builtin getnameinfo (default=no)])
++  ],
++  [
++    if test x"$enableval" = xyes; then
++      AC_DEFINE(USE_GETNAMEINFO, 1, [Define if using builtin getnameinfo()])
++    fi
++  ])
++
++dnl Capabilities support
++AC_ARG_ENABLE(cap,
++  [AC_HELP_STRING(
++    [--enable-cap],
++    [enable POSIX.1e capabilities (default=yes on Linux)])
++  ])
++
++dnl Curses/ncurses support
++AC_ARG_ENABLE(curses,
++  [AC_HELP_STRING(
++    [--disable-curses],
++    [disable use of curses (default=no)])
++  ])
++
++AC_ARG_ENABLE(ncurses,
++  [AC_HELP_STRING(
++    [--disable-ncurses],
++    [disable use of ncurses (default=no)])
++  ])
++
++dnl Workaround for broken setpassent on FreeBSD.
++AC_ARG_ENABLE(force-setpassent,
++  [AC_HELP_STRING(
++    [--enable-force-setpassent],
++    [force use of setpassent (default=no on FreeBSD)])
++  ])
++
++dnl IPv6 support.
++AC_ARG_ENABLE(ipv6,
++  [AC_HELP_STRING(
++    [--enable-ipv6],
++    [enable IPv6 support (default=no)])
++  ],
++  [ if test "$enableval" = "yes" ; then
++      AC_DEFINE(USE_IPV6, 1, [Define if using IPv6 support.])
++    fi
++  ])
++
++dnl Sendfile support.
++AC_ARG_ENABLE(sendfile,
++  [AC_HELP_STRING(
++    [--enable-sendfile],
++    [enable sendfile support (default=no)])
++  ])
++
++dnl Check for enabled shadow password support.
++AC_ARG_ENABLE(shadow,
++  [AC_HELP_STRING(
++    [--enable-shadow],
++    [force compilation of shadowed password support])
++  ],
++  [
++    dnl AIX does not have shadow file/library support.  Try to prevent a
++    dnl bad build if the admin, configuring on an AIX box, uses this option.
++    if test "$enableval" = "yes" && test "$OSTYPE" = "-DAIX4"; then
++      AC_MSG_WARN([AIX does not support traditional shadowed passwords])
++      enableval="no" 
++    fi
++
++    if test "$enableval" = "no" ; then
++      use_shadow=""
++      force_shadow="no"
++    else
++      AC_DEFINE(USE_SHADOW)
++      force_shadow="yes"
++    fi ])
++
++dnl Enable support for Tru64's C2 SIA authentication
++AC_ARG_ENABLE(sia,
++  [AC_HELP_STRING(
++    [--enable-sia],
++    [enable SIA authentication support (Tru64)])
++  ],
++  [
++    if test x"$enableval" = xyes ; then
++
++      dnl Tru64's C2/SIA authentication requires these headers
++      AC_CHECK_HEADERS(sia.h siad.h sys/security.h)
++
++      AC_CHECK_FUNCS(set_auth_parameters, ,
++        [AC_CHECK_LIB(security, set_auth_parameters)])
++      AC_CHECK_FUNCS(getprpwent, ,
++        [AC_CHECK_LIB(sec, getprpwent)])
++
++      AC_DEFINE(USE_SIA)
++    fi
++  ])
++
++dnl Enable developer code
++pr_devel_cflags="-DPR_DEVEL -g -Wcast-align -Wchar-subscripts -Winline -Wstrict-prototypes -Wmissing-declarations -Wnested-externs -Wpointer-arith -Wshadow -Wundef"
++pr_devel_libs=""
++
++AC_ARG_ENABLE(devel,
++  [AC_HELP_STRING(
++    [--enable-devel],
++    [enable code of interest to developers])
++  ],
++  [
++    if test x"$enableval" != xno ; then
++      devel="yes"
++
++      dnl Check to see if specific developer flags were requested
++
++      if test `echo $enableval | grep -c coredump` = "1" ; then
++        pr_devel_cflags="-DPR_DEVEL_COREDUMP $pr_devel_cflags"
++      fi
++
++      if test `echo $enableval | grep -c nodaemon` = "1" ; then
++        pr_devel_cflags="-DPR_DEVEL_NO_DAEMON $pr_devel_cflags"
++      fi
++
++      if test `echo $enableval | grep -c nofork` = "1" ; then
++        pr_devel_cflags="-DPR_DEVEL_NO_FORK $pr_devel_cflags"
++      fi
++
++      if test `echo $enableval | grep -c profile` = "1" ; then
++        pr_devel_cflage="-p -pg $pr_devel_cflags"
++        pr_devel_libs="-pg $pr_devel_libs"
++      fi
++
++    else
++      devel="no"
++    fi
++  ])
++
++dnl The "tunable" options, from include/options.h
++AC_ARG_ENABLE(buffer-size,
++  [AC_HELP_STRING(
++    [--enable-buffer-size],
++    [tune the the size (in bytes) of internal buffers (default=1024)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(buffer size defaulting to 1024 bytes)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_BUFFER_SIZE, 1024,
++      [Default buffer size])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_BUFFER_SIZE, $enableval,
++      [Default buffer size])
++    fi
++  ])
++
++AC_ARG_ENABLE(pool-size,
++  [AC_HELP_STRING(
++    [--enable-pool-size],
++    [tune the size (in bytes) of memory pools (default=512)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(pool size defaulting to 512 bytes)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_NEW_POOL_SIZE, 512,
++      [Default pool size])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_NEW_POOL_SIZE, $enableval,
++      [Default pool size])
++    fi
++  ])
++
++AC_ARG_ENABLE(scoreboard-buffer-size,
++  [AC_HELP_STRING(
++    [--enable-scoreboard-buffer-size],
++    [tune the the size (in bytes) of certain scoreboard buffers (default=80)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(scoreboard buffer size defaulting to 80 bytes)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_SCOREBOARD_BUFFER_SIZE, 80,
++      [Default scoreboard buffer size])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_SCOREBOARD_BUFFER_SIZE, $enableval,
++      [Default scoreboard buffer size])
++    fi
++  ])
++
++AC_ARG_ENABLE(timeout-ident,
++  [AC_HELP_STRING(
++    [--enable-timeout-ident],
++    [set the default timeout (in secs) for RFC931 connections (default=10)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(ident timeout defaulting to 10 secs)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTIDENT, 10,
++      [Default ident timeout])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTIDENT, $enableval,
++      [Default ident timeout])
++    fi
++  ])
++
++AC_ARG_ENABLE(timeout-idle,
++  [AC_HELP_STRING(
++    [--enable-timeout-idle],
++    [set the default timeout (in secs) for idle connections (default=600)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(idle timeout defaulting to 600 secs)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTIDLE, 600,
++      [Default idle timeout])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTIDLE, $enableval,
++      [Default idle timeout])
++    fi
++  ])
++
++AC_ARG_ENABLE(timeout-linger,
++  [AC_HELP_STRING(
++    [--enable-timeout-linger],
++    [set the default timeout (in secs) for lingering closes (default=180)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(linger timeout defaulting to 180 secs)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTLINGER, 180,
++      [Default linger timeout])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTLINGER, $enableval,
++      [Default linger timeout])
++    fi
++  ])
++
++AC_ARG_ENABLE(timeout-login,
++  [AC_HELP_STRING(
++    [--enable-timeout-login],
++    [set the default timeout (in secs) for logging in after connecting (default=300)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(login timeout defaulting to 300 secs)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTLOGIN, 300,
++      [Default login timeout])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTLOGIN, $enableval,
++      [Default login timeout])
++    fi
++  ])
++
++AC_ARG_ENABLE(timeout-no-transfer,
++  [AC_HELP_STRING(
++    [--enable-timeout-no-transfer],
++    [set the default timeout (in secs) for no data transferred (default=300)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(no data transfer timeout defaulting to 300 secs)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTNOXFER, 300,
++      [Default when no data transferred])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTNOXFER, $enableval,
++      [Default when no data transferred])
++    fi
++  ])
++
++AC_ARG_ENABLE(timeout-stalled,
++  [AC_HELP_STRING(
++    [--enable-timeout-stalled],
++    [set the default timeout (in secs) for stalled transfers (default=3600)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(stalled timeout defaulting to 3600 secs)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTSTALLED, 3600,
++      [Default stalled timeout])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTSTALLED, $enableval,
++      [Default stalled timeout])
++    fi
++  ])
++
++AC_ARG_ENABLE(transfer-buffer-size,
++  [AC_HELP_STRING(
++    [--enable-transfer-buffer-size],
++    [tune the the size (in bytes) of data transfer buffers (default=buffer size)])
++  ],
++  [
++    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
++      AC_MSG_WARN(transfer buffer size defaulting to regular buffer size)
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_XFER_BUFFER_SIZE, 1024,
++      [Default buffer size])
++    else
++      AC_DEFINE_UNQUOTED(PR_TUNABLE_XFER_BUFFER_SIZE, $enableval,
++      [Specified transfer buffer size])
++    fi
++  ])
++
++dnl Checks for libraries.  Yes, this is the hard way, but it's necessary.
++AC_CACHE_CHECK(for standalone crypt,pr_cv_lib_standalone_crypt,
++  AC_TRY_LINK(,[crypt();],
++  	pr_cv_lib_standalone_crypt="yes", pr_cv_lib_standalone_crypt="no" ))
++
++if test "$pr_cv_lib_standalone_crypt" = "no"; then
++  AC_CHECK_LIB(crypt,crypt)
++fi
++
++AC_CACHE_CHECK(for standalone gethostbyname,pr_cv_lib_standalone_gethost,
++  AC_TRY_LINK(,[gethostbyname();],
++  	pr_cv_lib_standalone_gethost="yes",
++	pr_cv_lib_standalone_gethost="no" ))
++
++if test "$pr_cv_lib_standalone_gethost" = "no"; then
++  AC_CHECK_LIB(resolv,gethostbyname)
++  AC_CHECK_LIB(resolv,inet_aton)
++fi
++
++AC_CACHE_CHECK(for standalone inet_aton,pr_cv_lib_standalone_aton,
++  AC_TRY_LINK(,[inet_aton();],
++  	pr_cv_lib_standalone_aton="yes",
++	pr_cv_lib_standalone_aton="no" ))
++
++if test "$pr_cv_lib_standalone_aton" = "no"; then
++  AC_CHECK_LIB(bind,inet_aton)
++fi
++
++AC_CACHE_CHECK(for standalone nsl functions,pr_cv_lib_standalone_nsl,[
++  AC_TRY_LINK(,[gethostent();],
++  pr_cv_lib_standalone_nsl="yes", pr_cv_lib_standalone_nsl="no") ])
++
++if test "$pr_cv_lib_standalone_nsl" = "no"; then
++  AC_CHECK_LIB(nsl,gethostent)
++fi
++
++AC_CACHE_CHECK(for standalone socket functions,pr_cv_lib_standalone_sockets,
++  AC_TRY_LINK(,[bind();],
++  pr_cv_lib_standalone_sockets="yes", pr_cv_lib_standalone_sockets="no"))
++
++if test "$pr_cv_lib_standalone_sockets" = "no"; then
++  AC_CHECK_LIB(socket,bind)
++fi
++
++AC_CACHE_CHECK(for _pw_stayopen variable,pr_cv_var__pw_stayopen,
++  AC_TRY_LINK(
++    [extern int _pw_stayopen; ],
++    [_pw_stayopen = 1;],
++    pr_cv_var__pw_stayopen="yes", pr_cv_var__pw_stayopen="no"))
++
++if test "$pr_cv_var__pw_stayopen" = "yes"; then
++  AC_DEFINE(HAVE__PW_STAYOPEN)
++fi
++
++AC_CHECK_HEADERS(krb.h)
++AC_CHECK_HEADERS(prot.h)
++
++dnl HP-UX's hpsecurity.h can multiply define MAXINT and confuse configure
++AC_CHECK_HEADERS(hpsecurity.h, [
++    AC_SEARCH_LIBS(getprpwnam, sec)
++  ],
++  [
++    AC_MSG_CHECKING(for hpsecurity.h workaround)
++    AC_TRY_COMPILE([
++#include <values.h>
++#undef MAXINT
++#include <hpsecurity.h>
++  ], [],
++  [
++    AC_DEFINE(HAVE_HPSECURITY_H)
++    AC_SEARCH_LIBS(getprpwnam, sec)
++    AC_MSG_RESULT(yes)
++  ], [
++    AC_MSG_RESULT(no)
++  ])
++])
++
++dnl Checks for installation user/group
++
++if test x"$install_user" = x; then
++  if test "x$target_os" = "xcygwin"; then
++    install_user=`id -u`
++  else
++    install_user=root
++  fi
++fi
++if test x"$install_group" = x ; then
++  if test "x$target_os" = "xcygwin"; then
++    install_group=`id -g`
++  else
++    install_group=`sed -n '/.*:.*:0:/{s/^\(.*\):.*:0:.*/\1/p;q;}' /etc/group 2>/dev/null`
++  fi
++fi
++
++AC_SUBST(install_user)
++AC_SUBST(install_group)
++
++dnl Checks for header files.
++AC_HEADER_DIRENT
++AC_HEADER_STDC
++AC_HEADER_SYS_WAIT
++AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h unistd.h memory.h)
++if test x"$force_shadow" != xno ; then
++  AC_CHECK_HEADERS(shadow.h,
++    [ if test "$use_shadow" = "" && test -f /etc/shadow ; then
++        AC_DEFINE(USE_SHADOW)
++
++        AC_CHECK_MEMBER(struct spwd.sp_warn,
++          [AC_DEFINE(HAVE_SPWD_SP_WARN)],,
++          [#include <shadow.h>])
++        AC_CHECK_MEMBER(struct spwd.sp_inact,
++          [AC_DEFINE(HAVE_SPWD_SP_INACT)],,
++          [#include <shadow.h>])
++        AC_CHECK_MEMBER(struct spwd.sp_expire,
++          [AC_DEFINE(HAVE_SPWD_SP_EXPIRE)],,
++          [#include <shadow.h>])
++
++      fi ])
++fi
++
++dnl The pam test used to disable use_shadow, and I'm not sure why, libpam
++dnl really shouldn't have anything to do with force_shadow or use_shadow.
++if test x"$enable_auth_pam" != xno ; then
++  AC_CHECK_HEADERS(security/pam_appl.h pam/pam_appl.h,
++    [ if test `echo $ac_addl_modules | grep -c mod_auth_pam` = "0"; then
++        ac_addl_modules="mod_auth_pam.o $ac_addl_modules"
++        ac_build_addl_modules="modules/mod_auth_pam.o $ac_build_addl_modules"
++      fi ])
++
++  dnl This next check looks funky due to a linker problem with some versions
++  dnl of the PAM library.  Prior to 0.72 release, the Linux PAM shared library
++  dnl omitted requiring libdl linking information. PAM-0.72 or better ships
++  dnl with RedHat 6.2 and Debian 2.2 or better.
++  dnl
++  dnl This test used to add -lpam to the libraries list, however this isn't
++  dnl necessary in light of the fact that mod_auth_pam.c has the $Library $ tag
++  dnl and is picked up at configure time.  The only thing we need is to add
++  dnl -ldl in the event of broken PAM.
++
++  if test `echo $ac_addl_modules | grep -c mod_auth_pam` = "1"; then
++
++	AC_CHECK_LIB(pam, pam_start,
++		[AC_DEFINE(HAVE_PAM)],
++		[AC_CHECK_LIB(pam, pam_end,
++				[AC_DEFINE(HAVE_PAM)
++					LIBS="$LIBS -ldl"],,
++				[-ldl])])
++  fi
++
++fi
++
++ac_add_mod_cap="no"
++if test x"$enable_cap" != xno; then
++  case "$host" in
++    [*-linux-*])
++      rev=`uname -r | awk -F'[[.-]]' '{printf "%03d%03d%03d", $1, $2, $3}'`
++
++      if test $rev -ge 002001097; then
++        AC_CHECK_HEADER(linux/capability.h)
++ 
++        if test $ac_cv_header_linux_capability_h = "yes"; then
++          ac_add_mod_cap="yes"
++        fi
++      fi
++  esac
++fi
++
++AC_MSG_CHECKING([whether to enable mod_cap])
++AC_MSG_RESULT($ac_add_mod_cap)
++
++if test $ac_add_mod_cap = "yes"; then
++  ac_addl_modules="$ac_addl_modules mod_cap.o"
++  ac_build_addl_modules="modules/mod_cap.o $ac_build_addl_modules"
++fi
++
++AC_CHECK_HEADERS(ctype.h getopt.h crypt.h bstring.h limits.h)
++AC_CHECK_HEADERS(strings.h stropts.h)
++AC_CHECK_HEADERS(sys/file.h sys/mman.h sys/types.h sys/uio.h)
++
++dnl These particular checks are done a little differently because on some
++dnl platforms, <sys/mount.h> wants <sys/param.h> to be included first.
++AC_CHECK_HEADERS(sys/param.h sys/mount.h,,,
++  [
++    [
++     #if HAVE_SYS_PARAM_H
++     # include <sys/param.h>
++     #endif
++    ]
++  ])
++
++AC_CHECK_HEADERS(netdb.h netinet/in.h)
++
++AC_CHECK_HEADERS(netinet/in_systm.h,,,
++  [
++    [
++     #if HAVE_SYS_TYPES_H
++     # include <sys/types.h>
++     #endif
++    ]
++  ])
++
++AC_CHECK_HEADERS(netinet/ip.h,,,
++  [
++    [
++     #if HAVE_SYS_TYPES_H
++     # include <sys/types.h>
++     #endif
++     #if HAVE_NETINET_IN_H
++     # include <netinet/in.h>
++     #endif
++     #if HAVE_NETINET_IN_SYSTM_H
++     # include <netinet/in_systm.h>
++     #endif
++    ]
++  ])
++
++AC_CHECK_HEADERS(netinet/tcp.h arpa/inet.h)
++AC_CHECK_HEADERS(sys/stat.h errno.h sys/socket.h sys/termios.h sys/termio.h)
++AC_CHECK_HEADERS(sys/statvfs.h sys/vfs.h sys/select.h)
++AC_CHECK_HEADERS(dirent.h ndir.h sys/ndir.h sys/dir.h vmsdir.h)
++AC_CHECK_HEADERS(utmpx.h)
++AC_CHECK_HEADERS(regex.h)
++AC_CHECK_HEADER(syslog.h,have_syslog_h="yes",)
++AC_CHECK_HEADERS(curses.h ncurses.h)
++
++dnl Checks for typedefs, structures, and compiler characteristics.
++AC_C_CONST
++AC_C_INLINE
++AC_TYPE_UID_T
++AC_TYPE_PID_T
++AC_TYPE_SIZE_T
++AC_TYPE_MODE_T
++AC_TYPE_OFF_T
++AC_TYPE_GETGROUPS
++
++dnl Check to see if timer_t is already defined
++AC_CACHE_CHECK([for timer_t], pr_cv_header_timer_t,
++	AC_EGREP_HEADER([.*typedef.*timer_t;],sys/types.h,
++			pr_cv_header_timer_t="yes",
++	AC_EGREP_HEADER([.*typedef.*timer_t;],limits.h,
++			pr_cv_header_timer_t="yes",pr_cv_header_timer_t="no")))
++
++if test "$pr_cv_header_timer_t" = "yes"; then
++  AC_DEFINE(HAVE_TIMER_T)
++fi
++
++AC_CHECK_SIZEOF(short, 0)
++AC_CHECK_SIZEOF(int, 0)
++AC_CHECK_SIZEOF(long, 0)
++AC_CHECK_SIZEOF(long long, 0)
++AC_CHECK_SIZEOF(off_t, 0)
++
++AC_HEADER_TIME
++AC_STRUCT_TM
++
++dnl Check for generic typedefs
++AC_CHECK_TYPE(umode_t, mode_t)
++AC_CHECK_TYPE(ino_t, ino_t)
++AC_CHECK_TYPES(socklen_t, ,
++  [AC_DEFINE(socklen_t, int)],
++  [
++    #if HAVE_NETDB_H
++    # include <netdb.h>
++    #endif
++    #include <sys/socket.h>
++    #include <sys/types.h>
++  ])
++
++dnl See what type of utmp exists
++AC_CHECK_HEADERS(utmp.h, have_utmp=1, have_utmp=0)
++
++if test $have_utmp; then
++  AC_CACHE_CHECK(whether your struct utmp has ut_user,
++  		pr_cv_header_utmaxtype,
++	AC_EGREP_HEADER([ *ut_user.*;],utmp.h,
++			pr_cv_header_utmaxtype="yes",
++			pr_cv_header_utmaxtype="no"))
++  AC_CACHE_CHECK(whether your struct utmp has ut_host,
++  		pr_cv_header_ut_host,
++	AC_EGREP_HEADER([ *ut_host.*;],utmp.h,
++			pr_cv_header_ut_host="yes",
++			pr_cv_header_ut_host="no"))
++  AC_CACHE_CHECK(whether your struct utmp has ut_exit,
++		pr_cv_header_ut_exit,
++	AC_EGREP_HEADER([ *ut_exit.*;],utmp.h,
++			pr_cv_header_ut_exit="yes",
++			pr_cv_header_ut_exit="no"))
++  if test "$pr_cv_header_utmaxtype" = "yes"; then
++    AC_DEFINE(HAVE_UTMAXTYPE, 1, [If struct utmp has ut_user.])
++  fi
++  if test "$pr_cv_header_ut_host" = "yes"; then
++    AC_DEFINE(HAVE_UT_UT_HOST, 1, [If struct utmp has ut_host.])
++  fi
++  if test "$pr_cv_header_ut_exit" = "yes"; then
++    AC_DEFINE(HAVE_UT_UT_EXIT, 1, [If struct utmp has ut_exit.])
++  fi
++fi
++
++dnl See if various LOG_ macros are defined
++if test "$have_syslog_h" = "yes"; then
++  AC_DEFINE(HAVE_SYSLOG_H)
++
++  AC_CACHE_CHECK(whether your syslog.h defines LOG_CRON,
++  		pr_cv_header_syslog_log_cron,
++  	AC_EGREP_CPP(yes,[
++#include <syslog.h>
++#ifdef LOG_CRON
++  yes
++#endif
++	],pr_cv_header_syslog_log_cron="yes",
++	pr_cv_header_syslog_log_cron="no") )
++
++  AC_CACHE_CHECK(whether your syslog.h defines LOG_FTP,
++  		pr_cv_header_syslog_log_ftp,
++  	AC_EGREP_CPP(yes,[
++#include <syslog.h>
++#ifdef LOG_FTP
++  yes
++#endif
++	],pr_cv_header_syslog_log_ftp="yes",
++	pr_cv_header_syslog_log_ftp="no") )
++
++  if test "$pr_cv_header_syslog_log_cron" = "yes"; then
++    AC_DEFINE(HAVE_LOG_CRON)
++  fi
++  if test "$pr_cv_header_syslog_log_ftp" = "yes"; then
++    AC_DEFINE(HAVE_LOG_FTP)
++  fi
++fi
++
++dnl Check for directory file descriptor member ("d_fd", "dd_fd" or "__dd_fd")
++dnl of the DIR struct, possibly defining one of:
++dnl	HAVE_STRUCT_DIR_D_FD
++dnl	HAVE_STRUCT_DIR_DD_FD
++dnl	HAVE_STRUCT_DIR___DD_FD
++dnl Should use AC_C_STRUCT_MEMBER, when available in an official release.
++dnl The autoconf-2.14.1 floating around is NOT an official release.
++dnl Note: use of either the _POSIX_C_SOURCE or the _XOPEN_SOURCE preprocessor
++dnl macro could result in a wrong answer unless it is also defined here.
++dnl Doing so may be automatic or may take some care or reordering.
++dnl NB: autoheader won't pick up these macros, requiring acconfig.h entries.
++dnl
++for dirfd in d_fd dd_fd __dd_fd ; do
++	AC_MSG_CHECKING(for $dirfd in DIR structure)
++	AC_TRY_COMPILE([
++#include <stdio.h>
++#include <dirent.h>
++], [
++DIR *dirp;
++int i = dirp->$dirfd;
++], eval ac_cv_struct_dir_$dirfd=yes,)
++	if test "`eval echo x'$''ac_cv_struct_dir_'$dirfd`" = xyes ; then
++		ucdirfd=`echo $dirfd | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
++		AC_DEFINE_UNQUOTED(HAVE_STRUCT_DIR_$ucdirfd)
++		AC_MSG_RESULT(yes)
++		break
++	else
++		AC_MSG_RESULT(no)
++	fi
++done
++
++
++dnl Checks for library functions.
++
++AC_FUNC_ALLOCA
++
++dnl UnixWare's alloca is in libucb, in /usr/ucblib/. Muck about with
++dnl $LDFLAGS so AC_CHECK_LIB() will find it there.
++old_LDFLAGS=$LDFLAGS
++LDFLAGS="$LDFLAGS -L/usr/ucblib/"
++AC_CHECK_LIB(ucb, alloca)
++LDFLAGS=$old_LDFLAGS
++
++AC_PROG_GCC_TRADITIONAL
++AC_FUNC_SETPGRP
++AC_TYPE_SIGNAL
++AC_FUNC_VPRINTF
++AC_CHECK_FUNCS(bcopy crypt fgetgrent fgetpwent flock freeaddrinfo)
++AC_CHECK_FUNC(gai_strerror,
++  AC_DEFINE(HAVE_GAI_STRERROR),
++  LIB_OBJS="$LIB_OBJS glibc-gai_strerror.o"
++)
++AC_CHECK_FUNCS(getaddrinfo getcwd gethostbyname2 gethostname getnameinfo)
++AC_CHECK_FUNCS(getopt_long gettimeofday hstrerror inet_aton inet_ntop inet_pton)
++AC_CHECK_FUNCS(memcpy mempcpy mkdir mkstemp mlock mlockall munlock munlockall)
++AC_CHECK_FUNCS(rmdir select setgroups socket statfs strchr strcoll strerror)
++AC_CHECK_FUNCS(strsep strtol setprotoent endprotoent)
++# __snprintf and __vsnprintf are only on solaris and _really_ broken there.
++AC_CHECK_FUNCS(vsnprintf snprintf)
++if test x"$ac_cv_func_vsnprintf" != xyes || test x"$ac_cv_func_snprintf" != xyes
++then
++	AC_CHECK_FUNCS(fconvert fcvt)
++	AC_CHECK_HEADERS(floatingpoint.h)
++fi
++AC_CHECK_FUNCS(setsid setgroupent seteuid setegid)
++AC_CHECK_FUNCS(siginterrupt setpgid)
++AC_CHECK_FUNCS(regcomp)
++AC_CHECK_FUNCS(tzset)
++AC_CHECK_FUNCS(pathconf fpathconf)
++AC_CHECK_FUNCS(fgetspent)
++
++AC_CHECK_FUNC(setpassent,
++[case "$target_os:$enable_force_setpassent" in
++changequote(, )dnl
++  *freebsd[23]\.[0-3]*:)
++changequote([, ])dnl
++    AC_MSG_WARN(Disabling broken FreeBSD setpassent(), see README for details.)
++        ;;
++  *:no) ;;
++  *) AC_DEFINE(HAVE_SETPASSENT) ;;
++esac])
++
++dnl IPv4/IPv6-related checks
++AC_CHECK_MEMBER(struct sockaddr_in.sin_len,
++  [AC_DEFINE(SIN_LEN)],,
++  [
++    #if HAVE_SYS_TYPES_H
++    # include <sys/types.h>
++    #endif
++    #if HAVE_SYS_SOCKET_H
++    # include <sys/socket.h>
++    #endif
++    #if HAVE_NETINET_IN_H
++    # include <netinet/in.h>
++    #endif
++  ])
++
++PR_CHECK_STRUCT_ADDRINFO
++PR_CHECK_STRUCT_SS
++PR_CHECK_SS_FAMILY
++PR_CHECK_SS_LEN
++
++if test x"$enable_sendfile" = xyes ; then
++  AC_CACHE_CHECK(
++    [which sendfile() implementation to use],
++    pr_cv_func_sendfile,
++    pr_cv_func_sendfile="None"
++
++    dnl Linux.
++    if test "$pr_cv_func_sendfile" = "None"; then
++      AC_TRY_LINK(
++        [ #include <sys/types.h>
++          #include <sys/sendfile.h>
++          #include <unistd.h>
++        ],
++        [ int i;
++          off_t o;
++          size_t c;
++          (void)sendfile(i,i,&o,c);
++        ], pr_cv_func_sendfile="Linux")
++    fi
++
++    dnl BSD.
++    if test "$pr_cv_func_sendfile" = "None"; then
++      AC_TRY_LINK(
++        [ #include <sys/types.h>
++          #include <sys/socket.h>
++          #include <sys/uio.h>
++        ],
++        [ int i;
++          off_t o;
++          size_t n;
++          struct sf_hdtr h;
++          (void)sendfile(i,i,o,n,&h,&o,i);
++        ], pr_cv_func_sendfile="BSD")
++    fi
++
++    dnl AIX.
++    if test "$pr_cv_func_sendfile" = "None"; then
++      AC_TRY_LINK(
++        [ #include <sys/types.h>
++          #include <sys/socket.h>
++        ],
++        [ uint f;
++          int h;
++          struct sf_parms p;
++          (void)send_file(&(h),&(p),f);
++        ], pr_cv_func_sendfile="AIX")
++    fi
++
++    dnl Solaris
++    if test "$pr_cv_func_sendfile" = "None"; then
++      old_ldflags=$LDFLAGS
++      LDFLAGS="-lsendfile $LDFLAGS"
++      AC_TRY_LINK(
++        [ #include <sys/types.h>
++          #include <sys/sendfile.h>
++          #include <unistd.h>
++        ],
++        [ int i;
++          off_t o;
++          size_t c;
++          (void)sendfile(i,i,&o,c);
++        ], pr_cv_func_sendfile="Solaris")
++      LDFLAGS=$old_ldflags
++    fi
++  )
++
++  dnl Now, set the appropriate defines based on our investigations...
++
++  if test "$pr_cv_func_sendfile" != "None"; then
++    AC_DEFINE(HAVE_SENDFILE)
++  fi
++
++  case "$pr_cv_func_sendfile" in
++    "Linux")
++      AC_CHECK_HEADERS(sys/sendfile.h)
++      AC_DEFINE(HAVE_LINUX_SENDFILE)
++      ;;
++
++    "BSD")
++      AC_DEFINE(HAVE_BSD_SENDFILE)
++      ;;
++
++    "AIX")
++      AC_DEFINE(HAVE_AIX_SENDFILE)
++      ;;
++
++    "Solaris")
++      AC_CHECK_HEADERS(sys/sendfile.h)
++      AC_DEFINE(HAVE_SOLARIS_SENDFILE)
++      ac_build_addl_libraries="-lsendfile $ac_build_addl_libraries"
++      ;;
++  esac
++fi
++
++dnl Custom-rolled macro for checking return type of setgrent(3)
++PR_FUNC_SETGRENT_VOID
++
++dnl Perform checks for curses/ncurses libraries only if the corresponding
++dnl headers have been found.
++if test x"$ac_cv_header_curses_h" = xyes; then
++  AC_CHECK_LIB(curses, initscr,
++    [ CURSES_LIBS="-lcurses"
++      AC_DEFINE(HAVE_LIBCURSES, 1, [Define if you have curses])
++    ])
++fi
++
++if test x"$ac_cv_header_ncurses_h" = xyes; then
++  AC_CHECK_LIB(ncurses, initscr,
++    [ CURSES_LIBS="-lncurses"
++      AC_DEFINE(HAVE_LIBNCURSES, 1, [Define if you have ncurses])
++    ])
++fi
++
++if test x"$enable_curses" != xno ; then
++  AC_DEFINE(USE_CURSES)
++fi
++
++if test x"$enable_ncurses" != xno ; then
++  AC_DEFINE(USE_NCURSES)
++fi
++
++dnl Check for various argv[] replacing functions on various OSs
++AC_CHECK_FUNCS(setproctitle)
++AC_CHECK_HEADERS(libutil.h)
++AC_CHECK_LIB(util, setproctitle,
++	[AC_DEFINE(HAVE_SETPROCTITLE)
++		ac_cv_func_setproctitle="yes" ; LIBS="$LIBS -lutil"])
++
++if test "$ac_cv_func_setproctitle" = "yes"; then
++  AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_NONE)
++else
++  pf_argv_set="no"
++
++  AC_CHECK_HEADERS(sys/pstat.h,have_pstat_h="yes",have_pstat_h="no")
++  if test "$have_pstat_h" = "yes"; then
++    AC_CHECK_FUNCS(pstat)
++    
++    if test "$ac_cv_func_pstat" = "yes"; then
++	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_PSTAT)
++    else
++	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_WRITEABLE)
++    fi
++
++    pf_argv_set="yes"
++  fi
++
++  if test "$pf_argv_set" = "no"; then
++    AC_EGREP_HEADER([#define.*PS_STRINGS.*],sys/exec.h,
++			have_psstrings="yes",have_psstrings="no")
++    if test "$have_psstrings" = "yes"; then
++	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_PSSTRINGS)
++	pf_argv_set="yes"
++    fi
++  fi
++
++  if test "$pf_argv_set" = "no"; then
++    AC_CACHE_CHECK(whether __progname and __progname_full are available,
++		    pf_cv_var_progname,
++		    AC_TRY_LINK([extern char *__progname, *__progname_full;],
++			[__progname = "foo"; __progname_full = "foo bar";],
++			pf_cv_var_progname="yes", pf_cv_var_progname="no"))
++
++    if test "$pf_cv_var_progname" = "yes"; then
++	AC_DEFINE(HAVE___PROGNAME)
++    fi
++
++    AC_CACHE_CHECK(which argv replacement method to use,
++		    pf_cv_argv_type,
++		    AC_EGREP_CPP(yes,[
++#if defined(__GNU_HURD__)
++  yes
++#endif
++  ],pf_cv_argv_type="new", pf_cv_argv_type="writeable"))
++
++    if test "$pf_cv_argv_type" = "new"; then
++	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_NEW)
++	pf_argv_set="yes"
++    fi
++
++    if test "$pf_argv_set" = "no"; then
++	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_WRITEABLE)
++    fi
++  fi
++fi
++
++dnl Run a small test program to see if the host's printf(3) family can
++dnl actually handle the %llu format.
++AC_MSG_CHECKING([whether printf supports %llu format]);
++AC_TRY_RUN(
++  [ #include <stdio.h>
++    int main(int argc, char *argv[]) {
++      return (fprintf(stderr, "%llu\n", (unsigned long long) 1) == 2 ? 0 : 1);
++    }
++  ],
++  AC_MSG_RESULT(yes); AC_DEFINE(HAVE_LLU),
++  AC_MSG_RESULT(no); AC_DEFINE(HAVE_LU),
++  AC_MSG_RESULT(cross-compiling); AC_DEFINE(HAVE_LU)
++)
++
++dnl Add the proftpd support library
++LIBS="-lsupp $LIBS"
++
++dnl Module handling.
++for module in $ac_addl_modules; do
++  addonlibs=""
++  src=`echo "$module" | sed -e 's/\.o$//'`.c;
++  srcinc=`echo "$module" | sed -e 's/\.o$//'`.h;
++  if test -f $srcdir/modules/$src -o -f $srcdir/contrib/$src; then
++
++    if test ! -f $srcdir/modules/$src; then
++	olddir=`pwd`
++	cd $srcdir/modules
++	ln -s ../contrib/$src $src
++	cd $olddir
++    fi
++
++    if test ! -f $srcdir/include/$srcinc -a -f $srcdir/contrib/$srcinc ; then
++	olddir=`pwd`
++	cd $srcdir/include
++	ln -s ../contrib/$srcinc $srcinc
++	cd $olddir
++    fi
++
++    srclib=`cat $srcdir/modules/$src | grep "\\\$Libraries:" | sed -e 's/^.*\$Libraries: \(.*\)\\$/\1/'`
++
++    if test -f $srcdir/include/$srcinc ; then
++        inclib=`cat $srcdir/include/$srcinc | grep "\\\$Libraries:" | sed -e 's/^.*\$Libraries: \(.*\)\\$/\1/'`
++    else
++        inclib= 
++    fi
++
++
++    dnl Test for duplicate libraries, just in case.
++    for thelib in $srclib $inclib; do
++	dup="no"
++
++	for somelib in $ac_addl_libs $LIBS; do
++
++		if test "$thelib" = "$somelib"; then
++			dup="yes"
++			break
++		fi
++	done
++	
++	if test "$dup" = "no"; then
++		addonlibs="$addonlibs $thelib"
++	fi
++    done
++
++    test x"$addonlibs" = x || ac_addl_libs="$addonlibs $ac_addl_libs"
++
++    adir=`cat $srcdir/modules/$src | grep "\\\$Directories:" | sed -e 's/^.*\$Directories: \(.*\)\\$/\1/'`
++    test x"$adir" = x || ac_addl_dirs="$adir $ac_addl_dirs"
++
++  else
++
++    echo "source file '$srcdir/modules/$src' cannot be found -- aborting"
++    exit 1
++
++  fi
++done
++
++ac_addl_libs=`echo "$ac_addl_libs" | sed -e 's/ *\$//'`
++ac_addl_libs=`echo "$ac_addl_libs" | sed -e 's/^ *//'`
++test "x$ac_addl_libs" = x || LIBS="$LIBS $ac_addl_libs"
++ac_addl_dirs=`echo "$ac_addl_dirs" | sed -e 's/ *\$//'`
++ac_addl_dirs=`echo "$ac_addl_dirs" | sed -e 's/^ *//'`
++ADDL_DIRS="$ac_addl_dirs"
++
++INCLUDES="$ac_build_addl_includes"
++LIBRARIES="$ac_build_addl_libraries"
++MODULE_OBJS="$ac_core_modules $ac_addl_modules"
++BUILD_MODULE_OBJS="$ac_build_core_modules $ac_build_addl_modules"
++VERSION=`cat $srcdir/include/version.h | grep "#define VERSION " | sed -e 's/^.*\"\(.*\)\"/\1/'`
++
++dnl Substitute in our configuration paths as appropriate.  We also have to
++dnl sweet talk the environment into helping us get this right, like so...
++pr_saved_prefix="$prefix"
++pr_saved_exec_prefix="$exec_prefix"
++
++test "x$prefix" = xNONE && prefix=$ac_default_prefix
++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
++
++AC_DEFINE_UNQUOTED(CONFIG_FILE_PATH,
++			"`eval echo "${sysconfdir}/proftpd.conf"`")
++AC_DEFINE_UNQUOTED(PID_FILE_PATH,
++			"`eval echo "${localstatedir}/proftpd.pid"`")
++AC_DEFINE_UNQUOTED(RUN_DIR,
++			"`eval echo "${localstatedir}/proftpd"`")
++
++prefix="$pr_saved_prefix"
++exec_prefix="$pr_saved_exec_prefix"
++
++if test x"$devel" = xyes ; then
++  AC_DEFINE(USE_DEVEL)
++
++  if test x"$GCC" = xyes; then
++
++    dnl Remove any optimization flags from CFLAGS
++    CFLAGS=`echo "$CFLAGS" | sed -e 's/\-O2//'`
++    CFLAGS="$CFLAGS $pr_devel_cflags"
++    LIBS="$LIBS $pr_devel_libs"
++
++    dnl Some C compilers (e.g. older gcc versions) may not accept these
++    dnl options.  Check if they are supported.  They will be added to
++    dnl CFLAGS if supported.
++    PR_CHECK_CC_OPT(Wfloat-equal)
++  fi
++
++  dnl Do not strip symboles from developer object files.
++  INSTALL_STRIP=""
++else
++
++  dnl Make sure to strip symbols from non-developer object files.
++  INSTALL_STRIP="-s"
++fi
++
++dnl Check whether the C compiler accepts -Wno-long-double. This helps to
++dnl quell unnecessary OSX compiler complaints.  Use of this macro should
++dnl be as late in the configure script as possible, for it changes the
++dnl CFLAGS environment variable (which may possible cause other autoconf
++dnl tests to fail).
++PR_CHECK_CC_OPT(Wno-long-double)
++
++dnl And finally, generate the appropriate Make* and config.h
++AC_SUBST(INSTALL_STRIP)
++AC_SUBST(LIB_OBJS)
++AC_SUBST(MODULE_OBJS)
++AC_SUBST(BUILD_MODULE_OBJS)
++AC_SUBST(ADDL_DIRS)
++AC_SUBST(INCLUDES)
++AC_SUBST(LIBRARIES)
++AC_SUBST(CURSES_LIBS)
++AC_SUBST(VERSION)
++
++AC_CONFIG_HEADER(config.h)
++
++AC_OUTPUT(lib/Makefile
++          modules/Makefile
++          src/Makefile src/proftpd.8 src/xferlog.5
++          utils/Makefile utils/ftpcount.1 utils/ftpshut.8 utils/ftptop.1
++            utils/ftpwho.1
++          Makefile Make.rules,
++          [echo timestamp > stamp-h])
+diff -ruN proftpd-1.2.8+cvs20031020-old/configure.in proftpd-1.2.8+cvs20031020/configure.in
+--- proftpd-1.2.8+cvs20031020-old/configure.in	2003-10-15 22:37:53.000000000 +0200
++++ proftpd-1.2.8+cvs20031020/configure.in	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1328 +0,0 @@
+-dnl ProFTPD - FTP server daemon
+-dnl Copyright (c) 1997, 1998 Public Flood Software
+-dnl Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net>
+-dnl Copyright (c) 2001, 2002, 2003 The ProFTPD Project team
+-dnl
+-dnl This program is free software; you can redistribute it and/or modify
+-dnl it under the terms of the GNU General Public License as published by
+-dnl the Free Software Foundation; either version 2 of the License, or
+-dnl (at your option) any later version.
+-dnl
+-dnl This program is distributed in the hope that it will be useful,
+-dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-dnl GNU General Public License for more details.
+-dnl
+-dnl You should have received a copy of the GNU General Public License
+-dnl along with this program; if not, write to the Free Software
+-dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+-dnl
+-dnl Process this file with autoconf to produce a configure script.
+-
+-AC_INIT(include/conf.h)
+-
+-ac_core_modules="mod_core.o mod_xfer.o mod_auth_unix.o mod_auth_file.o mod_auth.o mod_ls.o mod_log.o mod_site.o"
+-ac_build_core_modules="modules/mod_core.o modules/mod_xfer.o modules/mod_auth_unix.o modules/mod_auth_file.o modules/mod_auth.o modules/mod_ls.o modules/mod_log.o modules/mod_site.o"
+-
+-dnl Get the OS type
+-AC_CONFIG_AUX_DIR(./)
+-AC_CANONICAL_SYSTEM
+-
+-dnl Create symlinks in modules/ and contrib/
+-olddir=`pwd`
+-cd contrib
+-test -f README.mod_sql || ln -s ../README.mod_sql README.mod_sql
+-cd $olddir
+-
+-OSTYPE=-D`echo $build_os | sed 's/\..*$//g' | sed 's/-.*//g' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+-OSREL=-D`echo $build_os | sed 's/-.*//g' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | tr '.' '_'`
+-
+-if test "$OSTYPE" = "$OSREL" ; then
+-  OSTYPE=""
+-fi
+-AC_SUBST(OSREL)
+-AC_SUBST(OSTYPE)
+-
+-dnl MacOS X requires -traditional-cpp; autodetecting it isn't impossible
+-dnl AFAIK, since assuming the need for -traditional-cpp breaks the build
+-dnl on other OSes. -jwm, 30 Jan 2001
+-if test "$OSTYPE" = "-DRHAPSODY5"; then
+-  CFLAGS="$CFLAGS -traditional-cpp -D__OT__"
+-fi
+-
+-dnl Checks for programs.
+-AC_PROG_CC
+-AC_PROG_MAKE_SET
+-AC_PROG_INSTALL
+-AC_PROG_RANLIB
+-
+-dnl This test must come as early as possible after the compiler
+-dnl configuration tests, because the choice of the file model can (in
+-dnl principle) affect whether functions and headers are available,
+-dnl whether they work, etc.
+-AC_SYS_LARGEFILE  
+-
+-# The native HP-UX 10 compiler needs -Ae to enable Extended ANSI compliance
+-# (-Ae is the default in the native compiler under HP-UX 11).
+-if test $ac_cv_prog_gcc = no -a "$OSTYPE" = "-DHPUX10"; then
+-  CFLAGS="$CFLAGS -Ae"
+-fi
+-
+-LDFLAGS="-Llib $LDFLAGS"
+-
+-if test $ac_cv_prog_gcc = yes; then
+-  if test x"$CFLAGS" = "x-g -O2"; then
+-    fullCFLAGS="-O2"
+-  else
+-    fullCFLAGS="$CFLAGS"
+-  fi
+-
+-  dnl Compilation tests
+-
+-  dnl test for -malign-jumps=2 -malign-loops=2 -malign-functions=2
+-  if echo $ac_cv_build_cpu | egrep "^i[[34567]]86$" > /dev/null 2>&1; then
+-    AC_MSG_CHECKING([whether the C compiler accepts -malign-jumps -malign-loops -malign-functions])
+-    CFLAGS="-malign-jumps=2 -malign-loops=2 -malign-functions=2"
+-    AC_TRY_COMPILE(,,
+-      AC_MSG_RESULT(yes); fullCFLAGS="$fullCFLAGS $CFLAGS",
+-      AC_MSG_RESULT(no))
+-  fi
+-
+-  dnl test for -Wall
+-  AC_MSG_CHECKING([whether the C compiler accepts -Wall])
+-  CFLAGS="-Wall"
+-  AC_TRY_COMPILE(,,
+-    AC_MSG_RESULT(yes); fullCFLAGS="$fullCFLAGS $CFLAGS",
+-    AC_MSG_RESULT(no))
+-
+-  CFLAGS="$fullCFLAGS"
+-fi
+-
+-dnl We substitute these in the man page templates.
+-if test x$exec_prefix = xNONE; then
+-  exec_prefix=$prefix
+-fi
+-
+-BINDIR=`eval echo $bindir`
+-AC_SUBST(BINDIR)
+-LOCALSTATEDIR=`eval echo $localstatedir`
+-AC_SUBST(LOCALSTATEDIR)
+-SBINDIR=`eval echo $sbindir`
+-AC_SUBST(SBINDIR)
+-SYSCONFDIR=`eval echo $sysconfdir`
+-AC_SUBST(SYSCONFDIR)
+-
+-AC_ARG_VAR(LIBS, [linker flags, e.g. -l<lib>.{a,so} if you have nonstandard libraries to link])
+-
+-dnl configure command line options...
+-
+-dnl --with options.
+-
+-dnl ProFTPD comes bundled with GNU's implementation of getopt, to be used
+-dnl in case the host system doesn't have getopt.  However, this causes
+-dnl problems for certain builds of proftpd, e.g. ProFTPD and MySQL (which
+-dnl itself similarly bundles a getopt implementation).  Thus, we need to
+-dnl support/handle --without-getopt, to disable use of ProFTPD's getopt.
+-dnl I don't know if MySQL supports any similar option.
+-LIB_OBJS="pr_fnmatch.o sstrncpy.o strsep.o vsnprintf.o glibc-glob.o glibc-hstrerror.o glibc-mkstemp.o pr-syslog.o pwgrent.o"
+-ac_pr_check_getopt="yes"
+-
+-AC_ARG_WITH(getopt,
+-  [AC_HELP_STRING(
+-      [--without-getopt],
+-      [prevent proftpd from using its bundled getopt implementation.  This is done automatically if the host supports getopt, but may need to be explicitly used when combining proftpd with other applications, such as MySQL])
+-  ],
+-  [
+-    if test "$withval" != "no" ; then
+-      LIB_OBJS="$LIB_OBJS getopt.o getopt1.o"
+-      AC_CHECK_FUNCS(getopt)
+-    fi
+-  ],
+-  [
+-    LIB_OBJS="$LIB_OBJS getopt.o getopt1.o"
+-    AC_CHECK_FUNCS(getopt)
+-  ])
+-
+-dnl Modules...'nuff said.
+-AC_ARG_WITH(includes,
+-  [AC_HELP_STRING(
+-    [--with-includes=LIST],
+-    [add additional include paths to proftpd. LIST is a colon-separated list of include paths to add e.g. --with-includes=/some/mysql/include:/my/include])
+-  ],
+-  [ ac_addl_includes=`echo "$withval" | sed -e 's/:/ /g'` ;
+-    for ainclude in $ac_addl_includes; do
+-      if test x"$ac_build_addl_includes" = x ; then
+-        ac_build_addl_includes="-I$ainclude"
+-      else
+-        ac_build_addl_includes="-I$ainclude $ac_build_addl_includes"
+-      fi
+-    done ])
+-
+-AC_ARG_WITH(libraries,
+-  [AC_HELP_STRING(
+-    [--with-libraries=LIST],
+-    [add additional library paths to proftpd. LIST is a colon-separated list of include paths to add e.g. --with-libraries=/some/mysql/libdir:/my/libs])
+-  ],
+-  [ ac_addl_libraries=`echo "$withval" | sed -e 's/:/ /g'` ;
+-    for ainclude in $ac_addl_libraries; do
+-      if test x"$ac_build_addl_libraries" = x ; then
+-        ac_build_addl_libraries="-L$ainclude"
+-      else
+-        ac_build_addl_libraries="-L$ainclude $ac_build_addl_libraries"
+-      fi
+-    done ])
+-
+-AC_ARG_WITH(modules,
+-  [AC_HELP_STRING(
+-    [--with-modules=LIST],
+-    [add additional modules to proftpd. LIST is a colon-separated list of modules to add e.g. --with-modules=mod_auth_pam:mod_readme])
+-  ],
+-  [ ac_addl_modules=`echo "$withval" | sed -e 's/:/.o /g'`.o ;
+-    for amodule in $ac_addl_modules; do
+-      ac_build_addl_modules="modules/$amodule $ac_build_addl_modules"
+-    done ])
+-
+-dnl --enable/--disable options.
+-
+-AC_ARG_ENABLE(auth-unix,
+-  [AC_HELP_STRING(
+-    [--disable-auth-unix],
+-    [omit mod_auth_unix from core modules])
+-  ],
+-  [
+-    if test "$enableval" = "no"; then
+-      ac_core_modules=`echo "$ac_core_modules" | sed -e 's/mod_auth_unix\.o//'`
+-      ac_build_core_modules=`echo "$ac_build_core_modules" | sed -e 's/modules\/mod_auth_unix\.o//'`
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(auth-file,
+-  [AC_HELP_STRING(
+-    [--disable-auth-file],
+-    [omit mod_auth_file from core modules])
+-  ],
+-  [
+-    if test "$enableval" = "no"; then
+-      ac_core_modules=`echo "$ac_core_modules" | sed -e 's/mod_auth_file\.o//'`
+-      ac_build_core_modules=`echo "$ac_build_core_modules" | sed -e 's/modules\/mod_auth_file\.o//'`
+-    fi
+-  ])
+- 
+-dnl Auto-detection of shadow passwords.
+-AC_ARG_ENABLE(autoshadow,
+-  [AC_HELP_STRING(
+-    [--enable-autoshadow],
+-    [enable run-time auto-detection of shadowed passwords (requires shadow)])
+-  ],
+-  [
+-    dnl AIX does not have shadow file/library support.  Try to prevent a
+-    dnl bad build if the admin, configuring on an AIX box, uses this option.
+-    if test "$enableval" = "yes" && test "$OSTYPE" = "-DAIX4"; then
+-      AC_MSG_WARN(AIX does not support traditional shadowed passwords)
+-      enableval="no"
+-    fi
+-
+-    if test "$enableval" != "no" ; then
+-      AC_DEFINE(USE_SHADOW, 1, [Define if using /etc/shadow files.])
+-      AC_DEFINE(USE_AUTO_SHADOW, 1,
+-      [Define if auto-detection of shadow passwords is wanted.])
+-      force_shadow="yes"
+-    fi ])
+-
+-dnl PAM support.
+-AC_ARG_ENABLE(auth-pam,
+-  [AC_HELP_STRING(
+-    [--enable-auth-pam],
+-    [enable PAM support (default=yes)])
+-  ],
+-  [ if test "$enableval" = "no" && \
+-       test `echo $ac_addl_modules | grep -c mod_auth_pam` != "0"; then
+-      AC_MSG_ERROR([You cannot run configure with --disable-auth-pam and include mod_auth_pam in --with-modules at the same time])
+-    fi ])
+-
+-dnl Workaround for broken getaddrinfo on some systems
+-AC_ARG_ENABLE(builtin-getaddrinfo,
+-  [AC_HELP_STRING(
+-    [--enable-builtin-getaddrinfo],
+-    [force use of builtin getaddrinfo (default=no)])
+-  ],
+-  [
+-    if test x"$enableval" = xyes; then
+-      AC_DEFINE(USE_GETADDRINFO, 1, [Define if using builtin getaddrinfo()])
+-    fi
+-  ])
+-
+-dnl Workaround for borken getnameinfo on some systems
+-AC_ARG_ENABLE(builtin-getnameinfo,
+-  [AC_HELP_STRING(
+-    [--enable-builtin-getnameinfo],
+-    [force use of builtin getnameinfo (default=no)])
+-  ],
+-  [
+-    if test x"$enableval" = xyes; then
+-      AC_DEFINE(USE_GETNAMEINFO, 1, [Define if using builtin getnameinfo()])
+-    fi
+-  ])
+-
+-dnl Capabilities support
+-AC_ARG_ENABLE(cap,
+-  [AC_HELP_STRING(
+-    [--enable-cap],
+-    [enable POSIX.1e capabilities (default=yes on Linux)])
+-  ])
+-
+-dnl Curses/ncurses support
+-AC_ARG_ENABLE(curses,
+-  [AC_HELP_STRING(
+-    [--disable-curses],
+-    [disable use of curses (default=no)])
+-  ])
+-
+-AC_ARG_ENABLE(ncurses,
+-  [AC_HELP_STRING(
+-    [--disable-ncurses],
+-    [disable use of ncurses (default=no)])
+-  ])
+-
+-dnl Workaround for broken setpassent on FreeBSD.
+-AC_ARG_ENABLE(force-setpassent,
+-  [AC_HELP_STRING(
+-    [--enable-force-setpassent],
+-    [force use of setpassent (default=no on FreeBSD)])
+-  ])
+-
+-dnl IPv6 support.
+-AC_ARG_ENABLE(ipv6,
+-  [AC_HELP_STRING(
+-    [--enable-ipv6],
+-    [enable IPv6 support (default=no)])
+-  ],
+-  [ if test "$enableval" = "yes" ; then
+-      AC_DEFINE(USE_IPV6, 1, [Define if using IPv6 support.])
+-    fi
+-  ])
+-
+-dnl Sendfile support.
+-AC_ARG_ENABLE(sendfile,
+-  [AC_HELP_STRING(
+-    [--enable-sendfile],
+-    [enable sendfile support (default=no)])
+-  ])
+-
+-dnl Check for enabled shadow password support.
+-AC_ARG_ENABLE(shadow,
+-  [AC_HELP_STRING(
+-    [--enable-shadow],
+-    [force compilation of shadowed password support])
+-  ],
+-  [
+-    dnl AIX does not have shadow file/library support.  Try to prevent a
+-    dnl bad build if the admin, configuring on an AIX box, uses this option.
+-    if test "$enableval" = "yes" && test "$OSTYPE" = "-DAIX4"; then
+-      AC_MSG_WARN([AIX does not support traditional shadowed passwords])
+-      enableval="no" 
+-    fi
+-
+-    if test "$enableval" = "no" ; then
+-      use_shadow=""
+-      force_shadow="no"
+-    else
+-      AC_DEFINE(USE_SHADOW)
+-      force_shadow="yes"
+-    fi ])
+-
+-dnl Enable support for Tru64's C2 SIA authentication
+-AC_ARG_ENABLE(sia,
+-  [AC_HELP_STRING(
+-    [--enable-sia],
+-    [enable SIA authentication support (Tru64)])
+-  ],
+-  [
+-    if test x"$enableval" = xyes ; then
+-
+-      dnl Tru64's C2/SIA authentication requires these headers
+-      AC_CHECK_HEADERS(sia.h siad.h sys/security.h)
+-
+-      AC_CHECK_FUNCS(set_auth_parameters, ,
+-        [AC_CHECK_LIB(security, set_auth_parameters)])
+-      AC_CHECK_FUNCS(getprpwent, ,
+-        [AC_CHECK_LIB(sec, getprpwent)])
+-
+-      AC_DEFINE(USE_SIA)
+-    fi
+-  ])
+-
+-dnl Enable developer code
+-pr_devel_cflags="-DPR_DEVEL -g -Wcast-align -Wchar-subscripts -Winline -Wstrict-prototypes -Wmissing-declarations -Wnested-externs -Wpointer-arith -Wshadow -Wundef"
+-pr_devel_libs=""
+-
+-AC_ARG_ENABLE(devel,
+-  [AC_HELP_STRING(
+-    [--enable-devel],
+-    [enable code of interest to developers])
+-  ],
+-  [
+-    if test x"$enableval" != xno ; then
+-      devel="yes"
+-
+-      dnl Check to see if specific developer flags were requested
+-
+-      if test `echo $enableval | grep -c coredump` = "1" ; then
+-        pr_devel_cflags="-DPR_DEVEL_COREDUMP $pr_devel_cflags"
+-      fi
+-
+-      if test `echo $enableval | grep -c nodaemon` = "1" ; then
+-        pr_devel_cflags="-DPR_DEVEL_NO_DAEMON $pr_devel_cflags"
+-      fi
+-
+-      if test `echo $enableval | grep -c nofork` = "1" ; then
+-        pr_devel_cflags="-DPR_DEVEL_NO_FORK $pr_devel_cflags"
+-      fi
+-
+-      if test `echo $enableval | grep -c profile` = "1" ; then
+-        pr_devel_cflage="-p -pg $pr_devel_cflags"
+-        pr_devel_libs="-pg $pr_devel_libs"
+-      fi
+-
+-    else
+-      devel="no"
+-    fi
+-  ])
+-
+-dnl The "tunable" options, from include/options.h
+-AC_ARG_ENABLE(buffer-size,
+-  [AC_HELP_STRING(
+-    [--enable-buffer-size],
+-    [tune the the size (in bytes) of internal buffers (default=1024)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(buffer size defaulting to 1024 bytes)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_BUFFER_SIZE, 1024,
+-      [Default buffer size])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_BUFFER_SIZE, $enableval,
+-      [Default buffer size])
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(pool-size,
+-  [AC_HELP_STRING(
+-    [--enable-pool-size],
+-    [tune the size (in bytes) of memory pools (default=512)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(pool size defaulting to 512 bytes)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_NEW_POOL_SIZE, 512,
+-      [Default pool size])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_NEW_POOL_SIZE, $enableval,
+-      [Default pool size])
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(scoreboard-buffer-size,
+-  [AC_HELP_STRING(
+-    [--enable-scoreboard-buffer-size],
+-    [tune the the size (in bytes) of certain scoreboard buffers (default=80)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(scoreboard buffer size defaulting to 80 bytes)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_SCOREBOARD_BUFFER_SIZE, 80,
+-      [Default scoreboard buffer size])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_SCOREBOARD_BUFFER_SIZE, $enableval,
+-      [Default scoreboard buffer size])
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(timeout-ident,
+-  [AC_HELP_STRING(
+-    [--enable-timeout-ident],
+-    [set the default timeout (in secs) for RFC931 connections (default=10)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(ident timeout defaulting to 10 secs)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTIDENT, 10,
+-      [Default ident timeout])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTIDENT, $enableval,
+-      [Default ident timeout])
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(timeout-idle,
+-  [AC_HELP_STRING(
+-    [--enable-timeout-idle],
+-    [set the default timeout (in secs) for idle connections (default=600)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(idle timeout defaulting to 600 secs)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTIDLE, 600,
+-      [Default idle timeout])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTIDLE, $enableval,
+-      [Default idle timeout])
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(timeout-linger,
+-  [AC_HELP_STRING(
+-    [--enable-timeout-linger],
+-    [set the default timeout (in secs) for lingering closes (default=180)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(linger timeout defaulting to 180 secs)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTLINGER, 180,
+-      [Default linger timeout])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTLINGER, $enableval,
+-      [Default linger timeout])
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(timeout-login,
+-  [AC_HELP_STRING(
+-    [--enable-timeout-login],
+-    [set the default timeout (in secs) for logging in after connecting (default=300)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(login timeout defaulting to 300 secs)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTLOGIN, 300,
+-      [Default login timeout])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTLOGIN, $enableval,
+-      [Default login timeout])
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(timeout-no-transfer,
+-  [AC_HELP_STRING(
+-    [--enable-timeout-no-transfer],
+-    [set the default timeout (in secs) for no data transferred (default=300)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(no data transfer timeout defaulting to 300 secs)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTNOXFER, 300,
+-      [Default when no data transferred])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTNOXFER, $enableval,
+-      [Default when no data transferred])
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(timeout-stalled,
+-  [AC_HELP_STRING(
+-    [--enable-timeout-stalled],
+-    [set the default timeout (in secs) for stalled transfers (default=3600)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(stalled timeout defaulting to 3600 secs)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTSTALLED, 3600,
+-      [Default stalled timeout])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_TIMEOUTSTALLED, $enableval,
+-      [Default stalled timeout])
+-    fi
+-  ])
+-
+-AC_ARG_ENABLE(transfer-buffer-size,
+-  [AC_HELP_STRING(
+-    [--enable-transfer-buffer-size],
+-    [tune the the size (in bytes) of data transfer buffers (default=buffer size)])
+-  ],
+-  [
+-    if test "$enableval" = "yes" || test "$enableval" = "no" ; then
+-      AC_MSG_WARN(transfer buffer size defaulting to regular buffer size)
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_XFER_BUFFER_SIZE, 1024,
+-      [Default buffer size])
+-    else
+-      AC_DEFINE_UNQUOTED(PR_TUNABLE_XFER_BUFFER_SIZE, $enableval,
+-      [Specified transfer buffer size])
+-    fi
+-  ])
+-
+-dnl Checks for libraries.  Yes, this is the hard way, but it's necessary.
+-AC_CACHE_CHECK(for standalone crypt,pr_cv_lib_standalone_crypt,
+-  AC_TRY_LINK(,[crypt();],
+-  	pr_cv_lib_standalone_crypt="yes", pr_cv_lib_standalone_crypt="no" ))
+-
+-if test "$pr_cv_lib_standalone_crypt" = "no"; then
+-  AC_CHECK_LIB(crypt,crypt)
+-fi
+-
+-AC_CACHE_CHECK(for standalone gethostbyname,pr_cv_lib_standalone_gethost,
+-  AC_TRY_LINK(,[gethostbyname();],
+-  	pr_cv_lib_standalone_gethost="yes",
+-	pr_cv_lib_standalone_gethost="no" ))
+-
+-if test "$pr_cv_lib_standalone_gethost" = "no"; then
+-  AC_CHECK_LIB(resolv,gethostbyname)
+-  AC_CHECK_LIB(resolv,inet_aton)
+-fi
+-
+-AC_CACHE_CHECK(for standalone inet_aton,pr_cv_lib_standalone_aton,
+-  AC_TRY_LINK(,[inet_aton();],
+-  	pr_cv_lib_standalone_aton="yes",
+-	pr_cv_lib_standalone_aton="no" ))
+-
+-if test "$pr_cv_lib_standalone_aton" = "no"; then
+-  AC_CHECK_LIB(bind,inet_aton)
+-fi
+-
+-AC_CACHE_CHECK(for standalone nsl functions,pr_cv_lib_standalone_nsl,[
+-  AC_TRY_LINK(,[gethostent();],
+-  pr_cv_lib_standalone_nsl="yes", pr_cv_lib_standalone_nsl="no") ])
+-
+-if test "$pr_cv_lib_standalone_nsl" = "no"; then
+-  AC_CHECK_LIB(nsl,gethostent)
+-fi
+-
+-AC_CACHE_CHECK(for standalone socket functions,pr_cv_lib_standalone_sockets,
+-  AC_TRY_LINK(,[bind();],
+-  pr_cv_lib_standalone_sockets="yes", pr_cv_lib_standalone_sockets="no"))
+-
+-if test "$pr_cv_lib_standalone_sockets" = "no"; then
+-  AC_CHECK_LIB(socket,bind)
+-fi
+-
+-AC_CACHE_CHECK(for _pw_stayopen variable,pr_cv_var__pw_stayopen,
+-  AC_TRY_LINK(
+-    [extern int _pw_stayopen; ],
+-    [_pw_stayopen = 1;],
+-    pr_cv_var__pw_stayopen="yes", pr_cv_var__pw_stayopen="no"))
+-
+-if test "$pr_cv_var__pw_stayopen" = "yes"; then
+-  AC_DEFINE(HAVE__PW_STAYOPEN)
+-fi
+-
+-AC_CHECK_HEADERS(krb.h)
+-AC_CHECK_HEADERS(prot.h)
+-
+-dnl HP-UX's hpsecurity.h can multiply define MAXINT and confuse configure
+-AC_CHECK_HEADERS(hpsecurity.h, [
+-    AC_SEARCH_LIBS(getprpwnam, sec)
+-  ],
+-  [
+-    AC_MSG_CHECKING(for hpsecurity.h workaround)
+-    AC_TRY_COMPILE([
+-#include <values.h>
+-#undef MAXINT
+-#include <hpsecurity.h>
+-  ], [],
+-  [
+-    AC_DEFINE(HAVE_HPSECURITY_H)
+-    AC_SEARCH_LIBS(getprpwnam, sec)
+-    AC_MSG_RESULT(yes)
+-  ], [
+-    AC_MSG_RESULT(no)
+-  ])
+-])
+-
+-dnl Checks for installation user/group
+-
+-if test x"$install_user" = x; then
+-  if test "x$target_os" = "xcygwin"; then
+-    install_user=`id -u`
+-  else
+-    install_user=root
+-  fi
+-fi
+-if test x"$install_group" = x ; then
+-  if test "x$target_os" = "xcygwin"; then
+-    install_group=`id -g`
+-  else
+-    install_group=`sed -n '/.*:.*:0:/{s/^\(.*\):.*:0:.*/\1/p;q;}' /etc/group 2>/dev/null`
+-  fi
+-fi
+-
+-AC_SUBST(install_user)
+-AC_SUBST(install_group)
+-
+-dnl Checks for header files.
+-AC_HEADER_DIRENT
+-AC_HEADER_STDC
+-AC_HEADER_SYS_WAIT
+-AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h unistd.h memory.h)
+-if test x"$force_shadow" != xno ; then
+-  AC_CHECK_HEADERS(shadow.h,
+-    [ if test "$use_shadow" = "" && test -f /etc/shadow ; then
+-        AC_DEFINE(USE_SHADOW)
+-
+-        AC_CHECK_MEMBER(struct spwd.sp_warn,
+-          [AC_DEFINE(HAVE_SPWD_SP_WARN)],,
+-          [#include <shadow.h>])
+-        AC_CHECK_MEMBER(struct spwd.sp_inact,
+-          [AC_DEFINE(HAVE_SPWD_SP_INACT)],,
+-          [#include <shadow.h>])
+-        AC_CHECK_MEMBER(struct spwd.sp_expire,
+-          [AC_DEFINE(HAVE_SPWD_SP_EXPIRE)],,
+-          [#include <shadow.h>])
+-
+-      fi ])
+-fi
+-
+-dnl The pam test used to disable use_shadow, and I'm not sure why, libpam
+-dnl really shouldn't have anything to do with force_shadow or use_shadow.
+-if test x"$enable_auth_pam" != xno ; then
+-  AC_CHECK_HEADERS(security/pam_appl.h pam/pam_appl.h,
+-    [ if test `echo $ac_addl_modules | grep -c mod_auth_pam` = "0"; then
+-        ac_addl_modules="mod_auth_pam.o $ac_addl_modules"
+-        ac_build_addl_modules="modules/mod_auth_pam.o $ac_build_addl_modules"
+-      fi ])
+-
+-  dnl This next check looks funky due to a linker problem with some versions
+-  dnl of the PAM library.  Prior to 0.72 release, the Linux PAM shared library
+-  dnl omitted requiring libdl linking information. PAM-0.72 or better ships
+-  dnl with RedHat 6.2 and Debian 2.2 or better.
+-  dnl
+-  dnl This test used to add -lpam to the libraries list, however this isn't
+-  dnl necessary in light of the fact that mod_auth_pam.c has the $Library $ tag
+-  dnl and is picked up at configure time.  The only thing we need is to add
+-  dnl -ldl in the event of broken PAM.
+-
+-  if test `echo $ac_addl_modules | grep -c mod_auth_pam` = "1"; then
+-
+-	AC_CHECK_LIB(pam, pam_start,
+-		[AC_DEFINE(HAVE_PAM)],
+-		[AC_CHECK_LIB(pam, pam_end,
+-				[AC_DEFINE(HAVE_PAM)
+-					LIBS="$LIBS -ldl"],,
+-				[-ldl])])
+-  fi
+-
+-fi
+-
+-ac_add_mod_cap="no"
+-if test x"$enable_cap" != xno; then
+-  case "$host" in
+-    [*-linux-*])
+-      rev=`uname -r | awk -F'[[.-]]' '{printf "%03d%03d%03d", $1, $2, $3}'`
+-
+-      if test $rev -ge 002001097; then
+-        AC_CHECK_HEADER(linux/capability.h)
+- 
+-        if test $ac_cv_header_linux_capability_h = "yes"; then
+-          ac_add_mod_cap="yes"
+-        fi
+-      fi
+-  esac
+-fi
+-
+-AC_MSG_CHECKING([whether to enable mod_cap])
+-AC_MSG_RESULT($ac_add_mod_cap)
+-
+-if test $ac_add_mod_cap = "yes"; then
+-  ac_addl_modules="$ac_addl_modules mod_cap.o"
+-  ac_build_addl_modules="modules/mod_cap.o $ac_build_addl_modules"
+-fi
+-
+-AC_CHECK_HEADERS(ctype.h getopt.h crypt.h bstring.h limits.h)
+-AC_CHECK_HEADERS(strings.h stropts.h)
+-AC_CHECK_HEADERS(sys/file.h sys/mman.h sys/types.h sys/uio.h)
+-
+-dnl These particular checks are done a little differently because on some
+-dnl platforms, <sys/mount.h> wants <sys/param.h> to be included first.
+-AC_CHECK_HEADERS(sys/param.h sys/mount.h,,,
+-  [
+-    [
+-     #if HAVE_SYS_PARAM_H
+-     # include <sys/param.h>
+-     #endif
+-    ]
+-  ])
+-
+-AC_CHECK_HEADERS(netdb.h netinet/in.h)
+-
+-AC_CHECK_HEADERS(netinet/in_systm.h,,,
+-  [
+-    [
+-     #if HAVE_SYS_TYPES_H
+-     # include <sys/types.h>
+-     #endif
+-    ]
+-  ])
+-
+-AC_CHECK_HEADERS(netinet/ip.h,,,
+-  [
+-    [
+-     #if HAVE_SYS_TYPES_H
+-     # include <sys/types.h>
+-     #endif
+-     #if HAVE_NETINET_IN_H
+-     # include <netinet/in.h>
+-     #endif
+-     #if HAVE_NETINET_IN_SYSTM_H
+-     # include <netinet/in_systm.h>
+-     #endif
+-    ]
+-  ])
+-
+-AC_CHECK_HEADERS(netinet/tcp.h arpa/inet.h)
+-AC_CHECK_HEADERS(sys/stat.h errno.h sys/socket.h sys/termios.h sys/termio.h)
+-AC_CHECK_HEADERS(sys/statvfs.h sys/vfs.h sys/select.h)
+-AC_CHECK_HEADERS(dirent.h ndir.h sys/ndir.h sys/dir.h vmsdir.h)
+-AC_CHECK_HEADERS(utmpx.h)
+-AC_CHECK_HEADERS(regex.h)
+-AC_CHECK_HEADER(syslog.h,have_syslog_h="yes",)
+-AC_CHECK_HEADERS(curses.h ncurses.h)
+-
+-dnl Checks for typedefs, structures, and compiler characteristics.
+-AC_C_CONST
+-AC_C_INLINE
+-AC_TYPE_UID_T
+-AC_TYPE_PID_T
+-AC_TYPE_SIZE_T
+-AC_TYPE_MODE_T
+-AC_TYPE_OFF_T
+-AC_TYPE_GETGROUPS
+-
+-dnl Check to see if timer_t is already defined
+-AC_CACHE_CHECK([for timer_t], pr_cv_header_timer_t,
+-	AC_EGREP_HEADER([.*typedef.*timer_t;],sys/types.h,
+-			pr_cv_header_timer_t="yes",
+-	AC_EGREP_HEADER([.*typedef.*timer_t;],limits.h,
+-			pr_cv_header_timer_t="yes",pr_cv_header_timer_t="no")))
+-
+-if test "$pr_cv_header_timer_t" = "yes"; then
+-  AC_DEFINE(HAVE_TIMER_T)
+-fi
+-
+-AC_CHECK_SIZEOF(short, 0)
+-AC_CHECK_SIZEOF(int, 0)
+-AC_CHECK_SIZEOF(long, 0)
+-AC_CHECK_SIZEOF(long long, 0)
+-AC_CHECK_SIZEOF(off_t, 0)
+-
+-AC_HEADER_TIME
+-AC_STRUCT_TM
+-
+-dnl Check for generic typedefs
+-AC_CHECK_TYPE(umode_t, mode_t)
+-AC_CHECK_TYPE(ino_t, ino_t)
+-AC_CHECK_TYPES(socklen_t, ,
+-  [AC_DEFINE(socklen_t, int)],
+-  [
+-    #if HAVE_NETDB_H
+-    # include <netdb.h>
+-    #endif
+-    #include <sys/socket.h>
+-    #include <sys/types.h>
+-  ])
+-
+-dnl See what type of utmp exists
+-AC_CHECK_HEADERS(utmp.h, have_utmp=1, have_utmp=0)
+-
+-if test $have_utmp; then
+-  AC_CACHE_CHECK(whether your struct utmp has ut_user,
+-  		pr_cv_header_utmaxtype,
+-	AC_EGREP_HEADER([ *ut_user.*;],utmp.h,
+-			pr_cv_header_utmaxtype="yes",
+-			pr_cv_header_utmaxtype="no"))
+-  AC_CACHE_CHECK(whether your struct utmp has ut_host,
+-  		pr_cv_header_ut_host,
+-	AC_EGREP_HEADER([ *ut_host.*;],utmp.h,
+-			pr_cv_header_ut_host="yes",
+-			pr_cv_header_ut_host="no"))
+-  AC_CACHE_CHECK(whether your struct utmp has ut_exit,
+-		pr_cv_header_ut_exit,
+-	AC_EGREP_HEADER([ *ut_exit.*;],utmp.h,
+-			pr_cv_header_ut_exit="yes",
+-			pr_cv_header_ut_exit="no"))
+-  if test "$pr_cv_header_utmaxtype" = "yes"; then
+-    AC_DEFINE(HAVE_UTMAXTYPE, 1, [If struct utmp has ut_user.])
+-  fi
+-  if test "$pr_cv_header_ut_host" = "yes"; then
+-    AC_DEFINE(HAVE_UT_UT_HOST, 1, [If struct utmp has ut_host.])
+-  fi
+-  if test "$pr_cv_header_ut_exit" = "yes"; then
+-    AC_DEFINE(HAVE_UT_UT_EXIT, 1, [If struct utmp has ut_exit.])
+-  fi
+-fi
+-
+-dnl See if various LOG_ macros are defined
+-if test "$have_syslog_h" = "yes"; then
+-  AC_DEFINE(HAVE_SYSLOG_H)
+-
+-  AC_CACHE_CHECK(whether your syslog.h defines LOG_CRON,
+-  		pr_cv_header_syslog_log_cron,
+-  	AC_EGREP_CPP(yes,[
+-#include <syslog.h>
+-#ifdef LOG_CRON
+-  yes
+-#endif
+-	],pr_cv_header_syslog_log_cron="yes",
+-	pr_cv_header_syslog_log_cron="no") )
+-
+-  AC_CACHE_CHECK(whether your syslog.h defines LOG_FTP,
+-  		pr_cv_header_syslog_log_ftp,
+-  	AC_EGREP_CPP(yes,[
+-#include <syslog.h>
+-#ifdef LOG_FTP
+-  yes
+-#endif
+-	],pr_cv_header_syslog_log_ftp="yes",
+-	pr_cv_header_syslog_log_ftp="no") )
+-
+-  if test "$pr_cv_header_syslog_log_cron" = "yes"; then
+-    AC_DEFINE(HAVE_LOG_CRON)
+-  fi
+-  if test "$pr_cv_header_syslog_log_ftp" = "yes"; then
+-    AC_DEFINE(HAVE_LOG_FTP)
+-  fi
+-fi
+-
+-dnl Check for directory file descriptor member ("d_fd", "dd_fd" or "__dd_fd")
+-dnl of the DIR struct, possibly defining one of:
+-dnl	HAVE_STRUCT_DIR_D_FD
+-dnl	HAVE_STRUCT_DIR_DD_FD
+-dnl	HAVE_STRUCT_DIR___DD_FD
+-dnl Should use AC_C_STRUCT_MEMBER, when available in an official release.
+-dnl The autoconf-2.14.1 floating around is NOT an official release.
+-dnl Note: use of either the _POSIX_C_SOURCE or the _XOPEN_SOURCE preprocessor
+-dnl macro could result in a wrong answer unless it is also defined here.
+-dnl Doing so may be automatic or may take some care or reordering.
+-dnl NB: autoheader won't pick up these macros, requiring acconfig.h entries.
+-dnl
+-for dirfd in d_fd dd_fd __dd_fd ; do
+-	AC_MSG_CHECKING(for $dirfd in DIR structure)
+-	AC_TRY_COMPILE([
+-#include <stdio.h>
+-#include <dirent.h>
+-], [
+-DIR *dirp;
+-int i = dirp->$dirfd;
+-], eval ac_cv_struct_dir_$dirfd=yes,)
+-	if test "`eval echo x'$''ac_cv_struct_dir_'$dirfd`" = xyes ; then
+-		ucdirfd=`echo $dirfd | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+-		AC_DEFINE_UNQUOTED(HAVE_STRUCT_DIR_$ucdirfd)
+-		AC_MSG_RESULT(yes)
+-		break
+-	else
+-		AC_MSG_RESULT(no)
+-	fi
+-done
+-
+-
+-dnl Checks for library functions.
+-
+-AC_FUNC_ALLOCA
+-
+-dnl UnixWare's alloca is in libucb, in /usr/ucblib/. Muck about with
+-dnl $LDFLAGS so AC_CHECK_LIB() will find it there.
+-old_LDFLAGS=$LDFLAGS
+-LDFLAGS="$LDFLAGS -L/usr/ucblib/"
+-AC_CHECK_LIB(ucb, alloca)
+-LDFLAGS=$old_LDFLAGS
+-
+-AC_PROG_GCC_TRADITIONAL
+-AC_FUNC_SETPGRP
+-AC_TYPE_SIGNAL
+-AC_FUNC_VPRINTF
+-AC_CHECK_FUNCS(bcopy crypt fgetgrent fgetpwent flock freeaddrinfo)
+-AC_CHECK_FUNC(gai_strerror,
+-  AC_DEFINE(HAVE_GAI_STRERROR),
+-  LIB_OBJS="$LIB_OBJS glibc-gai_strerror.o"
+-)
+-AC_CHECK_FUNCS(getaddrinfo getcwd gethostbyname2 gethostname getnameinfo)
+-AC_CHECK_FUNCS(getopt_long gettimeofday hstrerror inet_aton inet_ntop inet_pton)
+-AC_CHECK_FUNCS(memcpy mempcpy mkdir mkstemp mlock mlockall munlock munlockall)
+-AC_CHECK_FUNCS(rmdir select setgroups socket statfs strchr strcoll strerror)
+-AC_CHECK_FUNCS(strsep strtol setprotoent endprotoent)
+-# __snprintf and __vsnprintf are only on solaris and _really_ broken there.
+-AC_CHECK_FUNCS(vsnprintf snprintf)
+-if test x"$ac_cv_func_vsnprintf" != xyes || test x"$ac_cv_func_snprintf" != xyes
+-then
+-	AC_CHECK_FUNCS(fconvert fcvt)
+-	AC_CHECK_HEADERS(floatingpoint.h)
+-fi
+-AC_CHECK_FUNCS(setsid setgroupent seteuid setegid)
+-AC_CHECK_FUNCS(siginterrupt setpgid)
+-AC_CHECK_FUNCS(regcomp)
+-AC_CHECK_FUNCS(tzset)
+-AC_CHECK_FUNCS(pathconf fpathconf)
+-AC_CHECK_FUNCS(fgetspent)
+-
+-AC_CHECK_FUNC(setpassent,
+-[case "$target_os:$enable_force_setpassent" in
+-changequote(, )dnl
+-  *freebsd[23]\.[0-3]*:)
+-changequote([, ])dnl
+-    AC_MSG_WARN(Disabling broken FreeBSD setpassent(), see README for details.)
+-        ;;
+-  *:no) ;;
+-  *) AC_DEFINE(HAVE_SETPASSENT) ;;
+-esac])
+-
+-dnl IPv4/IPv6-related checks
+-AC_CHECK_MEMBER(struct sockaddr_in.sin_len,
+-  [AC_DEFINE(SIN_LEN)],,
+-  [
+-    #if HAVE_SYS_TYPES_H
+-    # include <sys/types.h>
+-    #endif
+-    #if HAVE_SYS_SOCKET_H
+-    # include <sys/socket.h>
+-    #endif
+-    #if HAVE_NETINET_IN_H
+-    # include <netinet/in.h>
+-    #endif
+-  ])
+-
+-PR_CHECK_STRUCT_ADDRINFO
+-PR_CHECK_STRUCT_SS
+-PR_CHECK_SS_FAMILY
+-PR_CHECK_SS_LEN
+-
+-if test x"$enable_sendfile" = xyes ; then
+-  AC_CACHE_CHECK(
+-    [which sendfile() implementation to use],
+-    pr_cv_func_sendfile,
+-    pr_cv_func_sendfile="None"
+-
+-    dnl Linux.
+-    if test "$pr_cv_func_sendfile" = "None"; then
+-      AC_TRY_LINK(
+-        [ #include <sys/types.h>
+-          #include <sys/sendfile.h>
+-          #include <unistd.h>
+-        ],
+-        [ int i;
+-          off_t o;
+-          size_t c;
+-          (void)sendfile(i,i,&o,c);
+-        ], pr_cv_func_sendfile="Linux")
+-    fi
+-
+-    dnl BSD.
+-    if test "$pr_cv_func_sendfile" = "None"; then
+-      AC_TRY_LINK(
+-        [ #include <sys/types.h>
+-          #include <sys/socket.h>
+-          #include <sys/uio.h>
+-        ],
+-        [ int i;
+-          off_t o;
+-          size_t n;
+-          struct sf_hdtr h;
+-          (void)sendfile(i,i,o,n,&h,&o,i);
+-        ], pr_cv_func_sendfile="BSD")
+-    fi
+-
+-    dnl AIX.
+-    if test "$pr_cv_func_sendfile" = "None"; then
+-      AC_TRY_LINK(
+-        [ #include <sys/types.h>
+-          #include <sys/socket.h>
+-        ],
+-        [ uint f;
+-          int h;
+-          struct sf_parms p;
+-          (void)send_file(&(h),&(p),f);
+-        ], pr_cv_func_sendfile="AIX")
+-    fi
+-
+-    dnl Solaris
+-    if test "$pr_cv_func_sendfile" = "None"; then
+-      old_ldflags=$LDFLAGS
+-      LDFLAGS="-lsendfile $LDFLAGS"
+-      AC_TRY_LINK(
+-        [ #include <sys/types.h>
+-          #include <sys/sendfile.h>
+-          #include <unistd.h>
+-        ],
+-        [ int i;
+-          off_t o;
+-          size_t c;
+-          (void)sendfile(i,i,&o,c);
+-        ], pr_cv_func_sendfile="Solaris")
+-      LDFLAGS=$old_ldflags
+-    fi
+-  )
+-
+-  dnl Now, set the appropriate defines based on our investigations...
+-
+-  if test "$pr_cv_func_sendfile" != "None"; then
+-    AC_DEFINE(HAVE_SENDFILE)
+-  fi
+-
+-  case "$pr_cv_func_sendfile" in
+-    "Linux")
+-      AC_CHECK_HEADERS(sys/sendfile.h)
+-      AC_DEFINE(HAVE_LINUX_SENDFILE)
+-      ;;
+-
+-    "BSD")
+-      AC_DEFINE(HAVE_BSD_SENDFILE)
+-      ;;
+-
+-    "AIX")
+-      AC_DEFINE(HAVE_AIX_SENDFILE)
+-      ;;
+-
+-    "Solaris")
+-      AC_CHECK_HEADERS(sys/sendfile.h)
+-      AC_DEFINE(HAVE_SOLARIS_SENDFILE)
+-      ac_build_addl_libraries="-lsendfile $ac_build_addl_libraries"
+-      ;;
+-  esac
+-fi
+-
+-dnl Custom-rolled macro for checking return type of setgrent(3)
+-PR_FUNC_SETGRENT_VOID
+-
+-dnl Perform checks for curses/ncurses libraries only if the corresponding
+-dnl headers have been found.
+-if test x"$ac_cv_header_curses_h" = xyes; then
+-  AC_CHECK_LIB(curses, initscr,
+-    [ CURSES_LIBS="-lcurses"
+-      AC_DEFINE(HAVE_LIBCURSES, 1, [Define if you have curses])
+-    ])
+-fi
+-
+-if test x"$ac_cv_header_ncurses_h" = xyes; then
+-  AC_CHECK_LIB(ncurses, initscr,
+-    [ CURSES_LIBS="-lncurses"
+-      AC_DEFINE(HAVE_LIBNCURSES, 1, [Define if you have ncurses])
+-    ])
+-fi
+-
+-if test x"$enable_curses" != xno ; then
+-  AC_DEFINE(USE_CURSES)
+-fi
+-
+-if test x"$enable_ncurses" != xno ; then
+-  AC_DEFINE(USE_NCURSES)
+-fi
+-
+-dnl Check for various argv[] replacing functions on various OSs
+-AC_CHECK_FUNCS(setproctitle)
+-AC_CHECK_HEADERS(libutil.h)
+-AC_CHECK_LIB(util, setproctitle,
+-	[AC_DEFINE(HAVE_SETPROCTITLE)
+-		ac_cv_func_setproctitle="yes" ; LIBS="$LIBS -lutil"])
+-
+-if test "$ac_cv_func_setproctitle" = "yes"; then
+-  AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_NONE)
+-else
+-  pf_argv_set="no"
+-
+-  AC_CHECK_HEADERS(sys/pstat.h,have_pstat_h="yes",have_pstat_h="no")
+-  if test "$have_pstat_h" = "yes"; then
+-    AC_CHECK_FUNCS(pstat)
+-    
+-    if test "$ac_cv_func_pstat" = "yes"; then
+-	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_PSTAT)
+-    else
+-	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_WRITEABLE)
+-    fi
+-
+-    pf_argv_set="yes"
+-  fi
+-
+-  if test "$pf_argv_set" = "no"; then
+-    AC_EGREP_HEADER([#define.*PS_STRINGS.*],sys/exec.h,
+-			have_psstrings="yes",have_psstrings="no")
+-    if test "$have_psstrings" = "yes"; then
+-	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_PSSTRINGS)
+-	pf_argv_set="yes"
+-    fi
+-  fi
+-
+-  if test "$pf_argv_set" = "no"; then
+-    AC_CACHE_CHECK(whether __progname and __progname_full are available,
+-		    pf_cv_var_progname,
+-		    AC_TRY_LINK([extern char *__progname, *__progname_full;],
+-			[__progname = "foo"; __progname_full = "foo bar";],
+-			pf_cv_var_progname="yes", pf_cv_var_progname="no"))
+-
+-    if test "$pf_cv_var_progname" = "yes"; then
+-	AC_DEFINE(HAVE___PROGNAME)
+-    fi
+-
+-    AC_CACHE_CHECK(which argv replacement method to use,
+-		    pf_cv_argv_type,
+-		    AC_EGREP_CPP(yes,[
+-#if defined(__GNU_HURD__)
+-  yes
+-#endif
+-  ],pf_cv_argv_type="new", pf_cv_argv_type="writeable"))
+-
+-    if test "$pf_cv_argv_type" = "new"; then
+-	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_NEW)
+-	pf_argv_set="yes"
+-    fi
+-
+-    if test "$pf_argv_set" = "no"; then
+-	AC_DEFINE(PF_ARGV_TYPE, PF_ARGV_WRITEABLE)
+-    fi
+-  fi
+-fi
+-
+-dnl Run a small test program to see if the host's printf(3) family can
+-dnl actually handle the %llu format.
+-AC_MSG_CHECKING([whether printf supports %llu format]);
+-AC_TRY_RUN(
+-  [ #include <stdio.h>
+-    int main(int argc, char *argv[]) {
+-      return (fprintf(stderr, "%llu\n", (unsigned long long) 1) == 2 ? 0 : 1);
+-    }
+-  ],
+-  AC_MSG_RESULT(yes); AC_DEFINE(HAVE_LLU),
+-  AC_MSG_RESULT(no); AC_DEFINE(HAVE_LU),
+-  AC_MSG_RESULT(cross-compiling); AC_DEFINE(HAVE_LU)
+-)
+-
+-dnl Add the proftpd support library
+-LIBS="-lsupp $LIBS"
+-
+-dnl Module handling.
+-for module in $ac_addl_modules; do
+-  addonlibs=""
+-  src=`echo "$module" | sed -e 's/\.o$//'`.c;
+-  srcinc=`echo "$module" | sed -e 's/\.o$//'`.h;
+-  if test -f $srcdir/modules/$src -o -f $srcdir/contrib/$src; then
+-
+-    if test ! -f $srcdir/modules/$src; then
+-	olddir=`pwd`
+-	cd $srcdir/modules
+-	ln -s ../contrib/$src $src
+-	cd $olddir
+-    fi
+-
+-    if test ! -f $srcdir/include/$srcinc -a -f $srcdir/contrib/$srcinc ; then
+-	olddir=`pwd`
+-	cd $srcdir/include
+-	ln -s ../contrib/$srcinc $srcinc
+-	cd $olddir
+-    fi
+-
+-    srclib=`cat $srcdir/modules/$src | grep "\\\$Libraries:" | sed -e 's/^.*\$Libraries: \(.*\)\\$/\1/'`
+-
+-    if test -f $srcdir/include/$srcinc ; then
+-        inclib=`cat $srcdir/include/$srcinc | grep "\\\$Libraries:" | sed -e 's/^.*\$Libraries: \(.*\)\\$/\1/'`
+-    else
+-        inclib= 
+-    fi
+-
+-
+-    dnl Test for duplicate libraries, just in case.
+-    for thelib in $srclib $inclib; do
+-	dup="no"
+-
+-	for somelib in $ac_addl_libs $LIBS; do
+-
+-		if test "$thelib" = "$somelib"; then
+-			dup="yes"
+-			break
+-		fi
+-	done
+-	
+-	if test "$dup" = "no"; then
+-		addonlibs="$addonlibs $thelib"
+-	fi
+-    done
+-
+-    test x"$addonlibs" = x || ac_addl_libs="$addonlibs $ac_addl_libs"
+-
+-    adir=`cat $srcdir/modules/$src | grep "\\\$Directories:" | sed -e 's/^.*\$Directories: \(.*\)\\$/\1/'`
+-    test x"$adir" = x || ac_addl_dirs="$adir $ac_addl_dirs"
+-
+-  else
+-
+-    echo "source file '$srcdir/modules/$src' cannot be found -- aborting"
+-    exit 1
+-
+-  fi
+-done
+-
+-ac_addl_libs=`echo "$ac_addl_libs" | sed -e 's/ *\$//'`
+-ac_addl_libs=`echo "$ac_addl_libs" | sed -e 's/^ *//'`
+-test "x$ac_addl_libs" = x || LIBS="$LIBS $ac_addl_libs"
+-ac_addl_dirs=`echo "$ac_addl_dirs" | sed -e 's/ *\$//'`
+-ac_addl_dirs=`echo "$ac_addl_dirs" | sed -e 's/^ *//'`
+-ADDL_DIRS="$ac_addl_dirs"
+-
+-INCLUDES="$ac_build_addl_includes"
+-LIBRARIES="$ac_build_addl_libraries"
+-MODULE_OBJS="$ac_core_modules $ac_addl_modules"
+-BUILD_MODULE_OBJS="$ac_build_core_modules $ac_build_addl_modules"
+-VERSION=`cat $srcdir/include/version.h | grep "#define VERSION " | sed -e 's/^.*\"\(.*\)\"/\1/'`
+-
+-dnl Substitute in our configuration paths as appropriate.  We also have to
+-dnl sweet talk the environment into helping us get this right, like so...
+-pr_saved_prefix="$prefix"
+-pr_saved_exec_prefix="$exec_prefix"
+-
+-test "x$prefix" = xNONE && prefix=$ac_default_prefix
+-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+-
+-AC_DEFINE_UNQUOTED(CONFIG_FILE_PATH,
+-			"`eval echo "${sysconfdir}/proftpd.conf"`")
+-AC_DEFINE_UNQUOTED(PID_FILE_PATH,
+-			"`eval echo "${localstatedir}/proftpd.pid"`")
+-AC_DEFINE_UNQUOTED(RUN_DIR,
+-			"`eval echo "${localstatedir}/proftpd"`")
+-
+-prefix="$pr_saved_prefix"
+-exec_prefix="$pr_saved_exec_prefix"
+-
+-if test x"$devel" = xyes ; then
+-  AC_DEFINE(USE_DEVEL)
+-
+-  if test x"$GCC" = xyes; then
+-
+-    dnl Remove any optimization flags from CFLAGS
+-    CFLAGS=`echo "$CFLAGS" | sed -e 's/\-O2//'`
+-    CFLAGS="$CFLAGS $pr_devel_cflags"
+-    LIBS="$LIBS $pr_devel_libs"
+-
+-    dnl Some C compilers (e.g. older gcc versions) may not accept these
+-    dnl options.  Check if they are supported.  They will be added to
+-    dnl CFLAGS if supported.
+-    PR_CHECK_CC_OPT(Wfloat-equal)
+-  fi
+-
+-  dnl Do not strip symboles from developer object files.
+-  INSTALL_STRIP=""
+-else
+-
+-  dnl Make sure to strip symbols from non-developer object files.
+-  INSTALL_STRIP="-s"
+-fi
+-
+-dnl Check whether the C compiler accepts -Wno-long-double. This helps to
+-dnl quell unnecessary OSX compiler complaints.  Use of this macro should
+-dnl be as late in the configure script as possible, for it changes the
+-dnl CFLAGS environment variable (which may possible cause other autoconf
+-dnl tests to fail).
+-PR_CHECK_CC_OPT(Wno-long-double)
+-
+-dnl And finally, generate the appropriate Make* and config.h
+-AC_SUBST(INSTALL_STRIP)
+-AC_SUBST(LIB_OBJS)
+-AC_SUBST(MODULE_OBJS)
+-AC_SUBST(BUILD_MODULE_OBJS)
+-AC_SUBST(ADDL_DIRS)
+-AC_SUBST(INCLUDES)
+-AC_SUBST(LIBRARIES)
+-AC_SUBST(CURSES_LIBS)
+-AC_SUBST(VERSION)
+-
+-AC_CONFIG_HEADER(config.h)
+-
+-AC_OUTPUT(lib/Makefile
+-          modules/Makefile
+-          src/Makefile src/proftpd.8 src/xferlog.5
+-          utils/Makefile utils/ftpcount.1 utils/ftpshut.8 utils/ftptop.1
+-            utils/ftpwho.1
+-          Makefile Make.rules,
+-          [echo timestamp > stamp-h])
+diff -ruN proftpd-1.2.8+cvs20031020-old/Makefile.in proftpd-1.2.8+cvs20031020/Makefile.in
+--- proftpd-1.2.8+cvs20031020-old/Makefile.in	2003-10-20 23:19:03.000000000 +0200
++++ proftpd-1.2.8+cvs20031020/Makefile.in	2003-10-20 23:19:03.000000000 +0200
+@@ -148,7 +148,7 @@
+ 
+ # autoheader might not change config.h.in, so touch a stamp file.
+ ${srcdir}/config.h.in: stamp-h.in
+-${srcdir}/stamp-h.in: configure.in acconfig.h
++${srcdir}/stamp-h.in: configure.ac acconfig.h
+ 	cd ${srcdir} && autoheader
+ 	echo timestamp > ${srcdir}/stamp-h.in
+ 
+@@ -156,7 +156,7 @@
+ stamp-h: config.h.in config.status
+ 	./config.status
+ 
+-${srcdir}/configure: configure.in
++${srcdir}/configure: configure.ac
+ 	cd ${srcdir} && autoconf
+ 
+ Make.rules: Make.rules.in config.status
--- proftpd-1.2.9.orig/debian/patches/08.misc.diff
+++ proftpd-1.2.9/debian/patches/08.misc.diff
@@ -0,0 +1,2038 @@
+diff -urN o/README.ftpasswd s/README.ftpasswd
+--- o/README.ftpasswd	Thu Jan  1 01:00:00 1970
++++ s/README.ftpasswd	Sun Oct 21 21:06:14 2001
+@@ -0,0 +1,82 @@
++---------------------------------------------------------------------------
++TJ Saunders
++2000-01-09
++---------------------------------------------------------------------------
++
++usage: ftpasswd [ -h ] [ --group | --passwd ]
++
++  If used with --passwd, ftpasswd creates a file in the passwd(5) format,
++  suitable for use with proftpd's AuthUserFile configuration directive.
++  You will be prompted for the password to use of the user, which will be
++  encrypted, and written out as the encrypted string.
++ 
++  By default, using --passwd will write output to "./ftpd.passwd".
++ 
++  Options:
++    -F          write output to specified file, rather than "./ftpd.passwd"
++    --file
++
++    -f          if the file to be used already exists, delete it and write a
++    --force     new one.
++
++    --gid       primary group ID for this user (optional, will default to
++                given --uid value if absent)
++
++    -h          displays this message
++    --help
++
++    --home      home directory for the user (required)
++
++    --name      name of the user account (required).  If the name does not
++                exist in the specified output-file, an entry will be created
++                for her.  Otherwise, the given fields will be updated.
++
++    --shell     shell for the user (required).  Recommended: /bin/false
++
++    --uid       numerical user ID (required)
++
++    --use-cracklib
++                causes ftpasswd to use Alec Muffet's cracklib routines in
++                order to determine and prevent the use of bad or weak
++                passwords.  The optional path to this option specifies
++                the path to the dictionary files to use -- default path
++                is "/usr/lib/cracklib_dict".  This requires the Perl
++                Crypt::Cracklib module to be installed on your system.
++
++  If used with --group, ftpasswd creates a file in the group(5) format,
++  suitable for use with proftpd's AuthGroupFile configuration directive.
++
++  By default, using --group will write output to "./ftpd.group".
++
++  Options:
++    --enable-group-passwd
++                prompt for a group password.  This is disabled by default.
++
++    -F          write output to specified file, rather than "./ftpd.group"
++    --file
++
++    -f          if the file be used already exists, delete it and write a new
++    --force     one.
++
++    --gid       numerical group ID (required)
++
++    -h
++    --help      displays this message
++
++    -m
++    --member    user to be a member of the group.  This argument may be used
++                multiple times to specify the full list of users to be members
++                of this group.
++
++    --name      name of the group (required).  If the name does not exist in
++                the specified output-file, an entry will be created for them.
++                Otherwise, the given fields will be updated.
++
++    --use-cracklib
++                causes ftpasswd to use Alec Muffet's cracklib routines in
++                order to determine and prevent the use of bad or weak
++                passwords.  The optional path to this option specifies
++                the path to the dictionary files to use -- default path
++                is "/usr/lib/cracklib_dict".  This requires the Perl
++                Crypt::Cracklib module to be installed on your system.
++
+diff -urN o/contrib/xferstats.holger-preiss s/contrib/xferstats.holger-preiss
+--- o/contrib/xferstats.holger-preiss	Sun Jun  3 15:38:04 2001
++++ s/contrib/xferstats.holger-preiss	Mon Oct 22 01:43:07 2001
+@@ -248,14 +248,14 @@
+ 
+ Total Transfers from each Archive Section (By bytes)
+ 
+-                                                 ---- Percent  Of ----
+-     Archive Section      Files Sent Bytes Sent  Files Sent Bytes Sent
+-------------------------- ---------- ----------- ---------- ----------
++                                                   ---- Percent  Of ----
++     Archive Section      Files Sent Bytes Sent    Files Sent Bytes Sent
++------------------------- ---------- ------------- ---------- ----------
+ .
+ 
+ format line2 =
+-@<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>>> @>>>>>>>   @>>>>>>>
+-$section,                 $files,    $bytes,     $pctfiles, $pctbytes
++@<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>>>>> @>>>>>>>   @>>>>>>>
++$section,                 $files,    $bytes,       $pctfiles, $pctbytes
+ .
+ 
+ $| = 1;
+diff -urN o/doc/draft-murray-auth-ftp-ssl-06.txt s/doc/draft-murray-auth-ftp-ssl-06.txt
+--- o/doc/draft-murray-auth-ftp-ssl-06.txt	Thu Jan  1 01:00:00 1970
++++ s/doc/draft-murray-auth-ftp-ssl-06.txt	Sun Oct 21 21:06:12 2001
+@@ -0,0 +1,1920 @@
++
++
++
++
++
++
++                                                    Paul Ford-Hutchinson
++<draft-murray-auth-ftp-ssl-06.txt>                            IBM UK Ltd
++                                                        Martin Carpenter
++                                                            Verisign Ltd
++                                                              Tim Hudson
++INTERNET-DRAFT (draft)                                 RSA Australia Ltd
++                                                             Eric Murray
++                                                        Wave Systems Inc
++                                                          Volker Wiegand
++                                                              SuSE Linux
++
++                                                    18th September, 2000
++This document expires on 17th March, 2001
++
++
++                         Securing FTP with TLS
++
++
++Status of this Memo
++
++   This document is an Internet-Draft and is in full conformance with
++   all provisions of Section 10 of RFC2026.
++
++   Internet-Drafts are working documents of the Internet Engineering
++   Task Force (IETF), its areas, and its working groups.  Note that
++   other groups may also distribute working documents as Internet-
++   Drafts.
++
++   Internet-Drafts are draft documents valid for a maximum of six months
++   and may be updated, replaced, or obsoleted by other documents at any
++   time.  It is inappropriate to use Internet-Drafts as reference
++   material or to cite them other than as "work in progress."
++
++   The list of current Internet-Drafts can be accessed at
++   http://www.ietf.org/1id-abstracts.txt
++
++   The list of Internet-Draft Shadow Directories can be accessed at
++   http://www.ietf.org/shadow.html
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand             [Page 1]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++Index
++      1. .......... Abstract
++      2. .......... Introduction
++      3. .......... Audience
++      4. .......... Session negotiation on the control port
++      5. .......... Response to FEAT command
++      6. .......... Data Connection Behaviour
++      7. .......... Mechanisms for the AUTH Command
++      8. .......... SASL Considerations
++      9. .......... Data Connection Security
++      10. ......... A discussion of negotiation behaviour
++      11. ......... Who negotiates what, where and how
++      12. ......... Timing Diagrams
++      13. ......... Implications of [FTP-EXT]
++      14. ......... Discussion of the 'REIN' command
++      15. ......... Security Considerations
++      16. ......... IANA Considerations
++      17. ......... Network Management
++      18. ......... Internationalization
++      19. ......... Scalability & Limits
++      20. ......... Applicability
++      21. ......... Acknowledgements
++      22. ......... References
++      23. ......... Authors' Contact Addresses
++                                  Appendices
++      A. .......... Summary of [RFC-2246]
++      B. .......... Summary of [RFC-2228]
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand             [Page 2]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++1. Abstract
++
++   This document describes a mechanism that can be used by FTP clients
++   and servers to implement security and authentication using the TLS
++   protocol defined by [RFC-2246] and the extensions to the FTP protocol
++   defined by [RFC-2228].  It describes the subset of the extensions
++   that are required and the parameters to be used; discusses some of
++   the policy issues that clients and servers will need to take;
++   considers some of the implications of those policies and discusses
++   some expected behaviours of implementations to allow interoperation.
++   This document is intended to provide TLS support for FTP in a similar
++   way to that provided for SMTP in [RFC-2487].
++
++   TLS is not the only mechanism for securing file transfer, however it
++   does offer some of the following positive attributes:-
++
++      - Flexible security levels.  TLS can support privacy, integrity,
++      authentication or some combination of all of these.  This allows
++      clients and servers to dynamically, during a session, decide on
++      the level of security required for a particular data transfer,
++
++      - It is possible to use X.509 certificates to authenticate client
++      users and not just client hosts.
++
++      - Formalised public key management.  By use of X.509 public
++      certificates during the authentication phase, certificate
++      management can be built into a central function.  Whilst this may
++      not be desirable for all uses of secured file transfer, it offers
++      advantages in certain structured environments such as access to
++      corporate data sources.
++
++      - Co-existence and interoperation with authentication mechanisms
++      that are already in place for the HTTPS protocol.  This allows web
++      browsers to incorporate secure file transfer using the same
++      infrastructure that has been set up to allow secure web browsing.
++
++   The TLS protocol is a development of the Netscape Communication
++   Corporation's SSL protocol and this document can be used to allow the
++   FTP protocol to be used with either SSL or TLS.  The actual protocol
++   used will be decided by the negotiation of the protected session by
++   the TLS/SSL layer.
++
++   Note that this specification is in accordance with the FTP RFC
++   [RFC-959] and relies on the TLS protocol [RFC-2246] and the FTP
++   security extensions [RFC-2228].
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand             [Page 3]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++2.  Introduction
++
++   This document is an attempt to describe how three other documents
++   should combined to provide a useful, interoperable, secure file
++   transfer protocol.  Those documents are:-
++
++
++      RFC 959 [RFC-959]
++
++         The description of the Internet File Transfer Protocol
++
++      RFC 2246 [RFC-2246]
++
++         The description of the Transport Layer Security protocol
++         (developed from the Netscape Secure Sockets Layer (SSL)
++         protocol version 3.0).
++
++      RFC 2228 [RFC-2228]
++
++         Extensions to the FTP protocol to allow negotiation of security
++         mechanisms to allow authentication, privacy and message
++         integrity.
++
++   The File Transfer Protocol (FTP) currently defined in [RFC-959] and
++   in place on the Internet is an excellent mechanism for exchanging
++   files.  The security extensions to FTP in [RFC-2228] offer a
++   comprehensive set of commands and responses that can be used to add
++   authentication, integrity and privacy to the FTP protocol.  The TLS
++   protocol is a popular (due to its wholesale adoption in the HTTP
++   environment) mechanism for generally securing a socket connection.
++   There are many ways in which these three protocols can be combined
++   which would ensure that interoperation is impossible.  This document
++   describes one method by which FTP can operate securely in such a way
++   as to provide both flexibility and interoperation.  This necessitates
++   a brief description of the actual negotiation mechanism (if used); a
++   much more detailed description of the policies and practices that
++   would be required and a discussion of the expected behaviours of
++   clients and servers to allow either party to impose their security
++   requirements on the FTP session.
++
++
++3.  Audience
++
++   This document is aimed at developers who wish to use TLS as a
++   security mechanism to secure FTP clients and/or servers.
++
++
++4.  Session negotiation on the control port
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand             [Page 4]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++   4.1  Negotiated Session Security
++
++      In this scenario, the server listens on the normal FTP control
++      port {FTP-PORT} and the session initiation is not secured at all.
++      Once the client wishes to secure the session, the AUTH command is
++      sent and the server may then allow TLS negotiation to take place.
++
++    4.1.1  Client wants a secured session
++
++        If a client wishes to attempt to secure a session then it
++        should, in accordance with [RFC-2228] send the AUTH command with
++        the parameter requesting TLS or SSL {TLS-PARM}.
++
++
++        The client then needs to behave according to its policies
++        depending on the response received from the server and also the
++        result of the TLS negotiation.  i.e. A client which receives an
++        'AUTH' rejection may choose to continue with the session
++        unprotected if it so desires.
++
++    4.1.2  Server wants a secured session
++
++        The FTP protocol does not allow a server to directly dictate
++        client behaviour, however the same effect can be achieved by
++        refusing to accept certain FTP commands until the session is
++        secured to an acceptable level to the server.
++
++    4.2  Implicit Session Security
++
++      In this scenario, the server listens on a distinct port {FTP-
++      TLSPORT} to the normal unsecured FTP server.  Upon connection, the
++      client is expected to start the TLS negotiation.  If the
++      negotiation fails or succeeds at an unacceptable level of security
++      then it will be a client and/or server policy decision to
++      disconnect the session.
++
++5.  Response to the FEAT command
++
++   The FEAT command (introduced in [RFC-2389]) allows servers with
++   additional features to advertise these to a client by responding to
++   the FEAT command.  If a server supports the 'FEAT' command then it
++   MUST advertise supported 'AUTH', 'PBSZ' and 'PROT' commands in the
++   reply as described in section 3.2 of [RFC-2389].  Additionally, the
++   'AUTH' command should have a reply that identifies 'TLS' as one of
++   the possible parameters to 'AUTH'.  It is not necessary to identify
++   the 'SSL', 'TLS-P' or 'TLS-C' parameters separately.
++
++   Example reply (in same style is [RFC-2389])
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand             [Page 5]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++      C> FEAT
++      S> 211-Extensions supported
++      S>  AUTH TLS
++      S>  PBSZ
++      S>  PROT
++      S> 211 END
++
++
++6. Data Connection Behaviour
++
++   The Data Connection in the FTP model can be used in one of three
++   ways.  (Note: these descriptions are not necessarily placed in exact
++   chronological order, but do describe the steps required. - See
++   diagrams later for clarification)
++
++         i) Classic FTP client/server data exchange
++
++         - The client obtains a port, sends the port number to the
++         server, the server connects to the client.  The client issues a
++         send or receive request to the server on the control connection
++         and the data transfer commences on the data connection.
++
++         ii) Firewall-Friendly client/server data exchange (as discussed
++         in [RFC-1579]) using the PASV command to reverse the direction
++         of the data connection.
++
++         - The client requests that the server open a port, the server
++         obtains a port and returns the address and port number to the
++         client.  The client connects to the server on this port.  The
++         client issues a send or receive request  on the control
++         connection and the data transfer commences on the data
++         connection.
++
++         iii) Client initiated server/server data exchange (proxy or
++         PASV connections)
++
++         - The client requests that server A opens a port, server A
++         obtains a port and returns it to the client.  The client sends
++         this port number to server B.  Server B connects to server A.
++         The client sends a send or receive request to server A and the
++         complement to server B and the data transfer commences.  In
++         this model server A is the proxy or PASV host and is a client
++         for the Data Connection to server B.
++
++   For i) and ii) the FTP client will be the TLS client and the FTP
++   server will be the TLS server.
++
++   That is to say, it does not matter which side initiates the
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand             [Page 6]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++   connection with a connect() call or which side reacts to the
++   connection via the accept() call, the FTP client as defined in
++   [RFC-959] is always the TLS client as defined in [RFC-2246].
++
++   In scenario iii) there is a problem in that neither server A nor
++   server B is the TLS client given the fact that an FTP server must act
++   as a TLS server for Firewall-Friendly FTP [RFC-1579].  Thus this is
++   explicitly excluded in the security extensions document [RFC-2228],
++   and in this document.
++
++
++
++7. Mechanisms for the AUTH Command
++
++   The AUTH command takes a single parameter to define the security
++   mechanism to be negotiated.  As the SSL/TLS protocols self-negotiate
++   their levels there is no need to distinguish SSL vs TLS in the
++   application layer.  The proposed mechanism name for negotiating
++   SSL/TLS will be the character string 'TLS'.  This will allow the
++   client and server to negotiate SSL or TLS on the control connection
++   without altering the protection of the data channel.  To protect the
++   data channel as well, the PBSZ, PROT command sequence should be used.
++   We call this "Explicit Data Channel Protection".
++
++   However, there are clients and servers that exist today which use the
++   string 'SSL' to indicate that negotiation should take place on the
++   control connection and that the data connection should be implicitly
++   protected (i.e. the PBSZ 0, PROT P command sequence is not required
++   but the client and server will protect the data channel as if it
++   had). This is "Implicit Data Channel Protection" and is included
++   primarily for backward compatibility.
++
++   To allow for streamlining of the negotiation, whilst allowing the
++   'SSL' string to sink peacefully into disuse, the strings 'TLS-P' and
++   'TLS-C' will also be defined.  'TLS-C' will be a synonym for 'TLS'
++   and 'TLS-P' a synonym for 'SSL'. Thus we allow for strict compliance
++   with [RFC-2228] by use of 'TLS' or 'TLS-C' and a quicker (2 less
++   commands) and perhaps more sensible option 'TLS-P' which will
++   implicitly secure the data connection at the same time as securing
++   the control connection.
++
++   Note: Regardless of the manner in which the data connection is
++   secured (either implicitly by use of 'TLS-P', 'SSL' or connection to
++   a well-known port for FTP protocol over TLS, or explicitly by use of
++   the PBSZ/PROT sequence) the data connection state may be modified by
++   the client issuing the PROT command with the new desired level of
++   data channel protection and the server replying in the affirmative.
++   This data channel protection negotiation can happen at any point in
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand             [Page 7]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++   the session (even straight after a PORT or PASV command) and as often
++   as is required.
++
++      See also Section 16, "IANA Considerations".
++
++
++8. SASL Considerations
++
++   SASL is the Simple Authentication Security Layer. Currently, its
++   definition can be found in the internet draft [RFC-2222]. This
++   document attempts to define the means by which a connection-based
++   protocol may identify and authenticate a client user to a server,
++   with additional optional negotiation of protection for the remainder
++   of that session.
++
++   Unfortunately, the SASL paradigm does not fit in neatly with the FTP-
++   TLS protocol, mainly due to the fact that FTP uses two (independent)
++   connections, and under FTP-TLS these may be at different (and
++   possibly renegotiable) protection levels. Consequently, it is
++   envisaged that SASL will sit underneath TLS on the control
++   connection, and TLS (on both, either or neither connection) will be
++   used for privacy and integrity (with optional authentication from TLS
++   on either connection).
++
++
++9. Data Connection Security
++
++   The Data Connection security level is determined by two factors.
++
++      1) The mechanism used to negotiate security on the control
++      connection will dictate the default (i.e. un-negotiated) security
++      level of the data port.
++
++      2) The PROT command, as specified in [RFC-2228] allows
++      client/server negotiation of the security level of the data
++      connection.  Once a PROT command has been issued by the client and
++      accepted by the server by returning the '200' reply, the security
++      of subsequent data connections should be at that level until
++      another PROT command is issued and accepted; the session ends; or
++      the security of the session (via an AUTH command) is re-
++      negotiated).
++
++   Data Connection Security Negotiation (the PROT command)
++
++      Note: In line with [RFC-2228], there is no facility for securing
++      the Data connection with an insecure Control connection.
++
++      The command defined in [RFC-2228] to negotiate data connection
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand             [Page 8]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++      security is the PROT command.  As defined there are four values
++      that the PROT command parameter can take.
++
++          'C' - Clear - neither Integrity nor Privacy
++
++          'S' - Safe - Integrity without Privacy
++
++          'E' - Confidential - Privacy without Integrity
++
++          'P' - Private - Integrity and Privacy
++
++      As TLS negotiation encompasses (and exceeds) the
++      Safe/Confidential/Private distinction, only Private (use TLS) and
++      Clear (don't use TLS) are used.
++
++      For TLS, the data connection can have one of two security levels.
++
++         1) Clear
++
++         2)Private
++
++      With 'Clear' protection level, the data connection is made without
++      TLS at all.  Thus the connection is unauthenticated and has no
++      privacy or integrity.  This might be the desired behaviour for
++      servers sending file lists, pre-encrypted data or non-sensitive
++      data (e.g. for anonymous FTP servers).
++
++      If the data connection security level is 'Private' then a TLS
++      negotiation must take place, to the satisfaction of the Client and
++      Server prior to any data being transmitted over the connection.
++      The TLS layers of the Client and Server will be responsible for
++      negotiating the exact TLS Cipher Suites that will be used (and
++      thus the eventual security of the connection).
++
++
++      In addition, the PBSZ (protection buffer size) command, as
++      detailed in [RFC-2228], is compulsory prior to any PROT command.
++      This document also defines a data channel encapsulation mechanism
++      for protected data buffers.  For FTP-TLS, which appears to the FTP
++      application as a streaming protection mechanism, this is not
++      required.  Thus the PBSZ command must still be issued, but must
++      have a parameter of '0' to indicate that no buffering is taking
++      place and the data connection should not be encapsulated. Note
++      that PBSZ 0 is not in the grammar of [RFC-2228], section 8.1,
++      where it is stated:
++         PBSZ <sp> <decimal-integer> <CRLF> <decimal-integer> ::= any
++         decimal integer from 1 to (2^32)-1
++      However it should be noted that using a value of '0' to mean a
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand             [Page 9]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++      streaming protocol is a reasonable use of '0' for that parameter
++      and is not ambiguous.
++
++   Initial Data Connection Security
++
++      For backward compatibility and ease of implementation the
++      following rules govern the initial expected protection setting of
++      the data connection.
++
++         Connections accepted on the 'secure FTP' port (see
++         {FTP-TLSPORT}).
++            The initial state of the data connection will be 'Private'
++            (Although this does not follow [RFC-2228], this is how such
++            clients tend to work today).
++
++         Connections accepted on the normal FTP port {FTP-PORT} with
++         TLS/SSL negotiated via an 'AUTH SSL' command.
++            The initial state of the data connection will be 'Private'
++            (Although this does not follow [RFC-2228], this is how such
++            clients tend to work today).
++
++         Connections accepted on the normal FTP port {FTP-PORT} with
++         TLS/SSL negotiated via an 'AUTH TLS' command.
++            The initial state of the data connection will be 'Clear'
++            (this is the correct behaviour as indicated by [RFC-2228].)
++
++      Note: Connections made on other ports may be still behave in one
++      of these ways, but that will be a local configuration issue.
++
++
++10. A Discussion of Negotiation Behaviour
++
++   All these discussions assume that the negotiation has taken place by
++   issuing the AUTH command with a mechanism that does not implicitly
++   protect the data channel.  Using a mechanism which does implicitly
++   secure the data channel or connecting to a port which is implicitly
++   protected will have similar issues.
++
++   10.1. The server's view of the control connection
++
++      A server may have a policy statement somewhere that might:
++
++         - Deny any command before TLS is negotiated (this might cause
++         problems if a SITE or some such command is required prior to
++         login)
++         - Deny certain commands before TLS is negotiated (such as USER,
++         PASS or ACCT)
++         - Deny insecure USER commands for certain users (e.g. not
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 10]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++         ftp/anonymous)
++         - Deny secure USER commands for certain users (e.g.
++         ftp/anonymous)
++         - Define the level(s) of TLS/SSL to be allowed
++         - Define the CipherSuites allowed to be used (perhaps on a per
++         host/domain/...  basis)
++         - Allow TLS authentication as a substitute for local
++         authentication.
++         - Define data connection policies (see next section)
++
++         Note: The TLS negotiation may not be completed satisfactorily
++         for the server, in which case it can be one of these states.
++
++            The TLS negotiation failed completely
++
++         In this case, the control connection should still be up in
++         unprotected mode and the server should issue an unprotected
++         '421' reply to end the session.
++
++            The TLS negotiation completed successfully, but the server
++            decides that the session parameters are not acceptable (e.g.
++            Distinguished Name in the client certificate is not
++            permitted to use the server)
++
++         In this case, the control connection should still be up in a
++         protected state, so the server can either continue to refuse to
++         service commands or issue a '421' reply and close the
++         connection.
++
++            The TLS negotiation failed during the TLS handshake
++
++         In this case, the control connection is in an unknown state and
++         the server should simply drop the control connection.
++
++      Server code will be responsible for implementing the required
++      policies and ensuring that the client is prevented from
++      circumventing the chosen security by refusing to service those
++      commands that are against policy.
++
++   10.2. The server's view of the data connection
++
++      The server can take one of four basic views of the data connection
++
++         1 - Don't allow encryption at all (in which case the PROT
++         command should not allow any value other than 'C' - if it is
++         allowed at all)
++         2 - Allow the client to choose protection or not
++         3 - Insist on data protection (in which case the PROT command
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 11]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++         must be issued prior to the first attempted data transfer)
++         4 - Decide on one of the above three for each and every data
++         connection
++
++      The server should only check the status of the data protection
++      level (for options 3 and 4 above) on the actual command that will
++      initiate the data transfer (and not on the PORT or PASV).  The
++      following commands cause data connections to be opened and thus
++      may be rejected (before any 1xx) message due to an incorrect PROT
++      setting.
++
++
++         STOR
++         RETR
++         NLST
++         LIST
++         STOU
++         APPE
++         MLST (if [FTP-EXT] is implemented)
++         MLSD (if [FTP-EXT] is implemented)
++
++
++      The reply to indicate that the PROT setting is incorrect is
++       '521 data connection cannot be opened with this PROT setting'
++      If the protection level indicates that TLS is required, then it
++      should be negotiated once the data connection is made.  Thus, the
++      '150' reply only states that the command can be used given the
++      current PROT level.  Should the server not like the TLS
++      negotiation then it will close the data port immediately and
++      follow the '150' command with a '522' reply indicating that the
++      TLS negotiation failed or was unacceptable.  (Note: this means
++      that the application can pass a standard list of CipherSuites to
++      the TLS layer for negotiation and review the one negotiated for
++      applicability in each instance).
++
++      It is quite reasonable for the server to insist that the data
++      connection uses a TLS cached session.  This might be a cache of a
++      previous data connection or of the control connection.  If this is
++      the reason for the the refusal to allow the data transfer then the
++      '522' reply should indicate this.
++      Note: this has an important impact on client design, but allows
++      servers to minimise the cycles used during TLS negotiation by
++      refusing to perform a full negotiation with a previously
++      authenticated client.
++
++      It should be noted that the TLS authentication of the server will
++      be authentication of the server host itself and not a user on the
++      server host.
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 12]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++   10.3. The client's view of the control connection
++
++      In most cases it is likely that the client will be using TLS
++      because the server would refuse to interact insecurely.  To allow
++      for this, clients must be able to be flexible enough to manage the
++      securing of a session at the appropriate time and still allow the
++      user/server policies to dictate exactly when in the session the
++      security is negotiated.
++
++      In the case where it is the client that is insisting on the
++      securing of the session, it will need to ensure that the
++      negotiations are all completed satisfactorily and will need to be
++      able to inform the user sensibly should the server not support, or
++      be prepared to use, the required security levels.
++
++      Clients must be coded in such a manner as to allow the timing of
++      the AUTH, PBSZ and PROT commands to be flexible and dictated by
++      the server.  It is quite reasonable for a server to refuse certain
++      commands prior to these commands, similarly it is quite possible
++      that a SITE or quoted command might be needed by a server prior to
++      the AUTH.  A client must allow a user to override the timing of
++      these commands to suit a specific server.
++      For example, a client should not insist on sending the AUTH as the
++      first command in a session, nor should it insist on issuing a
++      PBSZ, PROT pair directly after the AUTH.  This may well be the
++      default behaviour, but must be overridable by a user.
++
++      Note: The TLS negotiation may not be completed satisfactorily for
++      the client, in which case it will be in one of these states:
++
++            The TLS negotiation failed completely
++
++            In this case, the control connection should still be up in
++            unprotected mode and the client should issue an unprotected
++            QUIT command to end the session.
++
++            The TLS negotiation completed successfully, but the client
++            decides that the session parameters are not acceptable (e.g.
++            Distinguished Name in certificate is not the actual server
++            expected)
++
++            In this case, the control connection should still be up in a
++            protected state, so the client should issue a protected QUIT
++            command to end the session.
++
++            The TLS negotiation failed during the TLS handshake
++
++            In this case, the control connection is in an unknown state
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 13]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++            and the client should simply drop the control connection.
++
++   10.4. The client's view of the data connection
++
++   Client security policies
++
++      Clients do not typically have 'policies' as such, instead they
++      rely on the user defining their actions and, to a certain extent,
++      are reactive to the server policy.  Thus a client will need to
++      have commands that will allow the user to switch the protection
++      level of the data connection dynamically, however, there may be a
++      general 'policy' that attempts all LIST and NLST commands on a
++      Clear connection first (and automatically switches to Private if
++      it fails).  In this case there would need to be a user command
++      available to ensure that a given data transfer was not attempted
++      on an insecure data connection.
++
++      Clients also need to understand that the level of the PROT setting
++      is only checked for a particular data transfer after that transfer
++      has been requested.  Thus a refusal by the server to accept a
++      particular data transfer should not be read by the client as a
++      refusal to accept that data protection level in toto, as not only
++      may other data transfers be acceptable at that protection level,
++      but it is entirely possible that the same transfer may be accepted
++      at the same protection level at a later point in the session.
++
++      It should be noted that the TLS authentication of the client
++      should be authentication of a user on the client host and not the
++      client host itself.
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 14]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++11. Who negotiates what, where and how
++
++   11.1. Do we protect at all ?
++
++      Client issues AUTH <Mechanism>, server accepts or rejects.
++      If server needs AUTH, then it refuses to accept certain commands
++      until it gets a successfully protected session.
++
++   11.2. What level of protection do we use on the Control connection ?
++
++      Decided entirely by the TLS CipherSuite negotiation.
++
++   11.3. Do we protect data connections in general ?
++
++      Client issues PROT command, server accepts or rejects.
++
++
++   11.4. Is protection required for a particular data transfer ?
++
++      A client would already have issued a PROT command if it required
++      the connection to be protected.
++      If a server needs to have the connection protected then it will
++      reply to the STOR/RETR/NLST/... command with a '522' indicating
++      that the current state of the data connection protection level is
++      not sufficient for that data transfer at that time.
++
++   11.5. What level of protection is required for a particular data
++   transfer ?
++
++      Decided entirely by the TLS CipherSuite negotiation.
++
++   Thus it can be seen that, for flexibility, it is desirable for the
++   FTP application to be able to interact with the TLS layer upon which
++   it sits to define and discover the exact TLS CipherSuites that are to
++   be/have been negotiated and make decisions accordingly.  However it
++   should be entirely possible, using the mechanisms described in this
++   document, to have a TLS client or server sitting on top of a generic
++   'TLS socket layer'.  In this case, interoperability for a client with
++   a smart TLS-aware server may not be possible due to server policies.
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 15]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++12. Timing Diagrams
++
++   12.1. Establishing a protected session
++
++           Client                                 Server
++  control          data                   data               control
++====================================================================
++
++                                                             socket()
++                                                             bind()
++  socket()
++  connect()  ----------------------------------------------> accept()
++  AUTH TLS   ---------------------------------------------->
++            <----------------------------------------------  234
++  TLSneg()  <----------------------------------------------> TLSneg()
++  PBSZ 0     ---------------------------------------------->
++            <----------------------------------------------  200
++  PROT P     ---------------------------------------------->
++            <----------------------------------------------  200
++  USER fred  ---------------------------------------------->
++            <----------------------------------------------  331
++  PASS pass  ---------------------------------------------->
++            <----------------------------------------------  230
++
++Note: the order of the PBSZ/PROT pair and the USER/PASS pair (with
++respect to each other) is not important (i.e. the USER/PASS can happen
++prior to the PBSZ/PROT - or indeed the server can refuse to allow a
++PBSZ/PROT pair until the USER/PASS pair has happened).
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 16]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++   12.2. A standard data transfer without protection.
++
++           Client                                 Server
++  control          data                   data               control
++====================================================================
++
++                   socket()
++                   bind()
++  PORT w,x,y,z,a,b ----------------------------------------->
++      <----------------------------------------------------- 200
++  STOR file ------------------------------------------------>
++                                          socket()
++                                          bind()
++      <----------------------------------------------------- 150
++                   accept() <-----------  connect()
++                   write()   -----------> read()
++                   close()   -----------> close()
++      <----------------------------------------------------- 226
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 17]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++   12.3. A firewall-friendly data transfer without protection
++
++           Client                                 Server
++  control          data                   data               control
++====================================================================
++
++  PASV -------------------------------------------------------->
++                                          socket()
++                                          bind()
++      <------------------------------------------ 227 (w,x,y,z,a,b)
++                   socket()
++  STOR file --------------------------------------------------->
++                   connect()  ----------> accept()
++      <-------------------------------------------------------- 150
++                   write()    ----------> read()
++                   close()    ----------> close()
++      <-------------------------------------------------------- 226
++
++
++    Note: Implementors should be aware that then connect()/accept()
++    function is performed prior to the receipt of the reply from the
++    STOR command. This contrasts with situation when (non-firewall-
++    friendly) PORT is used prior to the STOR, and the accept()/connect()
++    is performed after the reply from the aforementioned STOR has been
++    dealt with.
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 18]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++   12.4. A standard data transfer with protection
++
++           Client                                 Server
++  control          data                   data               control
++====================================================================
++
++                   socket()
++                   bind()
++  PORT w,x,y,z,a,b -------------------------------------------->
++      <-------------------------------------------------------- 200
++  STOR file --------------------------------------------------->
++                                          socket()
++                                          bind()
++      <-------------------------------------------------------- 150
++                   accept()  <----------  connect()
++                   TLSneg()  <----------> TLSneg()
++                   TLSwrite() ----------> TLSread()
++                   close()    ----------> close()
++      <-------------------------------------------------------- 226
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 19]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++   12.5. A firewall-friendly data transfer with protection
++
++           Client                                 Server
++  control          data                   data               control
++====================================================================
++
++  PASV -------------------------------------------------------->
++                                          socket()
++                                          bind()
++      <------------------------------------------ 227 (w,x,y,z,a,b)
++                   socket()
++  STOR file --------------------------------------------------->
++                   connect()  ----------> accept()
++      <-------------------------------------------------------- 150
++                   TLSneg()   <---------> TLSneg()
++                   TLSwrite()  ---------> TLSread()
++                   close()     ---------> close()
++      <-------------------------------------------------------- 226
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 20]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++13. Implications of [FTP-EXT]
++
++   13.1. MLST and MLSD
++
++      MLST and MLSD are directory listing commands and should be treated
++      in the same manner as NLST and LIST for the purposes of this
++      document.
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 21]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++14. Discussion of the 'REIN' command
++
++   The 'REIN' command, defined in [RFC-959], allows the user to reset
++   the state of the FTP session.
++      REINITIALIZE (REIN)
++         This command terminates a USER, flushing all I/O and account
++         information, except to allow any transfer in progress to be
++         completed.  All parameters are reset to the default settings
++         and the control connection is left open.  This is identical to
++         the state in which a user finds himself immediately after the
++         control connection is opened.  A USER command may be expected
++         to follow.
++   The defined behaviour for TLS protected FTP sessons will depend on
++   the manner of session initialisation.
++   If the session has been explicity protected (see section 4.1) then
++   the TLS session(s) will be cleared and the control and data
++   connections revert to unprotected, clear communications.  It will be
++   acceptable to use cached TLS sessions for subsequent connections,
++   however a server should not mandate this.
++   If the session is implicitly protected  (see section 4.2) then the
++   control connection will continue to be protected using the exisiting
++   negotiated TLS session and the data connection will revert to being
++   implicitly protected, irrespective of any 'PROT' commands preceding
++   the 'REIN'.
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 22]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++15. Security Considerations
++
++   This entire document deals with security considerations related to
++   the File Transfer Protocol.
++
++   15.1. Verification of Authentication tokens
++
++      15.1.1. Server Certificates
++
++         Although it is entirely an implementation decision, it is
++         recommended that certificates used for server authentication of
++         the TLS session contain the server identification information
++         in a similar manner to those used for http servers.  (i.e.
++         SubjectCommonName or SubjectAltName of type dNSName).
++
++         Note that, if there is any future extensions to the FTP
++         protocol to allow multi-homed servers, then the interaction of
++         such a mechanism, the REIN commands and the certificate
++         presented by the server in the TLS handshake will need to be
++         considered carefully.
++
++      15.1.2. Client Certificates
++
++         - Deciding which client certificates to allow and defining
++         which fields define what authentication information is entirely
++         a server implementation issue.
++
++         - It is also server implementation issue to decide if the
++         authentication token presented for the data connection must
++         match the one used for the corresponding control connection.
++
++   15.2. Addressing FTP Security Considerations [RFC-2577]
++
++      15.2.1. Bounce Attack
++
++         A bounce attack should be harder in a secured FTP environment
++         because:
++
++            - The FTP server that is being used to initiate a false
++            connection will always be a 'server' in the TLS context.
++            Therefore, only services that act as 'clients' in the TLS
++            context could be vulnerable.  This would be a counter-
++            intuitive way to implement TLS on a service.
++
++            - The FTP server would detect that the authentication
++            credentials for the data connection are not the same as
++            those for the control connection, thus the server policies
++            could be set to drop the data connection.
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 23]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++            - Genuine users are less likely to initiate such attacks
++            when the authentication is strong and malicious users are
++            less likely to gain access to the FTP server if the
++            authentication is not easily subverted (password guessing,
++            network tracing, etc...)
++
++      15.2.2. Restricting Access
++
++         This document presents a strong mechanism for solving the issue
++         raised in this section.
++
++      15.2.3. Protecting Passwords
++
++         The twin solutions of strong authentication and data
++         confidentiality ensure that this is not an issue when TLS is
++         used to protect the control session.
++
++      15.2.4. Privacy
++
++         The TLS protocol ensures data confidentiality by encryption.
++         Privacy (e.g. access to download logs, user profile
++         information, etc...) is outside the scope of this document (and
++         [RFC-2577] presumably)
++
++      15.2.5. Protecting Usernames
++
++         This is not an issue when TLS is used as the primary
++         authentication mechanism.
++
++      15.2.6. Port Stealing
++
++         This proposal will do little for the Denial of Service element
++         of this section, however, strong authentication on the data
++         connection will prevent unauthorised connections retrieving or
++         submitting files.
++
++      15.2.7. Software-Base Security Problems
++
++         Nothing in this proposal will affect the discussion in this
++         section.
++
++
++
++
++16. IANA Considerations
++
++   {FTP-PORT} - The port assigned to the FTP control connection is 21.
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 24]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++   {FTP-TLSPORT} - A port to be assigned by the IANA for native TLS FTP
++   connections on the control socket.  This has been provisionally
++   reserved as port 990.
++
++   {TLS-PARM} - A parameter for the AUTH command to indicate that TLS is
++   required.  It is recommended that 'TLS', 'TLS-C', 'SSL' and 'TLS-P'
++   are acceptable, and mean the following :-
++
++       'TLS' or 'TLS-C' - the TLS protocol or the SSL protocol will be
++      negotiated on the control connection.  The default protection
++      setting for the Data connection is 'Clear'.
++
++       'SSL' or 'TLS-P' - the TLS protocol or the SSL protocol will be
++      negotiated on the control connection.  The default protection
++      setting for the Data connection is 'Private'.  This is primarily
++      for backward compatibility.
++
++         Note - [RFC-2228] states that these parameters are case-
++         insensitive.
++
++
++17. Network Management
++
++   NONE
++
++
++18. Internationalization
++
++   NONE
++
++
++19. Scalability & Limits
++
++   There are no issues other than those concerned with the ability of
++   the server to refuse to have a complete TLS negotiation for each and
++   every data connection, which will allow servers to retain throughput
++   whilst using cycles only when necessary.
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 25]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++20. Applicability
++
++   This mechanism is generally applicable as a mechanism for securing
++   the FTP protocol.  It is unlikely that anonymous FTP clients or
++   servers will require such security (although some might like the
++   authentication features without the privacy).
++
++
++21. Acknowledgements
++
++   o Netscape Communications Corporation for the original SSL protocol.
++
++   o Eric Young for the SSLeay libraries.
++
++   o University of California, Berkley for the original implementations
++   of FTP and ftpd on which the initial implementation of these
++   extensions were layered.
++
++   o IETF CAT working group.
++
++   o IETF TLS working group.
++
++   o IETF FTPEXT working group.
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 26]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++22. References
++
++   [RFC-959] J. Postel, "File Transfer Protocol"
++      RFC 959, October 1985.
++
++   [RFC-1579] Bellovin, S., "Firewall-Friendly FTP"
++      RFC 1579, February 1994.
++
++   [RFC-2222] J. Myers, "Simple Authentication and Security Layer"
++      RFC 2222, October 1997.
++
++   [RFC-2228] M. Horowitz, S. Lunt, "FTP Security Extensions"
++      RFC 2228, October 1997.
++
++   [RFC-2246] T. Dierks, C. Allen, "The TLS Protocol Version 1.0"
++      RFC 2246, January 1999.
++
++   [RFC-2389] P Hethmon, R.Elz, "Feature Negotiation Mechanism for the
++   File Transfer Protocol"
++      RFC 2389, August 1998.
++
++   [RFC-2487] P Hoffman, "SMTP Service Extension for Secure SMTP over
++   TLS"
++      RFC 2487, January 1999.
++
++   [RFC-2577] M Allman, S Ostermann "FTP Security Considerations"
++      RFC 2577, May 1999.
++
++   [FTP-EXT] R Elz, P Hethmon "Extensions to FTP"
++      draft-ietf-ftpext-mlst-07.txt, June 1999.
++
++   [SRA-FTP] "SRA - Secure RPC Authentication for TELNET and FTP Version
++   1.1"
++      file://ftp.funet.fi/security/login/telnet/doc/sra/sra.README
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 27]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++23. Authors' Contact Addresses
++
++Please send comments to Paul Ford-Hutchinson at the address below
++
++        Tim Hudson                  Paul Ford-Hutchinson
++           RSA Data Security           IBM UK Ltd
++             Australia Pty Ltd         PO Box 31
++                                       Birmingham Road
++                                       Warwick
++                                       United Kingdom
++  tel -   +61 7 3227 4444             +44 1926 462005
++  fax -   +61 7 3227 4400             +44 1926 496482
++email - tjh@rsasecurity.com.au    paulfordh@uk.ibm.com
++
++        Martin Carpenter            Eric Murray
++           Verisign Ltd                Wave Systems Inc.
++email -  mcarpenter@verisign.com    ericm@lne.com
++
++        Volker Wiegand
++           SuSE Linux
++email -  wiegand@suse.de
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 28]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++                               Appendices
++
++A.  Summary of [RFC-2246]
++
++   The TLS protocol was developed by the IETF TLS working group.  It is
++   based on the SSL protocol proposed by Netscape Communications
++   Corporation.  The structure of the start of a TLS session allows
++   negotiation of the level of the protocol to be used - in this way, a
++   client or server can simultaneously support TLS and SSL and negotiate
++   the most appropriate for the connection.
++
++   The TLS protocol defines three security mechanisms that may be used
++   (almost) independently.  They are Authentication, Integrity and
++   Privacy.  It is possible to have an Authenticated session with no
++   Privacy and with or without Integrity (useful for anonymous FTP
++   sites, or sites with pre-encrypted data). For example, sessions with
++   Authentication, Privacy and Integrity would be useful for control
++   connections over an insecure network and data connections
++   transferring confidential material.
++
++   The TLS protocol allows unauthenticated sessions; server
++   authentication or client and server authentication.  There is no
++   mechanism for authenticating a client without first authenticating
++   the server.
++
++   The basic mechanism of the TLS protocol is that (for an
++   Authenticated, Private session) asymmetric encryption is used to
++   authenticate clients and servers and exchange a session key for
++   symmetric encryption which is to be used for the rest of the session.
++
++   The structure of the TLS session initialisation is that the client
++   initiates the session with a 'ClientHello' message.  The server will
++   respond with a 'ServerHello' and the session negotiation will
++   continue.
++
++   The TLS protocol allows session caching which is achieved by the
++   client requesting that the server re-use a session context (Cipher
++   Suite and symmetric key) in the ClientHello message.  There is no
++   reason why a second connection could not request a 'cached' session
++   with the same context as an existing session.
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 29]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++B.  Summary of [RFC-2228]
++
++
++
++   Extensions to FTP
++
++   The FTP Security Extensions document has 8 new commands to enhance
++   the FTP protocol to allow negotiation of security and exchange of
++   security data.  Three of these commands (the AUTH, PBSZ and PROT
++   commands) are used by this document to allow an FTP client to
++   negotiate TLS with the server.  The other commands are not required.
++
++   i) AUTH
++
++      This command is a request by the client to use an authentication
++      and/or security mechanism.
++
++      The client will issue an 'AUTH <Mechanism>' command
++       which will be a request to the server to secure the control
++      connection using the TLS (or SSL) protocol. It also governs the
++      initial protection setting of the data channel (which may be
++      changed by a subsequent PROT command).
++
++   ii) ADAT
++
++      This command is used to transmit security data required by the
++      security mechanism agreed in a preceding AUTH command.
++      This document does not use the ADAT command.
++
++   iii) PROT
++
++      This command is used by the client to instruct the type of
++      security that is required on the Data connection.
++
++      The 'PROT C' command will mean that TLS should not be used to
++      secure the data connection; 'PROT P' means that TLS should be
++       used.  'PROT E' and 'PROT S' are not defined and generate
++       a '536' reply from the server.
++
++   iv) PBSZ
++
++      This command is used to negotiate the size of the buffer to be
++      used during secured data transfer.
++
++      The PBSZ command must be issued prior to the PROT command.  The
++      PBSZ command cannot be sent on an insecure control connection.
++      For FTP and TLS the only valid value for the parameter is '0', all
++      other values should receive a '200' reply with the text 'PBSZ=0'
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 30]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++      included.
++
++   v) CCC
++
++      This command is used to specify that the control channel no longer
++      requires protection.
++      This document does not use the CCC command.
++
++   vi) MIC
++
++      This command is used to send a normal FTP command with integrity
++      protection.
++      This document does not use the MIC command.
++
++   vii) CONF
++
++      This command is used to send a normal FTP command with
++      confidentiality protection (encrypted).
++      This document does not use the CONF command.
++
++   viii) ENC
++
++      This command is used to send a normal FTP command with
++      confidentiality and integrity protection.
++      This document does not use the ENC command.
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 31]
++
++
++
++
++
++Internet-Draft            Secure FTP using TLS      18th September, 2000
++
++
++Full Copyright Statement
++
++   Copyright (C) The Internet Society (2000).  All Rights Reserved.
++
++   This document and translations of it may be copied and furnished to
++   others, and derivative works that comment on or otherwise explain it
++   or assist in its implementation may be prepared, copied, published
++   and distributed, in whole or in part, without restriction of any
++   kind, provided that the above copyright notice and this paragraph are
++   included on all such copies and derivative works.  However, this
++   document itself may not be modified in any way, such as by removing
++   the copyright notice or references to the Internet Society or other
++   Internet organizations, except as needed for the purpose of
++   developing Internet standards in which case the procedures for
++   copyrights defined in the Internet Standards process must be
++   followed, or as required to translate it into languages other than
++   English.
++
++   The limited permissions granted above are perpetual and will not be
++   revoked by the Internet Society or its successors or assigns.
++
++   This document and the information contained herein is provided on an
++   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
++   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
++   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
++   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
++   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
++
++This document expires on 17th March, 2001
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand            [Page 32]
++
++
+diff -urN o/include/buildstamp.h s/include/buildstamp.h
+--- o/include/buildstamp.h	Thu Jan  1 01:00:00 1970
++++ s/include/buildstamp.h	Sun Oct 21 21:06:12 2001
+@@ -0,0 +1 @@
++#define BUILD_STAMP "do mrt 22 18:28:32 CET 2001"
--- proftpd-1.2.9.orig/debian/patches/09.mod_xfer.c.diff
+++ proftpd-1.2.9/debian/patches/09.mod_xfer.c.diff
@@ -0,0 +1,21 @@
+diff -urN proftpd-1.2.8/modules/mod_xfer.c proftpd-1.2.8-debian/modules/mod_xfer.c
+--- proftpd-1.2.8/modules/mod_xfer.c	2003-02-25 02:39:35.000000000 +0100
++++ proftpd-1.2.8-debian/modules/mod_xfer.c	2003-03-17 15:30:33.000000000 +0100
+@@ -1407,11 +1407,13 @@
+ 
+   fmode = file_mode(dir);
+ 
++  if(!fmode) {
++    pr_response_add_err(R_550,"%s: %s",cmd->arg,strerror(errno));
++    return ERROR(cmd);
++  }
++
+   if (!S_ISREG(fmode)) {
+-    if (!fmode)
+-      pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(errno));
+-    else
+-      pr_response_add_err(R_550, "%s: Not a regular file", cmd->arg);
++    pr_response_add_err(R_550,"%s: Not a regular file",cmd->arg);
+     return ERROR(cmd);
+   }
+ 
--- proftpd-1.2.9.orig/debian/patches/10.mod_unixpw.c.ldap.fix.diff
+++ proftpd-1.2.9/debian/patches/10.mod_unixpw.c.ldap.fix.diff
@@ -0,0 +1,27 @@
+diff -urN proftpd-1.2.8/modules/mod_auth_unix.c proftpd-1.2.8-debian/modules/mod_auth_unix.c
+--- proftpd-1.2.8/modules/mod_auth_unix.c	2003-02-18 18:55:22.000000000 +0100
++++ proftpd-1.2.8-debian/modules/mod_auth_unix.c	2003-03-17 15:35:17.000000000 +0100
+@@ -196,6 +196,11 @@
+ static struct passwd *p_getpwnam(const char *name) {
+   struct passwd *pw = NULL;
+ 
++  if (pwdfname!=NULL && !strncmp(pwdfname, "/etc/passwd", 12)) {
++    pw = getpwnam(name);
++   if (pw) return pw;
++  }
++
+   p_setpwent();
+   while ((pw = p_getpwent()) != NULL)
+     if (!strcmp(name,pw->pw_name))
+@@ -207,6 +212,11 @@
+ static struct passwd *p_getpwuid(uid_t uid) {
+   struct passwd *pw = NULL;
+ 
++  if (pwdfname!=NULL && !strncmp(pwdfname, "/etc/passwd", 12)) {
++    pw = getpwuid(uid);
++    if (pw) return pw;
++  }
++
+   p_setpwent();
+   while ((pw = p_getpwent()) != NULL)
+     if (pw->pw_uid == uid)
--- proftpd-1.2.9.orig/debian/patches/11.mod_auth.c.shell.null.segfault.diff
+++ proftpd-1.2.9/debian/patches/11.mod_auth.c.shell.null.segfault.diff
@@ -0,0 +1,11 @@
+--- proftpd-1.2.7/modules/mod_auth.c	2002-12-04 20:14:31.000000000 +0100
++++ proftpd-1.2.7/modules/mod_auth.c.debian	2003-01-27 12:32:58.000000000 +0100
+@@ -511,7 +511,7 @@
+     while (fgets(buf, sizeof(buf)-1, shellf)) {
+       buf[sizeof(buf)-1] = '\0'; CHOP(buf);
+ 
+-      if (!strcmp(shell, buf)) {
++      if (shell && !strcmp(shell, buf)) {
+         res = TRUE;
+         break;
+       }
--- proftpd-1.2.9.orig/debian/patches/12.ftpasswd.cracklib.location.diff
+++ proftpd-1.2.9/debian/patches/12.ftpasswd.cracklib.location.diff
@@ -0,0 +1,13 @@
+diff -urN proftpd-1.2.6/contrib/ftpasswd proftpd-1.2.6.new/contrib/ftpasswd
+--- proftpd-1.2.6/contrib/ftpasswd	2002-02-14 16:50:04.000000000 +0000
++++ proftpd-1.2.6.new/contrib/ftpasswd	2002-10-18 18:11:26.000000000 +0100
+@@ -37,7 +37,8 @@
+ my $default_passwd_file = "./ftpd.passwd";
+ my $default_group_file = "./ftpd.group";
+ my $shell_file = "/etc/shells";
+-my $default_cracklib_dict = "/usr/lib/cracklib_dict";
++#my $default_cracklib_dict = "/usr/lib/cracklib_dict";
++my $default_cracklib_dict = "/var/cache/cracklib";
+ my $cracklib_dict;
+ my $output_file;
+ my $version = "1.1.2";
--- proftpd-1.2.9.orig/debian/patches/13.mod_sql_mysql.c.diff
+++ proftpd-1.2.9/debian/patches/13.mod_sql_mysql.c.diff
@@ -0,0 +1,12 @@
+diff -urN proftpd-1.2.8+cvs20030620/contrib/mod_sql_mysql.c proftpd-1.2.8+cvs20030620-debian/contrib/mod_sql_mysql.c
+--- proftpd-1.2.8+cvs20030620/contrib/mod_sql_mysql.c	2003-06-03 14:28:18.000000000 +0200
++++ proftpd-1.2.8+cvs20030620-debian/contrib/mod_sql_mysql.c	2003-06-21 16:16:04.000000000 +0200
+@@ -134,7 +134,7 @@
+ 
+ #define _MYSQL_PORT "3306"
+ 
+-#include <mysql.h>
++#include <mysql/mysql.h>
+ #include "conf.h"
+ #include "../contrib/mod_sql.h"
+ 
--- proftpd-1.2.9.orig/debian/patches/14.quotatab_modules.diff
+++ proftpd-1.2.9/debian/patches/14.quotatab_modules.diff
@@ -0,0 +1,6594 @@
+diff -ruN proftpd-1.2.9-old/contrib/diskuse proftpd-1.2.9/contrib/diskuse
+--- proftpd-1.2.9-old/contrib/diskuse	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/diskuse	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,232 @@
++#!/usr/bin/perl
++# -------------------------------------------------------------------------
++# Copyright (C) 2002 TJ Saunders <tj@castaglia.org>
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
++#
++#  $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $
++#
++# -------------------------------------------------------------------------
++
++use strict;
++
++use Fcntl;
++use File::Basename qw(basename);
++use Getopt::Long;
++
++my $program = basename($0);
++my %opts = {};
++
++GetOptions(\%opts, 'G', 'K', 'M', 'dir-tally', 'group=s', 'help',
++  'user=s', 'verbose');
++
++my $verbose = 0;
++my $user_id = -1;
++my $group_id = -1;
++
++usage() if defined($opts{'help'});
++
++if (length(@ARGV) < 1) {
++  print STDOUT "$program: wrong number of parameters\n";
++  exit 0;
++}
++
++unless (defined($opts{'user'}) || defined($opts{'group'})) {
++  print STDOUT "$program: missing required --group or --user option\n";
++  exit 0;
++}
++
++if (defined($opts{'user'})) {
++  $user_id = getpwnam($opts{'user'}) or
++    die "$program: no such user: $opts{'user'}\n";
++}
++
++if (defined($opts{'group'})) {
++  $group_id = getgrnam($opts{'group'}) or
++    die "$program: no such group: $opts{'group'}\n";
++}
++
++$verbose = 1 if (defined($opts{'verbose'}));
++
++my ($total_bytes, $total_files);
++
++foreach my $dir (@ARGV) {
++  my ($bytes, $files) = get_dir_disk_use($dir);
++
++  $total_bytes += $bytes;
++  $total_files += $files;
++}
++
++my $byte_units = "bytes";
++
++if (defined($opts{'K'})) {
++  $total_bytes /= 1024;
++  $byte_units = "KB";
++
++} elsif (defined($opts{'M'})) {
++  $total_bytes /= (1024 * 1024);
++  $byte_units = "MB";
++
++} elsif (defined($opts{'G'})) {
++  $total_bytes /= (1024 * 1024 * 1024);
++  $byte_units = "GB";
++}
++
++my $file_units = "files";
++$file_units = "file" if ($total_files == 1);
++
++print STDOUT "$program: $total_bytes $byte_units in $total_files $file_units\n";
++
++# done
++exit 0;
++
++# --------------------------------------------------------------------------
++sub get_dir_disk_use {
++  my ($dir) = @_;
++
++  print STDOUT "$program: examining directory '$dir'\n" if $verbose;
++
++  my @subdirs = ();
++  my $nbytes = 0;
++  my $nfiles = 0;
++
++  unless (opendir(DIR, $dir)) {
++    print STDERR "$program: unable to open directory '$dir': $!\n";
++    return (0, 0);
++  }
++
++  my @files = readdir(DIR);
++  close(DIR);
++
++  foreach my $file (@files) {
++    my ($mode, $uid, $gid, $size) = (lstat("$dir/$file"))[2, 4, 5, 7];
++
++    # Is this entry a regular file, or a directory?
++    unless (-f "$dir/$file" || (-l "$dir/$file" && !-f "$dir/$file") || -d "$dir/$file") {
++      print STDOUT "$program: skipping '$dir/$file': not a file or directory\n" if $verbose;
++      next;
++    }
++
++    # Does this file match the given user/group ownership?
++    if ($user_id != -1 && $group_id != -1) {
++
++      if ($uid == $user_id && $gid == $group_id) {
++
++        if (defined($opts{'dir-tally'}) && $file eq ".") {
++          $nbytes += $size;
++          $nfiles++;
++ 
++        } elsif (! -d "$dir/$file") {
++          $nbytes += $size;
++          $nfiles++;
++        }
++
++      } else {
++        print STDOUT "$program: '$file' does not match UID $user_id, GID $group_id\n" if $verbose;
++      }
++
++    } elsif ($user_id != -1) {
++
++      if ($uid == $user_id) {
++
++        if (defined($opts{'dir-tally'}) && $file eq ".") {
++          $nbytes += $size;
++          $nfiles++;
++
++        } elsif (! -d "$dir/$file") {
++          $nbytes += $size;
++          $nfiles++;
++        }
++
++      } else {
++        print STDOUT "$program: '$file' does not match UID $user_id\n" if $verbose;
++      }
++
++    } elsif ($group_id != -1) {
++
++      if ($gid == $group_id) {
++
++        if (defined($opts{'dir-tally'}) && $file eq ".") {
++          $nbytes += $size;
++          $nfiles++;
++
++        } elsif (! -d "$dir/$file") {
++          $nbytes += $size;
++          $nfiles++;
++        }
++
++      } else {
++        print STDOUT "$program: '$file' does not match GID $group_id\n" if $verbose;
++      }
++    }
++
++    # Is this entry a directory?  If so, add it to the subdir list.
++    if (-d "$dir/$file") {
++
++      # Skip dot directories
++      push(@subdirs, "$dir/$file") unless ($file eq "." || $file eq "..");
++    }
++  }
++
++  # Now, recurse through the directory's subdirectories
++  foreach my $subdir (@subdirs) {
++    my ($bytecount, $filecount) = get_dir_disk_use($subdir);
++    $nbytes += $bytecount;
++    $nfiles += $filecount;
++  }
++
++  return ($nbytes, $nfiles);
++}
++
++# --------------------------------------------------------------------------
++sub usage {
++
++  print STDOUT <<END_OF_USAGE;
++
++usage: $program [options] dir1 dir2 ... dirN
++
++ $program calculates the amount of disk space used underneath the given
++ directory (or directories).  Either a --group or a --user option is required.
++ If both are used, only files whose ownership matches both the given name and
++ group will be added to the disk usage sum.
++
++ Options:
++
++  --G          Display the number of bytes in units of gigabytes.  The default
++               number is in bytes.
++
++  --K          Display the number of bytes in units of kilobytes.  The default
++               number is in bytes.
++
++  --M          Display the number of bytes in units of megabytes.  The default
++               number is in bytes.
++
++  --dir-tally  Count the size of directories toward the disk usage sum.  The
++               default is to consider regular files only.
++
++  --group      Count files owned by this group in the disk usage sum.
++
++  --help       Display this message.
++
++  --user       Count files owned by this user in the disk usage sum.
++
++  --verbose    Display diagnostic output while $program is running.
++
++END_OF_USAGE
++
++  exit 0;
++}
++
++# --------------------------------------------------------------------------
+diff -ruN proftpd-1.2.9-old/contrib/diskuse.html proftpd-1.2.9/contrib/diskuse.html
+--- proftpd-1.2.9-old/contrib/diskuse.html	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/diskuse.html	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,103 @@
++<!-- $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $ -->
++<!-- $Source: /cvsroot/pkg-proftpd/debian/patches/14.quotatab_modules.diff,v $ -->
++
++<html>
++<head>
++<title>diskuse: tool for ProFTPD mod_quotatab</title>
++</head>
++
++<body bgcolor=white>
++
++<hr><br>
++<center>
++<h2><b><code>diskuse</code>: tool for ProFTPD module <code>mod_quotatab</code></b></h2>
++</center>
++<hr><br>
++
++This program is distributed with the
++<a href="./mod_quotatab.html"><code>mod_quotatab</code></a> module for
++ProFTPD 1.2.  It is used to calculate the amount of disk space currently
++used by a given user and/or group.
++
++<p>
++The most current version of <code>diskuse</code> can be found at:
++<pre>
++  <a href="http://www.castaglia.org/proftpd/">http://www.castaglia.org/proftpd/</a>
++</pre>
++
++<h2>Author</h2>
++<p>
++Please contact TJ Saunders &lt;tj <i>at</i> castaglia.org&gt; with any
++questions, concerns, or suggestions regarding this program.
++
++<p>
++<hr><br>
++<h2><a name="Usage">Usage</a></h2>
++The following describes the common usage of the <code>diskuse</code> tool.
++The options supported are described in more detail
++<a href="#Options">later</a>.
++
++<p>
++Usage of this tool is fairly straightforward: choose the directory (or
++directories) to scan, and the user or group for whom you wish to calculate
++disk usage:
++<pre>
++  diskuse /home /usr /tmp --user=bob
++</pre>
++The <code>--K</code>, <code>--M</code>, and <code>--G</code> options can be
++used to display the disk usage calculated in kilobytes, megabytes, or
++gigabytes, respectively.
++
++<p>
++<hr><br>
++<h2><a name="Options">Options</a></h2>
++The following is the output from running <code>diskuse --help</code>:
++<pre>
++usage: diskuse [options] dir1 dir2 ... dirN
++
++ diskuse calculates the amount of disk space used underneath the given
++ directory (or directories).  Either a --group or a --user option is required.
++ If both are used, only files whose ownership matches both the given name and
++ group will be added to the disk usage sum.
++
++ Options:
++
++  --G          Display the number of bytes in units of gigabytes.  The default
++               number is in bytes.
++
++  --K          Display the number of bytes in units of kilobytes.  The default
++               number is in bytes.
++
++  --M          Display the number of bytes in units of megabytes.  The default
++               number is in bytes.
++
++  --dir-tally  Count the size of directories toward the disk usage sum.  The
++               default is to consider regular files only.
++
++  --group      Count files owned by this group in the disk usage sum.
++
++  --help       Display this message.
++
++  --user       Count files owned by this user in the disk usage sum.
++
++  --verbose    Display diagnostic output while diskuse is running.
++</pre>
++
++<p>
++<hr><br>
++
++Author: <i>$Author: frankie $</i><br>
++Last Updated: <i>$Date: 2003/11/17 15:30:12 $</i><br>
++
++<br><hr>
++
++<font size=2><b><i>
++&copy; Copyright 2000-2002 TJ Saunders<br>
++ All Rights Reserved<br>
++</i></b></font>
++
++<hr><br>
++
++</body>
++</html>
++
+diff -ruN proftpd-1.2.9-old/contrib/ftpquota proftpd-1.2.9/contrib/ftpquota
+--- proftpd-1.2.9-old/contrib/ftpquota	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/ftpquota	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,1071 @@
++#!/usr/bin/perl
++# -------------------------------------------------------------------------
++# Copyright (C) 2000-2002 TJ Saunders <tj@castaglia.org>
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
++#
++#  $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $
++#
++# -------------------------------------------------------------------------
++
++use strict;
++
++use Fcntl qw(:flock);
++use File::Basename qw(basename);
++use Getopt::Long;
++use IO::Seekable;
++
++my $program = basename($0);
++my $verbose = 0;
++
++# These formats are highly dependent on the quota record definitions in
++# mod_quotatab.h. Should those definitions change, these format strings will
++# need to be adjusted accordingly.
++my $limit_format = "Z81I1C1I1d3L3";
++my $tally_format = "Z81I1d3L3";
++
++# These sizes are determined by the sizes of the quota_limit_t and
++# quota_tally_t structs (NOT using C's sizeof(), though -- alignment issues)
++my $limit_reclen = 126;
++my $tally_reclen = 121;
++
++# the values for these variables is similarly dependent on the actual
++# values defined in mod_quotatab.h
++my $ALL_QUOTA = 10;
++my $USER_QUOTA = 20;
++my $GROUP_QUOTA = 30;
++my $CLASS_QUOTA = 40;
++
++my $HARD_LIMIT = 1;
++my $SOFT_LIMIT = 2;
++
++my $LIMIT_TABLE = 100;
++my $TALLY_TABLE = 101;
++
++my $LIMIT_MAGIC = hex(7626);
++my $TALLY_MAGIC = hex(7644);
++
++my $default_limit_table = "./ftpquota.limittab";
++my $default_tally_table = "./ftpquota.tallytab";
++my $default_name = "";
++my $default_quota_type = $ALL_QUOTA;
++my $default_limit_type = $HARD_LIMIT;
++my $default_per_session = 0;
++my $default_bytes_in = -1.0;
++my $default_bytes_out = -1.0;
++my $default_bytes_xfer = -1.0;
++my $default_files_in = 0;
++my $default_files_out = 0;
++my $default_files_xfer = 0;
++
++my $byte_units = "byte";
++
++my %opts = ();
++GetOptions(\%opts, 'Bu=n', 'bytes-upload=n', 'Bd=n', 'bytes-download=n',
++  'Bt=n', 'bytes-xfer=n', 'Fu=n', 'files-upload=n', 'Fd=n', 'files-download=n',
++  'Ft=n', 'files-xfer', 'L|limit-type=s', 'N|name=s', 'P|per-session',
++  'Q|quota-type=s', 'help', 'table-path=s', 'units=s', 'verbose', 'type=s',
++  'add-record', 'create-table', 'delete-record', 'show-records',
++  'update-record');
++
++usage() if (defined($opts{'help'}));
++
++my ($table, $table_type);
++my %record = ();
++
++parse_options();
++
++if (defined($opts{'add-record'})) {
++  open_table();
++  wlock_table();
++  add_record();
++  unlock_table();
++  close_table();
++  exit 0;
++}
++
++if (defined($opts{'create-table'})) {
++  open_table();
++  close_table();
++  exit 0;
++}
++
++if (defined($opts{'delete-record'})) {
++  open_table();
++  wlock_table();
++  delete_record();
++  unlock_table();
++  close_table();
++  exit 0;
++}
++
++if (defined($opts{'show-records'})) {
++  open_table();
++  rlock_table();
++  print_table();
++  unlock_table();
++  close_table();
++  exit 0;
++}
++
++if (defined($opts{'update-record'})) {
++  open_table();
++  wlock_table();
++  update_record();
++  unlock_table();
++  close_table();
++  exit 0;
++}
++
++# if no operations have been specified, note this and exit
++print STDOUT "$program: no operations to perform, exiting\n";
++
++exit;
++
++# -------------------------------------------------------------------------
++sub add_record {
++  print STDOUT "$program: adding record\n" if $verbose;
++
++  my $add_quota_type;
++
++  # first, find the matching record.  Note that this option requires
++  # both --name and --quota-type
++
++  if (!defined($opts{'Q'})) {
++    print STDOUT "$program: --add-record requires --quota-type option\n";
++    exit(1);
++
++  } else {
++    $add_quota_type = get_quota_type(quota_type => $opts{'Q'});
++  }
++
++  if ($add_quota_type != $ALL_QUOTA) {
++    if (!defined($opts{'N'})) {
++      print STDOUT "$program: --add-record requires --name option\n";
++      exit(1);
++    }
++  }
++
++  # now, see if there is a matching record already in the table
++  if (find_record(name => $opts{'N'}, quota_type => $add_quota_type)) {
++    print STDOUT "$program: unable to add record: matching record already exists\n";
++    exit(1);
++  }
++
++  # move to the end of the table, and write the new record
++  set_table_position(0, SEEK_END);
++
++  my $formatted_record;
++
++  if ($table_type == $LIMIT_TABLE) {
++    $formatted_record = pack($limit_format,
++      $record{'name'}, $record{'quota_type'},
++      $record{'per_session'}, $record{'limit_type'},
++      $record{'bytes_in'}, $record{'bytes_out'}, $record{'bytes_xfer'},
++      $record{'files_in'}, $record{'files_out'}, $record{'files_xfer'});
++
++  } elsif ($table_type == $TALLY_TABLE) {
++
++    $formatted_record = pack($tally_format,
++      $record{'name'}, $record{'quota_type'},
++      $record{'bytes_in'}, $record{'bytes_out'}, $record{'bytes_xfer'},
++      $record{'files_in'}, $record{'files_out'}, $record{'files_xfer'});
++  }
++
++  write_record(record => $formatted_record);
++}
++
++# -------------------------------------------------------------------------
++sub check_table {
++  my $data;
++
++  print STDOUT "$program: checking table '$table'\n" if $verbose;
++
++  sysread TABLE, $data, 4;
++
++  # unpack what was read in
++  my ($magic) = unpack("L", $data);
++
++  if ($table_type == $LIMIT_TABLE) {
++
++    if ($magic != $LIMIT_MAGIC) {
++      print STDOUT "$program: bad header: $magic != $LIMIT_MAGIC\n" if
++        $verbose;
++      die "$program: mismatched table header, exiting\n";
++
++    } else {
++      print STDOUT "$program: table has correct header\n" if $verbose;
++    }
++
++  } elsif ($table_type == $TALLY_TABLE) {
++
++    if ($magic != $TALLY_MAGIC) {
++      print STDOUT "$program: bad header magics: $magic != $TALLY_MAGIC\n" if
++        $verbose;
++      die "$program: mismatched table header, exiting\n";
++
++    } else {
++     print STDOUT "$program: table has correct header\n" if $verbose;
++    }
++  }
++}
++
++# -------------------------------------------------------------------------
++sub close_table {
++  print STDOUT "$program: closing table '$table'\n" if $verbose;
++
++  close(TABLE);
++}
++
++# -------------------------------------------------------------------------
++sub delete_record {
++  print STDOUT "$program: deleting record\n" if $verbose;
++
++  my $delete_quota_type;
++
++  # first, find the matching record.  Note that this option requires
++  # both --name and --quota-type
++
++  if (!defined($opts{'Q'})) {
++    print STDOUT "$program: --delete-record requires --quota-type option\n";
++    exit(1);
++
++  } else {
++    $delete_quota_type = get_quota_type(quota_type => $opts{'Q'});
++  }
++
++  if ($delete_quota_type != $ALL_QUOTA) {
++    if (!defined($opts{'N'})) {
++      print STDOUT "$program: --delete-record requires --name option\n";
++      exit(1);
++    }
++  }
++
++  # now, find the matching record in the table
++  unless (find_record(name => $opts{'N'}, quota_type => $delete_quota_type)) {
++    print STDOUT "$program: unable to delete record: no match found\n";
++    exit(1);
++  }
++  rewind_record();
++
++  print STDOUT "$program: modifying table '$table'\n" if $verbose;
++
++  # first, record the current file position
++  my $position = get_table_position();
++
++  # next, advance past this record to be deleted, and read in the
++  # rest of the file
++
++  seek_record(1);
++
++  my ($nrecords, @records) = read_table();
++
++  # Rewind the previous position, and "delete" that record by simply
++  # overwriting it.  Note that this approach works for file tables --
++  # tables in other formats, such as SQL, will have a much easier time
++  # deleting a quota record.
++
++  set_table_position($position, SEEK_SET);
++
++  if ($nrecords > 0) {
++    for (my $i = 0; $i < $nrecords; $i++) {
++      write_record(record => $records[$i]);
++    }
++
++    # Truncate the table
++    truncate_table(len => get_table_position() - 4);
++
++  } else {
++
++    # Truncate the table
++    truncate_table(len => $position - 4);
++  }
++
++  # done
++  exit(0);
++}
++
++# -------------------------------------------------------------------------
++sub find_record {
++  my %args = @_;
++  my $nrecords = 0;
++ 
++  my $search_name = $args{'name'};
++  my $search_quota_type = $args{'quota_type'};
++
++  while (my $record = read_record()) {
++    $nrecords++;
++
++    my ($name, $quota_type, @junk);
++
++    # unpack the binary record structure
++    if ($table_type == $LIMIT_TABLE) {
++      ($name, $quota_type, @junk) = unpack($limit_format, $record);
++
++    } elsif ($table_type == $TALLY_TABLE) {
++      ($name, $quota_type, @junk) = unpack($tally_format, $record);
++    }
++
++    # remove any NULs from $name
++    $name =~ s/(\0*)?//;
++
++    if ($search_quota_type == $ALL_QUOTA and
++        $quota_type == $ALL_QUOTA) {
++      return $record;
++
++    } elsif ($name eq $search_name and
++             $quota_type == $search_quota_type) {
++      return $record;
++    }
++  }
++
++  return undef;
++}
++
++# -------------------------------------------------------------------------
++sub get_display_bytes {
++  my %args = @_;
++
++  my $bytes = $args{'bytes'};
++
++  if ($byte_units eq "byte") {
++    # no calculation necessary
++
++    unless ($bytes eq "unlimited") {
++      return sprintf "bytes:\t%.2f", $bytes;
++    } else {
++      return sprintf "bytes:\tunlimited";
++    }
++
++  } elsif ($byte_units eq "kilo") {
++    # divide by 1024.0
++    my $adj_bytes = $bytes / 1024.0;
++
++    unless ($bytes eq "unlimited") {
++      return sprintf "Kb:\t%.2f", $adj_bytes;
++    } else {
++      return sprintf "Kb:\tunlimited";
++    }
++
++  } elsif ($byte_units eq "mega") {
++    # divide by 1024.0 * 1024.0
++    my $adj_bytes = $bytes / (1024.0 * 1024.0);
++
++    unless ($bytes eq "unlimited") {
++      return sprintf "Mb:\t%.2f", $adj_bytes;
++    } else {
++      return sprintf "Mb:\tunlimited";
++    }
++
++  } elsif ($byte_units eq "giga") {
++    # divide by 1024.0 * 1024.0 * 1024.0
++    my $adj_bytes = $bytes / (1024.0 * 1024.0 * 1024.0);
++
++    unless ($bytes eq "unlimited") {
++      return sprintf "Gb:\t%.2f", $adj_bytes;
++    } else {
++      return sprintf "Gb:\tunlimited";
++    }
++  }
++}
++
++# -------------------------------------------------------------------------
++sub get_quota_type {
++  my %args = @_;
++
++  my $quota_type = $args{'quota_type'};
++
++  # given the command-line --quote-type option value, return the
++  # corresponding numeric value
++
++  if ($quota_type eq "all") {
++    return $ALL_QUOTA;
++
++  } elsif ($quota_type eq "user") {
++    return $USER_QUOTA;
++
++  } elsif ($quota_type eq "group") {
++    return $GROUP_QUOTA;
++
++  } elsif ($quota_type eq "class") {
++    return $CLASS_QUOTA;
++
++  } else {
++    print STDERR "$program: unknown quota type: $quota_type\n";
++    exit(1);
++  }
++}
++
++# -------------------------------------------------------------------------
++sub get_table_position {
++  return sysseek(TABLE, 0, 1);
++}
++
++# -------------------------------------------------------------------------
++sub open_table {
++
++  # if the table doesn't exist, create it if requested
++  if (defined($opts{'create-table'})) {
++    die "$program: cannot create existing table\n" if (-e $table);
++
++    print STDOUT "$program: creating new table\n" if $verbose;
++
++    open(TABLE, "> $table") or
++      die "$program: unable to create $table: $!\n";
++
++    print STDOUT "$program: writing header for new table\n" if $verbose;
++
++    # write out the identifying header for the table type
++    if ($table_type == $LIMIT_TABLE) {
++      syswrite TABLE, pack("L", $LIMIT_MAGIC);
++
++    } elsif ($table_type == $TALLY_TABLE) {
++      syswrite TABLE, pack("L", $TALLY_MAGIC);
++    }
++
++  } else {
++
++    print STDOUT "$program: opening table '$table'\n" if $verbose;
++
++    # NOTE: BUG -- this should NOT be +<.  Open using <, for reading the
++    # magic, then re-open in append mode if need be.
++
++    open(TABLE, "+< $table") or
++      die "$program: unable to open $table: $!\n";
++
++    check_table();
++  }
++}
++
++# -------------------------------------------------------------------------
++sub parse_options {
++
++  $verbose = 1 if (defined($opts{'verbose'}));
++
++  if (defined($opts{'type'})) {
++
++    die "$program: unknown table type: $opts{'type'}\n" if
++      ($opts{'type'} ne 'limit' and $opts{'type'} ne 'tally');
++
++    if ($opts{'type'} eq 'limit') {
++      $table_type = $LIMIT_TABLE;
++      $table = $default_limit_table;
++    }
++
++    if ($opts{'type'} eq 'tally') {
++      $table_type = $TALLY_TABLE;
++      $table = $default_tally_table;
++    }
++
++  } else {
++    die "$program: missing required --type parameter\n";
++  }
++
++  $table = $opts{'table-path'} if (defined($opts{'table-path'}));
++
++  if (defined($opts{'N'})) {
++    $record{'name'} = $opts{'N'};
++
++    # make sure the name is not too long
++    die "$program: name is too long, must be less than 80 characters\n"
++      if (length($record{'name'}) >= 80);
++
++  } else {
++    $record{'name'} = $default_name;
++  }
++
++  if (defined($opts{'P'})) {
++    $record{'per_session'} = 1;
++
++  } else {
++    $record{'per_session'} = $default_per_session;
++  }
++
++  if (defined($opts{'Q'})) {
++    if ($opts{'Q'} eq "all") {
++      $record{'quota_type'} = $ALL_QUOTA;
++
++    } elsif ($opts{'Q'} eq "user") {
++      $record{'quota_type'} = $USER_QUOTA;
++
++      # it's an error if there's no -N option present as well
++      unless (defined($opts{'N'})) {
++        print STDOUT "$program: quota type \"user\" requires --name option\n";
++        exit(1);
++      }
++
++    } elsif ($opts{'Q'} eq "group") {
++      $record{'quota_type'} = $GROUP_QUOTA;
++
++      # it's an error if there's no -N option present as well
++      unless (defined($opts{'N'})) {
++        print STDOUT "$program: quota type \"group\" requires --name option\n";
++        exit(1);
++      }
++
++    } elsif ($opts{'Q'} eq "class") {
++      $record{'quota_type'} = $CLASS_QUOTA;
++
++      # it's an error if there's no -N option present as well
++      unless (defined($opts{'N'})) {
++        print STDOUT "$program: quota type \"class\" requires --name option\n";
++        exit(1);
++      }
++
++    } else {
++      print STDERR "$program: unknown quota type: $opts{'Q'}\n";
++      exit(1);
++    }
++
++  } else {
++    $record{'quota_type'} = $ALL_QUOTA;
++  }
++
++  if (defined($opts{'L'})) {
++    if ($opts{'L'} eq "hard") {
++      $record{'limit_type'} = $HARD_LIMIT;
++
++    } elsif ($opts{'L'} eq "soft") {
++      $record{'limit_type'} = $SOFT_LIMIT;
++ 
++    } else {
++      print STDERR "$program: unknown limit type: $opts{'L'}\n";
++      exit(1);
++    }
++
++  } else {
++    $record{'limit_type'} = $HARD_LIMIT;
++  }
++
++  # process the --units option, if present
++  if (defined($opts{'units'})) {
++
++    if ($opts{'units'} eq "B" or $opts{'units'} eq "byte") {
++      $byte_units = "byte";
++
++    } elsif ($opts{'units'} eq "Kb" or $opts{'units'} eq "kilo") {
++      $byte_units = "kilo";
++
++    } elsif ($opts{'units'} eq "Mb" or $opts{'units'} eq "mega") {
++      $byte_units = "mega";
++
++    } elsif ($opts{'units'} eq "Gb" or $opts{'units'} eq "giga") {
++      $byte_units = "giga";
++
++    } else {
++      print STDERR "$program: unknown unit type: $opts{'units'}\n";
++      exit(1);
++    }
++  }
++
++  if (defined($opts{'Bu'}) || defined($opts{'bytes-upload'})) {
++    if (defined($opts{'Bu'}) && defined($opts{'bytes-upload'})) {
++      print STDOUT "$program: do not use both --Bu and --bytes-upload options\n";
++      exit(1);
++    }
++
++    $record{'bytes_in'} = $opts{'Bu'} if (defined($opts{'Bu'}));
++    $record{'bytes_in'} = $opts{'bytes-upload'} if
++      (defined($opts{'bytes-upload'}));
++
++    if ($record{'bytes_in'} != $default_bytes_in) {
++      if ($byte_units eq "kilo") {
++        $record{'bytes_in'} = $record{'bytes_in'} * 1024.0;
++
++      } elsif ($byte_units eq "mega") {
++        $record{'bytes_in'} = $record{'bytes_in'} * 1024.0 * 1024.0;
++
++      } elsif ($byte_units eq "giga") {
++        $record{'bytes_in'} = $record{'bytes_in'} * 1024.0 * 1024.0 * 1024.0;
++      }
++    }
++
++  } else {
++
++    $record{'bytes_in'} = $default_bytes_in if ($table_type == $LIMIT_TABLE);
++    $record{'bytes_in'} = 0.0 if ($table_type == $TALLY_TABLE);
++  }
++
++  if (defined($opts{'Bd'}) || defined($opts{'bytes-download'})) {
++    if (defined($opts{'Bd'}) && defined($opts{'bytes-download'})) {
++      print STDOUT "$program: do not use both --Bd and --bytes-download options\n";
++      exit(1);
++    }
++
++    $record{'bytes_out'} = $opts{'Bd'} if (defined($opts{'Bd'}));
++    $record{'bytes_out'} = $opts{'bytes-download'} if
++      (defined($opts{'bytes-download'}));
++
++    if ($record{'bytes_out'} != $default_bytes_out) {
++      if ($byte_units eq "kilo") {
++        $record{'bytes_out'} = $record{'bytes_out'} * 1024.0;
++
++      } elsif ($byte_units eq "mega") {
++        $record{'bytes_out'} = $record{'bytes_out'} * 1024.0 * 1024.0;
++
++      } elsif ($byte_units eq "giga") {
++        $record{'bytes_out'} = $record{'bytes_out'} * 1024.0 * 1024.0 * 1024.0;
++      }
++    }
++
++  } else {
++
++    $record{'bytes_out'} = $default_bytes_out if ($table_type == $LIMIT_TABLE);
++    $record{'bytes_out'} = 0.0 if ($table_type == $TALLY_TABLE);
++  }
++
++  if (defined($opts{'Bx'}) || defined($opts{'bytes-xfer'})) {
++    if (defined($opts{'Bx'}) && defined($opts{'bytes-xfer'})) {
++      print STDOUT "$program: do not use both --Bx and --bytes-xfer options\n";
++      exit(1);
++    }
++
++    $record{'bytes_xfer'} = $opts{'Bx'} if (defined($opts{'Bx'}));
++    $record{'bytes_xfer'} = $opts{'bytes-xfer'} if
++      (defined($opts{'bytes-xfer'}));
++
++    if ($record{'bytes_xfer'} != $default_bytes_xfer) {
++      if ($byte_units eq "kilo") {
++        $record{'bytes_xfer'} = $record{'bytes_xfer'} * 1024.0;
++
++      } elsif ($byte_units eq "mega") {
++        $record{'bytes_xfer'} = $record{'bytes_xfer'} * 1024.0 * 1024.0;
++
++      } elsif ($byte_units eq "giga") {
++        $record{'bytes_xfer'} =
++          $record{'bytes_xfer'} * 1024.0 * 1024.0 * 1024.0;
++      }
++    }
++
++  } else {
++
++    $record{'bytes_xfer'} = $default_bytes_xfer if
++      ($table_type == $LIMIT_TABLE);
++    $record{'bytes_xfer'} = 0.0 if ($table_type == $TALLY_TABLE);
++  }
++
++  if (defined($opts{'Fu'}) || defined($opts{'files-upload'})) {
++    if (defined($opts{'Fu'}) && defined($opts{'files-upload'})) {
++      print STDOUT "$program: do not use both --Fu and --files-upload options\n";
++      exit(1);
++    }
++
++    $record{'files_in'} = $opts{'Fu'} if (defined($opts{'Fu'}));
++    $record{'files_in'} = $opts{'files-upload'} if
++      (defined($opts{'files-upload'}));
++
++  } else {
++
++    $record{'files_in'} = $default_files_in if ($table_type == $LIMIT_TABLE);
++    $record{'files_in'} = 0 if ($table_type == $TALLY_TABLE);
++  }
++
++  if (defined($opts{'Fd'}) || defined($opts{'files-download'})) {
++    if (defined($opts{'Fd'}) && defined($opts{'files-download'})) {
++      print STDOUT "$program: do not use both --Fd and --files-download options\n";
++      exit(1);
++    }
++
++    $record{'files_out'} = $opts{'Fd'} if (defined($opts{'Fd'}));
++    $record{'files_out'} = $opts{'files-download'} if
++      (defined($opts{'files-download'}));
++
++  } else {
++
++    $record{'files_out'} = $default_files_out if ($table_type == $LIMIT_TABLE);
++    $record{'files_out'} = 0 if ($table_type == $TALLY_TABLE);
++  }
++
++  if (defined($opts{'Fx'}) || defined($opts{'files-xfer'})) {
++    if (defined($opts{'Fx'}) && defined($opts{'files-xfer'})) {
++      print STDOUT "$program: do not use both --Fx and --files-xfer options\n";
++      exit(1);
++    }
++
++    $record{'files_xfer'} = $opts{'Fx'} if (defined($opts{'Fx'}));
++    $record{'files_xfer'} = $opts{'files-xfer'} if
++      (defined($opts{'files-xfer'}));
++
++  } else {
++
++    $record{'files_xfer'} = $default_files_xfer if
++      ($table_type == $LIMIT_TABLE);
++    $record{'files_xfer'} = 0 if ($table_type == $TALLY_TABLE);
++  }
++}
++
++# -------------------------------------------------------------------------
++sub print_record {
++  my %args = @_;
++
++  my $record = $args{'record'};
++
++  my ($name, $quota_type, $per_session, $limit_type, $bytes_in, $bytes_out,
++    $bytes_xfer, $files_in, $files_out, $files_xfer);
++
++  if ($table_type == $LIMIT_TABLE) {
++    ($name, $quota_type, $per_session, $limit_type, $bytes_in, $bytes_out,
++     $bytes_xfer, $files_in, $files_out, $files_xfer) = unpack($limit_format,
++     $record);
++
++  } elsif ($table_type == $TALLY_TABLE) {
++
++    ($name, $quota_type, $bytes_in, $bytes_out, $bytes_xfer,
++     $files_in, $files_out, $files_xfer) = unpack($tally_format, $record);
++  }
++
++
++  # make the symbolic values legible
++  $quota_type = "All" if ($quota_type == $ALL_QUOTA);
++  $quota_type = "User" if ($quota_type == $USER_QUOTA);
++  $quota_type = "Group" if ($quota_type == $GROUP_QUOTA);
++  $quota_type = "Class" if ($quota_type == $CLASS_QUOTA);
++
++  if ($table_type == $LIMIT_TABLE) {
++    $limit_type = "Hard" if ($limit_type == $HARD_LIMIT);
++    $limit_type = "Soft" if ($limit_type == $SOFT_LIMIT);
++
++    if ($per_session eq 1) {
++      $per_session = "True";
++
++    } else {
++      $per_session = "False";
++    }
++  }
++
++  # print "unlimited" if quota is unlimited, but only for limit tables
++  if ($table_type == $LIMIT_TABLE) {
++    $bytes_in = "unlimited" if ($bytes_in < 0.0);
++    $bytes_out = "unlimited" if ($bytes_out < 0.0);
++    $bytes_xfer = "unlimited" if ($bytes_xfer < 0.0);
++
++    $files_in = "unlimited" if ($files_in == 0);
++    $files_out = "unlimited" if ($files_out == 0);
++    $files_xfer = "unlimited" if ($files_xfer == 0);
++  }
++
++  print STDOUT "-------------------------------------------\n";
++  print STDOUT "  Name: $name\n";
++  print STDOUT "  Quota Type: $quota_type\n";
++
++  if ($table_type == $LIMIT_TABLE) {
++    print STDOUT "  Per Session: $per_session\n";
++    print STDOUT "  Limit Type: $limit_type\n";
++  }
++
++  print STDOUT "    Uploaded ", get_display_bytes('bytes' => $bytes_in), "\n";
++  print STDOUT "    Downloaded ", get_display_bytes('bytes' => $bytes_out),
++    "\n";
++  print STDOUT "    Transferred ", get_display_bytes('bytes' => $bytes_xfer),
++    "\n";
++
++  print STDOUT "    Uploaded files:\t$files_in\n";
++  print STDOUT "    Downloaded files:\t$files_out\n";
++  print STDOUT "    Transferred files:\t$files_xfer\n";
++}
++
++# -------------------------------------------------------------------------
++sub print_table {
++  my $have_records = 0;
++
++  while (my $record = read_record()) {
++    $have_records = 1;
++    print_record(record => $record);
++  }
++  print STDOUT "$program: (empty table)\n" unless ($have_records);
++
++  # done
++  exit(0);
++}
++
++# -------------------------------------------------------------------------
++sub read_record {
++  my $record;
++  my $bread;
++
++  if ($table_type == $LIMIT_TABLE) {
++    $bread = sysread TABLE, $record, $limit_reclen;
++
++  } elsif ($table_type == $TALLY_TABLE) {
++    $bread = sysread TABLE, $record, $tally_reclen;
++  }
++
++  if ($bread) {
++    return $record;
++
++  } else {
++    return undef;
++  }
++}
++
++# -------------------------------------------------------------------------
++sub read_table {
++  my @records = ();
++  my $nrecords_read = 0;
++
++  # read from TABLE
++  while (my $record = read_record()) {
++    $nrecords_read++;
++    push(@records, $record);
++  }
++
++  return ($nrecords_read, @records);
++}
++
++# -------------------------------------------------------------------------
++sub rewind_record {
++  if ($table_type == $LIMIT_TABLE) {
++    sysseek TABLE, -$limit_reclen, 1;
++
++  } elsif ($table_type == $TALLY_TABLE) {
++    sysseek TABLE, -$tally_reclen, 1;
++  }
++}
++
++# -------------------------------------------------------------------------
++sub rlock_table {
++  print STDOUT "$program: read-locking table '$table'\n" if $verbose;
++
++  flock(TABLE, LOCK_SH);
++}
++
++# -------------------------------------------------------------------------
++sub seek_record {
++  my ($n) = @_;
++
++  if ($table_type == $LIMIT_TABLE) {
++    sysseek TABLE, $limit_reclen, $n;
++  
++  } elsif ($table_type == $TALLY_TABLE) {
++    sysseek TABLE, $tally_reclen, $n;
++  }
++}
++
++# -------------------------------------------------------------------------
++sub set_table_position {
++  my ($position, $whence) = @_;
++
++  my $result = sysseek(TABLE, $position, $whence);
++
++  print STDOUT "$program: set table position to $result\n" if $verbose;
++
++  return $result;
++}
++
++# -------------------------------------------------------------------------
++sub truncate_table {
++  my %args = @_;
++
++  my $length = $args{'len'};
++
++  # don't forget about the header (4 bytes)
++  truncate TABLE, $length + 4;
++}
++
++# -------------------------------------------------------------------------
++sub unlock_table {
++  print STDOUT "$program: unlocking table '$table'\n" if $verbose;
++
++  flock(TABLE, LOCK_UN);
++}
++
++# -------------------------------------------------------------------------
++sub update_record {
++  my $current_record;
++  my $search_quota_type;
++
++  # first, find the matching record.  Note that this option requires
++  # both --name and --quota-type
++
++  if (!defined($opts{'Q'})) {
++    print STDOUT "$program: --update-record requires --quota-type option\n";
++    exit(1);
++
++  } else {
++    $search_quota_type = get_quota_type(quota_type => $opts{'Q'});
++  }
++
++  if ($search_quota_type != $ALL_QUOTA) {
++    if (!defined($opts{'N'})) {
++      print STDOUT "$program: --update-record requires --name option\n";
++      exit(1);
++    }
++  }
++
++  # now, find the matching record in the table
++  open_table();
++  unless ($current_record = find_record(name => $opts{'N'},
++      quota_type => $search_quota_type)) {
++    print STDOUT "$program: unable to update record: no match found\n";
++    exit(1);
++  }
++  rewind_record();
++
++  print STDOUT "$program: updating table '$table'\n" if $verbose;
++
++  # now, adjust the current record with the updated values in the requested
++  # record
++
++  my ($name, $quota_type, $per_session, $limit_type, @junk);
++
++  if ($table_type == $LIMIT_TABLE) { 
++    ($name, $quota_type, $per_session, $limit_type,
++      @junk) = unpack($limit_format, $current_record);
++
++  } elsif ($table_type == $TALLY_TABLE) {
++
++    ($name, $quota_type, @junk) = unpack($tally_format, $current_record);
++  }
++
++  my $formatted_record;
++
++  if ($table_type == $LIMIT_TABLE) {
++    $formatted_record = pack($limit_format, $name, $quota_type,
++      $record{'per_session'}, $record{'limit_type'},
++      $record{'bytes_in'}, $record{'bytes_out'}, $record{'bytes_xfer'},
++      $record{'files_in'}, $record{'files_out'}, $record{'files_xfer'});
++
++  } elsif ($table_type == $TALLY_TABLE) {
++
++    $formatted_record = pack($tally_format, $name, $quota_type,
++      $record{'bytes_in'}, $record{'bytes_out'}, $record{'bytes_xfer'},
++      $record{'files_in'}, $record{'files_out'}, $record{'files_xfer'});
++  }
++
++  write_record(record => $formatted_record);
++
++  # done
++  exit(0);
++}
++
++# -------------------------------------------------------------------------
++sub wlock_table {
++  print STDOUT "$program: write-locking table '$table'\n" if $verbose;
++
++  flock(TABLE, LOCK_EX);
++}
++
++# -------------------------------------------------------------------------
++sub write_record {
++  my %args = @_;
++  my $record = $args{'record'};
++
++  print STDOUT "$program: writing record\n" if $verbose;
++
++  die "$program: error writing table: $!\n" unless
++    syswrite TABLE, $record;
++}
++
++# -------------------------------------------------------------------------
++sub usage {
++
++  print STDOUT <<END_OF_USAGE;
++
++usage: $program [options]
++
++ The following options describe the type of operation to be performed:
++
++  --add-record         Create a new record with the specified limits.  Any
++                       limits left unspecified with have their default 
++                       values.  This option requires the --name and 
++                       --quota-type options.
++
++  --create-table       Create the table if not present.  Used to initialize
++                       a table.  The default limit table path is
++                       "$default_limit_table".  The default tally table path is
++                       "$default_tally_table".
++
++  --delete-record      Deletes a quota record from the table.  This option
++                       requires the --name and --quote-type options.
++
++  --show-records       Prints out all of the quota records in the table in
++                       a legible format.
++
++  --update-record      Updates a quota record with the specified limits.  Any
++                       limits left unspecified will be updated with their
++                       default value.  This option requires the --name and
++                       --quota-type options.
++
++ The following option describes the type of table on which to operate:
++
++  --type               Specifies a table type to use.  The allowable options
++                       are: "limit" or "tally".  This is required.
++
++ The following options are used to specify specific quota limits:
++
++  --Bu                 Specifies the limit of the number of bytes that may be
++  --bytes-upload       uploaded.  Defaults to -1 (unlimited).
++
++  --Bd                 Specifies the limit of the number of bytes that may be
++  --bytes-download     downloaded.  Defaults to -1 (unlimited).
++
++  --Bx                 Specifies the limit of the number of bytes that may be
++  --bytes-xfer         transferred.  Note that this total includes uploads,
++                       downloads, AND directory listings.  Defaults to
++                       -1 (unlimited).
++
++  --Fu                 Specifies the limit of the number of files that may be
++  --files-upload       uploaded.  Defaults to -1 (unlimited).
++
++  --Fd                 Specifies the limit of the number of files that may be
++  --files-download     downloaded.  Defaults to -1 (unlimited).
++
++  --Fx                 Specifies the limit of the number of files that may be
++  --files-xfer         transferred, including uploads and downloads.  Defaults
++                       to -1 (unlimited).
++
++  -L                   Specifies the type of limit, "hard" or "soft", of
++  --limit-type         the bytes limits.  If "hard", any uploaded files that
++                       push the bytes used counter past the limit will be
++                       automatically deleted; if "soft", those extra bytes
++                       will be allowed, but future uploads will be denied.
++                       This option only makes sense if --type is "limit".
++
++  -N                   Specifies a name for the quota record.  This name
++  --name               will be the user/login name, group name, or class
++                       name, depending on the quota type.  This option
++                       is ignored if the quota type specified is "all".
++
++  -P
++  --per-session        Specifies that the quota limit is to be applied only
++                       to each session, rather than persisting across
++                       sessions.  By default, quotas are persistent.
++
++  -Q                   Specifies a "quota type" for this record, where
++  --quota-type         the type means to which category of FTP users this
++                       quota will apply.  The quota type must be one of:
++                       "user", "group", "class", or "all".
++
++ The following options are miscellaneous:
++
++  --help               Displays this message.
++
++  --table-path         Specifies the path to a quota table file to use.
++
++  --units              Specifies whether to treats bytes as is, in kilobytes,
++                       megabytes, or gigabytes.  Allowable options are:
++                       "B" or "byte", "Kb" or "kilo", "Mb" or "mega",
++                       and "Gb" or "giga".  Defaults to "byte".
++
++  --verbose            Toggles more verbose information about the doings of
++                       the tool as it works.
++
++END_OF_USAGE
++
++  exit 0;
++}
++
++# -------------------------------------------------------------------------
++
+diff -ruN proftpd-1.2.9-old/contrib/ftpquota.html proftpd-1.2.9/contrib/ftpquota.html
+--- proftpd-1.2.9-old/contrib/ftpquota.html	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/ftpquota.html	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,289 @@
++<!-- $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $ -->
++<!-- $Source: /cvsroot/pkg-proftpd/debian/patches/14.quotatab_modules.diff,v $ -->
++
++<html>
++<head>
++<title>ftpquota: tool for ProFTPD mod_quotatab</title>
++</head>
++
++<body bgcolor=white>
++
++<hr><br>
++<center>
++<h2><b><code>ftpquota</code>: tool for ProFTPD module <code>mod_quotatab</code></b></h2>
++</center>
++<hr><br>
++
++This program is distributed with the
++<a href="./mod_quotatab.html"><code>mod_quotatab</code></a> module for
++ProFTPD 1.2.  It is used to create and manage quota tables of type
++&quot;file&quot;.
++
++<p>
++The most current version of <code>ftpquota</code> can be found at:
++<pre>
++  <a href="http://www.castaglia.org/proftpd/">http://www.castaglia.org/proftpd/</a>
++</pre>
++
++<h2>Author</h2>
++<p>
++Please contact TJ Saunders &lt;tj <i>at</i> castaglia.org&gt; with any
++questions, concerns, or suggestions regarding this program.
++
++<p>
++<hr><br>
++<h2><a name="Usage">Usage</a></h2>
++The following describes the common usage of the <code>ftpquota</code> tool.
++The options supported are described in more detail
++<a href="#Options">later</a>.
++
++<p>
++<b>Creating Tables</b><br>
++To start using <code>mod_quotatab</code>, the two required tables are required.
++Tables of type &quot;file&quot; have identifying magic headers such that
++<code>ftpquota</code> is needed to initially create both tables.  It is an
++error to attempt to create a table that already exists:
++<pre>
++  # ftpquota --create-table --type=limit
++  ftpquota: cannot create existing table
++</pre>
++
++<p>
++To create the initial limit table:
++<pre>
++  ftpquota --create-table --type=limit
++</pre>
++To create the initial tally table:
++<pre>
++  ftpquota --create-table --type=tally
++</pre>
++The population of a tally table file with the tally for <code>user</code>s,
++<code>group</code>s, <code>class</code>es, and <code>all</code> is done
++automatically by <code>mod_quotatab</code>.
++
++<p>
++For both of these operations, the <code>--table-path</code> can be used to
++create a table in a non-default location.
++
++<p>
++<b>Updating Tables</b><br>
++Now that you have the initial tables created, but blank, you need to add
++records (to the limit table) for the users, groups, classes, etc on which
++you, as the administrator, wish to impose quotas.
++
++<p>
++To a basic limit record for a user <code>bob</code> using the default quotas
++(which are all &quot;unlimited&quot; by default):
++<pre>
++  ftpquota --add-record --type=limit --name=bob --quota-type=user
++</pre>
++Similarly for quotas of type <code>group</code> or <code>class.</code>  Note
++that for quotas of type <code>all</code>, the <code>--name</code> option
++is not necessary; the <code>all</code> record applies to everyone, regardless
++of name or group or class membership.  If no byte or file limits are
++specified, the default settings (<b>unlimited</b> numbers of bytes/files)
++are used.
++
++<p>
++It is an error to add a record that already exists.  Note, however, that it
++is possible to have multiple records of the same name, but different
++quota types.  The record to use for a given session is identified by the
++combination of name and quota type.
++
++<p>
++An example of creating a limit record with more complex quotas for a class
++named &quot;browsers&quot;
++<pre>
++  ftpquota --add-record --type=limit --name=browsers --quota-type=class \
++    --files-upload=0  --files-download=25 --table-path=/usr/local/etc/ftplimit.tab
++</pre>
++or, another way:
++<pre>
++  ftpquota --add-record --type=limit --name=browsers --quota-type=class \
++    --bytes-upload=0 --bytes-download=2 --units=Gb --table-path=/usr/local/etc/ftplimit.tab
++</pre>
++In general, it is a good idea to use either byte quotas or file quotas, but
++not both, unless you know what you are doing.  In these examples, the 
++<code>--table-path</code> option is used to add the record to a limit table in
++a non-default location.
++
++<p>
++Another option available when creating limit records is the
++<code>--per-session</code> option.  By default, quotas are persistent, and
++apply to the user (or group, class, or everyone) across all sessions.  Using
++this option means the limits will be enforced only for the duration of
++the client's session, and that the limits will apply only to that client.
++In other words, using this option for <code>group</code>, <code>class</code>,
++or <code>all</code> quotas is not a good idea.
++
++<p>
++Similarly, for removing records from the limit table (effectively removing
++quotas from affecting that <code>user/group/class/all</code>) or from the
++tally table (effectively resetting the quotas to zero for that
++<code>user/group/class/all</code>), there is the
++<code>--delete-record</code> option:
++<pre>
++  ftpquota --delete-record --type=limit --name=browsers --quota-type=class
++</pre>
++
++<p>
++In addition to adding and removing records, an administrator may want to
++simply change the quotas in a given record, either in the limit or tally
++tables.  In this case, use <code>--update-record</code>:
++<pre>
++  ftpquota --update-record --type=tally --name=bob --quota-type=user \
++    --bytes-download=100 --files-download=1
++</pre>
++This example command manually sets user <code>bob</code>'s download tally to
++100 bytes, 1 file.  It is an error to update a record that does not exist.
++
++<p>
++There are some administrators who wish to impose quotas on a daily basis, that
++is, to have a per-day quota.  At present, the easiest way to do this is to
++have a cron job that, once a day, does the following:
++<pre>
++  ftpquota --update-record --type=tally --name=<i>name</i> --quota-type=<i>quotatype</i>
++</pre>
++This command will &quot;reset&quot; the matching tally record.  By default, if
++no byte or file quotas are set, the default values are used: <b>unlimited</b>
++if updating a limit record, zero if updating a tally record.
++
++<p>
++When editing the tables, <code>ftpquota</code> will obtain read or write
++locks as necessary.  If those tables are being used by a running server, which
++also performs locking, the script will wait until it is able to obtain a lock.
++Changing of in-use table information is ideally done while the server is
++quiescent.  This locking is to avoid data synchronization and corruption
++issues.
++
++<p>
++<b>Showing Tables</b><br>
++Having tables in binary format makes it difficult to easily see what
++the current records are, to double-check limits or simply to view the
++current tally.  <code>ftpquota</code> thus supports the dumping out of
++table contents in human-legible form via the <code>--show-records</code>
++option:
++<pre>
++  ftpquota --show-records --type=limit
++</pre>
++or, for a tally table not in the location where the scripts expects it to
++be:
++<pre>
++  ftpquota --show-records --type=tally --table-path=/usr/local/etc/ftpd/quota-tally.tab
++</pre>
++When viewing tables this way, the <code>--units</code> option can be used
++to display byte quotas in other units (<i>e.g.</i> Kb, Mb, etc).
++
++<p>
++<hr><br>
++<h2><a name="Options">Options</a></h2>
++The following is the output from running <code>ftpquota --help</code>:
++<pre>
++usage: ftpquota [options]
++
++ The following options describe the type of operation to be performed:
++
++  --add-record         Create a new record with the specified limits.  Any
++                       limits left unspecified with have their default
++                       values.  This option requires the --name and
++                       --quota-type options.
++
++  --create-table       Create the table if not present.  Used to initialize
++                       a table.  The default limit table path is
++                       "./ftpquota.limittab".  The default tally table path is
++                       "./ftpquota.tallytab".
++
++  --delete-record      Deletes a quota record from the table.  This option
++                       requires the --name and --quote-type options.
++
++  --show-records       Prints out all of the quota records in the table in
++                       a legible format.
++
++  --update-record      Updates a quota record with the specified limits.  Any
++                       limits left unspecified will be updated with their
++                       default value.  This option requires the --name and
++                       --quota-type options.
++
++ The following option describes the type of table on which to operate:
++
++  --type               Specifies a table type to use.  The allowable options
++                       are: "limit" or "tally".  This is required.
++
++ The following options are used to specify specific quota limits:
++
++  --Bu                 Specifies the limit of the number of bytes that may be
++  --bytes-upload       uploaded.  Defaults to -1 (unlimited).
++
++  --Bd                 Specifies the limit of the number of bytes that may be
++  --bytes-download     downloaded.  Defaults to -1 (unlimited).
++
++  --Bx                 Specifies the limit of the number of bytes that may be
++  --bytes-xfer         transferred.  Note that this total includes uploads,
++                       downloads, AND directory listings.  Defaults to
++                       -1 (unlimited).
++
++  --Fu                 Specifies the limit of the number of files that may be
++  --files-upload       uploaded.  Defaults to -1 (unlimited).
++
++  --Fd                 Specifies the limit of the number of files that may be
++  --files-download     downloaded.  Defaults to -1 (unlimited).
++
++  --Fx                 Specifies the limit of the number of files that may be
++  --files-xfer         transferred, including uploads and downloads.  Defaults
++                       to -1 (unlimited).
++
++  -L                   Specifies the type of limit, "hard" or "soft", of
++  --limit-type         the bytes limits.  If "hard", any uploaded files that
++                       push the bytes used counter past the limit will be
++                       automatically deleted; if "soft", those extra bytes
++                       will be allowed, but future uploads will be denied.
++                       This option only makes sense if --type is "limit".
++
++  -N                   Specifies a name for the quota record.  This name
++  --name               will be the user/login name, group name, or class
++                       name, depending on the quota type.  This option
++                       is ignored if the quota type specified is "all".
++
++  -P
++  --per-session        Specifies that the quota limit is to be applied only
++                       to each session, rather than persisting across
++                       sessions.  By default, quotas are persistent.
++
++  -Q                   Specifies a "quota type" for this record, where
++  --quota-type         the type means to which category of FTP users this
++                       quota will apply.  The quota type must be one of:
++                       "user", "group", "class", or "all".
++
++ The following options are miscellaneous:
++
++  --help               Displays this message.
++
++  --table-path         Specifies the path to a quota table file to use.
++
++  --units              Specifies whether to treats bytes as is, in kilobytes,
++                       megabytes, or gigabytes.  Allowable options are:
++                       "B" or "byte", "Kb" or "kilo", "Mb" or "mega",
++                       and "Gb" or "giga".  Defaults to "byte".
++
++  --verbose            Toggles more verbose information about the doings of
++                       the tool as it works.
++</pre>
++
++<p>
++<hr><br>
++
++Author: <i>$Author: frankie $</i><br>
++Last Updated: <i>$Date: 2003/11/17 15:30:12 $</i><br>
++
++<br><hr>
++
++<font size=2><b><i>
++&copy; Copyright 2000-2002 TJ Saunders<br>
++ All Rights Reserved<br>
++</i></b></font>
++
++<hr><br>
++
++</body>
++</html>
++
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab.c proftpd-1.2.9/contrib/mod_quotatab.c
+--- proftpd-1.2.9-old/contrib/mod_quotatab.c	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab.c	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,2042 @@
++/*
++ * ProFTPD: mod_quotatab -- a module for managing FTP byte/file quotas via
++ *                          centralized tables
++ *
++ * Copyright (c) 2001-2003 TJ Saunders
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
++ *
++ * As a special exemption, TJ Saunders gives permission to link this program
++ * with OpenSSL, and distribute the resulting executable, without including
++ * the source code for OpenSSL in the source distribution.
++ *
++ * This is mod_quotatab, contrib software for proftpd 1.2 and above.
++ * For more information contact TJ Saunders <tj@castaglia.org>.  It is based
++ * the ideas in Eric Estabrook's mod_quota, available from
++ * ftp://pooh.urbanrage.com/pub/c/.  This module, however, has been written
++ * from scratch to implement quotas in a different way.
++ *
++ * $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $
++ */
++
++#include "mod_quotatab.h"
++
++typedef struct regtab_obj {
++  struct regtab_obj *next;
++ 
++  /* Table source type name */
++  const char *regtab_name;
++
++  /* Initialization function for this type of table source */
++  quota_table_t *(*regtab_open)(pool *, quota_tabtype_t, const char *);
++
++  /* Flags for this type of table: QUOTATAB_LIMIT_SRC, QUOTATAB_TALLY_SRC.
++   * Used to restrict some sources to only certain table types (ie
++   * LDAP to limit tables).
++   */
++  unsigned int regtab_srcs;
++
++} quota_regtab_t;
++
++/* Quota objects for the current session */
++static quota_table_t *limit_tab;
++static quota_table_t *tally_tab;
++
++/* Memory pool for this module */
++static pool *quotatab_pool = NULL;
++
++/* List of registered quotatab sources */
++static quota_regtab_t *quota_regtab_list = NULL;
++
++/* Logging data */
++static int quota_logfd = -1; 
++static char *quota_logname = NULL;
++
++static unsigned char allow_site_quota = TRUE;
++static unsigned char use_dirs = FALSE;
++static unsigned char use_quotas = FALSE;
++static unsigned char have_quota_entry = FALSE;
++static unsigned char have_quota_limit_table = FALSE;
++static unsigned char have_quota_tally_table = FALSE;
++static quota_units_t byte_units = BYTE;
++
++/* For transmitting number of bytes from PRE_CMD to POST_CMD handlers
++ * (for use by APPE, DELE, MKD, RMD, RNTO, STOR, STOU, XMKD, and XRMD
++ * commands)
++ */
++static off_t quotatab_disk_bytes;
++
++/* It is the case where sometimes a command may be denied by a PRE_CMD
++ * handler of this module, in which case an appropriate error response is
++ * added to the response chain.  When the matching POST_CMD_ERR handler
++ * then runs, it will add another response.  Sometimes, however, the
++ * POST_CMD_ERR handlers may be run for other reasons, and the response
++ * added is not a duplicate.  Use this flag to signal when a response has
++ * already been added.
++ */
++static unsigned char have_err_response = FALSE;
++
++/* convenience macros */
++#define DISPLAY_BYTES_IN(x) \
++    quota_display_bytes((x)->tmp_pool, \
++    quotatab_tally.bytes_in_used, quotatab_limit.bytes_in_avail, IN)
++
++#define DISPLAY_BYTES_OUT(x) \
++    quota_display_bytes((x)->tmp_pool, \
++    quotatab_tally.bytes_out_used, quotatab_limit.bytes_out_avail, OUT)
++
++#define DISPLAY_BYTES_XFER(x) \
++    quota_display_bytes((x)->tmp_pool, \
++    quotatab_tally.bytes_xfer_used, quotatab_limit.bytes_xfer_avail, XFER)
++
++#define DISPLAY_FILES_IN(x) \
++    quota_display_files((x)->tmp_pool, \
++    quotatab_tally.files_in_used, quotatab_limit.files_in_avail, IN)
++
++#define DISPLAY_FILES_OUT(x) \
++    quota_display_files((x)->tmp_pool, \
++    quotatab_tally.files_out_used, quotatab_limit.files_out_avail, OUT)
++
++#define DISPLAY_FILES_XFER(x) \
++    quota_display_files((x)->tmp_pool, \
++    quotatab_tally.files_xfer_used, quotatab_limit.files_xfer_avail, XFER)
++
++#define QUOTATAB_TALLY_READ \
++  if (!quotatab_limit.quota_per_session) { \
++    if (quotatab_read() < 0) \
++      quotatab_log("error: unable to read tally: %s", strerror(errno)); \
++  }
++
++#define QUOTATAB_TALLY_WRITE(bi, bo, bx, fi, fo, fx) \
++  if (quotatab_write((bi), (bo), (bx), (fi), (fo), (fx)) < 0) \
++    quotatab_log("error: unable to write tally: %s", strerror(errno));
++
++/* necessary prototypes */
++MODRET quotatab_pre_stor(cmd_rec *);
++MODRET quotatab_post_stor(cmd_rec *);
++MODRET quotatab_post_stor_err(cmd_rec *);
++static int quotatab_rlock(quota_tabtype_t);
++static int quotatab_unlock(quota_tabtype_t);
++static int quotatab_wlock(quota_tabtype_t);
++
++/* Support routines
++ */
++
++/* Quota units routines */
++
++static char *quota_display_bytes(pool *p, double bytes_used,
++    double bytes_avail, quota_xfer_t xfer_type) {
++  double adj_used = 0.0, adj_avail = 0.0;
++  char *display = (char *) pcalloc(p, 80);
++  char *xferstr = NULL;
++
++  switch (xfer_type) {
++    case IN:
++      xferstr = "upload";
++      break;
++
++    case OUT:
++      xferstr = "download";
++      break;
++
++    case XFER:
++      xferstr = "transfer";
++      break;
++
++    default:
++      break;
++  }
++
++  switch (byte_units) {
++
++    case BYTE:
++      /* no manipulation needed */
++      sprintf(display, "%.2f of %.2f %s byte%s", bytes_used, bytes_avail,
++        xferstr, bytes_avail != 1.0 ? "s" : "");
++      break;
++
++    case KILO:
++      /* divide by 1024.0 */
++      adj_used = (bytes_used / 1024.0);
++      adj_avail = (bytes_avail / 1024.0);
++      sprintf(display, "%.2f of %.2f %s Kb", adj_used, adj_avail, xferstr);
++
++      break;
++
++    case MEGA:
++      /* divide by 1024.0 * 1024.0 */
++      adj_used = (bytes_used / (1024.0 * 1024.0));
++      adj_avail = (bytes_avail / (1024.0 * 1024.0));
++      sprintf(display, "%.2f of %.2f %s Mb", adj_used, adj_avail, xferstr);
++
++      break;
++
++    case GIGA:
++      /* divide by 1024.0 * 1024.0 * 1024.0 */
++      adj_used = (bytes_used / (1024.0 * 1024.0 * 1024.0));
++      adj_avail = (bytes_avail / (1024.0 * 1024.0 * 1024.0));
++      sprintf(display, "%.2f of %.2f %s Gb", adj_used, adj_avail, xferstr);
++
++      break;
++
++    /* always have a fallthrough case, even if it _should_ never be reached
++     */
++    default:
++      quotatab_log("warning: unknown QuotaDisplayUnits");
++      break;
++  }
++
++  return display;
++}
++
++static char *quota_display_files(pool *p, unsigned int files_used,
++    unsigned int files_avail, quota_xfer_t xfer_type) {
++  char *display = (char *) pcalloc(p, 80);
++  char *xferstr = NULL;
++
++  switch (xfer_type) {
++    case IN:
++      xferstr = "upload";
++      break;
++
++    case OUT:
++      xferstr = "download";
++      break;
++
++    case XFER:
++      xferstr = "transfer";
++      break;
++
++    default:
++      break;
++  }
++
++  sprintf(display, "%u of %u %s %s", files_used, files_avail, xferstr,
++    files_avail != 1.0 ? "files" : "file");
++
++  return display;
++}
++
++static char *quota_display_site_bytes(pool *p, double bytes_used,
++    double bytes_avail) {
++  double adj_used = 0.0, adj_avail = 0.0;
++  char *display = (char *) pcalloc(p, 80);
++
++  switch (byte_units) {
++    case BYTE:
++      /* no calculation needed */
++
++      if (bytes_avail > 0.0)
++        sprintf(display, "bytes:\t%.2f/%.2f", bytes_used, bytes_avail);
++      else
++        sprintf(display, "bytes:\tunlimited");
++      break;
++
++    case KILO:
++      /* divide by 1024.0 */
++      adj_used = (bytes_used / 1024.0);
++      adj_avail = (bytes_avail / 1024.0);
++
++      if (adj_avail > 0.0)
++        sprintf(display, "Kb:\t%.2f/%.2f", adj_used, adj_avail);
++      else
++        sprintf(display, "Kb:\tunlimited");
++      break;
++
++    case MEGA:
++      /* divide by 1024.0 * 1024.0 */
++      adj_used = (bytes_used / (1024.0 * 1024.0));
++      adj_avail = (bytes_avail / (1024.0 * 1024.0));
++
++      if (adj_avail > 0.0)
++        sprintf(display, "Mb:\t%.2f/%.2f", adj_used, adj_avail);
++      else
++        sprintf(display, "Mb:\tunlimited");
++      break;
++
++    case GIGA:
++      /* divide by 1024.0 * 1024.0 * 1024.0 */
++      adj_used = (bytes_used / (1024.0 * 1024.0 * 1024.0));
++      adj_avail = (bytes_avail / (1024.0 * 1024.0 * 1024.0));
++
++      if (adj_avail > 0.0)
++        sprintf(display, "Gb:\t%.2f/%.2f", adj_used, adj_avail);
++      else
++        sprintf(display, "Gb:\tunlimited");
++      break;
++
++    default:
++      quotatab_log("warning: unknown QuotaDisplayUnits");
++      break;
++  }
++
++  return display;
++}
++
++static char *quota_display_site_files(pool *p, unsigned int files_used,
++    unsigned int files_avail) {
++  char *display = (char *) pcalloc(p, 80);
++
++  if (files_avail != 0)
++    sprintf(display, "files:\t%u/%u", files_used, files_avail);
++  else
++    sprintf(display, "files:\tunlimited");
++
++  return display;
++}
++
++/* Quota logging routines */
++static int quotatab_closelog(void) {
++  /* sanity check */
++  if (quota_logfd != -1) {
++    close(quota_logfd);
++    quota_logfd = -1;
++    quota_logname = NULL;
++  }
++
++  return 0;
++}
++
++int quotatab_log(const char *fmt, ...) {
++  char buf[PR_TUNABLE_BUFFER_SIZE] = {'\0'};
++  time_t timestamp = time(NULL);
++  struct tm *t = NULL;
++  va_list msg;
++
++  /* sanity check */
++  if (!quota_logname)
++    return 0;
++
++  t = localtime(&timestamp);
++
++  /* prepend the timestamp */
++  strftime(buf, sizeof(buf), "%b %d %H:%M:%S ", t);
++  buf[sizeof(buf) - 1] = '\0';
++
++  /* prepend a small header */
++  snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
++           MOD_QUOTATAB_VERSION "[%u]: ", (unsigned int) getpid());
++
++  buf[sizeof(buf) - 1] = '\0';
++
++  /* affix the message */
++  va_start(msg, fmt);
++  vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, msg);
++  va_end(msg);
++
++  buf[strlen(buf)] = '\n';
++  buf[sizeof(buf) - 1] = '\0';
++
++  if (write(quota_logfd, buf, strlen(buf)) < 0)
++    return -1;
++
++  return 0;
++}
++
++int quotatab_openlog(void) {
++  int res = 0;
++
++  /* Sanity checks. */
++  if (quota_logname)
++    return 0;
++
++  if ((quota_logname = (char *) get_param_ptr(main_server->conf,
++      "QuotaLog", FALSE)) == NULL)
++    return 0;
++
++  /* check for "none" */
++  if (strcasecmp(quota_logname, "none") == 0) {
++    quota_logname = NULL;
++    return 0;
++  }
++
++  pr_signals_block();
++  PRIVS_ROOT
++  res = log_openfile(quota_logname, &quota_logfd, 0640);
++  PRIVS_RELINQUISH
++  pr_signals_unblock();
++
++  return res;
++}
++
++static int quotatab_close(quota_tabtype_t tab_type) {
++  int res = 0;
++
++  if (tab_type == TYPE_TALLY) {
++    res = tally_tab->tab_close(tally_tab);
++    tally_tab = NULL;
++
++  } else if (tab_type == TYPE_LIMIT) {
++    res = limit_tab->tab_close(limit_tab); 
++    limit_tab = NULL;
++  }
++
++  return res;
++}
++
++static int quotatab_verify(quota_tabtype_t tab_type) {
++
++  /* Request the table source object to verify itself */
++  if (tab_type == TYPE_TALLY) {
++    if (tally_tab->tab_verify(tally_tab))
++      return TRUE;
++    else
++      quotatab_log("error: unable to use QuotaTallyTable: bad table header");
++
++  } else if (tab_type == TYPE_LIMIT) {
++    if (limit_tab->tab_verify(limit_tab))
++      return TRUE;
++    else
++      quotatab_log("error: unable to use QuotaLimitTable: bad table header");
++  }
++
++  return FALSE;
++}
++
++static int quotatab_create(void) {
++
++  /* Creation of an entry only ever occurs in the tally table -- the limit
++   * table is considered read-only.
++   */
++
++  /* Obtain a writer lock for the entry in question. */
++  if (quotatab_wlock(TYPE_TALLY) < 0)
++    return FALSE;
++
++  if (tally_tab->tab_create(tally_tab) < 0) {
++    quotatab_unlock(TYPE_TALLY);
++    return FALSE;
++  }
++
++  /* Release the lock */
++  if (quotatab_unlock(TYPE_TALLY) < 0)
++    return FALSE;
++
++  return TRUE;
++}
++
++static void quotatab_exit_cb(void) {
++  if (use_quotas && have_quota_tally_table)
++    if (quotatab_close(TYPE_TALLY) < 0)
++      quotatab_log("error: unable to close QuotaTallyTable: %s",
++        strerror(errno));
++
++  quotatab_closelog();
++  return;
++}
++
++static int quotatab_open(quota_tabtype_t tab_type) {
++
++  if (tab_type == TYPE_TALLY) {
++    register config_rec *c = NULL;
++    register quota_regtab_t *regtab = NULL;
++    unsigned char have_type = FALSE;
++
++    if ((c = find_config(main_server->conf, CONF_PARAM, "QuotaTallyTable",
++        FALSE)) == NULL) {
++      quotatab_log("notice: no QuotaTallyTable configured");
++      return -1;
++    }
++
++    /* Look up the table source open routine by name, and invoke it */
++    for (regtab = quota_regtab_list; regtab; regtab = regtab->next) {
++      if ((regtab->regtab_srcs & QUOTATAB_TALLY_SRC) &&
++          !strcmp(regtab->regtab_name, (char *) c->argv[0])) {
++        if ((tally_tab = regtab->regtab_open(quotatab_pool, TYPE_TALLY,
++            c->argv[1])) == NULL)
++          return -1;
++
++        else {
++          have_type = TRUE;
++          break;
++        }
++      }
++    }
++
++    if (!have_type) {
++      quotatab_log("error: unsupported tally table type: '%s'", c->argv[0]);
++      return -1;
++    }
++
++  } else if (tab_type == TYPE_LIMIT) {
++    register config_rec *c = NULL;
++    register quota_regtab_t *regtab = NULL;
++    unsigned char have_type = FALSE;
++
++    if ((c = find_config(main_server->conf, CONF_PARAM, "QuotaLimitTable",
++        FALSE)) == NULL) {
++      quotatab_log("notice: no QuotaLimitTable configured");
++      return -1;
++    }
++
++    /* Look up the table source open routine by name, and invoke it */
++    for (regtab = quota_regtab_list; regtab; regtab = regtab->next) {
++      if ((regtab->regtab_srcs & QUOTATAB_LIMIT_SRC) &&
++          !strcmp(regtab->regtab_name, (char *) c->argv[0])) {
++        if ((limit_tab = regtab->regtab_open(quotatab_pool, TYPE_LIMIT,
++            c->argv[1])) == NULL)
++          return -1;
++
++        else {
++          have_type = TRUE;
++          break;
++        }
++      }
++    }
++
++    if (!have_type) {
++      quotatab_log("error: unsupported limit table type: '%s'", c->argv[0]);
++      return -1;
++    }
++  }
++
++  return 0;
++}
++
++/* Reads via this function are only ever done on tally tables.  Limit tables
++ * are read via the quotatab_lookup function.
++ */
++int quotatab_read(void) {
++  int bread = 0;
++
++  /* Make sure the tally table can support reads. */
++  if (!tally_tab || !tally_tab->tab_read) {
++    errno = EPERM;
++    return -1;
++  }
++
++  /* Obtain a reader lock for the entry in question. */
++  if (quotatab_rlock(TYPE_TALLY) < 0) {
++    quotatab_log("error: unable to obtain read lock: %s", strerror(errno));
++    return -1;
++  }
++
++  /* Read from the current point in the stream enough information to populate
++   * the quota structs.
++   */
++  if ((bread = tally_tab->tab_read(tally_tab)) < 0) {
++    quotatab_unlock(TYPE_TALLY);
++    return -1;
++  }
++
++  /* Release the lock */
++  if (quotatab_unlock(TYPE_TALLY) < 0) {
++    quotatab_log("error: unable to release read lock: %s", strerror(errno));
++    return -1;
++  }
++
++  return bread;
++}
++
++int quotatab_register(const char *srcname,
++    quota_table_t *(*srcopen)(pool *, quota_tabtype_t, const char *),
++    unsigned int tabsrcs) {
++
++  /* Note: I know that use of permanent_pool is discouraged as much as
++   * possible, but in this particular instance, I need a pool that
++   * persists across rehashes.  The registration of a table type only
++   * happens once, on module init when the server first starts up, so
++   * this will not constitute a memory leak.
++   */
++  quota_regtab_t *regtab = pcalloc(permanent_pool, sizeof(quota_regtab_t));
++ 
++  regtab->regtab_name = pstrdup(permanent_pool, srcname);
++  regtab->regtab_open = srcopen;
++  regtab->regtab_srcs = tabsrcs;
++
++  /* Add this object to the list. */
++  regtab->next = quota_regtab_list;
++  quota_regtab_list = regtab;
++
++  return 0;
++}
++
++static int quotatab_rlock(quota_tabtype_t tab_type) {
++
++  if (tab_type == TYPE_TALLY)
++    return tally_tab->tab_rlock(tally_tab);
++
++  else if (tab_type == TYPE_LIMIT)
++    return limit_tab->tab_rlock(limit_tab);
++
++  /* default */
++  errno = EINVAL;
++  return -1;
++}
++
++/* Note: this function will only find the first occurrence of the given
++ *  name and type in the table.  This means that if there is a malformed
++ *  quota table, with duplicate name/type pairs, the duplicates will be
++ *  ignored.
++ */
++unsigned char quotatab_lookup(quota_tabtype_t tab_type, const char *name,
++    quota_type_t quota_type) {
++
++  if (tab_type == TYPE_TALLY) {
++
++    /* Make sure the requested table can do lookups. */
++    if (!tally_tab || !tally_tab->tab_lookup) {
++      errno = EPERM;
++      return FALSE;
++    }
++
++    return tally_tab->tab_lookup(tally_tab, name, quota_type);
++  
++  } else if (tab_type == TYPE_LIMIT) {
++
++    /* Make sure the requested table can do lookups. */
++    if (!limit_tab || !limit_tab->tab_lookup) {
++      errno = EPERM;
++      return FALSE;
++    }
++
++    return limit_tab->tab_lookup(limit_tab, name, quota_type);
++  }
++
++  /* default */
++  return FALSE;
++}
++
++static int quotatab_unlock(quota_tabtype_t tab_type) {
++
++  if (tab_type == TYPE_TALLY)
++    return tally_tab->tab_unlock(tally_tab);
++
++  else if (tab_type == TYPE_LIMIT)
++    return limit_tab->tab_unlock(limit_tab);
++
++  /* default */
++  errno = EINVAL;
++  return -1;
++}
++
++static int quotatab_wlock(quota_tabtype_t tab_type) {
++
++  if (tab_type == TYPE_TALLY)
++    return tally_tab->tab_wlock(tally_tab);
++
++  else if (tab_type == TYPE_LIMIT)
++    return limit_tab->tab_wlock(limit_tab);
++
++  /* default */
++  errno = EINVAL;
++  return -1;
++}
++
++int quotatab_write(double bytes_in_inc, double bytes_out_inc,
++    double bytes_xfer_inc, int files_in_inc, int files_out_inc,
++    int files_xfer_inc) {
++
++  /* Make sure the tally table can support writes. */
++  if (!tally_tab || !tally_tab->tab_write) {
++    errno = EPERM;
++    return -1;
++  }
++
++  /* Obtain a writer lock for the entry in question */
++  if (quotatab_wlock(TYPE_TALLY) < 0) {
++    quotatab_log("error: unable to obtain write lock: %s", strerror(errno));
++    return -1;
++  }
++
++  /* Make sure the deltas are cleared. */
++  memset(&quotatab_deltas, '\0', sizeof(quotatab_deltas));
++
++  /* Read in the tally (to catch any possible updates by other processes). */
++  if (quotatab_read() < 0)
++    quotatab_log("error: unable to read current tally: %s", strerror(errno));
++
++  /* Only update the tally if the value is not "unlimited". */
++  if (quotatab_limit.bytes_in_avail > 0.0) {
++    quotatab_tally.bytes_in_used += bytes_in_inc;
++
++    /* Prevent underflows. */
++    if (quotatab_tally.bytes_in_used < 0.0)
++      quotatab_tally.bytes_in_used = 0.0;
++
++    quotatab_deltas.bytes_in_delta = bytes_in_inc;
++  }
++
++  /* Only update the tally if the value is not "unlimited". */
++  if (quotatab_limit.bytes_out_avail > 0.0) {
++    quotatab_tally.bytes_out_used += bytes_out_inc;
++
++    /* Prevent underflows. */
++    if (quotatab_tally.bytes_out_used < 0.0)
++      quotatab_tally.bytes_out_used = 0.0;
++
++    quotatab_deltas.bytes_out_delta = bytes_out_inc;
++  }
++
++  /* Only update the tally if the value is not "unlimited". */
++  if (quotatab_limit.bytes_xfer_avail > 0.0) {
++    quotatab_tally.bytes_xfer_used += bytes_xfer_inc;
++
++    /* Prevent underflows. */
++    if (quotatab_tally.bytes_xfer_used < 0.0)
++      quotatab_tally.bytes_xfer_used = 0.0;
++
++    quotatab_deltas.bytes_xfer_delta = bytes_xfer_inc;
++  }
++
++  /* Only update the tally if the value is not "unlimited". */
++  if (quotatab_limit.files_in_avail != 0) {
++
++    /* Prevent underflows. As this is an unsigned data type, the 
++     * underflow check is not as straightforward as checking for a value
++     * less than zero.
++     */
++    if (!(quotatab_tally.files_in_used == 0 && files_in_inc < 0))
++      quotatab_tally.files_in_used += files_in_inc;
++
++    quotatab_deltas.files_in_delta = files_in_inc;
++  }
++
++  /* Only update the tally if the value is not "unlimited". */
++  if (quotatab_limit.files_out_avail != 0) {
++
++    /* Prevent underflows. As this is an unsigned data type, the
++     * underflow check is not as straightforward as checking for a value
++     * less than zero.
++     */
++    if (!(quotatab_tally.files_out_used == 0 && files_out_inc < 0))
++      quotatab_tally.files_out_used += files_out_inc;
++
++    quotatab_deltas.files_out_delta = files_out_inc;
++  }
++
++  /* Only update the tally if the value is not "unlimited". */
++  if (quotatab_limit.files_xfer_avail != 0) {
++
++    /* Prevent underflows. As this is an unsigned data type, the
++     * underflow check is not as straightforward as checking for a value
++     * less than zero.
++     */
++    if (!(quotatab_tally.files_xfer_used == 0 && files_xfer_inc < 0))
++      quotatab_tally.files_xfer_used += files_xfer_inc;
++
++    quotatab_deltas.files_xfer_delta = files_xfer_inc;
++  }
++
++  /* No need to write out to the stream if per-session quotas are in effect. */
++  if (quotatab_limit.quota_per_session) {
++    memset(&quotatab_deltas, '\0', sizeof(quotatab_deltas));
++    quotatab_unlock(TYPE_TALLY);
++    return 0;
++  }
++
++  if (tally_tab->tab_write(tally_tab) < 0) {
++    quotatab_log("error: unable to update tally entry: %s", strerror(errno));
++    quotatab_unlock(TYPE_TALLY);
++    memset(&quotatab_deltas, '\0', sizeof(quotatab_deltas));
++    return -1;
++  }
++
++  /* Release the lock */
++  if (quotatab_unlock(TYPE_TALLY) < 0) {
++    quotatab_log("error: unable to release write lock: %s", strerror(errno));
++    memset(&quotatab_deltas, '\0', sizeof(quotatab_deltas));
++    return -1;
++  }
++
++  memset(&quotatab_deltas, '\0', sizeof(quotatab_deltas));
++  return 0;
++}
++
++/* Configuration handlers
++ */
++
++/* usage: QuotaDirectoryTally <on|off> */
++MODRET set_quotadirtally(cmd_rec *cmd) {
++  int bool = -1;
++  config_rec *c = NULL;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  if ((bool = get_boolean(cmd, 1)) == -1)
++    CONF_ERROR(cmd, "expected boolean argument");
++
++  c = add_config_param(cmd->argv[0], 1, NULL);
++  c->argv[0] = pcalloc(c->pool, sizeof(unsigned char));
++  *((unsigned char *) c->argv[0]) = (unsigned char) bool;
++
++  return HANDLED(cmd);
++}
++
++/* usage: QuotaDisplayUnits <b|Kb|Mb|Gb> */
++MODRET set_quotadisplayunits(cmd_rec *cmd) {
++  quota_units_t units = BYTE;
++  config_rec *c = NULL;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  if (strcasecmp(cmd->argv[1], "b") == 0) {
++    /* No need to assign to the units variable, as it defaults to
++     * displaying bytes
++     */
++    ;
++
++  } else if (strcasecmp(cmd->argv[1], "Kb") == 0) {
++    units = KILO;
++
++  } else if (strcasecmp(cmd->argv[1], "Mb") == 0) {
++    units = MEGA;
++
++  } else if (strcasecmp(cmd->argv[1], "Gb") == 0) {
++    units = GIGA;
++
++  } else
++    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, ": unknown display units: ",
++      cmd->argv[1], NULL));
++
++  c = add_config_param(cmd->argv[0], 1, NULL);
++  c->argv[0] = palloc(c->pool, sizeof(quota_units_t));
++  *((quota_units_t *) c->argv[0]) = units;
++
++  return HANDLED(cmd);
++}
++
++/* usage: QuotaEngine <on|off> */
++MODRET set_quotaengine(cmd_rec *cmd) {
++  int bool = -1;
++  config_rec *c = NULL;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  if ((bool = get_boolean(cmd, 1)) == -1)
++    CONF_ERROR(cmd, "expected boolean argument");
++
++  c = add_config_param(cmd->argv[0], 1, NULL);
++  c->argv[0] = pcalloc(c->pool, sizeof(unsigned char));
++  *((unsigned char *) c->argv[0]) = (unsigned char) bool;
++
++  return HANDLED(cmd);
++}
++
++/* usage: QuotaLock file */
++MODRET set_quotalock(cmd_rec *cmd) {
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  /* Check for non-absolute paths */
++  if (*cmd->argv[1] != '/')
++    CONF_ERROR(cmd, "absolute path required");
++
++  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
++
++  return HANDLED(cmd);
++}
++
++/* usage: QuotaLog path|"none" */
++MODRET set_quotalog(cmd_rec *cmd) {
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
++
++  return HANDLED(cmd);
++}
++
++/* usage: QuotaShowQuotas <on|off> */
++MODRET set_quotashowquotas(cmd_rec *cmd) {
++  int bool = -1;
++  config_rec *c = NULL;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  if ((bool = get_boolean(cmd, 1)) == -1)
++    CONF_ERROR(cmd, "expected boolean argument");
++
++  c = add_config_param(cmd->argv[0], 1, NULL);
++  c->argv[0] = pcalloc(c->pool, sizeof(unsigned char));
++  *((unsigned char *) c->argv[0]) = (unsigned char) bool;
++
++  return HANDLED(cmd);
++}
++
++/* usage: Quota{Limit,Tally}Table <source-type:source-info> */
++MODRET set_quotatable(cmd_rec *cmd) {
++  register quota_regtab_t *regtab = NULL;
++  unsigned char have_registration = FALSE;
++  char *tmp = NULL;
++  unsigned int tabflag = 0;
++
++  CHECK_ARGS(cmd, 1);
++  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
++
++  /* Separate the parameter into the separate pieces.  The parameter is 
++   * given as one string to enhance its similarity to URL syntax.
++   */
++  if ((tmp = strchr(cmd->argv[1], ':')) == NULL)
++    CONF_ERROR(cmd, "badly formatted parameter");
++
++  *tmp++ = '\0';
++
++  /* Verify that the requested source type has been registered, and supports
++   * the table type (limit or tally).
++   */
++  if (!strcasecmp(cmd->argv[0], "QuotaLimitTable"))
++    tabflag = QUOTATAB_LIMIT_SRC;
++
++  else if (!strcasecmp(cmd->argv[0], "QuotaTallyTable"))
++    tabflag = QUOTATAB_TALLY_SRC;
++
++  for (regtab = quota_regtab_list; regtab; regtab = regtab->next)
++    if ((regtab->regtab_srcs & tabflag) &&
++        !strcasecmp(regtab->regtab_name, cmd->argv[1])) {
++      have_registration = TRUE;
++      break;
++    }
++
++  if (!have_registration)
++    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "unsupported table source type: '",
++      cmd->argv[1], "'", NULL));
++
++  add_config_param_str(cmd->argv[0], 2, cmd->argv[1], tmp);
++  return HANDLED(cmd);
++}
++
++/* Command handlers
++ */
++
++MODRET quotatab_pre_appe(cmd_rec *cmd) {
++  struct stat sbuf;
++
++  /* sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* refresh the tally */
++  QUOTATAB_TALLY_READ
++
++  /* Briefly cache the size (in bytes) of the file being appended to, so that
++   * if successful, the byte counts can be adjusted correctly.
++   */
++  pr_fs_clear_cache();
++  if (pr_fsio_lstat(cmd->arg, &sbuf) < 0)
++    quotatab_disk_bytes = 0;
++  else
++    quotatab_disk_bytes = sbuf.st_size;
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_post_appe(cmd_rec *cmd) {
++  struct stat sbuf;
++  off_t append_bytes = session.xfer.total_bytes;
++
++  /* sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Check on the size of the appended-to file again, and use the difference
++   * in file size as the increment.  Make sure that no caching effects 
++   * mess with the stat.
++   */
++  pr_fs_clear_cache();
++  if (pr_fsio_lstat(cmd->arg, &sbuf) >= 0)
++    append_bytes = sbuf.st_size - quotatab_disk_bytes;
++
++  /* Write out an updated quota entry. */
++  QUOTATAB_TALLY_WRITE(append_bytes, 0, session.xfer.total_bytes, 0, 0, 0)
++
++  /* Check the bytes quotas to see if any have been reached.  Report this
++   * to the user if so.
++   */
++  if (quotatab_limit.bytes_in_avail > 0.0 &&
++      quotatab_tally.bytes_in_used >= quotatab_limit.bytes_in_avail) {
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_IN(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_IN(cmd));
++
++  } else if (quotatab_limit.bytes_xfer_avail > 0.0 &&
++      quotatab_tally.bytes_xfer_used >= quotatab_limit.bytes_xfer_avail) {
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_XFER(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_XFER(cmd));
++  }
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_post_appe_err(cmd_rec *cmd) {
++  struct stat sbuf;
++  off_t append_bytes = session.xfer.total_bytes;
++
++  /* sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Check on the size of the appended-to file again, and use the difference
++   * in file size as the increment.  Make sure that no caching effects 
++   * mess with the stat.
++   */
++  pr_fs_clear_cache();
++  if (pr_fsio_lstat(cmd->arg, &sbuf) >= 0)
++    append_bytes = sbuf.st_size - quotatab_disk_bytes;
++
++  /* Write out an updated quota entry */
++  QUOTATAB_TALLY_WRITE(append_bytes, 0, session.xfer.total_bytes, 0, 0, 0)
++
++  /* Check the bytes quotas to see if any have been reached.  Report this
++   * to the user if so.
++   */
++  if (quotatab_limit.bytes_in_avail > 0.0 &&
++      quotatab_tally.bytes_in_used >= quotatab_limit.bytes_in_avail) {
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_IN(cmd));
++    pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++      cmd->argv[0], DISPLAY_BYTES_IN(cmd));
++
++  } else if (quotatab_limit.bytes_xfer_avail > 0.0 &&
++      quotatab_tally.bytes_xfer_used >= quotatab_limit.bytes_xfer_avail) {
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_XFER(cmd));
++    pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++      cmd->argv[0], DISPLAY_BYTES_XFER(cmd));
++  }
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_pre_dele(cmd_rec *cmd) {
++  struct stat sbuf;
++
++  /* sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Briefly cache the size (in bytes) of the file to be deleted, so that
++   * if successful, the byte counts can be adjusted correctly.
++   */
++  pr_fs_clear_cache();
++  if (pr_fsio_lstat(cmd->arg, &sbuf) < 0)
++    quotatab_disk_bytes = 0;
++
++  else
++    quotatab_disk_bytes = sbuf.st_size;
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_post_dele(cmd_rec *cmd) {
++
++  /* sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd); 
++
++  /* Write out an updated quota entry. */
++  QUOTATAB_TALLY_WRITE(-quotatab_disk_bytes, 0, -quotatab_disk_bytes,
++    -1, 0, -1)
++
++  /* NOTE: if use_dirs is TRUE, also take into consideration the decreased
++   * disk usage caused by any decrease in the size of the containing directory.
++   */
++
++  /* Clear the cached bytes. */
++  quotatab_disk_bytes = 0;
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_pre_mkd(cmd_rec *cmd) {
++
++  /* Sanity check. */
++  if (!use_dirs)
++    return DECLINED(cmd);
++
++  /* Use quotatab_pre_stor() for most of the work. */
++  return quotatab_pre_stor(cmd);
++}
++
++MODRET quotatab_post_mkd(cmd_rec *cmd) {
++
++  /* Sanity check. */
++  if (!use_dirs)
++    return DECLINED(cmd);
++
++  /* Use quotatab_post_stor() for most of the work. */
++  return quotatab_post_stor(cmd);
++}
++
++MODRET quotatab_post_mkd_err(cmd_rec *cmd) {
++
++  /* Sanity check. */
++  if (!use_dirs)
++    return DECLINED(cmd);
++
++  /* Use quotatab_post_stor_err() for most of the work. */
++  return quotatab_post_stor_err(cmd);
++}
++
++MODRET quotatab_post_pass(cmd_rec *cmd) {
++  unsigned char have_limit_entry = FALSE;
++  have_quota_entry = FALSE;
++
++  /* Be done now if there is no quota table */
++  if (!use_quotas || !have_quota_limit_table || !have_quota_tally_table) {
++    use_quotas = FALSE;
++    quotatab_log("turning QuotaEngine off");
++    return DECLINED(cmd);
++  }
++
++  /* Check for a limit and a tally entry for this user. */
++  if (quotatab_lookup(TYPE_LIMIT, session.user, USER_QUOTA)) {
++    quotatab_log("found limit entry for user '%s'", session.user);
++    have_limit_entry = TRUE;
++
++    if (quotatab_lookup(TYPE_TALLY, session.user, USER_QUOTA)) {
++      quotatab_log("found tally entry for user '%s'", session.user);
++      have_quota_entry = TRUE;
++    }
++  }
++
++  /* Check for a limit and a tally entry for this group. */
++  if (!have_limit_entry) {
++    if (quotatab_lookup(TYPE_LIMIT, session.group, GROUP_QUOTA)) {
++      quotatab_log("found limit entry for group '%s'", session.group);
++      have_limit_entry = TRUE;
++
++      if (quotatab_lookup(TYPE_TALLY, session.group, GROUP_QUOTA)) {
++        quotatab_log("found tally entry for group '%s'", session.group);
++        have_quota_entry = TRUE;
++      }
++    }
++  }
++
++  /* Check for a limit and a tally entry for this class. */
++  if (!have_limit_entry && session.class) {
++    if (quotatab_lookup(TYPE_LIMIT, session.class->name, CLASS_QUOTA)) {
++      quotatab_log("found limit entry for class '%s'", session.class->name);
++      have_limit_entry = TRUE;
++
++      if (quotatab_lookup(TYPE_TALLY, session.class->name, CLASS_QUOTA)) {
++        quotatab_log("found tally entry for class '%s'", session.class->name);
++        have_quota_entry = TRUE;
++      }
++    }
++  }
++
++  /* Check for a limit and a tally entry for everyone. */
++  if (!have_limit_entry) {
++    if (quotatab_lookup(TYPE_LIMIT, NULL, ALL_QUOTA)) {
++      quotatab_log("found limit entry for all");
++      have_limit_entry = TRUE;
++
++      if (quotatab_lookup(TYPE_TALLY, NULL, ALL_QUOTA)) {
++        quotatab_log("found tally entry for all");
++        have_quota_entry = TRUE;
++      }
++    }
++  }
++
++  /* Close the limit table -- no need to keep it open anymore */
++  if (quotatab_close(TYPE_LIMIT) < 0)
++    quotatab_log("error closing QuotaLimitTable: %s", strerror(errno));
++
++  /* Only create a new tally entry if there is a corresponding limit
++   * entry.
++   */
++
++  if (have_limit_entry && !have_quota_entry) {
++    memset(quotatab_tally.name, '\0', sizeof(quotatab_tally.name));
++    snprintf(quotatab_tally.name, sizeof(quotatab_tally.name), "%s",
++      quotatab_limit.name);
++    quotatab_tally.name[sizeof(quotatab_tally.name)-1] = '\0';
++
++    quotatab_tally.quota_type = quotatab_limit.quota_type;
++
++    /* Initial tally values. */
++    quotatab_tally.bytes_in_used = 0.0F;
++    quotatab_tally.bytes_out_used = 0.0F;
++    quotatab_tally.bytes_xfer_used = 0.0F;
++    quotatab_tally.files_in_used = 0U;
++    quotatab_tally.files_out_used = 0U;
++    quotatab_tally.files_xfer_used = 0U;
++
++    quotatab_log("creating new tally entry to match limit entry");
++
++    if (quotatab_create()) {
++      quotatab_log("new tally entry successfully created");
++      have_quota_entry = TRUE;
++
++    } else
++      quotatab_log("error: unable to create tally entry: %s",
++        strerror(errno));
++  }
++
++  if (have_quota_entry) {
++
++    /* Assume that quotatab_lookup() does the reading in of the necessary
++     * data from the quota source table as well.
++     */
++
++    /* If per-session quotas are in effect, zero the tally record now */
++    if (quotatab_limit.quota_per_session) {
++      quotatab_tally.bytes_in_used = 0.0F;
++      quotatab_tally.bytes_out_used = 0.0F;
++      quotatab_tally.bytes_xfer_used = 0.0F;
++      quotatab_tally.files_in_used = 0U;
++      quotatab_tally.files_out_used = 0U;
++      quotatab_tally.files_xfer_used = 0U;
++    }
++
++  } else {
++
++    /* No quota entry for this user.  Make sure the quotas are not used. */
++    quotatab_log("no quota entry found, turning QuotaEngine off");
++    use_quotas = FALSE;
++  }
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_pre_retr(cmd_rec *cmd) {
++
++  /* Sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Refresh the tally */
++  QUOTATAB_TALLY_READ
++
++  /* Check quotas to see if bytes download or total quota has been reached.
++   * Block command if so.
++   */
++  if (quotatab_limit.bytes_out_avail > 0.0 &&
++      quotatab_tally.bytes_out_used >= quotatab_limit.bytes_out_avail) {
++
++    /* Report the exceeding of the threshhold. */
++    quotatab_log("%s denied: quota exceeded: used %s", cmd->argv[0],
++      DISPLAY_BYTES_OUT(cmd));
++    pr_response_add_err(R_451, "%s denied: quota exceeded: used %s",
++      cmd->argv[0], DISPLAY_BYTES_OUT(cmd));
++    have_err_response = TRUE;
++    return ERROR(cmd);
++
++  } else if (quotatab_limit.bytes_xfer_avail > 0.0 &&
++      quotatab_tally.bytes_xfer_used >= quotatab_limit.bytes_xfer_avail) {
++
++    /* Report the exceeding of the threshhold. */
++    quotatab_log("%s denied: quota exceeded: used %s", cmd->argv[0],
++      DISPLAY_BYTES_XFER(cmd));
++    pr_response_add_err(R_451, "%s denied: quota exceeded: used %s",
++      cmd->argv[0], DISPLAY_BYTES_XFER(cmd));
++    have_err_response = TRUE;
++    return ERROR(cmd);
++  }
++
++  /* Check quotas to see if files download or total quota has been reached.
++   * Block command if so.
++   */
++  if (quotatab_limit.files_out_avail != 0 &&
++      quotatab_tally.files_out_used >= quotatab_limit.files_out_avail) {
++
++    /* Report the exceeding of the threshhold. */
++    quotatab_log("%s denied: quota exceeded: used %s", cmd->argv[0],
++      DISPLAY_FILES_OUT(cmd));
++    pr_response_add_err(R_451, "%s denied: quota exceeded: used %s",
++      cmd->argv[0], DISPLAY_FILES_OUT(cmd));
++    have_err_response = TRUE;
++    return ERROR(cmd);
++
++  } else if (quotatab_limit.files_xfer_avail != 0 &&
++      quotatab_tally.files_xfer_used >= quotatab_limit.files_xfer_avail) {
++
++    /* Report the exceeding of the threshhold. */
++    quotatab_log("%s: denied: quota exceeded: used %s", cmd->argv[0],
++      DISPLAY_FILES_XFER(cmd));
++    pr_response_add(R_451, "%s denied: quota exceeded: used %s", cmd->argv[0],
++      DISPLAY_FILES_XFER(cmd));
++    have_err_response = TRUE;
++    return ERROR(cmd);
++  }
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_post_retr(cmd_rec *cmd) {
++
++  /* Sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Write out an updated tally */
++  QUOTATAB_TALLY_WRITE(0, session.xfer.total_bytes, session.xfer.total_bytes,
++    0, 1, 1)
++
++  /* Check quotas to see if bytes download or total quota has been reached.
++   * Report this to user if so.
++   */
++  if (quotatab_limit.bytes_out_avail > 0.0 &&
++      quotatab_tally.bytes_out_used >= quotatab_limit.bytes_out_avail) {
++
++    /* Report the reaching of the threshhold. */
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_OUT(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_OUT(cmd));
++
++  } else if (quotatab_limit.bytes_xfer_avail > 0.0 &&
++      quotatab_tally.bytes_xfer_used >= quotatab_limit.bytes_xfer_avail) {
++
++    /* Report the reaching of the threshhold. */
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_XFER(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_XFER(cmd));
++  }
++
++  /* Check quotas to see if files download or total quota has been reached.
++   * Report this to user if so.
++   */
++  if (quotatab_limit.files_out_avail != 0 && 
++      quotatab_tally.files_out_used >= quotatab_limit.files_out_avail) {
++
++    /* Report the reaching of the threshhold. */
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_OUT(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_OUT(cmd));
++
++  } else if (quotatab_limit.files_xfer_avail != 0 &&
++    quotatab_tally.files_xfer_used >= quotatab_limit.files_xfer_avail) {
++
++    /* Report the reaching of the threshhold. */
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_XFER(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_XFER(cmd));
++  }
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_post_retr_err(cmd_rec *cmd) {
++
++  /* Sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Write out an updated tally */
++  QUOTATAB_TALLY_WRITE(0, session.xfer.total_bytes, session.xfer.total_bytes,
++    0, 0, 0)
++
++  /* Check quotas to see if bytes download or total quota has been reached.
++   * Report this to user if so (if not already reported).
++   */
++  if (quotatab_limit.bytes_out_avail > 0.0 &&
++      quotatab_tally.bytes_out_used >= quotatab_limit.bytes_out_avail) {
++
++    if (!have_err_response) {
++
++      /* Report the reaching of the threshhold. */
++      quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++        DISPLAY_BYTES_OUT(cmd));
++      pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++        cmd->argv[0], DISPLAY_BYTES_OUT(cmd));
++    }
++
++  } else if (quotatab_limit.bytes_xfer_avail > 0.0 &&
++      quotatab_tally.bytes_xfer_used >= quotatab_limit.bytes_xfer_avail) {
++
++    if (!have_err_response) {
++
++      /* Report the reaching of the threshhold. */
++      quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++        DISPLAY_BYTES_XFER(cmd));
++      pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++        cmd->argv[0], DISPLAY_BYTES_XFER(cmd));
++    }
++  }
++
++  /* Check quotas to see if files download or total quota has been reached.
++   * Report this to user if so (if not already reported).
++   */
++  if (quotatab_limit.files_out_avail != 0 &&
++      quotatab_tally.files_out_used >= quotatab_limit.files_out_avail) {
++
++    if (!have_err_response) {
++
++      /* Report the reaching of the treshhold. */
++      quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++        DISPLAY_FILES_OUT(cmd));
++      pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++        cmd->argv[0], DISPLAY_FILES_OUT(cmd));
++    }
++
++  } else if (quotatab_limit.files_xfer_avail != 0 &&
++    quotatab_tally.files_xfer_used >= quotatab_limit.files_xfer_avail) {
++
++    if (!have_err_response) {
++
++      /* Report the reaching of the treshhold. */
++      quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++        DISPLAY_FILES_XFER(cmd));
++      pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++        cmd->argv[0], DISPLAY_FILES_XFER(cmd));
++    }
++  }
++
++  have_err_response = FALSE;
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_pre_rmd(cmd_rec *cmd) {
++  struct stat sbuf;
++
++  /* Sanity check. */
++  if (!use_quotas || !use_dirs)
++    return DECLINED(cmd);
++
++  /* Briefly cache the size (in bytes) of the directory to be deleted, so that
++   * if successful, the byte counts can be adjusted correctly.
++   */
++  pr_fs_clear_cache();
++  if (pr_fsio_lstat(cmd->arg, &sbuf) < 0)
++    quotatab_disk_bytes = 0;
++  else
++    quotatab_disk_bytes = sbuf.st_size;
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_post_rmd(cmd_rec *cmd) {
++
++  /* Sanity check. */
++  if (!use_quotas || !use_dirs)
++    return DECLINED(cmd);
++
++  /* Write out an updated quota entry. */
++  QUOTATAB_TALLY_WRITE(-quotatab_disk_bytes, 0, -quotatab_disk_bytes,
++    -1, 0, -1)
++
++  /* Clear the cached bytes. */
++  quotatab_disk_bytes = 0;
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_pre_rnto(cmd_rec *cmd) {
++  struct stat sbuf;
++
++  /* Sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Briefly cache the size (in bytes) of the file being overwritten, so that
++   * if successful, the byte counts can be adjusted correctly.
++   */
++  pr_fs_clear_cache();
++  if (pr_fsio_lstat(cmd->arg, &sbuf) < 0)
++    quotatab_disk_bytes = 0;
++  else
++    quotatab_disk_bytes = sbuf.st_size;
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_post_rnto(cmd_rec *cmd) {
++
++  /* Sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Write out an updated quota entry. */
++  QUOTATAB_TALLY_WRITE(-quotatab_disk_bytes, 0, -quotatab_disk_bytes,
++    -1, 0, -1)
++
++  /* Clear the cached bytes. */
++  quotatab_disk_bytes = 0;
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_pre_stor(cmd_rec *cmd) {
++  struct stat sbuf;
++ 
++  /* Sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Refresh the tally */
++  QUOTATAB_TALLY_READ
++
++  /* Check quotas to see if bytes upload or total quota has been reached.
++   * Block command if so.
++   */
++  if (quotatab_limit.bytes_in_avail > 0.0 &&
++      quotatab_tally.bytes_in_used >= quotatab_limit.bytes_in_avail) {
++
++    /* Report the exceeding of the threshhold. */
++    quotatab_log("%s denied: quota exceeded: used %s", cmd->argv[0],
++      DISPLAY_BYTES_IN(cmd));
++    pr_response_add_err(R_552, "%s denied: quota exceeded: used %s",
++      cmd->argv[0], DISPLAY_BYTES_IN(cmd));
++    have_err_response = TRUE;
++    return ERROR(cmd);
++
++  } else if (quotatab_limit.bytes_xfer_avail > 0.0 &&
++      quotatab_tally.bytes_xfer_used >= quotatab_limit.bytes_xfer_avail) {
++
++    /* Report the exceeding of the threshhold. */
++    quotatab_log("%s denied: quota exceeded: used %s", cmd->argv[0],
++      DISPLAY_BYTES_XFER(cmd));
++    pr_response_add_err(R_552, "%s denied: quota exceeded: used %s",
++      cmd->argv[0], DISPLAY_BYTES_XFER(cmd));
++    have_err_response = TRUE;
++    return ERROR(cmd);
++  }
++
++  /* Check quotas to see if files upload or total quota has been reached.
++   * Block the command if so.
++   */
++  if (quotatab_limit.files_in_avail != 0 &&
++      quotatab_tally.files_in_used >= quotatab_limit.files_in_avail) {
++
++    /* Repor the exceeding of the threshhold. */
++    quotatab_log("%s denied: quota exceeded: used %s", cmd->argv[0],
++      DISPLAY_FILES_IN(cmd));
++    pr_response_add_err(R_552, "%s denied: quota exceeded: used %s",
++      cmd->argv[0], DISPLAY_FILES_IN(cmd));
++    have_err_response = TRUE;
++    return ERROR(cmd);
++
++  } else if (quotatab_limit.files_xfer_avail != 0 &&
++      quotatab_tally.files_xfer_used >= quotatab_limit.files_xfer_avail) {
++
++    /* Report the exceeding of the threshhold. */
++    quotatab_log("%s denied: quota exceeded: used %s", cmd->argv[0],
++      DISPLAY_FILES_IN(cmd));
++    pr_response_add_err(R_552, "%s denied: quota exceeded: used %s",
++      cmd->argv[0], DISPLAY_FILES_IN(cmd));
++    have_err_response = TRUE;
++    return ERROR(cmd);
++  }
++
++  /* Briefly cache the size (in bytes) of the file being appended to, so that
++   * if successful, the byte counts can be adjusted correctly.  If the
++   * stat fails, it means that a new file is being uploaded, so set the
++   * disk_bytes to be zero. 
++   */
++  pr_fs_clear_cache();
++  if (pr_fsio_lstat(cmd->arg, &sbuf) < 0)
++    quotatab_disk_bytes = 0;
++  else
++    quotatab_disk_bytes = sbuf.st_size;
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_post_stor(cmd_rec *cmd) {
++  struct stat sbuf;
++  off_t store_bytes = session.xfer.total_bytes;
++
++  /* Sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Check on the size of the stored file again, and use the difference
++   * in file size as the increment.  Make sure that no caching effects
++   * mess with the stat.
++   */
++  pr_fs_clear_cache();
++  if (pr_fsio_lstat(cmd->arg, &sbuf) >= 0) 
++    store_bytes = sbuf.st_size - quotatab_disk_bytes;
++
++  /* NOTE: if use_dirs is TRUE, also take into consideration the increased
++   * disk usage caused by any increase in the size of the containing directory.
++   */
++
++  /* Write out an updated quota entry */
++  QUOTATAB_TALLY_WRITE(store_bytes, 0, session.xfer.total_bytes,
++    quotatab_disk_bytes ? 0 : 1, 0, 1)
++
++  /* Check quotas to see if bytes upload or total quota has been reached.
++   * Report this to user if so.  If it is a hard bytes limit, delete the
++   * uploaded file.
++   */
++  if (quotatab_limit.bytes_in_avail > 0.0 &&
++      quotatab_tally.bytes_in_used >= quotatab_limit.bytes_in_avail) {
++
++    /* Report the reaching of the threshhold. */
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_IN(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_IN(cmd));
++
++    if (quotatab_tally.bytes_in_used > quotatab_limit.bytes_in_avail &&
++        quotatab_limit.quota_limit_type == HARD_LIMIT) {
++      if (pr_fsio_unlink(cmd->arg) < 0) {
++        quotatab_log("notice: unable to unlink '%s': %s", cmd->arg,
++          strerror(errno));
++
++      } else {
++        QUOTATAB_TALLY_WRITE(-store_bytes, 0, -session.xfer.total_bytes,
++          -1, 0, -1);
++        
++        /* Report the removal of the file. */
++        quotatab_log("%s: quota reached: '%s' removed", cmd->argv[0], cmd->arg);
++        pr_response_add(R_DUP, "%s: notice: quota reached: '%s' removed",
++          cmd->argv[0], cmd->arg);
++      }
++    }
++
++  } else if (quotatab_limit.bytes_xfer_avail > 0.0 &&
++      quotatab_tally.bytes_xfer_used >= quotatab_limit.bytes_xfer_avail) {
++
++    /* Report the reaching of the threshhold. */ 
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_XFER(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_BYTES_XFER(cmd));
++
++    if (quotatab_tally.bytes_xfer_used > quotatab_limit.bytes_xfer_avail &&
++        quotatab_limit.quota_limit_type == HARD_LIMIT) {
++      if (pr_fsio_unlink(cmd->arg) < 0) {
++        quotatab_log("notice: unable to unlink '%s': %s", cmd->arg,
++          strerror(errno));
++
++      } else {
++        QUOTATAB_TALLY_WRITE(-store_bytes, 0, -session.xfer.total_bytes,
++          -1, 0, -1);
++
++        /* Report the removal of the file. */
++        quotatab_log("%s: quota reached: '%s' removed", cmd->argv[0], cmd->arg);
++        pr_response_add(R_DUP, "%s: notice: quota reached: '%s' removed",
++          cmd->argv[0], cmd->arg);
++      }
++    }
++  }
++
++  /* Check quotas to see if files upload or total quota has been reached.
++   * Report this to user if so.
++   */
++  if (quotatab_limit.files_in_avail != 0 &&
++      quotatab_tally.files_in_used >= quotatab_limit.files_in_avail) {
++
++    /* Report the reaching of the treshhold. */
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_IN(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_IN(cmd));
++
++  } else if (quotatab_limit.files_xfer_avail != 0 &&
++      quotatab_tally.files_xfer_used >= quotatab_limit.files_xfer_avail) {
++
++    /* Report the reaching of the threshhold. */
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_XFER(cmd));
++    pr_response_add(R_DUP, "%s: notice: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_XFER(cmd));
++  }
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_post_stor_err(cmd_rec *cmd) {
++  struct stat sbuf;
++  off_t store_bytes = session.xfer.total_bytes;
++
++  /* Sanity check */
++  if (!use_quotas)
++    return DECLINED(cmd);
++
++  /* Check on the size of the stored file again, and use the difference
++   * in file size as the increment.  Make sure that no caching effects 
++   * mess with the stat.
++   */
++  pr_fs_clear_cache();
++  if (pr_fsio_lstat(cmd->arg, &sbuf) >= 0) 
++    store_bytes = sbuf.st_size - quotatab_disk_bytes;
++
++  /* Write out an updated quota entry */
++  QUOTATAB_TALLY_WRITE(store_bytes, 0, session.xfer.total_bytes, 0, 0, 0)
++
++  /* Check quotas to see if bytes upload or total quota has been reached.
++   * Report this to user if so (if not already reported).  If it is a hard
++   * bytes limit, delete the uploaded file.
++   */
++  if (quotatab_limit.bytes_in_avail > 0.0 &&
++      quotatab_tally.bytes_in_used >= quotatab_limit.bytes_in_avail) {
++
++    if (!have_err_response) {
++
++      /* Report the reaching of the threshhold. */
++      quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++        DISPLAY_BYTES_IN(cmd));
++      pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++        cmd->argv[0], DISPLAY_BYTES_IN(cmd));
++    }
++
++    if (quotatab_tally.bytes_in_used > quotatab_limit.bytes_in_avail) {
++      if (quotatab_limit.quota_limit_type == HARD_LIMIT) {
++        if (pr_fsio_unlink(cmd->arg) < 0) {
++          quotatab_log("notice: unable to unlink '%s': %s", cmd->arg,
++            strerror(errno));
++
++        } else {
++
++          /* Report the removal of the file. */
++          quotatab_log("%s: quota reached: '%s' removed", cmd->argv[0],
++            cmd->arg);
++          pr_response_add_err(R_DUP, "%s: notice: quota reached: '%s' removed",
++            cmd->argv[0], cmd->arg);
++        }
++      }
++
++      QUOTATAB_TALLY_WRITE(-store_bytes, 0, -session.xfer.total_bytes, 0, 0, 0);
++    }
++
++  } else if (quotatab_limit.bytes_xfer_avail > 0.0 &&
++      quotatab_tally.bytes_xfer_used >= quotatab_limit.bytes_xfer_avail) {
++
++    if (!have_err_response) {
++
++      /* Report the reaching of the threshhold. */
++      quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++        DISPLAY_BYTES_XFER(cmd));
++      pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++        cmd->argv[0], DISPLAY_BYTES_XFER(cmd));
++    }
++
++    if (quotatab_tally.bytes_xfer_used > quotatab_limit.bytes_xfer_avail) {
++      if (quotatab_limit.quota_limit_type == HARD_LIMIT) {
++        if (pr_fsio_unlink(cmd->arg) < 0) {
++          quotatab_log("notice: unable to unlink '%s': %s", cmd->arg,
++            strerror(errno));
++
++        } else {
++
++          /* Report the removal of the file. */
++          quotatab_log("%s: quota reached: '%s' removed", cmd->argv[0],
++            cmd->arg);
++          pr_response_add_err(R_DUP, "%s: notice: quota reached: '%s' removed",
++            cmd->argv[0], cmd->arg);
++        }
++      }
++
++      QUOTATAB_TALLY_WRITE(-store_bytes, 0, -session.xfer.total_bytes, 0, 0, 0);
++    }
++  }
++
++  /* Check quotas to see if files upload or total quota has been reached.
++   * Report this to user if so.
++   */
++  if (quotatab_limit.files_in_avail != 0 &&
++      quotatab_tally.files_in_used >= quotatab_limit.files_in_avail) {
++
++    /* Report the reaching of the threshhold. */
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_IN(cmd));
++    pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++      cmd->argv[0], DISPLAY_FILES_IN(cmd));
++
++  } else if (quotatab_limit.files_xfer_avail != 0 &&
++      quotatab_tally.files_xfer_used >= quotatab_limit.files_xfer_avail) {
++
++    /* Report the reaching of the threshhold. */
++    quotatab_log("%s: quota reached: used %s", cmd->argv[0],
++      DISPLAY_FILES_XFER(cmd));
++    pr_response_add_err(R_DUP, "%s: notice: quota reached: used %s",
++      cmd->argv[0], DISPLAY_FILES_XFER(cmd));
++  }
++
++  return DECLINED(cmd);
++}
++
++MODRET quotatab_site(cmd_rec *cmd) {
++
++  /* Make sure it's a valid SITE QUOTA command */
++  if (cmd->argc < 2)
++    return DECLINED(cmd);
++
++  if (strcasecmp(cmd->argv[1], "QUOTA") == 0) {
++    unsigned char *authenticated = get_param_ptr(cmd->server->conf,
++      "authenticated", FALSE);
++
++    /* The user is required to be authenticated/logged in, first */
++    if (!authenticated || *authenticated == FALSE) {
++      pr_response_send(R_530, "Please login with USER and PASS");
++      return ERROR(cmd);
++    }
++
++    /* Is showing of the user's quota barred by configuration? */
++    if (!allow_site_quota) {
++      pr_response_add_err(R_500, "'SITE QUOTA' not understood.");
++      return ERROR(cmd);
++    }
++
++    /* Check for <Limit> restrictions. */
++    if (!dir_check(cmd->tmp_pool, "SITE_QUOTA", "NONE", session.cwd, NULL)) {
++      pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EPERM));
++      return ERROR(cmd);
++    }
++
++    /* Log that the user requested their quota. */
++    quotatab_log("SITE QUOTA requested by user %s", session.user);
++
++    /* If quotas are not in use, no need to do anything. */
++    if (!use_quotas || !have_quota_entry) {
++      pr_response_add(R_202, "No quotas in effect");
++      return HANDLED(cmd);
++    }
++
++    /* Refresh the tally. */
++    QUOTATAB_TALLY_READ
++
++    pr_response_add(R_200, "The current quota for this session are "
++      "[current/limit]:");
++
++    pr_response_add(R_DUP, "Name: %s", quotatab_limit.name);
++    pr_response_add(R_DUP, "Quota Type: %s",
++      (quotatab_limit.quota_type == USER_QUOTA ? "User" :
++       quotatab_limit.quota_type == GROUP_QUOTA ? "Group" :
++       quotatab_limit.quota_type == CLASS_QUOTA ? "Class" :
++       quotatab_limit.quota_type == ALL_QUOTA ? "All" :
++       "(unknown)"));
++
++    pr_response_add(R_DUP, "Per Session: %s",
++      quotatab_limit.quota_per_session ? "True" : "False");
++
++    pr_response_add(R_DUP, "Limit Type: %s",
++      (quotatab_limit.quota_limit_type == HARD_LIMIT ? "Hard" :
++       quotatab_limit.quota_limit_type == SOFT_LIMIT ? "Soft" :
++       "(unknown)"));
++
++    pr_response_add(R_DUP, "  Uploaded %s",
++      quota_display_site_bytes(cmd->tmp_pool, quotatab_tally.bytes_in_used,
++      quotatab_limit.bytes_in_avail));
++    pr_response_add(R_DUP, "  Downloaded %s",
++      quota_display_site_bytes(cmd->tmp_pool, quotatab_tally.bytes_out_used,
++      quotatab_limit.bytes_out_avail));
++    pr_response_add(R_DUP, "  Transferred %s",
++      quota_display_site_bytes(cmd->tmp_pool, quotatab_tally.bytes_xfer_used,
++      quotatab_limit.bytes_xfer_avail));
++
++    pr_response_add(R_DUP, "  Uploaded %s",
++      quota_display_site_files(cmd->tmp_pool, quotatab_tally.files_in_used,
++      quotatab_limit.files_in_avail));
++    pr_response_add(R_DUP, "  Downloaded %s",
++      quota_display_site_files(cmd->tmp_pool, quotatab_tally.files_out_used,
++      quotatab_limit.files_out_avail));
++    pr_response_add(R_DUP, "  Transferred %s",
++      quota_display_site_files(cmd->tmp_pool, quotatab_tally.files_xfer_used,
++      quotatab_limit.files_xfer_avail));
++
++    /* Add one final line to preserve the spacing. */
++    pr_response_add(R_DUP,
++      "Please contact %s if these entries are inaccurate",
++      cmd->server->ServerAdmin ? cmd->server->ServerAdmin : "ftp-admin");
++
++    return HANDLED(cmd);
++  }
++
++  if (strcasecmp(cmd->argv[1], "HELP") == 0) {
++
++    /* Add a description of SITE QUOTA to the output. */
++    pr_response_add(R_214, "QUOTA");
++  }
++
++  return DECLINED(cmd);
++}
++
++/* Initialization functions
++ */
++
++static void quotatab_rehash(void *data) {
++
++  /* "Bounce" the log file descriptor. */
++  quotatab_closelog();
++  quotatab_openlog();
++
++  /* Reset the module's memory pool. */
++  destroy_pool(quotatab_pool);
++  quotatab_pool = make_sub_pool(permanent_pool);
++
++  return;
++}
++
++static int quotatab_init(void) {
++
++  /* Initialize the module's memory pool. */
++  if (!quotatab_pool)
++    quotatab_pool = make_sub_pool(permanent_pool);
++
++  /* Register a rehash handler. */
++  pr_rehash_register_handler(NULL, quotatab_rehash);
++
++  return 0;
++}
++
++static int quotatab_sess_init(void) {
++  unsigned char *quotatab_engine = NULL, *quotatab_showquotas = NULL,
++    *quotatab_usedirs = NULL;
++  quota_units_t *units = NULL;
++
++  /* Check to see if quotas are enabled for this server. */
++  if ((quotatab_engine = get_param_ptr(main_server->conf, "QuotaEngine",
++      FALSE)) != NULL && *quotatab_engine == TRUE) {
++    use_quotas = TRUE;
++
++  } else {
++    use_quotas = FALSE;
++    return 0;
++  }
++
++  /* Check to see if SITE QUOTA enabled for this server. */
++  if ((quotatab_showquotas = get_param_ptr(main_server->conf, "QuotaShowQuotas",
++      FALSE)) != NULL && *quotatab_showquotas == FALSE)
++    allow_site_quota = FALSE;
++
++ else
++    allow_site_quota = TRUE;
++
++  quotatab_openlog();
++
++  /* Open the quota limit and tally tables.  This is being done while the
++   * proces still has root privs, so the tables _can_ be opened.  In the case
++   * of file quotastreams, the file descriptor is cached, so that this process,
++   * once root privs are dropped, is still able to read from and write to the
++   * streams.  Other confstream mechanisms may need to cache something
++   * similarly.
++   */
++  PRIVS_ROOT
++  if (quotatab_open(TYPE_LIMIT) < 0) {
++    PRIVS_RELINQUISH
++    quotatab_log("error: unable to open QuotaLimitTable: %s", strerror(errno));
++    have_quota_limit_table = FALSE;
++
++  } else {
++    PRIVS_RELINQUISH
++
++    /* Verify that it's a valid limit table */
++    if (quotatab_verify(TYPE_LIMIT))
++      have_quota_limit_table = TRUE;
++    else
++      use_quotas = FALSE;
++  }
++
++  PRIVS_ROOT
++  if (quotatab_open(TYPE_TALLY) < 0) {
++    PRIVS_RELINQUISH
++    quotatab_log("error: unable to open QuotaTallyTable: %s", strerror(errno));
++    have_quota_tally_table = FALSE;
++
++  } else {
++    PRIVS_RELINQUISH
++
++    /* Verify that it's a valid tally table */
++    if (quotatab_verify(TYPE_TALLY))
++      have_quota_tally_table = TRUE;
++    else
++      use_quotas = FALSE;
++  }
++
++  /* Make sure the tables will be closed when the child exits */
++  pr_exit_register_handler(quotatab_exit_cb);
++
++  /* Check for the units to display for byte quotas. */
++  units = get_param_ptr(main_server->conf, "QuotaDisplayUnits", FALSE);
++  byte_units = units ? *units : BYTE;
++
++  /* Check to see if directories are to be used for tallies for this server. */
++  if ((quotatab_usedirs = get_param_ptr(main_server->conf,
++      "QuotaDirectoryTally", FALSE)) != NULL && *quotatab_usedirs == TRUE)
++    use_dirs = TRUE;
++
++ else
++    use_dirs = FALSE;
++
++  return 0;
++}
++
++/* Module API tables
++ */
++
++static conftable quotatab_conftab[] = {
++  { "QuotaDirectoryTally",	set_quotadirtally,	NULL },
++  { "QuotaDisplayUnits",	set_quotadisplayunits,	NULL },
++  { "QuotaEngine",		set_quotaengine,	NULL },
++  { "QuotaLimitTable",		set_quotatable,		NULL },
++  { "QuotaLock",		set_quotalock,		NULL },
++  { "QuotaLog",			set_quotalog,		NULL },
++  { "QuotaShowQuotas",		set_quotashowquotas,	NULL },
++  { "QuotaTallyTable",		set_quotatable,		NULL },
++  { NULL }
++};
++
++static cmdtable quotatab_cmdtab[] = {
++  { PRE_CMD,		C_APPE, G_NONE, quotatab_pre_appe,	FALSE,	FALSE },
++  { POST_CMD,		C_APPE,	G_NONE,	quotatab_post_appe,	FALSE,	FALSE },
++  { POST_CMD_ERR,	C_APPE,	G_NONE,	quotatab_post_appe_err,	FALSE,	FALSE },
++  { PRE_CMD,		C_DELE,	G_NONE,	quotatab_pre_dele,	FALSE,	FALSE },
++  { POST_CMD,		C_DELE,	G_NONE,	quotatab_post_dele,	FALSE,	FALSE },
++  { PRE_CMD,		C_MKD,	G_NONE,	quotatab_pre_mkd,	FALSE,	FALSE },
++  { POST_CMD,		C_MKD,	G_NONE,	quotatab_post_mkd,	FALSE,	FALSE },
++  { POST_CMD_ERR,	C_MKD,	G_NONE,	quotatab_post_mkd_err,	FALSE,	FALSE },
++  { POST_CMD,		C_PASS,	G_NONE,	quotatab_post_pass,	FALSE,	FALSE },
++  { PRE_CMD,		C_RETR, G_NONE, quotatab_pre_retr,	FALSE,	FALSE },
++  { POST_CMD,		C_RETR,	G_NONE,	quotatab_post_retr,	FALSE,	FALSE },
++  { POST_CMD_ERR,	C_RETR,	G_NONE,	quotatab_post_retr_err,	FALSE,	FALSE },
++  { PRE_CMD,		C_RMD,	G_NONE,	quotatab_pre_rmd,	FALSE,	FALSE },
++  { POST_CMD,		C_RMD,	G_NONE,	quotatab_post_rmd,	FALSE,	FALSE },
++  { PRE_CMD,		C_RNTO,	G_NONE,	quotatab_pre_rnto,	FALSE,	FALSE },
++  { POST_CMD,		C_RNTO,	G_NONE,	quotatab_post_rnto,	FALSE,	FALSE },
++  { CMD,		C_SITE,	G_NONE,	quotatab_site,		FALSE,	FALSE },
++  { PRE_CMD,		C_STOR,	G_NONE, quotatab_pre_stor,	FALSE,	FALSE },
++  { POST_CMD,		C_STOR,	G_NONE,	quotatab_post_stor,	FALSE,	FALSE },
++  { POST_CMD_ERR,	C_STOR,	G_NONE,	quotatab_post_stor_err,	FALSE,	FALSE },
++  { PRE_CMD,		C_STOU,	G_NONE,	quotatab_pre_stor,	FALSE,	FALSE },
++  { POST_CMD,		C_STOU,	G_NONE,	quotatab_post_stor,	FALSE,	FALSE },
++  { POST_CMD_ERR,	C_STOU,	G_NONE,	quotatab_post_stor_err,	FALSE,	FALSE },
++  { PRE_CMD,		C_XMKD,	G_NONE,	quotatab_pre_mkd,	FALSE,	FALSE },
++  { POST_CMD,		C_XMKD,	G_NONE,	quotatab_post_mkd,	FALSE,	FALSE },
++  { POST_CMD_ERR,	C_XMKD,	G_NONE,	quotatab_post_mkd_err,	FALSE,	FALSE },
++  { PRE_CMD,		C_XRMD,	G_NONE,	quotatab_pre_rmd,	FALSE,	FALSE },
++  { POST_CMD,		C_XRMD,	G_NONE,	quotatab_post_rmd,	FALSE,	FALSE },
++  { 0, NULL }
++};
++
++module quotatab_module = {
++  NULL, NULL,
++
++  /* Module API version 2.0 */
++  0x20,
++
++  /* Module name */
++  "quotatab",
++
++  /* Module configuration handler table */
++  quotatab_conftab,
++
++  /* Module command handler table */
++  quotatab_cmdtab,
++
++  /* Module authentication handler table */
++  NULL,
++
++  /* Module initialization function */
++  quotatab_init,
++
++  /* Session initialization function */
++  quotatab_sess_init
++};
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab_file.c proftpd-1.2.9/contrib/mod_quotatab_file.c
+--- proftpd-1.2.9-old/contrib/mod_quotatab_file.c	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab_file.c	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,442 @@
++/*
++ * ProFTPD: mod_quotatab_file -- a mod_quotatab sub-module for managing quota
++ *                          data via file-based tables
++ *
++ * Copyright (c) 2002-2003 TJ Saunders
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
++ *
++ * As a special exemption, TJ Saunders gives permission to link this program
++ * with OpenSSL, and distribute the resulting executable, without including
++ * the source code for OpenSSL in the source distribution.
++ *
++ * $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $
++ */
++
++#include "mod_quotatab.h"
++
++#include <sys/types.h>
++#include <sys/uio.h>
++#include <unistd.h>
++
++/* bloody lack of consistency... */
++#if defined(FREEBSD4)
++#  define QUOTATAB_IOV_BASE_TYPE        (char *)
++#elif defined(LINUX)
++#  define QUOTATAB_IOV_BASE_TYPE        (__ptr_t)
++#elif defined(SOLARIS2)
++#  define QUOTATAB_IOV_BASE_TYPE        (caddr_t)
++#else
++#  define QUOTATAB_IOV_BASE_TYPE        (void *)
++#endif
++
++static int filetab_close(quota_table_t *filetab) {
++  int res = close(filetab->tab_handle);
++  filetab->tab_handle = -1;
++  return res;
++}
++
++static int filetab_create(quota_table_t *filetab) {
++  int res = -1;
++  struct iovec quotav[8];
++  off_t current_pos = 0;
++
++  /* Use writev() to make this more efficient.  It is done piecewise, rather
++   * than doing a normal write(2) directly from the struct pointer, to avoid
++   * alignment/padding issues.
++   */
++
++  quotav[0].iov_base = QUOTATAB_IOV_BASE_TYPE quotatab_tally.name;
++  quotav[0].iov_len = sizeof(quotatab_tally.name);
++
++  quotav[1].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.quota_type;
++  quotav[1].iov_len = sizeof(quotatab_tally.quota_type);
++
++  quotav[2].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.bytes_in_used;
++  quotav[2].iov_len = sizeof(quotatab_tally.bytes_in_used);
++
++  quotav[3].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.bytes_out_used;
++  quotav[3].iov_len = sizeof(quotatab_tally.bytes_out_used);
++
++  quotav[4].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.bytes_xfer_used;
++  quotav[4].iov_len = sizeof(quotatab_tally.bytes_xfer_used);
++
++  quotav[5].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.files_in_used;
++  quotav[5].iov_len = sizeof(quotatab_tally.files_in_used);
++
++  quotav[6].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.files_out_used;
++  quotav[6].iov_len = sizeof(quotatab_tally.files_out_used);
++
++  quotav[7].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.files_xfer_used;
++  quotav[7].iov_len = sizeof(quotatab_tally.files_xfer_used);
++
++  /* Seek to the end of the table */
++  current_pos = lseek(filetab->tab_handle, 0, SEEK_END);
++
++  if ((res = writev(filetab->tab_handle, quotav, 8)) > 0)
++
++    /* Rewind to the start of the entry. */
++    lseek(filetab->tab_handle, current_pos, SEEK_SET);
++
++  else if (res == 0)
++    /* If no bytes were written, it's an error. */
++    res = -1;
++
++  return res;
++}
++
++static unsigned char filetab_lookup(quota_table_t *filetab, const char *name,
++    quota_type_t quota_type) {
++
++  /* Make sure the table pointer is positioned at the start of the table,
++   * skipping the magic header value of the table.
++   */
++  lseek(filetab->tab_handle, sizeof(unsigned int), SEEK_SET);
++
++  /* Handle tally and limit tables differently... */
++
++  if (filetab->tab_type == TYPE_TALLY) {
++    while (filetab->tab_read(filetab) >= 0) {
++
++      /* Compare quota types.  If the quota type is ALL_QUOTA, don't
++       * worry about the name.
++       */
++      if (quota_type == quotatab_tally.quota_type) {
++
++        /* Match names if need be */
++        if (name && !strcmp(name, quotatab_tally.name))
++          return TRUE;
++
++        if (quota_type == ALL_QUOTA)
++          return TRUE;
++      }
++
++      /* Undo the auto-rewind of a single record's length done by
++       * filetab_read(), so that the while loop actually does iterate through
++       * all the available records.
++       */
++      lseek(filetab->tab_handle, filetab->tab_quotalen, SEEK_CUR);
++    }
++
++  } else if (filetab->tab_type == TYPE_LIMIT) {
++    while (filetab->tab_read(filetab) >= 0) {
++      if (quota_type == quotatab_limit.quota_type) {
++        if (name && !strcmp(name, quotatab_limit.name))
++          return TRUE;
++
++        if (quota_type == ALL_QUOTA)
++          return TRUE;
++      }
++
++      lseek(filetab->tab_handle, filetab->tab_quotalen, SEEK_CUR);
++    }
++  }
++
++  /* Default return value */
++  return FALSE;
++}
++
++static int filetab_read(quota_table_t *filetab) {
++  int res = -1;
++  struct iovec quotav[10];
++
++  /* Mark the current file position. */
++  off_t current_pos = lseek(filetab->tab_handle, 0, SEEK_CUR);
++
++  /* Use readv() to make this more efficient.  It is done piecewise, rather
++   * than doing a normal read(2) directly into the struct pointer, to avoid
++   * alignment/padding issues.
++   */
++
++  /* Handle the limit and tally tables differently. */
++
++  if (filetab->tab_type == TYPE_TALLY) {
++
++    quotav[0].iov_base = QUOTATAB_IOV_BASE_TYPE quotatab_tally.name;
++    quotav[0].iov_len = sizeof(quotatab_tally.name);
++
++    quotav[1].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.quota_type;
++    quotav[1].iov_len = sizeof(quotatab_tally.quota_type);
++
++    quotav[2].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.bytes_in_used;
++    quotav[2].iov_len = sizeof(quotatab_tally.bytes_in_used);
++
++    quotav[3].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.bytes_out_used;
++    quotav[3].iov_len = sizeof(quotatab_tally.bytes_out_used);
++
++    quotav[4].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.bytes_xfer_used;
++    quotav[4].iov_len = sizeof(quotatab_tally.bytes_xfer_used);
++
++    quotav[5].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.files_in_used;
++    quotav[5].iov_len = sizeof(quotatab_tally.files_in_used);
++
++    quotav[6].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.files_out_used;
++    quotav[6].iov_len = sizeof(quotatab_tally.files_out_used);
++
++    quotav[7].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.files_xfer_used;
++    quotav[7].iov_len = sizeof(quotatab_tally.files_xfer_used);
++
++    if ((res = readv(filetab->tab_handle, quotav, 8)) > 0)
++
++      /* Always rewind after reading a record. */
++      lseek(filetab->tab_handle, current_pos, SEEK_SET);
++
++    else if (res == 0) {
++
++      /* Assume end-of-file. */
++      errno = EOF;
++      res = -1;
++    }
++
++    return res;
++
++  } else if (filetab->tab_type == TYPE_LIMIT) {
++
++    quotav[0].iov_base = QUOTATAB_IOV_BASE_TYPE quotatab_limit.name;
++    quotav[0].iov_len = sizeof(quotatab_limit.name);
++
++    quotav[1].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_limit.quota_type;
++    quotav[1].iov_len = sizeof(quotatab_limit.quota_type);
++
++    quotav[2].iov_base = QUOTATAB_IOV_BASE_TYPE
++      &quotatab_limit.quota_per_session;
++    quotav[2].iov_len = sizeof(quotatab_limit.quota_per_session);
++
++    quotav[3].iov_base = QUOTATAB_IOV_BASE_TYPE
++      &quotatab_limit.quota_limit_type;
++    quotav[3].iov_len = sizeof(quotatab_limit.quota_limit_type);
++
++    quotav[4].iov_base = QUOTATAB_IOV_BASE_TYPE
++      &quotatab_limit.bytes_in_avail;
++    quotav[4].iov_len = sizeof(quotatab_limit.bytes_in_avail);
++
++    quotav[5].iov_base = QUOTATAB_IOV_BASE_TYPE
++      &quotatab_limit.bytes_out_avail;
++    quotav[5].iov_len = sizeof(quotatab_limit.bytes_out_avail);
++
++    quotav[6].iov_base = QUOTATAB_IOV_BASE_TYPE
++      &quotatab_limit.bytes_xfer_avail;
++    quotav[6].iov_len = sizeof(quotatab_limit.bytes_xfer_avail);
++
++    quotav[7].iov_base = QUOTATAB_IOV_BASE_TYPE
++      &quotatab_limit.files_in_avail;
++    quotav[7].iov_len = sizeof(quotatab_limit.files_in_avail);
++
++    quotav[8].iov_base = QUOTATAB_IOV_BASE_TYPE
++      &quotatab_limit.files_out_avail;
++    quotav[8].iov_len = sizeof(quotatab_limit.files_out_avail);
++
++    quotav[9].iov_base = QUOTATAB_IOV_BASE_TYPE
++      &quotatab_limit.files_xfer_avail;
++    quotav[9].iov_len = sizeof(quotatab_limit.files_xfer_avail);
++
++    if ((res = readv(filetab->tab_handle, quotav, 10)) > 0)
++
++      /* Always rewind after reading a record. */
++      lseek(filetab->tab_handle, current_pos, SEEK_SET);
++
++    else if (res == 0) {
++
++      /* Assume end-of-file. */
++      errno = EOF;
++      res = -1;
++    }
++
++    return res;
++  }
++
++  /* default */
++  errno = EINVAL;
++  return -1;
++}
++
++static unsigned char filetab_verify(quota_table_t *filetab) {
++  unsigned int magic = 0L;
++
++  /* Make sure we are positioned at the start of the table. */
++  lseek(filetab->tab_handle, 0, SEEK_SET);
++
++  /* Check the header of this table, to make sure it's valid. */
++  if (read(filetab->tab_handle, &magic, sizeof(magic)) != sizeof(magic))
++    return FALSE;
++
++  if (magic == filetab->tab_magic)
++    return TRUE;
++
++  return FALSE;
++}
++
++static int filetab_write(quota_table_t *filetab) {
++  int res = -1;
++  struct iovec quotav[8];
++
++  /* Mark the current file position. */
++  off_t current_pos = lseek(filetab->tab_handle, 0, SEEK_CUR);
++
++  /* Use writev() to make this more efficient.  It is done piecewise, rather
++   * than doing a normal write(2) directly from the struct pointer, to avoid
++   * alignment/padding issues.
++   */
++
++  quotav[0].iov_base = QUOTATAB_IOV_BASE_TYPE quotatab_tally.name;
++  quotav[0].iov_len = sizeof(quotatab_tally.name);
++
++  quotav[1].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.quota_type;
++  quotav[1].iov_len = sizeof(quotatab_tally.quota_type);
++
++  quotav[2].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.bytes_in_used;
++  quotav[2].iov_len = sizeof(quotatab_tally.bytes_in_used);
++
++  quotav[3].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.bytes_out_used;
++  quotav[3].iov_len = sizeof(quotatab_tally.bytes_out_used);
++
++  quotav[4].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.bytes_xfer_used;
++  quotav[4].iov_len = sizeof(quotatab_tally.bytes_xfer_used);
++
++  quotav[5].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.files_in_used;
++  quotav[5].iov_len = sizeof(quotatab_tally.files_in_used);
++
++  quotav[6].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.files_out_used;
++  quotav[6].iov_len = sizeof(quotatab_tally.files_out_used);
++
++  quotav[7].iov_base = QUOTATAB_IOV_BASE_TYPE &quotatab_tally.files_xfer_used;
++  quotav[7].iov_len = sizeof(quotatab_tally.files_xfer_used);
++
++  if ((res = writev(filetab->tab_handle, quotav, 8)) >= 0)
++
++    /* Always rewind after writing a record. */
++    lseek(filetab->tab_handle, current_pos, SEEK_SET);
++
++  else if (res == 0)
++
++    /* It's an error if no bytes are written. */
++    res = -1;
++
++  return res;
++}
++
++static int filetab_rlock(quota_table_t *filetab) {
++  filetab->tab_lock.l_type = F_RDLCK;
++  return fcntl(filetab->tab_handle, F_SETLK, &filetab->tab_lock);
++}
++
++static int filetab_unlock(quota_table_t *filetab) {
++  filetab->tab_lock.l_type = F_UNLCK;
++  return fcntl(filetab->tab_handle, F_SETLK, &filetab->tab_lock);
++}
++
++static int filetab_wlock(quota_table_t *filetab) {
++  filetab->tab_lock.l_type = F_WRLCK;
++  return fcntl(filetab->tab_handle, F_SETLK, &filetab->tab_lock);
++}
++
++static quota_table_t *filetab_open(pool *parent_pool,
++    quota_tabtype_t tab_type, const char *srcinfo) {
++  quota_table_t *tab = NULL;
++  pool *tab_pool = make_sub_pool(parent_pool);
++
++  tab = (quota_table_t *) pcalloc(tab_pool, sizeof(quota_table_t));
++  tab->tab_pool = tab_pool;
++  tab->tab_type = tab_type;
++
++  if (tab->tab_type == TYPE_TALLY) {
++
++    /* File-based tally table magic number */
++    tab->tab_magic = 0x07644;
++
++    /* File-based tally record length, manually defined to avoid alignment/
++     * padding issues when using sizeof().
++     */
++    tab->tab_quotalen = 121;
++
++    tab->tab_lock.l_whence = SEEK_CUR;
++    tab->tab_lock.l_start = 0;
++    tab->tab_lock.l_len = tab->tab_quotalen;
++
++    /* Open the table handle */
++    if ((tab->tab_handle = open(srcinfo, O_RDWR)) < 0) {
++      destroy_pool(tab->tab_pool);
++      return NULL;
++    }
++
++  } else if (tab->tab_type == TYPE_LIMIT) {
++
++    /* File-based limit table magic number */
++    tab->tab_magic = 0x07626;
++
++    /* File-based limit record length, manually defined to avoid alignment/
++     * padding issues when using sizeof().
++     */
++    tab->tab_quotalen = 126;
++    tab->tab_lock.l_whence = SEEK_CUR;
++    tab->tab_lock.l_start = 0;
++    tab->tab_lock.l_len = tab->tab_quotalen;
++
++    /* Open the table handle */
++    if ((tab->tab_handle = open(srcinfo, O_RDONLY)) < 0) {
++      destroy_pool(tab->tab_pool);
++      return NULL;
++    }
++  }
++
++  /* Set all the necessary function pointers. */
++  tab->tab_close = filetab_close;
++  tab->tab_create = filetab_create;
++  tab->tab_lookup = filetab_lookup;
++  tab->tab_read = filetab_read;
++  tab->tab_verify = filetab_verify;
++  tab->tab_write = filetab_write;
++
++  tab->tab_rlock = filetab_rlock;
++  tab->tab_unlock = filetab_unlock;
++  tab->tab_wlock = filetab_wlock;
++
++  return tab;
++}
++
++static int filetab_init(void) {
++
++  /* Initialize the quota source objects for type "file".
++   */
++  quotatab_register("file", filetab_open,
++    QUOTATAB_LIMIT_SRC|QUOTATAB_TALLY_SRC);
++
++  return 0;
++}
++
++module quotatab_file_module = {
++  NULL, NULL,
++
++  /* Module API version 2.0 */
++  0x20,
++
++  /* Module name */
++  "quotatab_file",
++
++  /* Module configuration handler table */
++  NULL,
++
++  /* Module command handler table */
++  NULL,
++
++  /* Module authentication handler table */
++  NULL,
++
++  /* Module initialization function */
++  filetab_init,
++
++  /* Module child initialization function */
++  NULL
++};
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab_file.html proftpd-1.2.9/contrib/mod_quotatab_file.html
+--- proftpd-1.2.9-old/contrib/mod_quotatab_file.html	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab_file.html	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,77 @@
++<!-- $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $ -->
++<!-- $Source: /cvsroot/pkg-proftpd/debian/patches/14.quotatab_modules.diff,v $ -->
++
++<html>
++<head>
++<title>ProFTPD module mod_quotatab_file</title>
++</head>
++
++<body bgcolor=white>
++
++<hr><br>
++<center>
++<h2><b>ProFTPD module <code>mod_quotatab_file</code></b></h2>
++</center>
++<hr><br>
++
++This <code>mod_quotatab</code> submodule is contained in the
++<code>mod_quotatab_file.c</code>, and is found as part of the
++<code>mod_quotatab</code> package available
++<a href="http://www.castaglia.org/proftpd/">here</a>,
++and is not compiled by default.  See the <code>mod_quotatab</code>
++<a href="http://www.castaglia.org/proftpd/modules/mod_quotatab.html#Installation">installation</a> instructions.
++
++<p>
++This submodule provides the file-specific &quot;driver&quot; for storing quota
++table information in files.
++
++<h2>Author</h2>
++<p>
++Please contact TJ Saunders &lt;tj <i>at</i> castaglia.org&gt; with any
++questions, concerns, or suggestions regarding this module.
++
++<p>
++<hr><h2><a name="FileTables">File Quota Tables</a></h2>
++Using file-based quota tables (<em>source-type</em> of &quot;file&quot;) the
++data will be stored in binary fixed-record format.  This module is accompanied
++by a tool, <a href="ftpquota.html"><code>ftpquota</code></a>, to help in
++creating and managing these file-based tables.
++
++<p>
++The <code>mod_quotatab_file</code> module supports the &quot;file&quot; string
++for the <em>source-type</em> parameter of the
++<a href="mod_quotatab.html#QuotaLimitTable"><code>QuotaLimitTable</code></a>
++and
++<a href="mod_quotatab.html#QuotaTallyTable"><code>QuotaTallyTable</code></a>
++configuration directives.  If the &quot;file&quot; <em>source-type</em>
++is used, then the <em>source-info</em> parameter must be the full path to
++the file table.
++
++<p>
++Examples:
++<pre>
++  # Using a file-based limit table
++  QuotaLimitTable file:/usr/local/proftpd/ftpquota.limittab
++
++  # Using a file-based tally table
++  QuotaTallyTable file:/usr/local/proftpd/ftpquota.tallytab
++</pre>
++
++<p>
++<hr><br>
++
++Author: <i>$Author: frankie $</i><br>
++Last Updated: <i>$Date: 2003/11/17 15:30:12 $</i><br>
++
++<br><hr>
++
++<font size=2><b><i>
++&copy; Copyright 2000-2003 TJ Saunders<br>
++ All Rights Reserved<br>
++</i></b></font>
++
++<hr><br>
++
++</body>
++</html>
++
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab.h proftpd-1.2.9/contrib/mod_quotatab.h
+--- proftpd-1.2.9-old/contrib/mod_quotatab.h	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab.h	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,219 @@
++/*
++ * ProFTPD: mod_quotatab -- a module for managing FTP byte/file quotas via
++ *                          centralized tables
++ *
++ * Copyright (c) 2001-2003 TJ Saunders
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
++ *
++ * As a special exemption, TJ Saunders and other respective copyright holders
++ * give permission to link this program with OpenSSL, and distribute the
++ * resulting executable, without including the source code for OpenSSL in the
++ * source distribution.
++ *
++ * This is mod_quotatab, contrib software for proftpd 1.2 and above.
++ * For more information contact TJ Saunders <tj@castaglia.org>.  It is based
++ * the ideas in Eric Estabrook's mod_quota, available from
++ * ftp://pooh.urbanrage.com/pub/c/.  This module, however, has been written
++ * from scratch to implement quotas in a different way.
++ *
++ * $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $
++ */
++
++#ifndef MOD_QUOTATAB_H
++#define MOD_QUOTATAB_H
++
++#include "conf.h"
++#include "privs.h"
++
++#define MOD_QUOTATAB_VERSION "mod_quotatab/1.2.11"
++
++/* Make sure the version of proftpd is as necessary. */
++#if PROFTPD_VERSION_NUMBER < 0x0001020902
++# error "ProFTPD 1.2.9rc2 or later required"
++#endif
++
++/* Quota types */
++typedef enum {
++  ALL_QUOTA = 10,
++  USER_QUOTA = 20,
++  GROUP_QUOTA = 30,
++  CLASS_QUOTA = 40
++} quota_type_t;
++
++/* Bytes quota limit types */
++typedef enum {
++  HARD_LIMIT = 1,
++  SOFT_LIMIT = 2
++} quota_limit_type_t;
++
++/* Quota objects */
++typedef struct {
++  char name[81];
++
++  /* name refers to user, group, or class */
++  quota_type_t quota_type;
++
++  /* are quotas enforced per session or not? */
++  unsigned char quota_per_session;
++
++  /* are byte quotas hard or soft? */
++  quota_limit_type_t quota_limit_type;
++
++  /* Configured bytes limits. */
++  double bytes_in_avail;
++  double bytes_out_avail;
++  double bytes_xfer_avail;
++
++  /* Configured files limits.  These have no "limit type", as they are
++   * always hard.
++   */
++  unsigned int files_in_avail;
++  unsigned int files_out_avail;
++  unsigned int files_xfer_avail;
++
++} quota_limit_t;
++
++typedef struct {
++  char name[81];
++
++  quota_type_t quota_type;
++
++  /* Current bytes tallies. */
++  double bytes_in_used;
++  double bytes_out_used;
++  double bytes_xfer_used;
++
++  /* Current files tallies. */
++  unsigned int files_in_used;
++  unsigned int files_out_used;
++  unsigned int files_xfer_used;
++
++} quota_tally_t;
++
++/* Quota table type (ie limit or tally) */
++typedef enum {
++  TYPE_LIMIT = 100,
++  TYPE_TALLY
++
++} quota_tabtype_t;
++
++/* Quota display units */
++typedef enum {
++  BYTE = 10,
++  KILO,
++  MEGA,
++  GIGA
++
++} quota_units_t;
++
++typedef enum {
++  IN = 100,
++  OUT,
++  XFER,
++
++} quota_xfer_t;
++
++/* Quota deltas -- used to mark the changes in tallies per-operation.
++ * This structure is useful for submodules (eg mod_quotatab_sql) that are
++ * more interested in the deltas, rather than in the current tallies.
++ */
++typedef struct {
++ 
++  /* Deltas of bytes tallies. */
++  double bytes_in_delta;
++  double bytes_out_delta;
++  double bytes_xfer_delta;
++
++  /* Deltas of files tallies. */
++  int files_in_delta;
++  int files_out_delta;
++  int files_xfer_delta;
++ 
++} quota_deltas_t;
++
++/* Interim quota source abstraction object (use until Confstreams are added) */
++typedef struct table_obj {
++
++  /* Memory pool for this object */
++  pool *tab_pool;
++
++  /* Table type, limit or tally */
++  quota_tabtype_t tab_type;
++
++  /* Table handle */
++  int tab_handle;
++
++  /* Table "magic" number */
++  unsigned int tab_magic;
++
++  /* Table record length */
++  unsigned int tab_quotalen;
++
++  /* Arbitrary data pointer */
++  void *tab_data;
++
++  /* Table I/O routines */
++  int (*tab_close)(struct table_obj *);
++  int (*tab_create)(struct table_obj *);
++  unsigned char (*tab_lookup)(struct table_obj *, const char *, quota_type_t);
++  int (*tab_read)(struct table_obj *);
++  unsigned char (*tab_verify)(struct table_obj *);
++  int (*tab_write)(struct table_obj *);
++
++  /* Table locking routines */
++  struct flock tab_lock;
++  int (*tab_rlock)(struct table_obj *);
++  int (*tab_unlock)(struct table_obj *);
++  int (*tab_wlock)(struct table_obj *);
++
++} quota_table_t;
++
++#define QUOTATAB_LIMIT_SRC      0x0001
++#define QUOTATAB_TALLY_SRC      0x0002
++
++/* Quota objects for the current session. */
++quota_limit_t quotatab_limit;
++quota_tally_t quotatab_tally;
++quota_deltas_t quotatab_deltas;
++
++/* Function prototypes necessary for quotatab sub-modules */
++int quotatab_log(const char *, ...);
++int quotatab_openlog(void);
++int quotatab_register(const char *,
++  quota_table_t *(*tab_open)(pool *, quota_tabtype_t, const char *),
++  unsigned int);
++
++/* Function prototypes necessary for consumers of quotatab data. */
++
++/* Note: this function will only find the first occurrence of the given
++ *  name and type in the table.  This means that if there is a malformed
++ *  quota table, with duplicate name/type pairs, the duplicates will be
++ *  ignored.  Returns TRUE if found, FALSE otherwise.
++ */
++unsigned char quotatab_lookup(quota_tabtype_t, const char *, quota_type_t);
++
++/* Reads via this function are only ever done on tally tables.  Limit tables
++ * are read via the quotatab_lookup function.  Returns 0 on success,
++ * -1 on failure (with errno set appropriately).
++ */
++int quotatab_read(void);
++
++/* Writes via this function are only ever done on tally tables.  Returns 0
++ * on success, -1 on failure (with errno set appropriately).
++ */
++int quotatab_write(double, double, double, int, int, int);
++
++#endif /* no MOD_QUOTATAB_H */
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab.html proftpd-1.2.9/contrib/mod_quotatab.html
+--- proftpd-1.2.9-old/contrib/mod_quotatab.html	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab.html	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,477 @@
++<!-- $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $ -->
++<!-- $Source: /cvsroot/pkg-proftpd/debian/patches/14.quotatab_modules.diff,v $ -->
++
++<html>
++<head>
++<title>ProFTPD module mod_quotatab</title>
++</head>
++
++<body bgcolor=white>
++
++<hr><br>
++<center>
++<h2><b>ProFTPD module <code>mod_quotatab</code></b></h2>
++</center>
++<hr><br>
++
++This module is contained in the <code>mod_quotatab.c</code>,
++<code>mod_quotatab.h</code>, and in its submodule source files, for
++ProFTPD 1.2, found <a href="http://www.castaglia.org/proftpd/">here</a>,
++and is not compiled by default.  Installation instructions can be found
++<a href="#Installation">here</a>.
++
++<p>
++This module is designed to impose quotas, both byte- and file-based, on
++FTP accounts, based on user, group, class, or for all accounts.  It is based
++on the ideas contained in Eric Estabrook's <code>mod_quota</code>; however,
++this module has been written from scratch to implement quotas in a very
++different manner.  A more detailed explanation of the <a href="#Usage">usage</a>
++of this module follows the directive explanations.
++
++<p>
++The most current version of <code>mod_quotatab</code>'s submodules supports
++storage of quota table information in various formats:
++<a name="submodules"></a>
++<ul>
++  <li><a href="http://www.castaglia.org/proftpd/modules/mod_quotatab_file.html"><code>mod_quotatab_file</code></a> for file-based quota tables<br>
++  <li><a href="http://www.castaglia.org/proftpd/modules/mod_quotatab_ldap.html"><code>mod_quotatab_ldap</code></a> for LDAP-based quota limit tables<br>
++  <li><a href="http://www.castaglia.org/proftpd/modules/mod_quotatab_sql.html"><code>mod_quotatab_sql</code></a> for SQL-based quota tables<br>
++</ul>
++
++<p>
++The most current version of <code>mod_quotatab</code> can be found at:
++<pre>
++  <a href="http://www.castaglia.org/proftpd/">http://www.castaglia.org/proftpd/</a>
++</pre>
++
++<h2>Author</h2>
++<p>
++Please contact TJ Saunders &lt;tj <i>at</i> castaglia.org&gt; with any
++questions, concerns, or suggestions regarding this module.
++
++<h2>Thanks</h2>
++<p>
++<i>2002-01-12</i>: Thanks to SupaFly &lt;ntlfy <i>at</i> ntlworld.com&gt; for
++helping debug an issue with a missing tally table.
++
++<p>
++<i>2002-03-30</i>: Thanks to Kai Langheim &lt;kl <i>at</i> q-nic.de&gt; for
++pointing out several small bugs affecting users with no quota entries.
++
++<p>
++<i>2003-01-24</i>: Thanks to Arne Blankerts &lt;Blankerts <i>at</i> tow.de&gt;
++for noting small bug with the file upload counter being incorrectly incremented
++for overwritten files.
++
++<h2>Directives</h2>
++<ul>
++  <li><a href="#QuotaDirectoryTally">QuotaDirectoryTally</a>
++  <li><a href="#QuotaDisplayUnits">QuotaDisplayUnits</a>
++  <li><a href="#QuotaEngine">QuotaEngine</a>
++  <li><a href="#QuotaLimitTable">QuotaLimitTable</a>
++  <li><a href="#QuotaLock">QuotaLock</a>
++  <li><a href="#QuotaLog">QuotaLog</a>
++  <li><a href="#QuotaShowQuotas">QuotaShowQuotas</a>
++  <li><a href="#QuotaTallyTable">QuotaTallyTable</a>
++</ul>
++
++<p>
++<h2><code>SITE</code> Commands</h2>
++<ul>
++  <li><a href="#SITE_QUOTA">SITE QUOTA</a>
++</ul>
++
++<hr>
++<h2><a name="QuotaDirectoryTally">QuotaDirectoryTally</a></h2>
++<strong>Syntax:</strong> QuotaDirectoryTally <em>on|off</em><br>
++<strong>Default:</strong> QuotaDirectoryTally off<br>
++<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
++<strong>Module:</strong> mod_quotatab<br>
++<strong>Compatibility:</strong> 1.2.5rc2 and later
++
++<p>
++The <code>QuotaDirectoryTally</code> directive configures
++<code>mod_quotatab</code> to take directory operations (<i>e.g.</i> creating
++a directory, removing a directory) into account when tallying.
++
++<p>
++<hr>
++<h2><a name="QuotaDisplayUnits">QuotaDisplayUnits</a></h2>
++<strong>Syntax:</strong> QuotaDisplayUnits <em>&quot;b&quot;|&quot;Kb&quot;|&quot;Mb&quot;|&quot;Gb&quot;</em><br>
++<strong>Default:</strong> None<br>
++<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
++<strong>Module:</strong> mod_quotatab<br>
++<strong>Compatibility:</strong> 1.2.5rc2 and later
++
++<p>
++This directive configures how the user's current byte quota values will be
++reported to them.  Note that this directive does not affect how the quota
++values are stored in the quota table, only their presentation to the user.
++
++<p>
++<em>&quot;b&quot;</em> causes quotas to be displayed in bytes;
++<em>&quot;Kb&quot;</em>, kilobytes; <em>&quot;Mb&quot;</em>, megabytes; and
++<em>&quot;Gb&quot;</em>, gigabytes.
++
++<p>
++Example:
++<pre>
++  # display quota information in megabytes
++  QuotaDisplayUnits Mb
++</pre>
++
++<p>
++<hr>
++<h2><a name="QuotaEngine">QuotaEngine</a></h2>
++<strong>Syntax:</strong> QuotaEngine <em>on|off</em><br>
++<strong>Default:</strong> None<br>
++<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
++<strong>Module:</strong> mod_quotatab<br>
++<strong>Compatibility:</strong> 1.2.5rc2 and later</a>
++
++<p>
++The <code>QuotaEngine</code> directive enables or disables the module's runtime
++quota engine.  If it is set to <em>off</em> this module does no runtime
++processing at all.  Use this directive to disable the module instead of
++commenting out all <code>mod_quotatab</code> directives.
++
++<p>
++<hr>
++<h2><a name="QuotaLimitTable">QuotaLimitTable </a></h2>
++<strong>Syntax:</strong>  QuotaLimitTable <em>source-type:source-info</em><br>
++<strong>Default:</strong> None<br>
++<strong>Context:</strong> <br>
++<strong>Module:</strong> mod_quotatab<br>
++<strong>Compatibility:</strong> 1.2.5rc2 and later</a>
++
++<p>
++This directive configures the information necessary for the module to locate
++and use the table containing the quota <i>limit</i>, the maximum number
++of bytes and/or files defined for use by specific users, groups, classes,
++<i>etc</i>, and is <b>required</b> for <code>mod_quotatab</code> to function.
++
++<p>
++Please consult the relevant <a href="#submodule">submodule</a> documentation
++for details on that module's syntax for this configuration directive.
++
++<p>
++See also: <a href="#QuotaTallyTable">QuotaTallyTable</a>
++
++<p>
++<hr>
++<h2><a name="QuotaLock">QuotaLock</a></h2>
++<strong>Syntax:</strong>  QuotaLock <em>file</em><br>
++<strong>Default:</strong> None<br>
++<strong>Context:</strong> <br>
++<strong>Module:</strong> mod_quotatab<br>
++<strong>Compatibility:</strong> 1.2.9rc1 and later</a>
++
++<p>
++The <code>QuotaLock</code> directive sets the filename for a synchronization
++lockfile which <code>mod_quotatab</code> needs when communicating with
++some submodules, such as for SQL-based tables, which have trouble providing
++the needed synchronization/locking semantics.  Use of <code>QuotaLock</code>
++is recommended, but not required.
++
++<p>
++If <code>QuotaLock</code> is used, it is <b>strongly advised</b> that the
++configured lock file <b>not</b> be on an NFS (or any other network) filesystem.
++
++<p>
++<hr>
++<h2><a name="QuotaLog">QuotaLog</a></h2>
++<strong>Syntax:</strong>  QuotaLog <em>file|&quot;none&quot;</em><br>
++<strong>Default:</strong> None<br>
++<strong>Context:</strong> <br>
++<strong>Module:</strong> mod_quotatab<br>
++<strong>Compatibility:</strong> 1.2.5rc2 and later</a>
++
++<p>
++The <code>QuotaLog</code> directive is used to a specify a log file for
++<code>mod_quotatab</code> reporting, and can be done a per-server basis.
++The <em>file</em> parameter must be the full path to the file to use for
++logging.  Note that this path must <b>not</b> be to a world-writeable
++directory and, unless <code>AllowLogSymlinks</code> is explicitly set to
++<em>on</em> (generally a bad idea), the path must <b>not</b> be a symbolic
++link.
++
++<p>
++If <em>file</em> is &quot;none&quot;, no logging will be done at all; this
++setting can be used to override a <code>QuotaLog</code> setting inherited from
++a <code>&lt;Global&gt;</code> context.
++
++<p>
++<hr>
++<h2><a name="QuotaShowQuotas">QuotaShowQuotas</a></h2>
++<strong>Syntax:</strong>  QuotaShowQuotas <em>on|off</em><br>
++<strong>Default:</strong> on<br>
++<strong>Context:</strong> <br>
++<strong>Module:</strong> mod_quotatab<br>
++<strong>Compatibility:</strong> 1.2.5rc2 and later</a>
++
++<p>
++The <code>QuotaShowQuotas</code> directive can be used to enable/disable
++<code>mod_quotatab</code>'s response to a <code>SITE QUOTA</code> request.
++For some sites, revealing the current quota information may be considered
++an unnecessary, perhaps even detrimental, information leak; other sites
++may consider this a definite feature.
++
++<p>
++<hr>
++<h2><a name="QuotaTallyTable">QuotaTallyTable</a></h2>
++<strong>Syntax:</strong> QuotaTallyTable <em>source-type:source-info</em><br>
++<strong>Default:</strong> None<br>
++<strong>Context:</strong> <br>
++<strong>Module:</strong> mod_quotatab<br>
++<strong>Compatibility:</strong> 1.2.5rc2 and later</a>
++
++<p>
++This directive configures the information necessary for the module to locate
++and use the table containing the quota <i>tally</i>, or the current byte/file
++counts for users, groups, classes, <i>etc</i>, and is <b>required</b> for
++<code>mod_quotatab</code> to function.
++
++<p>
++Please consult the relevant <a href="#submodule">submodule</a> documentation
++for details on that module's syntax for this configuration directive.
++
++<p>
++See also: <a href="#QuotaLimitTable">QuotaLimitTable</a>
++
++<p>
++<hr><br>
++
++<p>
++<h2><a name="SITE_QUOTA">SITE QUOTA</a></h2>
++<p>
++The <code>SITE QUOTA</code> command will display the quota, both the limit
++and the current tally, to the client.  This <code>SITE</code> command accepts
++no parameters, and can only be used once the client has successfully logged
++in.
++
++<p>
++Example:
++<pre>
++ftp> quote SITE QUOTA
++200-The current quota for this session are [current/limit]:
++ Name: tj
++ Quota Type: User
++ Per Session: True
++ Limit Type: Hard
++   Uploaded Kb:         unlimited
++   Downloaded Kb:       unlimited
++   Transferred Kb:      unlimited
++   Uploaded files:      1/1
++   Downloaded files:    unlimited
++   Transferred files:   unlimited
++200 Please contact root@familiar.castaglia.org if these entries are inaccurate
++ftp> 
++</pre>
++Use of this <code>SITE</code> command can be controlled via
++<code>&lt;Limit&gt;</code>, <i>e.g.</i>:
++<pre>
++  &lt;Limit SITE_QUOTA&gt;
++    AllowUser tj
++    DenyAll
++  &lt;/Limit&gt;
++</pre>
++
++<p>
++Like many <code>SITE</code> commands, the FTP client will probably not
++recognize or support <code>SITE QUOTA</code>.  Hopefully the client <i>does</i>
++have the ability to send arbitrary commands to the server, as the common
++<code>ftp(1)</code> client does via <code>quote</code>.
++
++<p>
++The email address displayed in the <code>SITE QUOTA</code> output can be
++configured via the <a href="http://www.proftpd.org/docs/directives/linked/config_ref_ServerAdmin.html"><code>ServerAdmin</code></a> directive.
++
++<p>
++<hr><br>
++
++<p>
++<h2><a name="Usage">Usage</a></h2>
++<p>
++To use <code>mod_quotatab</code>'s functionality, you must first define the
++tables that together contain the quota information.
++
++<p>
++There are two such quota tables: one table for providing quota information
++about the absolute byte/file limits for users, groups, and classes, and
++a separate table for maintaining the current tally, or number of bytes/files
++used, for those same users, groups, and classes.  This separation of
++information allows for a configuration such as using LDAP to efficiently
++distribute the limit information, and local SQL databases for efficiently
++storing the tally.  The limit table is considered a read-only table, and
++is only accessed at the start of session in order to determine what the
++session limits should be.  The tally table is accessed in read-write mode,
++and is updated after the relevant FTP commands have been processed.
++
++<p>
++This module was not explicitly designed for easy interaction with other
++applications, but rather for other criteria:
++<ul>
++  <li>efficient lookups and updates
++  <li>no need for <code>~/.quota</code> files
++  <li>no need of requirement for root privileges to access quotas
++  <li>easy support for an abstraction layer for storing quota information in
++      other formats
++  <li>support for a SITE command that allows users to view their current quotas
++</ul>
++
++<p>
++This module maintains its quotas based solely on FTP commands - it does not
++enforce quotas based on files that may have been added, deleted, or moved
++via shell access or any mechanism other than through the proftpd server.
++
++<p>
++When a client logs in, assuming <code>QuotaEngine</code> is <em>on</em>,
++<code>mod_quotatab</code> will check the limit table for the record most
++appropriate for that client.  This check first examines the table for records
++of type <code>user</code> that match the client's login name.  If no such
++matching records are found, it checks for records of type <code>group</code>
++that match any of the user's groups (both primary and supplemental). Failing
++that, it will check for records of type <code>class</code> that belong to the
++class (if enabled) from which the client is connecting.  If still no matching
++records are found, the table will be searched for a record of type
++<code>all</code>; if absent, the module will assume that no quotas apply to
++the client.
++
++<p>
++Once the limits for the current session have been established,
++<code>mod_quotatab</code> examines the tally table to see what the current
++numbers in the matching tally record are.  Should the client have an
++applicable limit record but no matching tally record, the module will
++initialize a new record in the tally table.
++
++<p>
++For the purposes of tracking the number of <i>uploaded</i> bytes/files,
++the tally will be adjusted accordingly upon use of the following FTP commands:
++<code>APPE</code> (bytes only), <code>DELE</code>, <code>STOR</code>, and
++<code>STOU</code>.  The number of bytes used for the calculation will be
++determined from the difference in file size of the file in question.
++
++<p>
++For the purposes of tracking the number of <i>downloaded</i> bytes/files,
++the tally will be adjusted accordingly upon use of the following FTP commands:
++<code>RETR</code>.  The number of bytes used for the calculation will be
++determined from the number of bytes sent to the client.
++
++<p>
++For the purposes of tracking the number of <i>transferred</i> bytes/files,
++the tally will be adjusted accordingly upon use of the following FTP commands:
++<code>APPE</code> (bytes only), <code>DELE</code>, <code>RETR</code>,
++<code>STOR</code>, and <code>STOU</code>.  The number of bytes used for
++the calculation will be determined from the number of bytes sent to the
++client.  This type of limit allows for byte/file limits to be set that
++encompass both uploads and downloads.
++
++<p>
++Note that if all three types of quotas are set (upload, download, and
++transfer), any quota reached will cause denial of FTP commands.  This means
++that a high upload quota will never be reached if a low transfer quota is
++in effect.  This holds true for bytes and files quota.  For example, if
++a user has a limited number of both bytes and files to be uploaded in their
++limit record, the first limit reached (bytes or files) is the effective
++limit. <i>Caveat emptor</i>.
++
++<p>
++For any quota limit that is set as &quot;unlimited&quot;,
++<code>mod_quotatab</code> will not keep the tally.  Many site administrators
++might want this ability, for accounting purposes.  However, that ability is
++outside of the intended design of this module; other logging modules are
++much better suited for accounting purposes (<i>e.g.</i> <code>mod_sql</code>'s
++<code>SQLLog</code> directive).
++
++<p>
++A &quot;hard&quot; limit type means that a user's tally will <b>never</b>
++be allowed to exceed the limit; any file uploaded that exceeds the user's
++quota limit will be deleted, and the tally will not be incremented.  A
++&quot;soft&quot; limit type, on the other hand, is a little less strict,
++for it will allow a user to exceed the quota limit by one file only.  For
++example, assume a user's tally is close their limit.  That user uploads
++a large file, one that pushes the tally up over the quota limit.  If their
++limit type is &quot;hard&quot;, the large file will be deleted once uploaded,
++and a message returned to the client informing them of this.  If the user's
++limit type is &quot;soft&quot;, the large file will be allowed, but any
++other uploads are denied (until the user deletes some files, and brings
++their tally back down below the quota limit).
++
++<p>
++If any developers wish to make use of <code>mod_quotatab</code>'s quota
++information, or to develop a new submodule, there is developer documentation
++available <a href="http://www.castaglia.org/proftpd/doc/devel-guide/advanced/Quotatab/">here</a>.
++
++<p>
++<hr><br>
++<h2><a name="Installation">Installation</a></h2>
++To install <code>mod_quotatab</code>, follow these instructions.  After
++unpacking the tarball, copy the <code>mod_quotatab.c</code>,
++<code>mod_quotatab.h</code>, <code>mod_quotatab_file.c</code>,
++<code>mod_quotatab_ldap.c</code>, and <code>mod_quotatab_sql.c</code> files
++into:
++<pre>
++  <i>proftpd-dir</i>/contrib/
++</pre>
++after unpacking the latest proftpd-1.2 source code. Follow the usual steps for
++using third-party modules in proftpd: 
++<pre>
++  ./configure --with-modules=<i>quotatab-modules</i>
++  make
++  make install
++</pre>
++where <i>quotatab-modules</i> will depend on the types of quota tables
++you wish to support.
++
++<p>
++For file-based quota tables, include the <code>mod_quotatab_file</code>
++submodule, <i>e.g.</i>:
++<pre>
++  mod_quotatab:mod_quotatab_file
++</pre>
++
++<p>
++For LDAP-based quota limit tables, include <code>mod_quotatab_ldap</code>
++in addition to either <code>mod_quotatab_file</code> or
++<code>mod_quotatab_sql</code>:
++<pre>
++  mod_quotatab:mod_quotatab_file:mod_quotatab_ldap
++</pre>
++Note that file- or SQL-based tally tables are needed since
++<code>mod_quotatab_ldap</code> cannot handle tally tables, only limit tables.
++<code>mod_quotatab_ldap</code> also requires a correct installation of the
++<code>mod_ldap</code> module.
++
++<p>
++For SQL-based quota tables, include the <code>mod_quotatab_sql</code>
++submodule, <i>e.g.</i>:
++<pre>
++  mod_quotatab:mod_quotatab_sql
++</pre>
++And, if you wish to support file- and SQL-based quota tables:
++<pre>
++  mod_quotatab:mod_quotatab_file:mod_quotatab_sql
++</pre>
++Note that SQL tables require that a correct installation of
++<code>mod_sql</code> (and any of its backend modules) also be used.
++Consult the <code>mod_sql</code> documentation for installation instructions
++for that module.
++
++<p>
++<hr><br>
++
++Author: <i>$Author: frankie $</i><br>
++Last Updated: <i>$Date: 2003/11/17 15:30:12 $</i><br>
++
++<br><hr>
++
++<font size=2><b><i>
++&copy; Copyright 2000-2003 TJ Saunders<br>
++ All Rights Reserved<br>
++</i></b></font>
++
++<hr><br>
++
++</body>
++</html>
++
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab_ldap.c proftpd-1.2.9/contrib/mod_quotatab_ldap.c
+--- proftpd-1.2.9-old/contrib/mod_quotatab_ldap.c	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab_ldap.c	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,162 @@
++/*
++ * ProFTPD: mod_quotatab_ldap -- a mod_quotatab sub-module for obtaining
++ *                               quota information from an LDAP directory.
++ *
++ * Copyright (c) 2002 TJ Saunders
++ * Copyright (c) 2002-3 John Morrissey
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
++ *
++ * As a special exemption, the respective copyright holders give permission
++ * to link this program with OpenSSL, and distribute the resulting
++ * executable, without including the source code for OpenSSL in the source
++ * distribution.
++ */
++
++#include "mod_quotatab.h"
++
++static int ldaptab_close(quota_table_t *ldaptab) {
++
++  /* Nothing really needs to be done here. */
++  return 0;
++}
++
++static unsigned char ldaptab_lookup(quota_table_t *ldaptab, const char *name,
++    quota_type_t quota_type) {
++  char **values = NULL;
++  array_header *ldap_data = NULL;
++  pool *tmp_pool = NULL;
++  cmdtable *ldap_cmdtab = NULL;
++  cmd_rec *ldap_cmd = NULL;
++  modret_t *ldap_res = NULL;
++
++  if (quota_type != USER_QUOTA) {
++    quotatab_log("error: mod_quotatab_ldap only supports user quotas");
++    return FALSE;
++  }
++
++  /* Find the cmdtable for the ldap_quota_lookup command. */
++  if ((ldap_cmdtab = pr_stash_get_symbol(PR_SYM_CMD, "ldap_quota_lookup", NULL, NULL)) == NULL) {
++    quotatab_log("error: unable to find LDAP hook symbol 'ldap_quota_lookup'");
++    return FALSE;
++  }
++
++  /* Allocate a temporary pool for the duration of this lookup. */
++  tmp_pool = make_sub_pool(ldaptab->tab_pool);
++
++  /* Prepare the command and call the handler. */
++  ldap_cmd = pr_cmd_alloc(tmp_pool, 4, name);
++  ldap_res = call_module(ldap_cmdtab->m, ldap_cmdtab->handler, ldap_cmd);
++
++  destroy_pool(tmp_pool);
++
++  /* Check the results. */
++  if (!ldap_res || MODRET_ISERROR(ldap_res)) {
++    quotatab_log("error performing LDAP search");
++    return FALSE;
++  }
++
++  ldap_data = (array_header *) ldap_res->data;
++  if (ldap_data->nelts != 9) {
++    quotatab_log("LDAP search returned wrong number of elements");
++    return FALSE;
++  }
++
++  values = (char **) ldap_data->elts;
++
++  /* Retrieve the limit record (9 values):
++   *  name
++   *  per_session
++   *  limit_type
++   *  bytes_{in,out,xfer}_avail
++   *  files_{in,out,xfer}_avail
++   */
++
++  memmove(quotatab_limit.name, values[0], strlen(values[0]) + 1);
++  quotatab_limit.quota_type = USER_QUOTA;
++
++  if (!strcasecmp(values[1], "false"))
++    quotatab_limit.quota_per_session = FALSE;
++  else if (!strcasecmp(values[1], "true"))
++    quotatab_limit.quota_per_session = TRUE;
++
++  if (!strcasecmp(values[2], "soft"))
++    quotatab_limit.quota_limit_type = SOFT_LIMIT;
++  else if (!strcasecmp(values[2], "hard"))
++    quotatab_limit.quota_limit_type = HARD_LIMIT;
++
++  quotatab_limit.bytes_in_avail   = atof(values[3]);
++  quotatab_limit.bytes_out_avail  = atof(values[4]);
++  quotatab_limit.bytes_xfer_avail = atof(values[5]);
++  quotatab_limit.files_in_avail   = atoi(values[6]);
++  quotatab_limit.files_out_avail  = atoi(values[7]);
++  quotatab_limit.files_xfer_avail = atoi(values[8]);
++
++  return TRUE;
++}
++
++static unsigned char ldaptab_verify(quota_table_t *ldaptab) {
++
++  /* Always TRUE. */
++  return TRUE;
++}
++
++static quota_table_t *ldaptab_open(pool *parent_pool, quota_tabtype_t tab_type,
++    const char *srcinfo) {
++
++  pool *tab_pool = make_sub_pool(parent_pool);
++  quota_table_t *tab = NULL;
++
++  tab = (quota_table_t *) pcalloc(tab_pool, sizeof(quota_table_t));
++  tab->tab_pool = tab_pool;
++  tab->tab_type = tab_type;
++
++  /* Set all the necessary function pointers. */
++  tab->tab_close = ldaptab_close;
++  tab->tab_lookup = ldaptab_lookup;
++  tab->tab_verify = ldaptab_verify;
++
++  return tab;
++}
++
++static int ldaptab_init(void) {
++  quotatab_register("ldap", ldaptab_open, QUOTATAB_LIMIT_SRC);
++  return 0;
++}
++
++module quotatab_ldap_module = {
++  NULL, NULL,
++
++  /* Module API version 2.0 */
++  0x20,
++
++  /* Module name */
++  "quotatab_ldap",
++
++  /* Module configuration handler table */
++  NULL,
++
++  /* Module command handler table */
++  NULL,
++
++  /* Module authentication handler table */
++  NULL,
++
++  /* Module initialization function */
++  ldaptab_init,
++
++  /* Module child initialization function */
++  NULL
++};
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab_ldap.html proftpd-1.2.9/contrib/mod_quotatab_ldap.html
+--- proftpd-1.2.9-old/contrib/mod_quotatab_ldap.html	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab_ldap.html	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,92 @@
++<!-- $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $ -->
++<!-- $Source: /cvsroot/pkg-proftpd/debian/patches/14.quotatab_modules.diff,v $ -->
++
++<html>
++<head>
++<title>ProFTPD module mod_quotatab_ldap</title>
++</head>
++
++<body bgcolor=white>
++
++<hr><br>
++<center>
++<h2><b>ProFTPD module <code>mod_quotatab_ldap</code></b></h2>
++</center>
++<hr><br>
++
++This <code>mod_quotatab</code> submodule is contained in the
++<code>mod_quotatab_ldap.c</code>, part of the <code>mod_quotatab</code> package
++available <a href="http://www.castaglia.org/proftpd/">here</a>, and is not
++compiled by default.  See the <code>mod_quotatab</code> documentation for
++<a href="http://www.castaglia.org/proftpd/modules/mod_quotatab.html#Installation">installation</a> instructions.
++
++<p>
++This submodule provides the LDAP-specific &quot;driver&quot; for retrieving
++quota limit table information from an LDAP server.
++
++<h2>Author</h2>
++<p>
++Please contact John Morrissey &lt;jwm <i>at</i> horde.net&gt; with any
++questions, concerns, or suggestions regarding this module.
++
++<p>
++<hr><h2><a name="LDAPTables">LDAP Limit Quota Tables</a></h2>
++LDAP-based quota tables (<em>source-type</em> of &quot;ldap&quot;) can
++only be used for limit tables, <b>not</b> for tally tables.  The frequent
++updates needed for maintaining tally tables mean that LDAP is not well-suited
++to handle tally table storage.
++
++<p>
++The <code>mod_quotatab_ldap</code> module supports the &quot;ldap&quot; string
++for the <em>source-type</em> parameter of the
++<a href="mod_quotatab.html#QuotaLimitTable"><code>QuotaLimitTable</code></a>
++configuration directive.
++
++<p>
++To enable LDAP-provisioned limit tables, you need to configure
++<code>mod_ldap</code> to lookup the proper attribute using the
++<a href="http://www.proftpd.org/docs/directives/linked/config_ref_LDAPDoQuotaLookups.html"><code>LDAPDoQuotaLookups</code></a> configuration directive.
++
++<p>
++The LDAP attribute to be looked up (named <code>ftpQuota</code> by default)
++should contain a comma-separated list of values, in the following order:
++<pre>
++  <i>per_session,limit_type,bytes_in_avail,bytes_out_avail,bytes_xfer_avail,
++    files_in_avail,files_out_avail,files_xfer_avail</i>
++</pre>
++For example:
++<pre>
++  &quot;false,hard,100,100,100,100,100,100&quot;
++</pre>
++
++<p>
++An example <code>proftpd.conf</code> configuration might look like:
++<pre>
++  &lt;IfModule mod_quotatab.c&gt;
++    &lt;IfModule mod_quotatab_ldap.c&gt;
++      # Enable LDAP quota lookups
++      LDAPDoQuotaLookups on
++
++      # Use an LDAP-based limit table.  Note that there is no additional
++      # information supplied after the source-type: this is intentional. 
++      # mod_ldap handles the rest.
++      QuotaLimitTable ldap:
++    &lt;/IfModule&gt;
++
++    # Use a file-based tally table
++    QuotaTallyTable file:/usr/local/proftpd/ftpquota.tallytab
++  &lt;/IfModule&gt;
++</pre>
++
++<br><hr>
++
++<font size=2><b><i>
++&copy; Copyright 2003 TJ Saunders<br>
++ All Rights Reserved<br>
++</i></b></font>
++
++<hr><br>
++
++</body>
++</html>
++
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab_sql.c proftpd-1.2.9/contrib/mod_quotatab_sql.c
+--- proftpd-1.2.9-old/contrib/mod_quotatab_sql.c	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab_sql.c	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,691 @@
++/*
++ * ProFTPD: mod_quotatab_sql -- a mod_quotatab sub-module for managing quota
++ *                              data via SQL-based tables
++ *
++ * Copyright (c) 2002-2003 TJ Saunders
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
++ *
++ * As a special exemption, TJ Saunders gives permission to link this program
++ * with OpenSSL, and distribute the resulting executable, without including
++ * the source code for OpenSSL in the source distribution.
++ *
++ * $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $
++ */
++
++#include "mod_quotatab.h"
++#include "mod_sql.h"
++
++/* For synchronizing on database table operations among sessions. */
++static char *sqltab_lock_file = NULL;
++static int sqltab_lock_fd = -1;
++
++static cmd_rec *sql_cmd_create(pool *parent_pool, int argc, ...) {
++  pool *cmd_pool = NULL;
++  cmd_rec *cmd = NULL;
++  register unsigned int i = 0;
++  va_list argp;
++
++  cmd_pool = make_sub_pool(parent_pool);
++  cmd = (cmd_rec *) pcalloc(cmd_pool, sizeof(cmd_rec));
++  cmd->pool = cmd_pool;
++
++  cmd->argc = argc;
++  cmd->argv = (char **) pcalloc(cmd->pool, argc * sizeof(char *));
++
++  /* Hmmm... */
++  cmd->tmp_pool = cmd->pool;
++
++  va_start(argp, argc);
++  for (i = 0; i < argc; i++)
++    cmd->argv[i] = va_arg(argp, char *);
++  va_end(argp);
++
++  return cmd;
++}
++
++static int sqltab_close(quota_table_t *sqltab) {
++
++  /* Is there really anything that needs to be done here? */
++  return 0;
++}
++
++static int sqltab_create(quota_table_t *sqltab) {
++  pool *tmp_pool = NULL;
++  cmdtable *sql_cmdtab = NULL;
++  cmd_rec *sql_cmd = NULL;
++  modret_t *sql_res = NULL;
++  char *insert_query = NULL, *tally_quota_name = NULL, *tally_quota_type = NULL,
++    *tally_bytes_in = NULL, *tally_bytes_out = NULL, *tally_bytes_xfer = NULL,
++    *tally_files_in = NULL, *tally_files_out = NULL, *tally_files_xfer = NULL;
++
++  /* Allocate a sub pool for use by this function. */
++  tmp_pool = make_sub_pool(sqltab->tab_pool);
++
++  /* Allocate small buffers for stringifying most of the tally struct
++   * members: quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used,
++   * files_in_used, files_out_used, files_xfer_used.
++   */
++  tally_quota_name = pcalloc(tmp_pool, 83 * sizeof(char));
++  tally_quota_type = pcalloc(tmp_pool, 10 * sizeof(char));
++  tally_bytes_in = pcalloc(tmp_pool, 10 * sizeof(char));
++  tally_bytes_out = pcalloc(tmp_pool, 10 * sizeof(char));
++  tally_bytes_xfer = pcalloc(tmp_pool, 10 * sizeof(char));
++  tally_files_in = pcalloc(tmp_pool, 10 * sizeof(char));
++  tally_files_out = pcalloc(tmp_pool, 10 * sizeof(char));
++  tally_files_xfer = pcalloc(tmp_pool, 10 * sizeof(char));
++
++  /* Execute the INSERT NamedQuery */
++  insert_query = ((char **) sqltab->tab_data)[2];
++
++  /* Populate the INSERT query with the necessary data from the current
++   * limit record.  Need to stringify most of the tally struct members:
++   * quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used,
++   * files_in_used, files_out_used, files_xfer_used.
++   */
++  snprintf(tally_quota_name, 83, "'%s'", quotatab_tally.name);
++
++  if (quotatab_tally.quota_type == USER_QUOTA)
++    snprintf(tally_quota_type, 10, "'%s'", "user");
++
++  else if (quotatab_tally.quota_type == GROUP_QUOTA)
++    snprintf(tally_quota_type, 10, "'%s'", "group");
++
++  else if (quotatab_tally.quota_type == CLASS_QUOTA)
++    snprintf(tally_quota_type, 10, "'%s'", "class");
++
++  else if (quotatab_tally.quota_type == ALL_QUOTA)
++    snprintf(tally_quota_type, 10, "'%s'", "all");
++
++  snprintf(tally_bytes_in, 10, "%f", quotatab_tally.bytes_in_used);
++  snprintf(tally_bytes_out, 10, "%f", quotatab_tally.bytes_out_used);
++  snprintf(tally_bytes_xfer, 10, "%f", quotatab_tally.bytes_xfer_used);
++  snprintf(tally_files_in, 10, "%u", quotatab_tally.files_in_used);
++  snprintf(tally_files_out, 10, "%u", quotatab_tally.files_out_used);
++  snprintf(tally_files_xfer, 10, "%u", quotatab_tally.files_xfer_used);
++
++  sql_cmd = sql_cmd_create(tmp_pool, 10, "sql_change", insert_query,
++    tally_quota_name, tally_quota_type,
++    tally_bytes_in, tally_bytes_out, tally_bytes_xfer,
++    tally_files_in, tally_files_out, tally_files_xfer);
++
++  /* Find the cmdtable for the sql_change command. */
++  if ((sql_cmdtab = pr_stash_get_symbol(PR_SYM_HOOK, "sql_change", NULL,
++      NULL)) == NULL) {
++    quotatab_log("error: unable to find SQL hook symbol 'sql_change'");
++    destroy_pool(tmp_pool);
++    return -1;
++  }
++
++  /* Call the handler. */
++  sql_res = call_module(sql_cmdtab->m, sql_cmdtab->handler, sql_cmd);
++
++  /* Check the results. */
++  if (MODRET_ISERROR(sql_res)) {
++    quotatab_log("error executing NamedQuery '%s': %s", insert_query,
++      strerror(errno));
++    destroy_pool(tmp_pool);
++    return -1;
++  } 
++
++  destroy_pool(tmp_pool);
++  return 0;
++}
++
++static unsigned char sqltab_lookup(quota_table_t *sqltab, const char *name,
++    quota_type_t quota_type) {
++  pool *tmp_pool = NULL;
++  cmdtable *sql_cmdtab = NULL;
++  cmd_rec *sql_cmd = NULL;
++  modret_t *sql_res = NULL;
++  array_header *sql_data = NULL;
++  char *select_query = NULL;
++
++  /* Allocate a temporary pool for the duration of this lookup. */
++  tmp_pool = make_sub_pool(sqltab->tab_pool);
++
++  /* Handle tally and limit tables differently... */
++  if (sqltab->tab_type == TYPE_TALLY)
++    select_query = ((char **) sqltab->tab_data)[0];
++
++  else if (sqltab->tab_type == TYPE_LIMIT)
++    select_query = (char *) sqltab->tab_data;
++
++  /* Find the cmdtable for the sql_lookup command. */
++  if ((sql_cmdtab = pr_stash_get_symbol(PR_SYM_HOOK, "sql_lookup", NULL,
++      NULL)) == NULL) {
++    quotatab_log("error: unable to find SQL hook symbol 'sql_lookup'");
++    destroy_pool(tmp_pool);
++    return FALSE;
++  }
++
++  /* Prepare the SELECT query. */
++  sql_cmd = sql_cmd_create(tmp_pool, 4, "sql_lookup", select_query,
++    name ? name : "",
++    quota_type == USER_QUOTA ? "user" : quota_type == GROUP_QUOTA ? "group" :
++    quota_type == CLASS_QUOTA ? "class" : "all");
++
++  /* Call the handler. */
++  sql_res = call_module(sql_cmdtab->m, sql_cmdtab->handler, sql_cmd);
++
++  /* Check the results. */
++  if (!sql_res || MODRET_ISERROR(sql_res)) {
++    quotatab_log("error processing NamedQuery '%s'", select_query);
++    destroy_pool(tmp_pool);
++    return FALSE;
++  }
++
++  sql_data = (array_header *) sql_res->data;
++
++  if (sqltab->tab_type == TYPE_TALLY) {
++    char **values = (char **) sql_data->elts;
++
++    /* Update the tally record with the 8 values:
++     *  name
++     *  quota_type
++     *  bytes_{in,out,xfer}_used
++     *  files_{in,out,xfer}_used
++     */
++
++    if (sql_data->nelts != 8) {
++
++      if (sql_data->nelts > 0)
++        quotatab_log("error: SQLNamedQuery '%s' returned incorrect number of "
++          "values (%d)", select_query, sql_data->nelts);
++
++      destroy_pool(tmp_pool);
++      return FALSE;
++    }
++
++    /* Process each element returned. */
++    memmove(quotatab_tally.name, values[0], sizeof(quotatab_tally.name));
++
++    if (!strcasecmp(values[1], "user"))
++      quotatab_tally.quota_type = USER_QUOTA;
++
++    else if (!strcasecmp(values[1], "group"))
++      quotatab_tally.quota_type = GROUP_QUOTA;
++
++    else if (!strcasecmp(values[1], "class"))
++      quotatab_tally.quota_type = CLASS_QUOTA;
++
++    else if (!strcasecmp(values[1], "all"))
++      quotatab_tally.quota_type = ALL_QUOTA;
++
++    /* Check if this is the requested record, now that enough information
++     * is in place.
++     */
++    if (quota_type != quotatab_tally.quota_type) {
++      destroy_pool(tmp_pool);
++      return FALSE;
++    }
++
++    /* Match names if need be */
++    if (quota_type != ALL_QUOTA &&
++        values[0] && strlen(values[0]) && strcmp(name, quotatab_tally.name)) {
++      destroy_pool(tmp_pool);
++      return FALSE;
++    }
++
++    quotatab_tally.bytes_in_used = atof(values[2]);
++    quotatab_tally.bytes_out_used = atof(values[3]);
++    quotatab_tally.bytes_xfer_used = atof(values[4]);
++    quotatab_tally.files_in_used = atoi(values[5]);
++    quotatab_tally.files_out_used = atoi(values[6]);
++    quotatab_tally.files_xfer_used = atoi(values[7]);
++
++    destroy_pool(tmp_pool);
++    return TRUE;
++
++  } else if (sqltab->tab_type == TYPE_LIMIT) {
++    char **values = (char **) sql_data->elts;
++
++    /* Update the limit record with the 10 values:
++     *  name
++     *  quota_type
++     *  per_session
++     *  limit_type
++     *  bytes_{in,out,xfer}_avail
++     *  files_{in,out,xfer}_avail
++     */
++
++    if (sql_data->nelts != 10) {
++
++      if (sql_data->nelts > 0)
++        quotatab_log("error: SQLNamedQuery '%s' returned incorrect number of "
++          "values (%d)", select_query, sql_data->nelts);
++
++      destroy_pool(tmp_pool);
++      return FALSE;
++    }
++
++    /* Process each element returned. */
++    memmove(quotatab_limit.name, values[0], sizeof(quotatab_limit.name));
++
++    if (!strcasecmp(values[1], "user"))
++      quotatab_limit.quota_type = USER_QUOTA;
++
++    else if (!strcasecmp(values[1], "group"))
++      quotatab_limit.quota_type = GROUP_QUOTA;
++
++    else if (!strcasecmp(values[1], "class"))
++      quotatab_limit.quota_type = CLASS_QUOTA;
++
++    else if (!strcasecmp(values[1], "all"))
++      quotatab_limit.quota_type = ALL_QUOTA;
++
++    /* Check if this is the requested record, now that enough information
++     * is in place.
++     */
++    if (quota_type != quotatab_limit.quota_type) {
++      destroy_pool(tmp_pool);
++      return FALSE;
++    }
++
++    /* Match names if need be */
++    if (quota_type != ALL_QUOTA &&
++        values[0] && strlen(values[0]) && strcmp(name, quotatab_limit.name)) {
++      destroy_pool(tmp_pool);
++      return FALSE;
++    }
++
++    if (!strcasecmp(values[2], "false"))
++      quotatab_limit.quota_per_session = FALSE;
++
++    else if (!strcasecmp(values[2], "true"))
++      quotatab_limit.quota_per_session = TRUE;
++
++    if (!strcasecmp(values[3], "soft"))
++      quotatab_limit.quota_limit_type = SOFT_LIMIT;
++
++    else if (!strcasecmp(values[3], "hard"))
++      quotatab_limit.quota_limit_type = HARD_LIMIT;
++
++    quotatab_limit.bytes_in_avail = atof(values[4]);
++    quotatab_limit.bytes_out_avail = atof(values[5]);
++    quotatab_limit.bytes_xfer_avail = atof(values[6]);
++    quotatab_limit.files_in_avail = atol(values[7]);
++    quotatab_limit.files_out_avail = atol(values[8]);
++    quotatab_limit.files_xfer_avail = atol(values[9]);
++
++    destroy_pool(tmp_pool);
++    return TRUE;
++  }
++
++  destroy_pool(tmp_pool);
++
++  /* default */
++  return FALSE;
++}
++
++/* Note: no need for this option, as the UPDATE query will do the read+update
++ * more atomically than this module can.  The SELECT query is then for
++ * the lookup handler only.
++ */
++static int sqltab_read(quota_table_t *sqltab) {
++  return 0;
++}
++
++static unsigned char sqltab_verify(quota_table_t *sqltab) {
++
++  /* Always TRUE. */
++  return TRUE;
++}
++
++static int sqltab_write(quota_table_t *sqltab) {
++  pool *tmp_pool = NULL;
++  cmdtable *sql_cmdtab = NULL;
++  cmd_rec *sql_cmd = NULL;
++  modret_t *sql_res = NULL;
++  char *update_query = NULL, *tally_quota_type = NULL,
++    *tally_bytes_in = NULL, *tally_bytes_out = NULL, *tally_bytes_xfer = NULL,
++    *tally_files_in = NULL, *tally_files_out = NULL, *tally_files_xfer = NULL;
++
++  /* Allocate a sub pool for use by this function. */
++  tmp_pool = make_sub_pool(sqltab->tab_pool);
++
++  /* Allocate small buffers for stringifying most of the tally struct
++   * members: quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used,
++   * files_in_used, files_out_used, files_xfer_used.
++   */
++  tally_quota_type = pcalloc(tmp_pool, 20 * sizeof(char));
++  tally_bytes_in = pcalloc(tmp_pool, 20 * sizeof(char));
++  tally_bytes_out = pcalloc(tmp_pool, 20 * sizeof(char));
++  tally_bytes_xfer = pcalloc(tmp_pool, 20 * sizeof(char));
++  tally_files_in = pcalloc(tmp_pool, 20 * sizeof(char));
++  tally_files_out = pcalloc(tmp_pool, 20 * sizeof(char));
++  tally_files_xfer = pcalloc(tmp_pool, 20 * sizeof(char));
++
++  /* Retrieve the UPDATE NamedQuery */
++  update_query = ((char **) sqltab->tab_data)[1];
++
++  /* Populate the UPDATE query with the necessary data from the current
++   * limit record.  Need to stringify most of the tally struct members:
++   * quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used,
++   * files_in_used, files_out_used, files_xfer_used.
++   */
++
++  if (quotatab_tally.quota_type == USER_QUOTA)
++    snprintf(tally_quota_type, 20, "%s", "user");
++
++  else if (quotatab_tally.quota_type == GROUP_QUOTA)
++    snprintf(tally_quota_type, 20, "%s", "group");
++
++  else if (quotatab_tally.quota_type == CLASS_QUOTA)
++    snprintf(tally_quota_type, 20, "%s", "class");
++
++  else if (quotatab_tally.quota_type == ALL_QUOTA)
++    snprintf(tally_quota_type, 20, "%s", "all");
++
++  /* Note: use the deltas data, not the tally members, so that the
++   * UPDATE can do an "atomic" read+update all in one shot.
++   */
++  snprintf(tally_bytes_in, 20, "%f", quotatab_deltas.bytes_in_delta);
++  snprintf(tally_bytes_out, 20, "%f", quotatab_deltas.bytes_out_delta);
++  snprintf(tally_bytes_xfer, 20, "%f", quotatab_deltas.bytes_xfer_delta);
++  snprintf(tally_files_in, 20, "%u", quotatab_deltas.files_in_delta);
++  snprintf(tally_files_out, 20, "%u", quotatab_deltas.files_out_delta);
++  snprintf(tally_files_xfer, 20, "%u", quotatab_deltas.files_xfer_delta);
++
++  sql_cmd = sql_cmd_create(tmp_pool, 10, "sql_change", update_query,
++    tally_bytes_in, tally_bytes_out, tally_bytes_xfer,
++    tally_files_in, tally_files_out, tally_files_xfer,
++    quotatab_tally.name, tally_quota_type);
++
++  /* Find the cmdtable for the sql_change command. */
++  if ((sql_cmdtab = pr_stash_get_symbol(PR_SYM_HOOK, "sql_change", NULL,
++      NULL)) == NULL) {
++    quotatab_log("error: unable to find SQL hook symbol 'sql_change'");
++    destroy_pool(tmp_pool);
++    return -1;
++  }
++
++  /* Call the handler. */
++  sql_res = call_module(sql_cmdtab->m, sql_cmdtab->handler, sql_cmd);
++
++  /* Check the results. */
++  if (MODRET_ISERROR(sql_res)) {
++    quotatab_log("error executing NamedQuery '%s': %s", update_query,
++      strerror(errno));
++    destroy_pool(tmp_pool);
++    return -1;
++  }
++
++  destroy_pool(tmp_pool);
++  return 0;
++}
++
++static int sqltab_rlock(quota_table_t *sqltab) {
++
++  /* Check for a configured lock file. */
++  if (sqltab_lock_file) {
++    sqltab->tab_lock.l_type = F_RDLCK;
++    return fcntl(sqltab_lock_fd, F_SETLK, &sqltab->tab_lock);
++  }
++
++  return 0;
++}
++
++static int sqltab_unlock(quota_table_t *sqltab) {
++
++  /* Check for a configured lock file. */
++  if (sqltab_lock_file) {
++    sqltab->tab_lock.l_type = F_UNLCK;
++    return fcntl(sqltab_lock_fd, F_SETLK, &sqltab->tab_lock);
++  }
++
++  return 0;
++}
++
++static int sqltab_wlock(quota_table_t *sqltab) {
++
++  /* Check for a configured lock file. */
++  if (sqltab_lock_file) {
++    sqltab->tab_lock.l_type = F_WRLCK;
++    return fcntl(sqltab_lock_fd, F_SETLK, &sqltab->tab_lock);
++  }
++
++  return 0;
++}
++
++static quota_table_t *sqltab_open(pool *parent_pool, quota_tabtype_t tab_type,
++    const char *srcinfo) {
++
++  quota_table_t *tab = NULL;
++  pool *tab_pool = make_sub_pool(parent_pool),
++    *tmp_pool = make_sub_pool(parent_pool);
++  config_rec *c = NULL;
++  char *named_query = NULL;
++
++  tab = (quota_table_t *) pcalloc(tab_pool, sizeof(quota_table_t));
++  tab->tab_pool = tab_pool;
++  tab->tab_type = tab_type;
++
++  if (tab->tab_type == TYPE_TALLY) {
++    char *start = NULL, *finish = NULL;
++    char *select_query = NULL, *update_query = NULL, *insert_query = NULL;
++
++    /* Parse the SELECT, UPDATE, and INSERT query names out of the srcinfo
++     * string.  Lookup and store the queries in the tab_data area, so that
++     * they need not be looked up later.
++     *
++     * The srcinfo string for this case should look like:
++     *  "/<select-named-query>/<update-named-query>/<insert-named-query>/"
++     */
++
++    if ((start = strchr(srcinfo, '/')) == NULL) {
++      quotatab_log("error: badly formatted source info '%s'", srcinfo);
++      destroy_pool(tmp_pool);
++      errno = EINVAL;
++      return NULL;
++    }
++
++    /* Find the next slash. */
++    if ((finish = strchr(++start, '/')) == NULL) {
++      quotatab_log("error: badly formatted source info '%s'", srcinfo);
++      destroy_pool(tmp_pool);
++      errno = EINVAL;
++      return NULL;
++    }
++
++    *finish = '\0';
++    select_query = pstrdup(tab->tab_pool, start);
++
++    /* Verify that the named query has indeed been defined. This is
++     * based on how mod_sql creates its config_rec names.
++     */
++    named_query = pstrcat(tmp_pool, "SQLNamedQuery_", select_query, NULL);
++
++    if ((c = find_config(main_server->conf, CONF_PARAM, named_query,
++        FALSE)) == NULL) {
++      quotatab_log("error: unable to resolve SQLNamedQuery name '%s'",
++        select_query);
++      destroy_pool(tmp_pool);
++      errno = EINVAL;
++      return NULL;
++    }
++
++    /* Now, find the next slash. */
++    start = finish;
++    if ((finish = strchr(++start, '/')) == NULL) {
++      quotatab_log("error: badly formatted source info '%s'", srcinfo);
++      destroy_pool(tmp_pool);
++      errno = EINVAL;
++      return NULL;
++    }
++
++    *finish = '\0';
++    update_query = pstrdup(tab->tab_pool, start);
++
++    /* Verify that the named query has indeed been defined. This is
++     * based on how mod_sql creates its config_rec names.
++     */
++    named_query = pstrcat(tmp_pool, "SQLNamedQuery_", update_query, NULL);
++
++    if ((c = find_config(main_server->conf, CONF_PARAM, named_query,
++        FALSE)) == NULL) {
++      quotatab_log("error: unable to resolve SQLNamedQuery name '%s'",
++        update_query);
++      destroy_pool(tmp_pool);
++      errno = EINVAL;
++      return NULL;
++    }
++
++    /* Assume the rest of the srcinfo string is the INSERT query (assuming
++     * there *is* a "rest of the string").
++     */
++    if (*(++finish) != '\0') {
++      insert_query = pstrdup(tab->tab_pool, finish);
++
++    } else {
++      quotatab_log("error: badly formatted source info '%s'", srcinfo);
++      destroy_pool(tmp_pool);
++      errno = EINVAL;
++      return NULL;
++    }
++
++    /* Verify that the named query has indeed been defined. This is
++     * based on how mod_sql creates its config_rec names.
++     */
++    named_query = pstrcat(tmp_pool, "SQLNamedQuery_", insert_query, NULL);
++
++    if ((c = find_config(main_server->conf, CONF_PARAM, named_query,
++        FALSE)) == NULL) {
++      quotatab_log("error: unable to resolve SQLNamedQuery name '%s'",
++        insert_query);
++      destroy_pool(tmp_pool);
++      errno = EINVAL;
++      return NULL;
++    }
++
++    tab->tab_data = (char **) pcalloc(tab->tab_pool, 3 * sizeof(char *));
++    ((char **) tab->tab_data)[0] = pstrdup(tab->tab_pool, select_query);
++    ((char **) tab->tab_data)[1] = pstrdup(tab->tab_pool, update_query);
++    ((char **) tab->tab_data)[2] = pstrdup(tab->tab_pool, insert_query);
++
++  } else if (tab->tab_type == TYPE_LIMIT) {
++    char *start = NULL, *select_query = NULL;
++
++    /* Parse the SELECT query name out of the srcinfo string.  Lookup and
++     * store the queries in the tab_data area, so that it need not be looked
++     * up later.
++     *
++     * The srcinfo string for this case should look like:
++     *  "/<select-named-query>"
++     */
++
++    if ((start = strchr(srcinfo, '/')) == NULL) {
++      quotatab_log("error: badly formatted source info '%s'", srcinfo);
++      destroy_pool(tmp_pool);
++      errno = EINVAL;
++      return NULL;
++    }
++    select_query = ++start;
++
++    /* Verify that the named query has indeed been defined. This is
++     * based on how mod_sql creates its config_rec names.
++     */
++    named_query = pstrcat(tmp_pool, "SQLNamedQuery_", select_query, NULL);
++
++    if ((c = find_config(main_server->conf, CONF_PARAM, named_query,
++        FALSE)) == NULL) {
++      quotatab_log("error: unable to resolve SQLNamedQuery name '%s'",
++        select_query);
++      destroy_pool(tmp_pool);
++      errno = EINVAL;
++      return NULL;
++    }
++
++    tab->tab_data = pcalloc(tab->tab_pool, sizeof(char));
++    ((char *) tab->tab_data) = pstrdup(tab->tab_pool, select_query);
++  }
++
++  /* Set all the necessary function pointers. */
++  tab->tab_close = sqltab_close;
++  tab->tab_create = sqltab_create;
++  tab->tab_lookup = sqltab_lookup;
++  tab->tab_read = sqltab_read;
++  tab->tab_verify = sqltab_verify;
++  tab->tab_write = sqltab_write;
++
++  tab->tab_rlock = sqltab_rlock;
++  tab->tab_unlock = sqltab_unlock;
++  tab->tab_wlock = sqltab_wlock;
++
++  /* Prepare the lock structure. */
++  tab->tab_lock.l_whence = SEEK_CUR;
++  tab->tab_lock.l_start = 0;
++  tab->tab_lock.l_len = 0;
++
++  destroy_pool(tmp_pool);
++  return tab;
++}
++
++static int sqltab_sess_init(void) {
++  quotatab_openlog();
++
++  /* Check for a configured lock file. */
++  if ((sqltab_lock_file = get_param_ptr(main_server->conf, "QuotaLock",
++      FALSE)) != NULL) {
++
++    /* Make sure the file exists. */
++    PRIVS_ROOT
++    if (unlink(sqltab_lock_file) < 0)
++      quotatab_log("error: unable to delete QuotaLock '%s': %s",
++        sqltab_lock_file, strerror(errno));
++    if ((sqltab_lock_fd = open(sqltab_lock_file, O_RDWR|O_CREAT, 0600)) < 0) {
++      quotatab_log("error: unable to open QuotaLock '%s': %s",
++        sqltab_lock_file, strerror(errno));
++      sqltab_lock_file = NULL;
++    }
++    PRIVS_RELINQUISH
++  }
++
++  return 0;
++}
++
++static int sqltab_init(void) {
++
++  /* Initialize the quota source objects for type "sql". */
++  quotatab_register("sql", sqltab_open,
++    QUOTATAB_LIMIT_SRC|QUOTATAB_TALLY_SRC);
++
++  return 0;
++}
++
++module quotatab_sql_module = {
++  NULL, NULL,
++
++  /* Module API version 2.0 */
++  0x20,
++
++  /* Module name */
++  "quotatab_sql",
++
++  /* Module configuration handler table */
++  NULL,
++
++  /* Module command handler table */
++  NULL,
++
++  /* Module authentication handler table */
++  NULL,
++
++  /* Module initialization function */
++  sqltab_init,
++
++  /* Module child initialization function */
++  sqltab_sess_init
++};
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab_sql.html proftpd-1.2.9/contrib/mod_quotatab_sql.html
+--- proftpd-1.2.9-old/contrib/mod_quotatab_sql.html	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab_sql.html	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,287 @@
++<!-- $Id: 14.quotatab_modules.diff,v 1.4 2003/11/17 15:30:12 frankie Exp $ -->
++<!-- $Source: /cvsroot/pkg-proftpd/debian/patches/14.quotatab_modules.diff,v $ -->
++
++<html>
++<head>
++<title>ProFTPD module mod_quotatab_sql</title>
++</head>
++
++<body bgcolor=white>
++
++<hr><br>
++<center>
++<h2><b>ProFTPD module <code>mod_quotatab_sql</code></b></h2>
++</center>
++<hr><br>
++
++This <code>mod_quotatab</code> submodule is contained in the
++<code>mod_quotatab_sql.c</code> file, and is found as part of the
++<code>mod_quotatab</code> package available
++<a href="http://www.castaglia.org/proftpd/">here</a>,
++and is not compiled by default.  See the <code>mod_quotatab</code>
++<a href="http://www.castaglia.org/proftpd/modules/mod_quotatab.html#Installation">installation</a> instructions.
++
++<p>
++This submodule provides the SQL database &quot;driver&quot; for storing quota
++table information in SQL tables.
++
++<h2>Author</h2>
++<p>
++Please contact TJ Saunders &lt;tj <i>at</i> castaglia.org&gt; with any
++questions, concerns, or suggestions regarding this module.
++
++<h2>Thanks</h2>
++<p>
++<i>2002-04-01</i>: Thanks to Tomasz Konefal &lt;tomk <i>at</i> compt.com&gt; for his great feedback and support in developing this module.
++
++<p>
++<i>2002-04-03</i>: Thanks to Noah &lt;sitz <i>at</i> onastick.net&gt; for suggesting the better form of the UPDATE query.
++
++<p>
++<hr><h2><a name="SQLTables">SQL Quota Tables</a></h2>
++The <code>mod_quotatab_sql</code> module supports the &quot;sql&quot; string
++for the <em>source-type</em> parameter of the
++<a href="mod_quotatab.html#QuotaLimitTable"><code>QuotaLimitTable</code></a>
++and
++<a href="mod_quotatab.html#QuotaTallyTable"><code>QuotaTallyTable</code></a>
++configuration directives. If the &quot;sql&quot; <em>source-type</em> is used,
++then the <em>source-info</em> parameter must be as described below.  Note
++that support for SQL-based quota tables <b>requires</b> the use of
++<code>mod_sql</code>.
++
++<p>
++<code>mod_quotatab_sql</code> requires five SQL-related configuration
++directives: <code>SQLConnectInfo</code>, and four <code>SQLNamedQuery</code>
++directives.  The <code>SQLConnectInfo</code> is needed to allow the module to
++connect to the SQL database.  The other four directives define the SQL queries
++that will be used by <code>mod_quotatab</code> for its storage/retrieval
++operations involving quota data.
++
++<p>
++When using SQL tables and <code>mod_sql</code>, the quota tables should appear
++in the database named by the <code>SQLConnectInfo</code> directive, which
++will probably also contain the authentication information tables.  This way
++your <code>proftpd</code>-specific tables are kept together.  Also, it is
++probably better to use a connection policy of PERSESSION, otherwise there will
++be more overhead associated with each new connection made to the database for
++each transaction; <code>mod_quotatab</code> makes a lot of reads and writes to
++its tables, each of which will require <code>mod_quotatab_sql</code>
++to use a database connection.
++
++<p>
++One <code>SQLNamedQuery</code> is needed to <code>SELECT</code> quota
++information from the limit table.  The defined SQL statement for this
++<b>must</b> return ten values, in the following order:
++<ul>
++  <li>name
++  <li>quota type
++  <li>quotas per session
++  <li>quota limit type
++  <li>upload limit in bytes
++  <li>download limit in bytes
++  <li>transfer limit in bytes
++  <li>upload limit in files
++  <li>download limit in files
++  <li>transfer limit in files
++</ul>
++A similar <code>SQLNamedQuery</code> is needed to <code>SELECT</code> quota
++information from the tally table; the SQL statement defined for this
++<b>must</b> return eight values, in the following order:
++<ul>
++  <li>name
++  <li>quota type
++  <li>upload tally in bytes
++  <li>download tally in bytes
++  <li>transfer tally in bytes
++  <li>upload tally in files
++  <li>download tally in files
++  <li>transfer tally in files
++</ul>
++The remaing two <code>SQLNamedQuery</code> directives are used to define the
++necessary <code>UPDATE</code> and <code>INSERT</code> operations on the
++tally table.  Failure to define any of the four required
++<code>SQLNamedQuery</code> directives will cause an error during
++<code>mod_quotatab_sql</code>'s operation.
++
++<p>
++For SQL tables, the format for the <code>QuotaLimitTable</code> directive
++is:
++<pre>
++  QuotaLimitTable sql:/<i>SELECT-SQLNamedQuery</i>
++</pre>
++And, for the <code>QuotaTallyTable</code> directive:
++<pre>
++  QuotaTallyTable sql:/<i>SELECT-SQLNamedQuery</i>/<i>UPDATE-SQLNamedQuery</i>/<i>INSERT-SQLNamedQuery</i>
++</pre>
++
++<p>
++Also note that SQL-based tally tables have an issue with proper synchronization
++of updates, especially when multiple sessions involving the same tally
++are ocurring.  In order to prevent the tally table from becoming out of
++sync, you are <b>strongly</b> encouraged to define a <a href="http://www.castaglia.org/proftpd/modules/mod_quotatab.html#QuotaLock"><code>QuotaLock</code></a>
++file.
++
++<p>
++<b>SQL Quota Tables Example</b><br>
++Here are example <code>SQLNamedQuery</code> directives to help demonstrate
++how the <code>mod_sql</code> hooks are used by <code>mod_quotatab</code>.
++These example SQL statements assume the existence of two tables: a
++<code>quotalimits</code> table that defines limit records, and a
++<code>quotatallies</code> table that holds the current tally records.  Note
++that these queries would appear all on a single line in your
++<code>proftpd.conf</code>.
++
++<pre>
++  SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, \
++    bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM quotalimits \
++    WHERE name = '%{0}' AND quota_type = '%{1}'"
++</pre>
++This defines the SQL statement to return the required limit column values, in
++the necessary order.  The <code>%{0}</code> and <code>%{1}</code> meta
++sequences will be substituted with the name being looked up (<i>e.g.</i> user
++name, primary group name, class name (if in effect), or the empty string) and
++the corresponding quota type (<i>e.g.</i> &quot;user&quot;, &quot;group&quot;,
++&quot;class&quot;, or &quot;all&quot;), respectively.
++
++<pre>
++  SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, \
++    bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM quotatallies \
++    WHERE name = '%{0}' AND quota_type = '%{1}'"
++</pre>
++Very similar to the above example, the SQL statement defined here is for
++the tally table, rather than the limit table.  The meta sequences will
++be substituted with the same values as above.
++
++<pre>
++  SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, \
++    bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, \
++    files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, \
++    files_xfer_used = files_xfer_used + %{5} \
++    WHERE name = '%{6}' AND quota_type = '%{7}'" quotatallies
++</pre>
++This SQL statement is used to update the tally table with the current tally
++values for the session.  The meta sequences will be substituted with the
++&quot;deltas&quot;, the difference in the known versus current tallies.
++The reason for forming the UPDATE query this way is to provide as atomic
++an update operation as possible; this query will update the current values
++in the table at the time of the update, in order that any race condition
++between a SELECT and an UPDATE query on that information be reduced to
++as small a window as possible.
++
++<pre>
++  SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" quotatallies
++</pre>
++This last SQL statement is used to create a new tally record, in the
++event that a limit record is found for the current session but no matching
++tally record is found.  The meta sequences will be substituted with:
++name, quota type, upload tally in bytes, download tally in bytes, transfer
++tally in bytes, upload tally in files, download tally in files, and transfer
++tally in files, in that order.  These values are initialized to zero for
++newly-created tally records by default.
++
++<p>
++Now, using the above defined queries, the table configuration directives would
++be:
++<pre>
++  QuotaLock /var/run/ftpd/tally.lock
++  QuotaLimitTable sql:/get-quota-limit
++  QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally
++</pre>
++
++<p>
++<b>Example Schema</b><br>
++Here are some example table schema for SQL-based quota tables:
++<ul>
++  <li><b><i>Limit table</i></b><br>
++    <i>MySQL example</i>:
++<pre>
++    CREATE TABLE quotalimits (
++      name VARCHAR(30),
++      quota_type ENUM("user", "group", "class", "all") NOT NULL,
++      per_session ENUM("false", "true") NOT NULL,
++      limit_type ENUM("soft", "hard") NOT NULL,
++      bytes_in_avail FLOAT NOT NULL,
++      bytes_out_avail FLOAT NOT NULL,
++      bytes_xfer_avail FLOAT NOT NULL,
++      files_in_avail INT UNSIGNED NOT NULL,
++      files_out_avail INT UNSIGNED NOT NULL,
++      files_xfer_avail INT UNSIGNED NOT NULL
++    );
++</pre>
++    <i>Postgres example</i>:
++<pre>
++    CREATE TABLE quotalimits (
++       name VARCHAR(32) NOT NULL,
++       quota_type VARCHAR(8) NOT NULL
++         CHECK (quota_type IN ('user', 'group', 'class', 'all')),
++       per_session BOOLEAN NOT NULL,
++       limit_type VARCHAR(4) NOT NULL
++         CHECK (limit_type IN ('soft', 'hard')),
++       bytes_in_avail FLOAT NOT NULL,
++       bytes_out_avail FLOAT NOT NULL,
++       bytes_xfer_avail FLOAT NOT NULL,
++       files_in_avail INT8 NOT NULL,
++       files_out_avail INT8 NOT NULL,
++       files_xfer_avail INT8 NOT NULL
++    );
++</pre>
++  </li>
++  <br>
++
++  <li><b><i>Tally table</i></b><br>
++    <i>MySQL example</i>:
++<pre>
++    CREATE TABLE quotatallies (
++      name VARCHAR(30) NOT NULL,
++      quota_type ENUM("user", "group", "class", "all") NOT NULL,
++      bytes_in_used FLOAT NOT NULL,
++      bytes_out_used FLOAT NOT NULL,
++      bytes_xfer_used FLOAT NOT NULL,
++      files_in_used INT UNSIGNED NOT NULL,
++      files_out_used INT UNSIGNED NOT NULL,
++      files_xfer_used INT UNSIGNED NOT NULL
++    );
++</pre>
++    <i>Postgres example</i>:
++<pre>
++    CREATE TABLE quotatallies (
++      name VARCHAR(32) NOT NULL,
++      quota_type VARCHAR(8) NOT NULL
++        CHECK (quota_type IN ('user','group','class','all')),
++      bytes_in_used FLOAT NOT NULL,
++      bytes_out_used FLOAT NOT NULL,
++      bytes_xfer_used FLOAT NOT NULL,
++      files_in_used INT8 NOT NULL,
++      files_out_used INT8 NOT NULL,
++      files_xfer_used INT8 NOT NULL
++    );
++</pre>
++  </li>
++</ul>
++
++<p>
++<code>mod_quotatab_sql</code> treats any number <b>zero or less</b> for a
++<b>bytes limit</b> as &quot;unlimited&quot;.  Similarly, it treats a value of
++<b>zero</b> for any of the <b>files limit</b>s as &quot;unlimited&quot;.
++&quot;Unlimited&quot; values are ignored, in that any limit that is
++&quot;unlimited&quot; is not used in any of <code>mod_quotatab</code>'s
++calculations. NULL values should be avoided whenever possible.
++
++<p>
++<hr><br>
++
++Author: <i>$Author: frankie $</i><br>
++Last Updated: <i>$Date: 2003/11/17 15:30:12 $</i><br>
++
++<br><hr>
++
++<font size=2><b><i>
++&copy; Copyright 2000-2003 TJ Saunders<br>
++ All Rights Reserved<br>
++</i></b></font>
++
++<hr><br>
++
++</body>
++</html>
++
+diff -ruN proftpd-1.2.9-old/contrib/README.mod_quotatab proftpd-1.2.9/contrib/README.mod_quotatab
+--- proftpd-1.2.9-old/contrib/README.mod_quotatab	1970-01-01 01:00:00.000000000 +0100
++++ proftpd-1.2.9/contrib/README.mod_quotatab	2003-11-01 21:27:19.000000000 +0100
+@@ -0,0 +1,354 @@
++  ------------------------------------------------------------------------
++
++                         ProFTPD module mod_quotatab
++
++  ------------------------------------------------------------------------
++
++This module is contained in the mod_quotatab.c, mod_quotatab.h, and in its
++submodule source files, for ProFTPD 1.2, found here, and is not compiled by
++default. Installation instructions can be found here.
++
++This module is designed to impose quotas, both byte- and file-based, on FTP
++accounts, based on user, group, class, or for all accounts. It is based on
++the ideas contained in Eric Estabrook's mod_quota; however, this module has
++been written from scratch to implement quotas in a very different manner. A
++more detailed explanation of the usage of this module follows the directive
++explanations.
++
++The most current version of mod_quotatab's submodules supports storage of
++quota table information in various formats:
++
++   * mod_quotatab_file for file-based quota tables
++   * mod_quotatab_sql for SQL-based quota tables
++
++The most current version of mod_quotatab can be found at:
++
++  http://www.castaglia.org/proftpd/
++
++The eventual goal of this module is to make use of the Confstream API, an
++experimental API described here. This API would make support for tables in
++other formats (e.g. LDAP, CDB, DBM) much easier to implement.
++
++Author
++
++Please contact TJ Saunders <tj at castaglia.org> with any questions,
++concerns, or suggestions regarding this module.
++
++Thanks
++
++2002-01-12: Thanks to SupaFly <ntlfy at ntlworld.com> for helping debug an
++issue with a missing tally table.
++
++2002-03-30: Thanks to Kai Langheim <kl at q-nic.de> for pointing out several
++small bugs affecting users with no quota entries.
++
++Directives
++
++   * QuotaDirectoryTally
++   * QuotaDisplayUnits
++   * QuotaEngine
++   * QuotaLimitTable
++   * QuotaLog
++   * QuotaShowQuotas
++   * QuotaTallyTable
++
++SITE Commands
++
++   * SITE QUOTA
++
++  ------------------------------------------------------------------------
++
++QuotaDirectoryTally
++
++Syntax: QuotaDirectoryTally on|off
++Default: QuotaDirectoryTally off
++Context: server config, <VirtualHost>, <Global>
++Module: mod_quotatab
++Compatibility: 1.2.5rc2 and later
++
++The QuotaDirectoryTally directive configures mod_quotatab to take directory
++operations (e.g. creating a directory, removing a directory) into account
++when tallying.
++
++  ------------------------------------------------------------------------
++
++QuotaDisplayUnits
++
++Syntax: QuotaDisplayUnits "b"|"Kb"|"Mb"|"Gb"
++Default: None
++Context: server config, <VirtualHost>, <Global>
++Module: mod_quotatab
++Compatibility: 1.2.5rc2 and later
++
++This directive configures how the user's current byte quota values will be
++reported to them. Note that this directive does not affect how the quota
++values are stored in the quota table, only their presentation to the user.
++
++"b" causes quotas to be displayed in bytes; "Kb", kilobytes; "Mb",
++megabytes; and "Gb", gigabytes.
++
++Example:
++
++  # display quota information in megabytes
++  QuotaDisplayUnits Mb
++
++  ------------------------------------------------------------------------
++
++QuotaEngine
++
++Syntax: QuotaEngine on|off
++Default: None
++Context: server config, <VirtualHost>, <Global>
++Module: mod_quotatab
++Compatibility: 1.2.5rc2 and later
++
++The QuotaEngine directive enables or disables the module's runtime quota
++engine. If it is set to off this module does no runtime processing at all.
++Use this directive to disable the module instead of commenting out all
++mod_quotatab directives.
++
++  ------------------------------------------------------------------------
++
++QuotaLimitTable
++
++Syntax: QuotaLimitTable source-type:source-info
++Default: None
++Context:
++Module: mod_quotatab
++Compatibility: 1.2.5rc2 and later
++
++This directive configures the information necessary for the module to locate
++and use the table containing the quota limit, the maximum number of bytes
++and/or files defined for use by specific users, groups, classes, etc, and is
++required for mod_quotatab to function.
++
++Please consult the relevant submodule documentation for details on that
++module's syntax for this configuration directive.
++
++See also: QuotaTallyTable
++
++  ------------------------------------------------------------------------
++
++QuotaLog
++
++Syntax: QuotaLog file|"none"
++Default: None
++Context:
++Module: mod_quotatab
++Compatibility: 1.2.5rc2 and later
++
++The QuotaLog directive is used to a specify a log file for mod_quotatab
++reporting, and can be done a per-server basis. The file parameter must be
++the full path to the file to use for logging. Note that this path must not
++be to a world-writeable directory and, unless AllowLogSymlinks is explicitly
++set to on (generally a bad idea), the path must not be a symbolic link.
++
++If file is "none", no logging will be done at all; this setting can be used
++to override a QuotaLog setting inherited from a <Global> context.
++
++  ------------------------------------------------------------------------
++
++QuotaShowQuotas
++
++Syntax: QuotaShowQuotas on|off
++Default: on
++Context:
++Module: mod_quotatab
++Compatibility: 1.2.5rc2 and later
++
++The QuotaShowQuotas directive can be used to enable/disable mod_quotatab's
++response to a SITE QUOTA request. For some sites, revealing the current
++quota information may be considered an unnecessary, perhaps even
++detrimental, information leak; other sites may consider this a definite
++feature.
++
++  ------------------------------------------------------------------------
++
++QuotaTallyTable
++
++Syntax: QuotaTallyTable source-type:source-info
++Default: None
++Context:
++Module: mod_quotatab
++Compatibility: 1.2.5rc2 and later
++
++This directive configures the information necessary for the module to locate
++and use the table containing the quota tally, or the current byte/file
++counts for users, groups, classes, etc, and is required for mod_quotatab to
++function.
++
++Please consult the relevant submodule documentation for details on that
++module's syntax for this configuration directive.
++
++See also: QuotaLimitTable
++
++  ------------------------------------------------------------------------
++
++SITE QUOTA
++
++The SITE QUOTA command will display the quota, both the limit and the
++current tally, to the client. This SITE command accepts no parameters, and
++can only be used once the client has successfully logged in.
++
++Example:
++
++ftp> quote SITE QUOTA
++200-The current quota for this session are [current/limit]:
++ Name: tj
++ Quota Type: User
++ Per Session: True
++ Limit Type: Hard
++   Uploaded Kb:         unlimited
++   Downloaded Kb:       unlimited
++   Transferred Kb:      unlimited
++   Uploaded files:      1/1
++   Downloaded files:    unlimited
++   Transferred files:   unlimited
++200 Please contact root@familiar.castaglia.org if these entries are inaccurate
++ftp>
++
++Use of this SITE command can be controlled via <Limit>, e.g.:
++
++  <Limit SITE_QUOTA>
++    AllowUser tj
++    DenyAll
++  </Limit>
++
++Like many SITE commands, the FTP client will probably not recognize or
++support SITE QUOTA. Hopefully the client does have the ability to send
++arbitrary commands to the server, as the common ftp(1) client does via
++quote.
++
++The email address displayed in the SITE QUOTA output can be configured via
++the ServerAdmin directive.
++
++  ------------------------------------------------------------------------
++
++Usage
++
++To use mod_quotatab's functionality, you must first define the tables that
++together contain the quota information.
++
++There are two such quota tables: one table for providing quota information
++about the absolute byte/file limits for users, groups, and classes, and a
++separate table for maintaining the current tally, or number of bytes/files
++used, for those same users, groups, and classes. This separation of
++information allows for a configuration such as using LDAP to efficiently
++distribute the limit information, and local SQL databases for efficiently
++storing the tally. The limit table is considered a read-only table, and is
++only accessed at the start of session in order to determine what the session
++limits should be. The tally table is accessed in read-write mode, and is
++updated after the relevant FTP commands have been processed.
++
++This module was not explicitly designed for easy interaction with other
++applications, but rather for other criteria:
++
++   * efficient lookups and updates
++   * no need for ~/.quota files
++   * no need of requirement for root privileges to access quotas
++   * easy support for an abstraction layer for storing quota information in
++     other formats
++   * support for a SITE command that allows users to view their current
++     quotas
++
++This module maintains its quotas based solely on FTP commands - it does not
++enforce quotas based on files that may have been added, deleted, or moved
++via shell access or any mechanism other than through the proftpd server.
++
++When a client logs in, assuming QuotaEngine is on, mod_quotatab will check
++the limit table for the record most appropriate for that client. This check
++first examines the table for records of type user that match the client's
++login name. If no such matching records are found, it checks for records of
++type group that match any of the user's groups (both primary and
++supplemental). Failing that, it will check for records of type class that
++belong to the class (if enabled) from which the client is connecting. If
++still no matching records are found, the table will be searched for a record
++of type all; if absent, the module will assume that no quotas apply to the
++client.
++
++Once the limits for the current session have been established, mod_quotatab
++examines the tally table to see what the current numbers in the matching
++tally record are. Should the client have an applicable limit record but no
++matching tally record, the module will initialize a new record in the tally
++table.
++
++For the purposes of tracking the number of uploaded bytes/files, the tally
++will be adjusted accordingly upon use of the following FTP commands: APPE
++(bytes only), DELE, STOR, and STOU. The number of bytes used for the
++calculation will be determined from the difference in file size of the file
++in question.
++
++For the purposes of tracking the number of downloaded bytes/files, the tally
++will be adjusted accordingly upon use of the following FTP commands: RETR.
++The number of bytes used for the calculation will be determined from the
++number of bytes sent to the client.
++
++For the purposes of tracking the number of transferred bytes/files, the
++tally will be adjusted accordingly upon use of the following FTP commands:
++APPE (bytes only), DELE, RETR, STOR, and STOU. The number of bytes used for
++the calculation will be determined from the number of bytes sent to the
++client. This type of limit allows for byte/file limits to be set that
++encompass both uploads and downloads.
++
++Note that if all three types of quotas are set (upload, download, and
++transfer), any quota reached will cause denial of FTP commands. This means
++that a high upload quota will never be reached if a low transfer quota is in
++effect. This holds true for bytes and files quota. For example, if a user
++has a limited number of both bytes and files to be uploaded in their limit
++record, the first limit reached (bytes or files) is the effective limit.
++Caveat emptor.
++
++For any quota limit that is set as "unlimited", mod_quotatab will not keep
++the tally. Many site administrators might want this ability, for accounting
++purposes. However, that ability is outside of the intended design of this
++module; other logging modules are much better suited for accounting purposes
++(e.g. mod_sql's SQLLog directive).
++
++If any developers wish to make use of mod_quotatab's quota information, or
++to develop a new submodule, there is developer documentation available here.
++
++  ------------------------------------------------------------------------
++
++Installation
++
++To install mod_quotatab, follow these instructions. After unpacking the
++tarball, copy the mod_quotatab.c, mod_quotatab.h, mod_quotatab_file.c, and
++mod_quotatab_sql.c files into:
++
++  proftpd-dir/contrib/
++
++after unpacking the latest proftpd-1.2 source code. Follow the usual steps
++for using third-party modules in proftpd:
++
++  ./configure --with-modules=quotatab-modules
++  make
++  make install
++
++where quotatab-modules will depend on the types of quota tables you wish to
++support.
++
++For file-based quota tables, include the mod_quotatab_file submodule, e.g.:
++
++  mod_quotatab:mod_quotatab_file
++
++For SQL-based quota tables, include the mod_quotatab_sql submodule, e.g.:
++
++  mod_quotatab:mod_quotatab_sql
++
++And, if you wish to support file- and SQL-based quota tables:
++
++  mod_quotatab:mod_quotatab_file:mod_quotatab_sql
++
++Note that SQL tables require that a correct installation of mod_sql (and any
++of its backend modules) also be used. Consult the mod_sql documentation for
++installation instructions for that module.
++
++  ------------------------------------------------------------------------
++
++Author: $Author: frankie $
++Last Updated: $Date: 2003/11/17 15:30:12 $
++
++  ------------------------------------------------------------------------
++© Copyright 2000-2002 TJ Saunders
++All Rights Reserved
++  ------------------------------------------------------------------------
--- proftpd-1.2.9.orig/debian/patches/15.mod_quotatab_sql.c.diff
+++ proftpd-1.2.9/debian/patches/15.mod_quotatab_sql.c.diff
@@ -0,0 +1,16 @@
+diff -ruN proftpd-1.2.9-old/contrib/mod_quotatab_sql.c proftpd-1.2.9/contrib/mod_quotatab_sql.c
+--- proftpd-1.2.9-old/contrib/mod_quotatab_sql.c	2004-02-17 19:19:33.000000000 +0100
++++ proftpd-1.2.9/contrib/mod_quotatab_sql.c	2004-02-17 19:22:53.000000000 +0100
+@@ -395,9 +395,9 @@
+   snprintf(tally_bytes_in, 20, "%f", quotatab_deltas.bytes_in_delta);
+   snprintf(tally_bytes_out, 20, "%f", quotatab_deltas.bytes_out_delta);
+   snprintf(tally_bytes_xfer, 20, "%f", quotatab_deltas.bytes_xfer_delta);
+-  snprintf(tally_files_in, 20, "%u", quotatab_deltas.files_in_delta);
+-  snprintf(tally_files_out, 20, "%u", quotatab_deltas.files_out_delta);
+-  snprintf(tally_files_xfer, 20, "%u", quotatab_deltas.files_xfer_delta);
++  snprintf(tally_files_in, 20, "%d", quotatab_deltas.files_in_delta);
++  snprintf(tally_files_out, 20, "%d", quotatab_deltas.files_out_delta);
++  snprintf(tally_files_xfer, 20, "%d", quotatab_deltas.files_xfer_delta);
+ 
+   sql_cmd = sql_cmd_create(tmp_pool, 10, "sql_change", update_query,
+     tally_bytes_in, tally_bytes_out, tally_bytes_xfer,
--- proftpd-1.2.9.orig/debian/patches/16.dirtree,c.diff
+++ proftpd-1.2.9/debian/patches/16.dirtree,c.diff
@@ -0,0 +1,21 @@
+diff -ruN proftpd-1.2.9-old/src/dirtree.c proftpd-1.2.9/src/dirtree.c
+--- proftpd-1.2.9-old/src/dirtree.c	2003-10-19 00:14:14.000000000 +0200
++++ proftpd-1.2.9/src/dirtree.c	2004-03-09 11:33:50.000000000 +0100
+@@ -1534,10 +1534,14 @@
+ 
+   if (cidr_mode) {
+ /* NOTE: encapsulation breakage note/IPv6 change needed here. */
+-#if 0
+-    if ((cli_addr->s_addr & htonl(cidr_mask)) == cidr_addr.s_addr)
+-#endif
++
++      if (pr_netaddr_get_family(cli_addr) == AF_INET) {
++  struct in_addr *cli_in_addr = pr_netaddr_get_inaddr(cli_addr);
++  if ((cli_in_addr->s_addr & htonl(cidr_mask)) == cidr_addr.s_addr) {
+       return 1;
++  }
++      };
++
+ 
+   } else {
+     pr_netaddr_t *acl_addr = NULL;
--- proftpd-1.2.9.orig/debian/NEWS.Debian
+++ proftpd-1.2.9/debian/NEWS.Debian
@@ -0,0 +1,21 @@
+proftpd (1.2.8-11) unstable; urgency=low
+
+ 	Since latest 1.2.8 releases, a lots of patches coming from CVS have been
+ 	merged  in the  code,  so  that debian  edition is  less buggy  than the
+ 	official edition.  All  patches  are reported  in changelog,  along with
+ 	ProFTP bugzilla crossrefs.
+
+ 	All old  debconf craps^Wcode for anonymous  enabling/disabling has been
+ 	removed, so that postinst configuration  is less intrusive than before.
+ 	The  system  'ftp' user  is  also  always  added  by default,  even  if
+ 	disabled.
+
+ 	Maintainer scripts now manage  anyway some simple directives migrations
+ 	and also inetd|standalone modes as before.  Also they now are (and will
+ 	be)  written to  point known  configuration gotchas  and pitfalls  when
+	needed.
+
+	Hopefully, this new policy will satisfy the conscious sys admin.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sat, 23 Aug 2003 10:39:04 +0200
+
--- proftpd-1.2.9.orig/debian/TODO.texi
+++ proftpd-1.2.9/debian/TODO.texi
@@ -0,0 +1,17 @@
+@subheading @anchor{MySQLRatios} MySQLRatios
+
+@format
+Syntax: MySQLRatios on
+Syntax: MySQLRatios frate-field fcred-field brate-field bcred-field
+Default: off, or (@samp{frate fcred brate bcred}) if fields unspecified.
+Context: server config
+Compatibility: only available with the Debian package.
+@end format
+
+Activates support for retrieving per-user ratios from the database.  To
+use this feature, @samp{SQLUserTable} (mod_sql) and @samp{Ratios on}
+(mod_ratios) directives are needed.
+
+For this to work you need to compile with -DMOD_MYSQL_RATIOS, and use
+mod_ratio version 2.0 or better.  The latest version is not included
+with stock ProFTPD, but the Debian package has it compiled in.
--- proftpd-1.2.9.orig/debian/basic.conf
+++ proftpd-1.2.9/debian/basic.conf
@@ -0,0 +1,101 @@
+# This is a basic ProFTPD configuration file (rename it to 
+# 'proftpd.conf' for actual use.  It establishes a single server
+# and a single anonymous login.  It assumes that you have a user/group
+# "nobody/nogroup" and "ftp" for normal operation and anon.
+
+ServerName			"Debian"
+ServerType			standalone
+DeferWelcome			off
+
+MultilineRFC2228		on
+DefaultServer			on
+ShowSymlinks			on
+AllowOverwrite			on
+
+TimeoutNoTransfer		600
+TimeoutStalled			600
+TimeoutIdle			1200
+
+DisplayLogin                    welcome.msg
+DisplayFirstChdir               .message
+ListOptions                	"-l"
+
+DenyFilter			\*.*/
+
+# Uncomment this if you are using NIS or LDAP to retrieve passwords:
+#PersistentPasswd		off
+
+# Uncomment this if you would use TLS module:
+#TLSEngine 			on
+
+# Uncomment this if you would use quota module:
+#Quotas				on
+
+# Uncomment this if you would use ratio module:
+#Ratios				on
+
+# Port 21 is the standard FTP port.
+Port				21
+
+# To prevent DoS attacks, set the maximum number of child processes
+# to 30.  If you need to allow more than 30 concurrent connections
+# at once, simply increase this value.  Note that this ONLY works
+# in standalone mode, in inetd mode you should use an inetd server
+# that allows you to limit maximum number of processes per service
+# (such as xinetd)
+MaxInstances			30
+
+# Set the user and group that the server normally runs at.
+User				nobody
+Group				nogroup
+
+<Directory /*>
+# Umask 022 is a good standard umask to prevent new files and dirs
+# (second parm) from being group and world writable.
+  Umask				022  022
+# Normally, we want files to be overwriteable.
+  AllowOverwrite		on
+</Directory>
+
+# A basic anonymous configuration, no upload directories.
+
+# <Anonymous ~ftp>
+#   User				ftp
+#   Group				nogroup
+#   # We want clients to be able to login with "anonymous" as well as "ftp"
+#   UserAlias			anonymous ftp
+#   # Cosmetic changes, all files belongs to ftp user
+#   DirFakeUser	on ftp
+#   DirFakeGroup on ftp
+# 
+#   RequireValidShell		off
+# 
+#   # Limit the maximum number of anonymous logins
+#   MaxClients			10
+# 
+#   # We want 'welcome.msg' displayed at login, and '.message' displayed
+#   # in each newly chdired directory.
+#   DisplayLogin			welcome.msg
+#   DisplayFirstChdir		.message
+# 
+#   # Limit WRITE everywhere in the anonymous chroot
+#   <Directory *>
+#     <Limit WRITE>
+#       DenyAll
+#     </Limit>
+#   </Directory>
+# 
+#   # Uncomment this if you're brave.
+#   # <Directory incoming>
+#   #   # Umask 022 is a good standard umask to prevent new files and dirs
+#   #   # (second parm) from being group and world writable.
+#   #   Umask				022  022
+#   #            <Limit READ WRITE>
+#   #            DenyAll
+#   #            </Limit>
+#   #            <Limit STOR>
+#   #            AllowAll
+#   #            </Limit>
+#   # </Directory>
+# 
+# </Anonymous>
--- proftpd-1.2.9.orig/debian/changelog
+++ proftpd-1.2.9/debian/changelog
@@ -0,0 +1,1365 @@
+proftpd (1.2.9-6.backports.org.1) unstable; urgency=high
+
+  * recompiled for http://www.backports.org/
+    + removed versions from debianutils and netbase dependencies
+
+ -- Norbert Tretkowski <tretkowski@inittab.de>  Wed, 14 Apr 2004 13:07:53 +0200
+
+proftpd (1.2.9-7) unstable; urgency=high
+
+  * Removed a double check for inetd update (proftpd.postinst)
+    (closes: #242013)
+  * Added an '|| true' into install_ftp (proftpd.postinst)
+  * Integrating a patch to avoid an infinite loop.
+    See http://bugs.proftpd.org/show_bug.cgi?id=2300 for patch.
+    Fixed by 17.netio.c.diff
+    (closes: #243071,#243277)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon, 12 Apr 2004 09:41:52 +0200
+
+proftpd (1.2.9-6) unstable; urgency=high
+
+  * Umpf. Previuous upload did not solve the issue. It seems definitively a
+    problem with ucf (Thanks Paul Slootman): --debconf-ok should be used
+    only before a db_stop. Also reverted again with redirection for
+    update-inetd. 
+    For some reason the whole problem was not so easily evident.
+    (closes: #239528)
+  * Previous upload missed patch 16.dirtree.c.diff due to outdated cvs
+    repository on alioth.
+  * Cosmetic changes into basic anon section (DirFake*).
+    Other issues are secondary/outdated.
+    (closes: #240209)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon, 29 Mar 2004 23:31:52 +0200
+
+proftpd (1.2.9-5) unstable; urgency=high
+                                                                                                                                         
+  * Reverted redirection of stdin and stdout for update-inetd. Also reverted
+    netbase versioning dependency. Apparently workaround in current
+    update-inetd does not work as it should.
+    (closes: #239528)
+                                                                                                                                         
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Wed, 24 Mar 2004 20:14:55 +0100
+                                                                                                                                         
+proftpd (1.2.9-4) unstable; urgency=high
+
+  * Typo introduced in postrm (closes: #236963)
+  * Removed redirection workaround for update-inetd (already builtin in netbase >=4.13).
+    Changed version dependency for netbase as consequence.
+    (closes: #236595)
+  * Security problem (although conf dependent) fixed in patch 16.dirtree.c.diff. (Thanks iSteve)
+    See http://bugs.proftpd.org/show_bug.cgi?id=2267 for hint and patch.
+  * Typo in ftpstats.8 corrected (Thanks iSteve)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue,  9 Mar 2004 11:50:36 +0100
+
+proftpd (1.2.9-3) unstable; urgency=low
+
+  * New patch 15.mod_quotatab_sql.c.diff. (Thanks Jerome Walters)
+    Bug found by Christian Schulte <cs@schulte.it>: delta values are signed,
+    and can be negative.
+  * Now use --debconf-ok for ucf, but needs versioning depends on ucf >= 0.30
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 26 Feb 2004 00:11:09 +0100
+
+proftpd (1.2.9-2) unstable; urgency=low
+
+  * Using basic.conf from 1.2.8 series, instead of the old one with prefixed
+    anonymous section.
+  * Added libncurses5-dev build-dep for ftptop.
+  * Policy bumped to 3.6.1 (no changes).
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon, 17 Nov 2003 13:59:24 +0100
+
+proftpd (1.2.9-1) unstable; urgency=low
+
+  * The first post-Halloween release now moving to sid. 
+    Now using upstream tarball.
+  * CVS repository enabled: tagging appropriately.
+  * Removed patch 14.manpages.diff: manpages are integrated in upstream
+    tarballs, even if not present in CVS.
+  * New patch: 14.mod_quotatab.diff: mod_quotatab 1.2.11 contributed module
+    now replaces the old 1.2.7.
+  * Removed 13.manpages.diff patch which is not due in off-cvs releases.
+  * Tries to manage upgrades from pre-1.2.9 series in a soft way:
+        - The scoreboard file format changed, so all inetd sessions need to be killed
+          and file moved before restarting the service. The file needs to be
+          moved for a standalone configuration, anyway.
+        - SocketOptions directive replaces and deprecates the following
+          directives: tcpReceiveWindow, and tcpSendWindow.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon,  3 Nov 2003 14:14:00 +0100
+
+proftpd (1.2.8+cvs20031020-1) experimental; urgency=low
+
+  * A new CVS snapshot (post 1.2.9rc3).
+  * Merged stuff from unstable branch
+  	- New russian template.
+  	- Added a versioned dependency from debianutils to proftpd-common
+   	- Removed RFCs
+        - Changed order in module loading for dependencies
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon, 20 Oct 2003 23:36:58 +0200
+
+proftpd (1.2.8+cvs20030927-1) experimental; urgency=high
+
+  * A new CVS snapshot (post 2003-9-24 exploit).
+  * Merged stuff from unstable branch (>= -9):
+         - Now using case insensitive egrep in init files
+         - Patches renumbered sequentially
+         - Removing anonymous access enabling/disabling. A well commented basic
+           configuration, to be modified by hand is much more effective and secure.
+           Also that code is completely failing if admin changed configuration on his
+           own, as generally done by everyone. So, debconf configuration is much less
+           intrusive, and it's performed anyway. User 'ftp' is also added by
+           default if not present, being a considered a 'system' one.
+
+           Added a NEWS.Debian file to explain the new policy.
+           Changed templates as consequence.
+         - International templates revised.
+         - Added strict version source dependency for proftpd-common.
+         - Use proftpd.org instead of .net in control file descriptions.
+         - Added NEWS.Debian as kept in unstable branch.
+         - Removed 05.ftpstats.diff (unuseful).
+         - Postinst revised to manage welcome.msg nicely.
+  * Bugs fixed at this time (see below):
+    (closes: #192590,#204157,#192590,#203230,#186074,#212416)
+    (closes: #145669 see http://www.castaglia.org/proftpd/patches/README.require-valid-user)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sun, 28 Sep 2003 17:52:31 +0200
+
+proftpd (1.2.8+cvs20030818-1) experimental; urgency=low
+
+  * A new CVS snapshot. IPV6 is now integrated.
+  * Removed previous patches 01.ipv6_rollback.diff and 00.ipv6.diff all IPv6
+    related.
+  * Changed patch 20.contrib.mod_ldap.c.diff to reflect modifications in
+    inet.h
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 19 Aug 2003 09:19:19 +0200
+
+proftpd (1.2.8+cvs20030805-1) experimental; urgency=low
+
+  * A new CVS snapshot. See NEWS file for a list of bugs solved.
+    All Debian patches applies but some hacks on the first one.
+  * Policy updated to 3.6.0
+  * Bugs closed at this time: #204157,#192590,#203230
+  * Added IPV6 support.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue,  5 Aug 2003 20:57:31 +0200
+
+proftpd (1.2.8+cvs20030620-1) experimental; urgency=low
+
+  * This is based on cvs tree at the date. It's not prime time ready.
+  * Removed duplicated tarball: fixes #192590
+  * Removed patches already in CVS:
+       AB.fixes_handling_of_contexts_to_use_proper_pool.diff
+       B2.mod_sql_postgres.c.diff
+       10.mod_cap.c.diff
+  * Added patches:
+       91.autoconf.diff - move configure.in to configure.ac to force use of autoconf2.50
+       B2.mod_sql_mysql.c.diff - use <mysql/mysql.h> instead of <mysql.h>
+       B3.manpages.diff - add man pages that are missing in the cvs tree
+  * Added autoconf build-dep.
+  * Policy updated to 3.5.10.
+  * Minor changes in rules file in order to build correctly.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sat, 21 Jun 2003 17:31:36 +0200
+
+proftpd (1.2.8-8) unstable; urgency=high
+
+  * Added a set +e before testing proftpd configuration.
+    Proftpd could crash in some cases when testing.
+    (closes: #197585)
+  * Added AB.fixes_handling_of_contexts_to_use_proper_pool.diff:
+    fixes handling of contexts to use properpool, by patching src/dirtree.c and src/sets.c.
+    This is from current CVS tree.
+    (closes: #197586)
+  * Security: added B2.mod_sql_postgres.c.diff:
+    See http://bugs.proftpd.org/show_bug.cgi?id=2087 for information. This
+    has been created using diff among mod_sql_postgres.c-1.16 and mod_sql_postgres.c-1.10.
+    This is from current CVS tree.
+    (closes: #197984)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 19 Jun 2003 13:50:29 +0200
+
+proftpd (1.2.8-7) unstable; urgency=high
+
+  * Added an input (</dev/tty) redirection for ucf in maint scripts.
+    (closes: #194359). This is a workaround for #193694 which is a
+    debconf/ucf interaction problem.
+  * Japanese podebconf template
+    (closes: #194646)
+  * Updated french podebconf template
+    (closes: #192406)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 27 May 2003 12:49:50 +0200
+
+proftpd (1.2.8-6) unstable; urgency=low
+
+  * Added missing HTML documentation to proftpd-doc. This also clarify misbehaving for mod_tls.
+    (closes: #150694)
+  * Added mod_rewrite, mod_radius, mod_wrap to all packages. So added
+    libwrap0-dev among build-deps.
+    (closes: #158305)
+  * Added more README files and removed a couple of obsoleted ones.
+  * debconf template and it.po revised as suggested.
+    (closes: #190821)
+  * New fr.po integrated.
+    (closes: #191227)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue,  6 May 2003 20:56:06 +0200
+
+proftpd (1.2.8-5) unstable; urgency=high
+
+  * Explicitly depends on libmysqlclient10-dev, which is the last LGPL licensed.
+    Also, current sql module is not tested with mysql4, so the conservative
+    approach is the safest one.
+  * Introduced Replaces in control/proftpd-common against old packages.
+    (closes: #188114)
+  * Policy updated.
+  * Maintainer script totally revised. Wow! Some more hints in basic.conf
+    added too. Also a new warning note is displayed when upgrading.
+    (closes: #168305, #145662, #187695, #186646, #187695)
+    Debconf IS NOT a configuration tool. Now I use it only for minimal
+    config interactions. We absolutely needed a more powerful config editor
+    for proftpd.conf, but I seriously doubt it can be really written.
+  * Introduced -q for savelog instead of stdout/stderr redirect, in
+    cron.monthly.
+    (closes: #188722)
+  * Now truly install ftpasswd.8 among proftpd-common man pages :-/
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 24 Apr 2003 12:31:26 +0200
+
+proftpd (1.2.8-4) unstable; urgency=medium
+
+  * Init file revised to use current default pidfile or PidFile directive.
+    Scoreboard file name no more has the daemon pid bundled.
+    (closes: #186312)
+  * Now postinst changes obsolete LsDefaultOptions in ListOptions directive.
+    That's needed in moving from 1.2.6 basic.conf. Added a list_options()
+    function for this.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 27 Mar 2003 11:09:00 +0100
+
+proftpd (1.2.8-3) unstable; urgency=high
+
+  * Removed dh_undocumented which is no more used.
+  * Added a new patch:
+  	10.mod_cap.c.diff - solves a double free in mod_cap which caused #185030.
+  * Re-added mod_cap thanks to previous patch. So readded libcap-dev.
+  * Patch 20.contrib.mod_ldap.c.diff revised.
+    (closes: #185125, #175581,#185567)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sat, 22 Mar 2003 11:56:53 +0100
+
+proftpd (1.2.8-2) unstable; urgency=high
+
+  * Removed mod_cap. It needs more investigation.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 18 Mar 2003 13:27:24 +0100
+
+proftpd (1.2.8-1) unstable; urgency=high
+
+  * New upstream release, merging with my experimental 1.2.7 pkg...
+    (closes: #185084)
+    This also solve a potential seriuous license bug as stated
+    in http://lists.debian.org/debian-legal/2003/debian-legal-200303/msg00287.html
+    and http://lists.debian.org/debian-legal/2003/debian-legal-200301/msg00287.html.
+  * IPv6 removed. It will be available in 1.2.9 anyway. It was also disabled in all
+    releases before 1.2.6-5, so I guess it's not a high-requested feature :)
+  * configure updated to 2.57.
+  * added config.(sub|guess) cleaning.
+  * Paul asked to become co-maintainer.
+  * Removed patches:
+  	30.libcap.change.build.dir.diff
+        32.libcap.compilation.fix.diff.uue
+        50.proftpd-1.2.6rc1-tls.2002.07.11.patch
+        AE.mod_tls.c.no.certificates.found.diff
+        91.mod_tls.diff
+        AF.ipv6.diff
+        B0.mod_ls.c.fsmatch.diff
+  * Added patches:
+  	90.man.diff
+  * Changed fr.po: now truly closes: #182889.
+  * Policy update.
+  * Added dep/build-dep from libcap2(-dev). It does not work with stable libcap.
+    (closes: #185030, hopefully #185125)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 18 Mar 2003 12:34:58 +0100
+                                                                                           
+proftpd (1.2.6-5) unstable; urgency=low
+
+  * Only restart the daemon if runlevels allow, in accordance with
+    policy section 10.3.3.2. (Closes: #166907)
+  * Revised contents of ftpstats.8 (frankie)
+  * Added ftpasswd.8 (frankie)
+  * Removed obsolete proftpd libcap building. Now uses standard one. (frankie)
+    (Closes: #168953)
+  * fr.po updated (frankie) (Closes: #182889)
+  * pt_BR.po updated (frankie) (Closes: #177226)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon,  3 Mar 2003 10:39:59 +0100
+
+proftpd (1.2.6-4) unstable; urgency=low
+
+  * debian/control: put proftpd-doc in section "doc".
+  * Now uses po-debconf templates (frankie).
+  * Added Italian template (frankie).
+  * debian/control: added frankie@debian.org as co-maintainer.
+  * debian/control: added build-depend on sharutils, as we now need
+    uudecode because of...
+  * debian/patches: two of the patches contain RCS Id tags in their
+    context, which got mangled by CVS, so they're now uuencoded, which
+    required changes to...
+  * debian/scripts/file2cat: now uudecodes files with .uue extension
+  * debian/scripts/dbs-build.mk: ignore CVS directories when applying
+    patches.
+  * debian/rules: use $$m instead of $m for loop variable.
+    (Closes: #166205)
+  * debian/patches/AC.mod_unixpw.c.ldap.fix.diff: if getpwnam/getpwuid
+    return NULL, revert to original method of getting pw entries.
+    (Closes: #165188)
+  * debian/rules: remove incorrect logic for detecting kernel version
+    which was causing linuxprivs never to be compiled in. Thanks to 
+    frankie for tracing this one. (Closes: #166215)
+
+ -- Paul Martin <pm@debian.org>  Mon, 28 Oct 2002 14:24:28 +0000
+
+proftpd (1.2.6-3) unstable; urgency=low
+
+  * debian/proftpd.config: unfortunately Ivo's patch had a bug in it.
+    Fixed this and another problematic conditional pointed out by Andrew
+    Suffield. (Closes: #164556,#164556)
+  * debian/proftpd.config: more compare-versions fixes. (Closes: #165677)
+
+ -- Paul Martin <pm@debian.org>  Mon, 21 Oct 2002 12:27:08 +0100
+
+proftpd (1.2.6-2) unstable; urgency=low
+
+  * New maintainer. (Closes: #163632)
+  * debian/proftpd.config: fix version test (Closes: #164556)
+  * debian/patches/B0.mod_ls.c.fsmatch.diff: Fixes the "virtual
+    filesystem" abstraction. Only contrib/mod_test.c would be
+    affected, if we built it.
+  * debian/rules: added undocumented.7 link to ftpasswd.8.
+    (Bug: #150101) Bug left open until proper manpage is written.
+  * debian/patches/B1.ftpasswd.cracklib.location.diff: Change the
+    default location of the cracklib dictionaries to match their
+    Debian location. (Closes: #159365)
+
+ -- Paul Martin <pm@debian.org>  Fri, 18 Oct 2002 18:12:59 +0100
+
+proftpd (1.2.6-1) unstable; urgency=low
+
+  * New upstream release.
+  * debian/patches/20.contrib.mod_ldap.c.diff: Updated.
+  * debian/patches/AF.ipv6.diff: Updated.
+  * debian/patches/AG.mod_ratio.c.3.3.diff: Removed.
+  * debian/patches/AH.mod_ldap.c.HEAD.diff: Removed.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat,  7 Sep 2002 14:49:52 +0200
+
+proftpd (1.2.5+1.2.6rc2-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/control: Change section from non-US to net.
+  * debian/copyright: Change licenses for mod_ldap.c and mod_ratio.c.
+  * Take advantage of the required new source upload to create an
+    .orig.tar.gz and a .diff.gz.
+  * debian/proftpd.postinst: Call db_stop before replace_file.
+  * debian/patches/33.mod_quota.c.exemption.fix.diff: Removed (upstream
+    has removed mod_quota.c).
+  * debian/rules: Don't include mod_quota.c in compilation.
+  * debian/patches/50proftpd-1.2.5-tls.2002.05.30.patch: Replaced by
+    50.proftpd-1.2.6rc1-tls.2002.07.11.patch.
+  * debian/patches/AB.mod_ls.c.large.files.support.diff: Removed (upstream
+    has included LFS).
+  * debian/patches/AF.ipv6.diff: Updated.
+  * debian/patches/AG.mod_ratio.c.3.3.diff: Update mod_ratio.c to version
+    3.3.
+  * debian/patches/AH.mod_ldap.c.HEAD.diff: Update mod_ldap.c to CVS HEAD.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun,  1 Sep 2002 17:06:41 +0200
+
+proftpd (1.2.5-3) unstable; urgency=low
+
+  * debian/proftpd.init:
+      - Remove bashism;
+      - signal(): remove superfluous "proftpd" in the find statement;
+        (Closes: #156878)
+      - Added new option "force-stop", which will try to kill proftpd even
+        though the config file says it is started from inetd (like
+        force-start). (Closes: #153922)
+  * debian/proftpd.config: Stop any running proftpd when the old setting
+    was to be run standalone, and the new setting to run from inetd.
+    (Closes: #144882, #151362)
+  * debian/proftpd.postrm: Remove debconf calls.
+    (Closes: #148727, #156464)
+  * debian/copyright:
+      - Include the license exception the ProFTPd team has given (long
+        ago) to allow binaries linked against OpenSSL to be distributed.
+      - Include licenses for contributed modules.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun, 18 Aug 2002 20:25:11 +0200
+
+proftpd (1.2.5-2) unstable; urgency=low
+
+  * debian/proftpd.init: Let the init script get the location of the
+    scoreboard from the config. (Closes: #150162)
+  * debian/patches/AE.mod_tls.c.no.certificates.found.diff: Don't try to
+    check certificate files on startup. (Closes: #153992, #154238)
+  * debian/patches/20.contrib.mod_ldap.diff: Fix segfault in uid-lookup in
+    proftpd-ldap. (Closes: #150525)
+  * debian/control: Changed sections from non-US/main to non-US.
+  * debian/patches/AF.ipv6.diff: IPv6 patch from Jan Rekorajski, Amand
+    TIHON and others.
+
+ -- Ivo Timmermans <ivo@debian.org>  Tue, 13 Aug 2002 23:23:54 +0200
+
+proftpd (1.2.5-1) unstable; urgency=low
+
+  * New upstream version. (Closes: #146839)
+  * Updated TLS patch.
+  * Upstream now includes ftpasswd, deleted it from 99.misc.diff.
+  * Deleted the patch to delete doc/rfc/draft-murray-auth-ftp-ssl-08.txt,
+    which has been deleted upstream.
+  * Updated AB.mod_ls.c.large.files.support.diff.
+  * Removed one "ShowSymlinks on" from basic.conf. (Closes: #148358)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 13 Jun 2002 17:16:10 +0200
+
+proftpd (1.2.4+1.2.5rc1-6) unstable; urgency=high
+
+  * One more try...
+  * /etc/proftpd.conf is no longer marked as a conffile.  Instead, we
+    verify its existence every time postinst is ran, possibly copying it
+    over from our default version in
+    /usr/share/doc/<package>/examples/proftpd.conf.  If we need to change
+    it, ucf is called to let the user merge in any changes he
+    made. (Closes: #143351)
+  * Rephrased the shared/proftpd/replace_file_install debconf question.
+    (Closes: #144715)
+  * Removed mention of obsolete proftpd-sql in package description.
+    (Closes: #144365)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun, 28 Apr 2002 10:22:42 +0200
+
+proftpd (1.2.4+1.2.5rc1-5) unstable; urgency=high
+
+  * Reworked postinst to handle configuration files better; allow the user
+    to review the changes before committing them.  Thanks to Roland Mas
+    for the help. (Closes: #143351)
+  * Stop proftpd from prerm. (Closes: #143376)
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon, 22 Apr 2002 13:50:50 +0200
+
+proftpd (1.2.4+1.2.5rc1-4) unstable; urgency=high
+
+  * Configuring proftpd-ldap, proftpd-*sql with debconf was broken, now
+    uses shared debconf templates.  This fixes a release critical bug
+    nobody reported.
+  * Properly mention that support for mysql or postgresql is included in
+    proftpd-{my,pg}sql package descriptions.
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed, 17 Apr 2002 12:07:20 +0200
+
+proftpd (1.2.4+1.2.5rc1-3) unstable; urgency=medium
+
+  * Use CFLAGS when running configure.
+  * Large file support (partially by Petr Cech, thank you).
+    (Closes: #139325)
+  * Fix typo in postinst. (Closes: #140498)
+  * Correct == to = in init script. (Closes: #140896)
+  * Apply fix for proftpd-ldap by Steve Langasek, which makes mod_unixpw
+    use getpwnam if pwdfname isn't /etc/passwd. (Closes: #141275)
+  * Fix crash of proftpd-*sql when user shell field is NULL.
+    (Closes: #140141)
+  * Updated debconf template for Brazilian Portugese. (Closes: #141690)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 11 Apr 2002 19:25:53 +0200
+
+proftpd (1.2.4+1.2.5rc1-2) unstable; urgency=low
+
+  * Changelog entry for 1.2.4-2 got lost, readded.
+  * Changed build dependency for postgresql-dev to 7.2 or higher.
+  * Added build dependency on bzip2.
+  * Patch, probably from Ignacy Gawedzki, to prevent server crash when
+    using REST+GET on unaccessible source. (Closes: #136696)
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon,  4 Mar 2002 19:37:21 +0100
+
+proftpd (1.2.4+1.2.5rc1-1) unstable; urgency=low
+
+  * New upstream version. (Closes: #125829)
+  * Switch to dbs.
+  * Updated TLS patch. (Closes: #118804)
+  * Fix ftpstats (see bugreport for details). (Closes: #133647)
+  * Updated init.d script, use /etc/defaults.  Thanks to Marc Haber for
+    the patch. (Closes: #120324, #128805)
+  * Fixed a typo in postinst which might have caused problems when
+    upgrading.
+  * Renamed the English debconf template, added French translation.
+    (Closes: #136104)
+  * Redirect stderr to /dev/null in cron.monthly. (Closes: #136309)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun,  3 Mar 2002 18:37:41 +0100
+
+proftpd (1.2.4-2) unstable; urgency=high
+
+  * Fix segfault on ls /////////// (Closes: 125829)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun, 23 Dec 2001 23:00:43 +0100
+
+proftpd (1.2.4-1) unstable; urgency=low
+
+  * New upstream release
+  * Added Russian debconf templates.
+    (Closes: #114953, #114954, #114955, #114957)
+  * Fixed small error in build script that prevented the German debconf
+    templates from being installed.
+  * Updated standards version.
+  * Make proftpd suggest proftpd-doc instead of recommend.
+    (Closes: #113673)
+  * Allow two extra digits for total number of bytes sent in the xferstat
+    script. (Closes: #107387)
+  * Link in mod_wrap. (Closes: #111454)
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon, 22 Oct 2001 01:45:19 +0200
+
+proftpd (1.2.2-1) unstable; urgency=high
+
+  * New upstream release (Closes: #109070):
+     - Doesn't use ifdef's inside a printf call.
+       (Closes: #104402, #104948)
+  * Don't log `No certificates found' message for each connection, only
+    print it on startup. (Closes: #103318)
+  * Change documentation for HideGroup. (Closes: #106548)
+  * Add new directives for proftpd-ldap: LDAPCheckAllow, LDAPCheckDeny,
+    LDAPHomedirOnDemandScript
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat, 18 Aug 2001 17:29:31 +0200
+
+proftpd (1.2.1+1.2.2rc3-3) unstable; urgency=low
+
+  * Depend on adduser. (Closes: #102944)
+  * Updated the Spanish debconf template. (Closes: #102135)
+  * Include genuser.pl and ftpasswd in the proftpd-common package.
+    (Closes: #102489)
+
+ -- Ivo Timmermans <ivo@debian.org>  Tue,  3 Jul 2001 01:01:44 +0200
+
+proftpd (1.2.1+1.2.2rc3-2) unstable; urgency=low
+
+  * Added -r to rm -f /var/run/proftpd in postrm.
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon,  2 Jul 2001 00:48:16 +0200
+
+proftpd (1.2.1+1.2.2rc3-1) unstable; urgency=low
+
+  * New upstream release.
+  * Applied the TLS patch by Peter Runestig.
+  * Included new config.sub and config.guess. (Closes: #99862)
+  * Fixed regexp in proftpd.init. (Closes: #98078)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 28 Jun 2001 11:57:49 +0200
+
+proftpd (1.2.1-9) unstable; urgency=low
+
+  * Changed sections now that postgresql is in non-US. (Closes: #97124)
+  * Kill any references to /usr/doc and /usr/man from debian/rules.
+
+ -- Ivo Timmermans <ivo@debian.org>  Fri, 11 May 2001 11:16:51 +0200
+
+proftpd (1.2.1-8) unstable; urgency=low
+
+  * Fixed the logic that determines how to handle
+    /etc/proftpd.conf. (Closes: #96593)
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed,  9 May 2001 10:57:32 +0200
+
+proftpd (1.2.1-7) unstable; urgency=low
+
+  * Check that /etc/proftpd.conf exists before calculating the md5sum
+    (doh).
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun,  6 May 2001 14:06:32 +0200
+
+proftpd (1.2.1-6) unstable; urgency=low
+
+  * Make proftpd-doc suggest proftpd-common. (Closes: #95724)
+  * Added tests to see if /etc/proftpd.conf exists. (Closes: #95650)
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed,  2 May 2001 15:09:40 +0200
+
+proftpd (1.2.1-5) unstable; urgency=low
+
+  * Include German debconf templates. (Closes: #93770, #93989)
+  * Redirect update-inetd stdout and stdin to /dev/tty.
+    (Closes: #93152)
+  * Include ftpusers(5) manual page, originally from the ftpd package.
+    (Closes: #94348)
+  * Automatically generate a proftpd.conf(5) manual page from the file
+    doc/Configuration.html; add perl-base to build dependencies.
+    (Closes: #65354)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 19 Apr 2001 03:13:02 +0200
+
+proftpd (1.2.1-4) unstable; urgency=low
+
+  * Make proftpd-common and -doc replace proftpd. (Closes: #93230)
+  * Don't edit /etc/init.d/proftpd from postinst, as this is already
+    handled correctly with a grep. (Closes: #93331)
+  * Split proftpd-sql into proftpd-mysql and proftpd-pgsql.  This is ugly,
+    but necessary. (Closes: #72347, #93150)
+  * proftpd-ldap no longer conflicts with itself.
+  * All the configure scripts use the same config.cache file.
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon,  9 Apr 2001 02:34:26 +0200
+
+proftpd (1.2.1-3) unstable; urgency=low
+
+  * `Let's split up' -- Created a separate package for SQL authentication,
+    drop mod_sql from the standard package.
+  * Created a separate package with mod_ldap for LDAP authentication
+    (untested!). (Closes: #60458)
+  * Check md5sum of /etc/proftpd.conf or ask user before asking questions
+    that mean we have to edit the file. (Closes: #90673)
+  * Needs debhelper 3.0 or later.
+  * Include Brazilian, Dutch and Spanish debconf templates.
+    (Closes: #92143, #92318)
+  * Move all debconf related stuff out of postinst into config.  This
+    makes update-inetd work correctly if it needs to ask something.
+    (Closes: #91931, #91987; addresses #90676)
+  * Also edit the ServerType directive in /etc/proftpd.conf when switching
+    to/from inetd mode. (Closes: #91931, #91987)
+  * Use /etc/pam.d/proftpd (fix typo). (Closes: #91745)
+  * Drop manual.uue from the source, delete sharutils from build depends.
+  * Remove the contents from /var/run/proftpd in postrm and postinst.
+    (Closes: #90675, #91262)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat, 24 Mar 2001 23:32:58 +0100
+
+proftpd (1.2.1-2) unstable; urgency=low
+
+  * Added postgresql-dev and sharutils to the build dependencies.
+    (Closes: #90650)
+  * Run proftpd as root from inetd.  proftpd switches to the user/group
+    that is given in the configuration file after startup anyway.
+    (Closes: #90643, #90645)
+  * Set priority to optional.
+  * In cron.monthly, test for ftpstats in the right directory
+    (/usr/sbin). (Closes: #90669)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 22 Mar 2001 18:21:46 +0100
+
+proftpd (1.2.1-1) unstable; urgency=low
+
+  * New upstream release.  (Closes: #49742, #60188, #62589, #64926,
+    Closes: #66784, #66785, #68848, #74153, #74545, #74758, #77701,
+    Closes: #76453, #78922, #80220, #81757, #82921, #83822, #85561,
+    Closes: #86175, #86855)
+  * New maintainer. (Closes: #66783, #67343, #68356, #72841, #75487,
+    Closes: #76258, #85259, #85589, #85710, #85724, #85940, #86011,
+    Closes: #86519, #87194, #90299)
+  * Send savelog output from cron.monthly to /dev/null.
+    (Closes: #72894, #88150)
+  * Applied a patch submitted by me that fixes segfaults due to using
+    a nonexistant postgres connection. (Closes: #76710)
+  * Fixed a small error. (Closes: #77701)
+  * Check for the presence of any SQL* directives in proftpd.conf on
+    upgrade, refer to README.mod_sql. (Closes: #77701)
+  * Added /etc/ftpusers file. (Closes: #79062, #87568)
+  * Changed modules/mod_pam.c to use /etc/pam.d/proftpd by default.
+  * Replace pam_unix_password by pam_unix and remove the shadow option
+    from /etc/pam.d/proftpd. (Closes: #81753)
+  * Ask whether proftpd should start from inetd or standalone.
+    (Closes: #67720)
+  * Test if ftpstats exists on the system before executing it in
+    cron.monthly. (Closes: #86773)
+  * postinst: Call cp in a separate shell to prevent ~ftp caching trouble.
+    (Closes: #44530)
+  * Made changes to contrib/mod_sql*.c to allow both mysql and postgres
+    modules to be linked in.
+  * Fixed small but obvious mistake in mod_sqlpw.c. (Closes: #76723)
+  * Apply fix from ftp://ftp.urbanrage.com/pub/c/mod_quota.c (by Dmitry
+    Alyabyev) for QuotaExempt.
+  * Added a line with PersistentPasswd to basic.conf, to please NIS and
+    LDAP users bugging about proftpd not finding their dynamic
+    users. (Closes: #62197)
+  * Set DenyFilter in basic.conf to prevent a DoS posted to bugtraq
+    (proftpd bug id 1066). (Closes: #89871)
+  * Move Umask to the <Directory> blocks.
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed,  7 Mar 2001 02:52:26 +0100
+
+proftpd (1.2.0pre10-2.1) unstable; urgency=high
+
+  * Non-Maintainer upload.
+  * Applied patch against string format buffer attack.
+  * Removed extra User/Group pair from basic.conf, server now runs as
+    user/group nobody by default.
+  * Added build dependencies on libmysqlclient-dev (instead of
+    mysql-dev), zlib1g-dev, debhelper and libpam-dev.
+  * In contrib/libcap/libcap.h: moved the capability.h include to just
+    below sys/types.h to fix horrible build errors.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat, 24 Feb 2001 02:32:02 +0100
+
+proftpd (1.2.0pre10-2) frozen unstable; urgency=high
+
+  * Use setproctitle(%s,foo) in main.c, lamagra@DIGIBEL.ORG advisory.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed,  5 Jul 2000 18:50:07 -0500
+
+proftpd (1.2.0pre10-1) unstable; urgency=low
+
+  * New upstream version (CVS), closes: #59851, #58043, #58149, #41090.
+  * Included lines in default config which make files overwritable,
+    closes: #58258.
+  * Added patch from Gerhard Poul to create xferreport in cron.daily,
+    closes: #57935.
+  * Added patch from Christian Hammers so the init.d script reliably kills
+    the daemon even in inetd mode, and without using killall, closes:
+    #48487, #45853.
+  * Added directory umask to default config, closes: #42279.
+  * Included more documentation and READMEs.
+  * Disabled mod_pgsql and statically linked to library for mod_mysql,
+    closes: #51120, #50342.
+  * Enabled new module mod_quota.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  7 Mar 2000 14:54:10 -0600
+
+proftpd (1.2.0pre9-7) unstable; urgency=low
+
+  * New upstream version (CVS), fixes TYPE L, closes: #58043.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 16 Feb 2000 16:17:00 -0600
+
+proftpd (1.2.0pre9-6) unstable; urgency=low
+
+  * Uploaded for the correct dist (unstable).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 20 Dec 1999 05:19:47 -0600
+
+proftpd (1.2.0pre9-5) unstable; urgency=low
+
+  * Included ftpstats manpage by Darren Benham (gecko), closes: #51867,
+    #39508.
+  * Changed xferstats to ftpstats in example crontab, closes: #50027.
+  * Slink version updated as of 2.1r4, closes: #33193, #36829, #34564.
+  * No longer asks debconf questions in the postinst, closes: #48353,
+    #46695.
+  * Included compile fixes from slink version, closes: #49170.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 17 Dec 1999 21:01:02 -0600
+
+proftpd (1.2.0pre9-4) stable; urgency=low
+
+  * Included compile fixes from slink version.
+  * Changed xferstats to ftpstats in example crontab, closes: #50027.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  8 Nov 1999 22:12:13 -0600
+
+proftpd (1.2.0pre9-3) stable; urgency=high
+
+  * Really really important security upload for slink.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  8 Nov 1999 19:35:58 -0600
+
+proftpd (1.2.0pre9-2) unstable; urgency=low
+
+  * New upstream version, closes: #49170 (have_sendfile on m68k).
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 30 Oct 1999 20:51:00 -0500
+
+proftpd (1.2.0pre9-1) unstable; urgency=low
+
+  * New upstream version, closes: #43842, #38203, #48274, #46407, #40085, #33206.
+  * Included patch from Madarasz Gergely so it works on 2.0 kernels again
+    (adopted upstream), closes: #47138.
+  * Database client libraries are linked dynamically, closes: #47147.
+  * Split of netbase ends inetd.conf problems, closes: #17514.
+  * Starting in standalone mode removes ftp from inetd.conf, closes: #29734.
+  * Changed PAM service class to 'ftp'.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 30 Oct 1999 20:44:31 -0500
+
+proftpd (1.2.0pre7-3) unstable; urgency=low
+
+  * New upstream version (pre8 beta).
+  * Added detection of slink (ancient non-FHS) system during build.
+  * Changed awkward name xferstats.proftpd to ftpstats.
+  * Debconfified install question.
+  * Updated SQL support.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  4 Oct 1999 13:32:59 -0500
+
+proftpd (1.2.0pre7-2) unstable; urgency=low
+
+  * Turned off debugging feature, closes: #46309.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 30 Sep 1999 09:49:00 -0500
+
+proftpd (1.2.0pre7-1) unstable; urgency=low
+
+  * New upstream version.
+  * Fixed pam configuration error, closes: #45775, #45769
+  * Split mod_sql out of mod_mysql; added mod_pgsql.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 27 Sep 1999 00:51:11 -0500
+
+proftpd (1.2.0pre6-3) unstable; urgency=low
+
+  * Updated mod_mysql module, updated CVS, added docs.
+  * Closing old bugs:
+    * Authentication (PAM) works, closes: #38229, #22894, #10360.
+    * Kills on upgrade, closes: #44531.  
+    * Restarts on upgrade, closes: #38560, #33540, #33205.
+    * But only if ServerType standalone, closes: #32950.
+    * No killall to fail, closes: #38260.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 18 Sep 1999 01:48:47 -0500
+
+proftpd (1.2.0pre6-2) unstable; urgency=high
+
+  * New upstream security update.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 16 Sep 1999 13:14:32 -0500
+
+proftpd (1.2.0pre6-1) unstable; urgency=low
+
+  * New upstream version.
+  * Separate PAM configuration file; PersistentPasswd defaults to off to
+    allow NIS and PAM auth to work.
+  * Reactivated linuxprivs module, fixed upstream.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 13 Sep 1999 02:50:19 -0500
+
+proftpd (1.2.0pre5-1) unstable; urgency=low
+
+  * New upstream version.
+  * ARM support (1.1.7r3-4 NMU, #29805), mod_mysql, and all debian patches
+    are now included upstream.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 10 Sep 1999 03:58:40 -0500
+
+proftpd (1.2.0pre4-3) unstable; urgency=low
+
+  * Updated to Standards-Version 3.0.1.1 (FHS).
+  * Purging proftpd will stop the daemon, closes: #44531.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun,  5 Sep 1999 09:50:48 -0500
+
+proftpd (1.2.0pre4-2) unstable; urgency=high
+
+  * More security fixes.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun,  5 Sep 1999 09:38:01 -0500
+
+proftpd (1.2.0pre4-1) unstable; urgency=high
+
+  * New upstream version, fixing remote root exploit.
+  * Prepared with the PAM of glibc 2.1, closes: #36742, #38562.
+  * Note: the README.Solaris2.5x is included as humor, illustrating how
+    bad non-free OSes can be, closes: #36540.
+  * Fixed segfault possibility in mysql module.
+  * Updated to Standards-Version 3.0.1.0.
+  * Conflicts with and provides ftp-server, closes: #42407.
+  * Added dependency on libpam-modules.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 30 Aug 1999 11:52:18 -0500
+
+proftpd (1.2.0pre2-7) unstable; urgency=low
+
+  * Added useful undocumented features to mod_ratio and mod_mysql.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  3 May 1999 12:23:18 -0400
+
+proftpd (1.2.0pre2-6) unstable; urgency=low
+
+  * Activated PAM support, closes: #24115, #24524.
+  * Also closes: #35292, fixed in 1.20pre2-4.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 23 Apr 1999 11:04:57 -0400
+
+proftpd (1.2.0pre2-5) unstable; urgency=low
+
+  * Changed default (undocumented) TimeoutStalled from 0 to 300.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 10 Apr 1999 17:53:29 -0400
+
+proftpd (1.2.0pre2-4) unstable; urgency=low
+
+  * Conflicts with wu-ftpd-academ, closes: #35036.
+  * The postrm no longer dies if proftpd is not currently running, closes:
+    #35292.
+  * Updated mod_ratio to 2.0beta, added experimental and utterly
+    undocumented mod_mysql 0.1.
+  * Updated to Standards-Version 2.5.0.0.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  8 Apr 1999 12:01:42 -0400
+
+proftpd (1.2.0pre2-3) unstable; urgency=low (high for glibc 2.1)
+
+  * New upstream version (1.2.0pre2)
+      * Fixes root priv problem with glibc 2.1 (mod_linuxprivs disabled),
+        closes: #34604.
+      * Fixes ls -lR again, closes: #34521, #33671, #33494
+      * Returns 550 instead of 553 when retrieving dir, closes: #29498.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 19 Mar 1999 10:29:43 -0500
+
+proftpd (1.2.0pre2-2) frozen unstable; urgency=medium
+
+  * Uploaded for frozen.  Fixes ls -alR looping bug discovered by Jim
+    Pick, closes: #33494.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  4 Mar 1999 08:11:14 -0500
+
+proftpd (1.2.0pre2-1) unstable; urgency=medium
+
+  * New upstream version, closes: #33494 (ls -alR looping bug discovered
+    by Jim Pick).
+  * Debugging turned off by default, closes: #33396.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 17 Feb 1999 12:46:15 -0500
+
+proftpd (1.2.0pre1-2) stable frozen unstable; urgency=high
+
+  * Uploaded for stable by request of Wichert Akkerman.  This fixes the
+    Palmetto bug discovered by netect.com.  Upgrade.  Now.
+  * Bug also fixed in slink and potato on Feb 4, closes: #32686, #33173.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 10 Feb 1999 09:26:18 -0500
+
+proftpd (1.2.0pre1-1) frozen unstable; urgency=medium
+
+  * Include path exploit fix (closes: #32686, important).
+  * Rehashing (-HUP) now properly discards old LogFormat logs, and
+    recreates from the conf file, closes: #28641.
+  * Fixed division by 0 in xferstats.proftp, closes: #26946.
+  * No longer complains to stderr when capababilities (a 2.2.x feature)
+    aren't supported by the kernel, closes: #27861.
+  * Includes ARM support (1.1.7r3-4 NMU), closes: #29805.
+  * Module mod_ls fixed so ncftp -R works, closes: #29520.
+  * Removing package kills proftpd, closes: #30157, #32331, #32607.
+  * No longer slow (846.68 kB/s over ethernet), closes: #29396.
+  * Tweaked regex in /etc/init.d/proftpd.
+  * Daemon is not pointlessly stopped during upgrade: #28900.
+  * Updated documentation from upstream website.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  4 Feb 1999 13:37:17 -0500
+
+proftpd (1.1.7r3-4) unstable; urgency=low
+
+  * Only queries about installing anonymous ftp once (#27873 and #25432).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 12 Oct 1998 18:24:59 -0400
+
+proftpd (1.1.7r3-3) unstable; urgency=low
+
+  * Merged fix from Alpha release by Paul Slootman (#27823).
+  * Bugs fixed prior to this release, or non-bugs: #20130, #24675, #25158,
+    #25162.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 12 Oct 1998 17:16:53 -0400
+
+proftpd (1.1.7r3-2) unstable; urgency=low
+
+  * New upstream version (CVS).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 12 Oct 1998 12:53:14 -0400
+
+proftpd (1.1.7r3-1.1) unstable; urgency=low
+
+  * non-maintainer (binary-only) upload for Alpha
+  * invoke "make install" with some modified parameters, else it tries to
+    create directories outside the source directory.
+
+ -- Paul Slootman <paul@debian.org>  Mon, 12 Oct 1998 21:07:12 +0200
+
+proftpd (1.1.7r3-1) unstable; urgency=low
+
+  * New upstream version (pristine).
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 10 Oct 1998 13:11:38 -0400
+
+proftpd (1.1.7r2-2) unstable; urgency=low
+
+  * New upstream version (CVS).
+  * Module linuxprivs is now compiled in for better security, on
+    architectures with kernel source newer than 2.1.103.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed,  7 Oct 1998 10:55:38 -0400
+
+proftpd (1.1.7r2-1) unstable; urgency=low, closes=26839
+
+  * New upstream version (pristine).
+  * Removal will not run init.d script if script doesn't exist (#26839).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  6 Oct 1998 14:17:08 -0400
+
+proftpd (1.1.7r1-1) unstable; urgency=low
+
+  * New upstream version 1.1.7pl1 (CVS).
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 23 Sep 1998 11:29:21 -0400
+
+proftpd (1.1.7pre1-1) unstable; urgency=low, closes=25168 16502 20868 26638 23485 25272
+
+  * New upstream version (CVS) includes ability to diable wtmp logging
+    (#16502) and a correct implementation of %L (#20868).
+  * Fixed xferstats conflict with hylafax-server (#26638).
+  * Removing proftpd now stops the running daemon (#25272).
+  * Bugs fixed prior to this release, by other packages, or non-bugs:
+    #25168, #23485.
+  * Updated to Standards-Version 2.4.1.4.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 12 Sep 1998 17:16:53 -0400
+
+proftpd (1.1.6r2-3) unstable; urgency=low
+
+  * Ratio support is accepted by upstream author as a "contrib" module,
+    and now fully documented.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Sep 1998 22:30:45 -0400
+
+proftpd (1.1.6r2-2) unstable; urgency=low, closes=26089 25133
+
+  * New upstream version (CVS), fixing symlink Bug (#26089) and general
+    slowness when used with 2.1.x kernels (#25133).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Sep 1998 14:54:59 -0400
+
+proftpd (1.1.6r2-1) unstable; urgency=low, closes=26167 26305 23156 17488
+
+  * New upstream version (CVS).
+  * Modified for new debhelper behavior (#26167, #26305).
+  * Closes #17488, as ls -lat is now supported.
+  * Added xferstats manpage and program wu-ftpd-academ, as modified by
+    Holger Preiss (TU Dresden) (#23156).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Sep 1998 12:29:25 -0400
+
+proftpd (1.1.6r-1.1) unstable; urgency=low
+
+  * non-maintainer upload for Alpha
+  * don't use wildcards in debian/examples, as that fails with debhelper_1.1.9
+
+ -- Paul Slootman &lt;paul@debian.org&gt;  Wed, 26 Aug 1998 22:37:29 +0200
+
+proftpd (1.1.6r-1) unstable; urgency=low
+
+  * New upstream version (CVS).
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 20 Aug 1998 10:51:04 -0400
+
+proftpd (1.1.6pre4-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  4 Aug 1998 12:25:14 -0400
+
+proftpd (1.1.6pre2-1) unstable; urgency=low
+
+  * New upstream version (fixes ident timeouts).
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 31 Jul 1998 11:51:32 -0400
+
+proftpd (1.1.6pre1-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 30 Jul 1998 14:29:27 -0400
+
+proftpd (1.1.5r-3) unstable; urgency=low
+
+  * New upstream version (1.1.5pl3).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 20 Jul 1998 23:04:08 -0400
+
+proftpd (1.1.5r-2) unstable; urgency=low
+
+  * Tweaked syslog logging: CWD command, initial connect, etc.
+  * Added HostRatio directive.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 14 Jul 1998 12:09:35 -0400
+
+proftpd (1.1.5r-1) unstable; urgency=low
+
+  * New upstream version.
+  * Removed extraneous debugging output from mod_ratio.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 14 Jul 1998 11:00:58 -0400
+
+proftpd (1.1.5pre3-2) unstable; urgency=low
+
+  * Added custom-written ratio module.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 14 Jul 1998 01:23:00 -0400
+
+proftpd (1.1.5pre3-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun, 12 Jul 1998 22:11:05 -0400
+
+proftpd (1.1.5pre1-1) unstable; urgency=low, closes=23568 17765 18589
+
+  * New upstream version.
+  * Source code uses correct FSF address (#23568).
+  * Recursive directory listings (ls -lR) now supported (#17765).
+  * No longer possible to crash/spin server with huge dirs (#18589).
+  * Probably fixes 10360, 16502, 18855, 20130, 22894, 23485, and 23875,
+    but more testing is needed.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun,  5 Jul 1998 18:24:45 -0400
+
+proftpd (1.0.3-1) unstable; urgency=low, closes=22207 22437 14447 21808
+
+  * New upstream version.
+  * ProFTPD now uses port 20 for outgoing data instead of "wierd ports"
+    (#14447).
+  * Pre-install script will not fail if init.d script is missing (#22207).
+  * Closes Bug #22437 against ncftp, incorrect handling of multiline
+    responses, actually due to proftpd's incorrect multiline response.
+  * Includes example configurations (#21808).
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 22 May 1998 17:17:20 -0400
+
+proftpd (1.0.2-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 21 May 1998 15:21:06 -0400
+
+proftpd (1.0.1-1) unstable; urgency=low
+
+  * New (somewhat unreleased) upstrem version, fixing potential segfault
+    problem.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 19 May 1998 13:48:26 -0400
+
+proftpd (1.0.0unoff1-2) unstable; urgency=low
+
+  * Real-time ratio levels are now logged for each user, at the higher
+    debugging levels (>= 3).
+  * Ratios are calculated at session start in addition to during chdir
+    commands.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun, 19 Apr 1998 20:06:01 -0400
+
+proftpd (1.0.0unoff1-1) unstable; urgency=low
+
+  * Now includes current directories in status output.
+  * The ftpwho command now shows the entire command being executed.
+  * Remoted commands logged separate from malloc debugging: most at level
+    3, STOR, RETR and CWD at level 2.
+  * Now logs the rough bandwidth of each transfer to syslog.
+  * Disabled NEED_PERSISTENT_PASSWORD so NIS works (#18144, #14916).
+  * Converted from debmake to debhelper packaging technology.
+  * Undocumented support for upload/download ratios added.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 18 Apr 1998 23:24:15 -0400
+
+proftpd (1.0.0-8) unstable; urgency=low
+
+  * Priority is now extra.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 18 Mar 1998 17:01:21 -0500
+
+proftpd (1.0.0-7) unstable; urgency=low
+
+  * Corrected spelling of proftpd in init.d message output.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 14 Mar 1998 19:47:23 -0500
+
+proftpd (1.0.0-6) unstable; urgency=low
+
+  * Included force-reload target in help text returned by init.d script,
+    and switched to the unofficial official downcase style.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri,  6 Feb 1998 23:43:19 -0500
+
+proftpd (1.0.0-5) unstable; urgency=low
+
+  * Corrected year and URL info in copyright file.
+  * Added reload and force-reload targets to init.d script.
+  * Updated to Standards-Version 2.4.0.0.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Feb 1998 15:05:51 -0500
+
+proftpd (1.0.0-4) unstable; urgency=low, closes=17489
+
+  * Applied proftpd-1.0.0-chmod.patch, fixing behavior of the SITE CHMOD
+    command when octal numbers do not begin with 0.
+  * Default config now shows symlinks as symlinks (#17489).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Feb 1998 13:14:10 -0500
+
+proftpd (1.0.0-3) unstable; urgency=low
+
+  * Built with new version of debmake to correct md5sum error.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 21 Jan 1998 13:33:39 -0500
+
+proftpd (1.0.0-2) unstable; urgency=low, closes=14234
+
+  * Setting up anonymous FTP now sets up an example welcome.msg (#14234).
+  
+ -- Johnie Ingram <johnie@debian.org>  Thu,  1 Jan 1998 14:02:50 -0500
+
+proftpd (1.0.0-1) unstable; urgency=low, closes=12753
+
+  * New upstream version, fixes MDTM and NOOP commands.
+  * Closed #12753, as install now asks to set up anonymous FTP.
+  * Init script modified for better compliance with policy 2.3.0.1 section
+    3.6.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 31 Dec 1997 23:43:20 -0500
+
+proftpd (0.99.0pl11-2) unstable; urgency=low
+
+  * Fixed bug in preinst discovered on powerpc architecture -- the preinst
+    script could fail with some versions of bash.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  9 Dec 1997 20:11:07 -0500
+
+proftpd (0.99.0pl11-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 11 Nov 1997 13:53:58 -0500
+
+proftpd (0.99.0pl10-1) unstable; urgency=low, closes=14725
+
+  * New upstream version, supporting md5 passwords (#14725).
+  * Fixed bug where proftpd would not start automatically after upgrade if
+    anonymous FTP was enabled.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 11 Nov 1997 12:36:52 -0500
+
+proftpd (0.99.0pl9-2) unstable; urgency=low
+
+  * Fixed errors in default proftpd.conf pointed out by Scott K. Ellis.
+  * Configuration script no longer asks if anonymous FTP should be
+    enabled, if anonymous FTP is enabled.
+  * Closed #10360, as proftpd now works correctly on both shadow and
+    non-shadow systems.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 29 Oct 1997 14:54:31 -0500
+
+proftpd (0.99.0pl9-1) unstable; urgency=low
+
+  * New upstream version.
+  * Features support for the SIZE command (#13963).
+  
+ -- Johnie Ingram <johnie@debian.org>  Wed, 29 Oct 1997 14:05:12 -0500
+
+proftpd (0.99.0pl8-1) unstable; urgency=low
+
+  * New upstream version.
+  * Includes support for the MDTM command used by the ftp method of dpkg
+    (#13959).
+  * Added code from Christoph Lameter to set up anonymous ftp (#13334).
+  * Removed patch to fix non-shadow support, as this feature has been
+    added to the configuration script.
+  * Added SHELL=/bin/bash to debian rules.
+  * Updated to Standards-Version 2.3.0.0 and debmake 3.4.2..
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 20 Oct 1997 16:11:05 -0400
+
+proftpd (0.99.0pl7-1) unstable; urgency=medium
+
+  * New upstream version.
+  * Fixes wtmp corruption program (#12013, #12483).
+  * Added patch to fix non-shadow support.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 24 Sep 1997 14:10:51 -0400
+
+proftpd (0.99.0pl6-5) unstable; urgency=low
+
+  * Tweaked packaging for better multi-architecture support.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun, 31 Aug 1997 00:38:31 -0400
+
+proftpd (0.99.0pl6-4) unstable; urgency=low
+
+  * Updated to Standards-Version 2.2.0.0 and debmake 3.3.11.
+  * Removed "Evil" code to auto-fetch HTML manual during package build
+    reported by James Troup (#11598).
+  * Switched to pristine upstream tar archive.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat,  9 Aug 1997 14:59:24 -0400
+
+proftpd (0.99.0pl6-3) unstable; urgency=low
+
+  * Linked against libc6 again on Intel architecture.
+  * Fixed errors in default proftpd.conf pointed out by Rob Browning.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 28 Jul 1997 04:26:05 -0400
+
+proftpd (0.99.0pl6-2) unstable; urgency=low
+
+  * Updated HTML manual, modifed build script to mirror automatically.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 10 Jul 1997 11:14:33 -0400
+
+proftpd (0.99.0pl6-1) unstable; urgency=low
+
+  * New upstream version.
+  * Added complete HTML manual and FAQ to package.
+  * Updated to Standards-Version 2.1.3.3 and debmake 3.3.4.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Jul 1997 23:46:06 -0400
+
+proftpd (0.99.0pl5-1) unstable; urgency=low
+
+  * New upstream version.
+  * No longer unnecessarily edits /etc/inetd.conf during upgrades,
+    and /etc/init.d/proftpd script now automatically detects when proftpd
+    is being run out of inetd instead (Bug #10462).
+  * Closed Bug #10373.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 11 Jun 1997 02:46:55 -0400
+
+proftpd (0.99.0pl4-3) unstable; urgency=low
+
+  * Built with libc5 (on i386 systems) in another attempt to fix Bug
+    #10373 (corruption of utmp and wtmp).
+  * Some tweaks to debian "clean" target.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat,  7 Jun 1997 11:47:45 -0400
+
+proftpd (0.99.0pl4-2) unstable; urgency=low
+
+  * Added TODO file and upstream changelog to package.
+  * Temporarily disabled wtmp logging since this corrupts the log on
+    libc5/libc6 systems (Bug #10373).
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  5 Jun 1997 20:14:17 -0400
+
+proftpd (0.99.0pl4-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  5 Jun 1997 13:28:13 -0400
+
+proftpd (0.99.0pl3-2) unstable; urgency=low
+
+  * Added patch from author to fix premature termination of the control
+    connection during MPUT commands.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Jun 1997 15:59:42 -0400
+
+proftpd (0.99.0pl3-1) unstable; urgency=low
+
+  * Initial Release.
+  * Contains two additional patches from the author to fix compilation on
+    libc6, and to log the full pathname in the xferlog.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Jun 1997 09:41:41 -0400
+
+
--- proftpd-1.2.9.orig/debian/conffiles.notused
+++ proftpd-1.2.9/debian/conffiles.notused
@@ -0,0 +1,5 @@
+/etc/pam.d/proftpd
+/etc/proftpd.conf
+/etc/init.d/proftpd
+/etc/cron.monthly/proftpd
+/etc/ftpusers
--- proftpd-1.2.9.orig/debian/control
+++ proftpd-1.2.9/debian/control
@@ -0,0 +1,131 @@
+Source: proftpd
+Section: net
+Priority: optional
+Maintainer: Francesco Paolo Lovergine <frankie@debian.org>
+Uploaders: Paul Martin <pm@debian.org>
+Standards-Version: 3.6.1
+Build-Depends: libmysqlclient10-dev, libpam-dev, debhelper (>=4.1.16), zlib1g-dev, postgresql-dev (>= 7.2), libldap2-dev, perl-base, libssl-dev, libwrap0-dev, patch, bzip2, sharutils, libcap-dev, libwrap0-dev, autoconf, libncurses5-dev
+
+Package: proftpd
+Architecture: any
+Depends: netbase, ${shlibs:Depends}, debconf (>= 0.5.00), proftpd-common (= ${Source-Version}), adduser, ucf (>= 0.30)
+Conflicts: wu-ftpd, wu-ftpd-academ, ftp-server, proftpd-mysql, proftpd-pgsql, proftpd-ldap
+Provides: ftp-server
+Suggests: proftpd-doc
+Description: Versatile, virtual-hosting FTP daemon
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package contains only the basic functionality of proftpd and PAM
+ authentication.  If you need SQL, use proftpd-mysql or proftpd-pgsql
+ and if you need LDAP, use proftpd-ldap.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-common
+Architecture: any
+Depends: netbase, ${perl:Depends}, ${shlibs:Depends}, debconf (>= 0.5.00), proftpd|proftpd-mysql|proftpd-pgsql|proftpd-ldap, debianutils
+Suggests: proftpd-doc
+Replaces: proftpd (<< 1.2.8-1), proftpd-mysql (<< 1.2.8-1), proftpd-pgsql (<< 1.2.8-1), proftpd-ldap (<< 1.2.8-1)
+Description: Versatile, virtual-hosting FTP daemon
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package provides the common administrative programs.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-doc
+Architecture: all
+Suggests: proftpd-common
+Replaces: proftpd (<= 1.2.1-2)
+Section: doc
+Description: Versatile, virtual-hosting FTP daemon (Documentation)
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-mysql
+Architecture: any
+Depends: netbase, ${shlibs:Depends}, debconf (>= 0.5.00), proftpd-common (= ${Source-Version}), adduser, ucf (>= 0.30)
+Conflicts: wu-ftpd, wu-ftpd-academ, ftp-server, proftpd, proftpd-pgsql, proftpd-ldap
+Provides: ftp-server
+Description: Versatile, virtual-hosting FTP daemon (with SQL support)
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package contains the proftpd daemon compiled with support for
+ MySQL user authentication.  It also supports PAM authentication.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-pgsql
+Architecture: any
+Depends: netbase, ${shlibs:Depends}, debconf (>= 0.5.00), proftpd-common (= ${Source-Version}), adduser, ucf (>= 0.30)
+Conflicts: wu-ftpd, wu-ftpd-academ, ftp-server, proftpd, proftpd-mysql, proftpd-ldap
+Provides: ftp-server
+Description: Versatile, virtual-hosting FTP daemon (with SQL support)
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package contains the proftpd daemon compiled with support for
+ PostgreSQL user authentication.  It also supports PAM authentication.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-ldap
+Architecture: any
+Depends: netbase, ${shlibs:Depends}, debconf (>= 0.5.00), proftpd-common (= ${Source-Version}), adduser, ucf (>= 0.30)
+Conflicts: wu-ftpd, wu-ftpd-academ, ftp-server, proftpd, proftpd-mysql, proftpd-pgsql
+Provides: ftp-server
+Description: Versatile, virtual-hosting FTP daemon (with LDAP support)
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package contains the proftpd daemon compiled with support for
+ LDAP user authentication.  It also supports PAM authentication.
+ .
+ More information can be found at http://www.proftpd.org/.
--- proftpd-1.2.9.orig/debian/copyright
+++ proftpd-1.2.9/debian/copyright
@@ -0,0 +1,104 @@
+This package was debianized by Johnie Ingram (johnie@debian.org)
+Mon,  2 Jun 1997 12:43:52 -0400, two minutes after its first public release.
+
+The canonical location is:
+	ftp://ftp.proftpd.net/pub/proftpd
+
+Copyright:
+
+The core code is made available under the terms of the GPL:
+
+ * ProFTPD - FTP server daemon
+ * Copyright (c) 1997, 1998 Public Flood Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ *
+ * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu
+ * and other respective copyright holders give permission to link this program
+ * with OpenSSL, and distribute the resulting executable, without including
+ * the source code for OpenSSL in the source distribution.
+
+On Debian GNU/Linux systems, the text of the GPL can be found in
+/usr/share/common-licenses/GPL.
+
+
+This package includes xferlog.5 and the xferstats program from
+wu-ftpd-academ, as modified by Holger Preiss (TU Dresden):
+
+    Copyright (c) 1994  Washington University in Saint Louis.
+    All rights reserved.
+
+    This product includes software developed by Washington University
+    in Saint Louis and its contributors.
+
+    Copyright (c) 1980, 1985, 1988, 1989, 1990  The Regents of the
+    University of California.  All rights reserved.
+
+    This product includes software developed by the University of
+    California, Berkeley and its contributors.
+
+    THIS SOFTWARE IS PROVIDED BY WASHINGTON UNIVERSITY AND CONTRIBUTORS
+    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASHINGTON
+    UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+
+Modifications for Debian are copyright (C) 1997-2000 Johnie Ingram,
+and also released under the terms of the GPL -- version 2, or any
+later version.
+
+On Debian GNU/Linux systems, the text of the GPL can be found in
+/usr/share/common-licenses/GPL.
+
+
+mod_tls.c is distributed under the following terms (BSD license):
+
+ * AUTH/TLS module for ProFTPD, based on the mod_sample.c file.
+ *
+ * Copyright (c) 2000 - 2002 Peter 'Luna' Runestig <peter@runestig.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifi-
+ * cation, are permitted provided that the following conditions are met:
+ *
+ *    o Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *
+ *    o Redistributions in binary form must reproduce the above copyright no-
+ *      tice, this list of conditions and the following disclaimer in the do-
+ *      cumentation and/or other materials provided with the distribution.
+ *
+ *    o The names of the contributors may not be used to endorse or promote
+ *      products derived from this software without specific prior written
+ *      permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI-
+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--- proftpd-1.2.9.orig/debian/default
+++ proftpd-1.2.9/debian/default
@@ -0,0 +1,9 @@
+# Defaults for proftpd initscript
+
+# Master system-wide proftpd switch. The initscript
+# will not run if it is not set to yes.
+RUN="yes"
+
+# Default options.
+# For more exhaustive logging, try "-d 3".
+OPTIONS=""
--- proftpd-1.2.9.orig/debian/dirs
+++ proftpd-1.2.9/debian/dirs
@@ -0,0 +1,6 @@
+etc/init.d
+etc/cron.monthly
+etc/default
+usr/bin
+usr/sbin
+var/run
--- proftpd-1.2.9.orig/debian/examples
+++ proftpd-1.2.9/debian/examples
@@ -0,0 +1,4 @@
+sample-configurations/anonymous.conf
+sample-configurations/basic.conf
+sample-configurations/virtual.conf
+debian/welcome.msg
--- proftpd-1.2.9.orig/debian/ftpasswd.8
+++ proftpd-1.2.9/debian/ftpasswd.8
@@ -0,0 +1,173 @@
+.\" Copyright (C) 2002 Francesco P. Lovergine
+.\"
+.\" This manual page is free software.  It is distributed under the
+.\" terms of the GNU General Public License as published by the Free
+.\" Software Foundation; either version 2 of the License, or (at your
+.\" option) any later version.
+.\"
+.\" This manual page 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 manual page; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+.\" USA
+.\"
+.TH FTPASSWD 8 "October 19, 2002" "1.1.2" "Debian GNU/Linux"
+.SH NAME
+ftpasswd \- manipulates ProFTPD authentication files
+.SH SYNOPSIS
+.TP 8
+\fBftpasswd\fR \fB--help\fR|\fB-h\fR|\fB--version\fR  
+.TP 8
+\fBftpasswd\fR \fB--hash\fR  [ \fB--des\fR|\fB--md5\fR ] [ \fB--stdin\fR ] [ \fB--use-cracklib\fR[=path] ]
+.TP 8
+\fBftpasswd\fR \fB--passwd\fR [ \fB-F\fR|\fB--force\fR ] [ \fB--file=\fRfilename ] [\fB--gecos=\fRstring ] 
+.br 
+[ \fB--gid=\fRgid ] [ \fB--des\fR | \fB--md5\fR ] [ \fB--not-system-password\fR ] 
+.br
+[ \fB--stdin\fR ] [ \fB--use-cracklib\fR[=path] ] \fB--home=\fRpath 
+.br \fB--name=\fRusername \fB--shell=\fRshellpath \fB--uid=\fRuid
+.TP 8
+\fBftpasswd\fR \fB--group\fR [ \fB-F\fR|\fB--force\fR ] [ \fB--enable-group-passwd\fR ] 
+.br
+[ \fB--file=\fRfilename ] [ \fB-m\fR|\fB--member\fR ] [ \fB--des\fR|\fB--md5\fR ]
+.br
+[ \fB--stdin\fR ] [ \fB--use-cracklib\fR[=path] ] \fB--gid=\fRgid 
+.br \fB--name=\fRgroupname 
+.TP 8
+\fBftpasswd\fR \fB--passwd\fR \fB--change-password\fR \fB--name\fR=username
+.br
+.PP
+.SH DESCRIPTION
+.P
+ftpasswd is a Perl script which can be used to manipulate
+the password and group files suitable for use with 
+ProFTPD AuthUserFile and AuthGroupFile configuration directives.
+The idea is somewhat similar to Apache's htpasswd program.
+.P
+Required options are --passwd, --group, or --hash.  
+These specify whether ftpasswd is to
+operate on a passwd(5) format file, on a group(5) format file, or simply
+to generate a password hash, respectively.
+.P
+If used with --passwd, ftpasswd creates a file in the passwd(5) format,
+suitable for use with proftpd's AuthUserFile configuration directive.
+You will be prompted for the password to use of the user, which will be
+encrypted, and written out as the encrypted string.
+By default, using --passwd will write output to "./ftpd.passwd",
+.P
+If used with --hash, ftpasswd generates a hash of a password, as would
+appear in an AuthUserFile.  The hash is written to standard out.
+This hash is suitable for use with proftpd's UserPassword directive.
+.P
+If used with --group, ftpasswd creates a file in the group(5) format,
+suitable for use with proftpd's AuthGroupFile configuration directive.
+By default, using --group will write output to "./ftpd.group".
+
+.SH OPTIONS
+.P
+.TP
+.B \-F, \-\-force
+If the password or group file be used already exists, delete it and write a new one.
+.TP
+.BR \-\-file= filename
+Write output to specified file (password or group files), 
+rather than default one. 
+.TP
+.BR \-\-gecos= string
+Descriptive string for the given user (usually the user's full name).
+.TP
+.BR \-\-gid= gid
+Set primary group ID for this user (optional, will default to
+given 
+.BR --uid 
+value if absent) when 
+.BR
+--passwd 
+is specified.
+.TP
+.BR \-\-uid= uid
+numerical group ID.
+.TP
+.B \-h,\ \-\-help,\ \-\-version
+Show usage and version of the program.
+.TP
+.BR \-\-home= path
+Set the home directory for the user (required).
+.TP
+.B \-\-des,\ \-\-md5
+Use the DES or MD5 algorithm for encrypting passwords. 
+The latter is the default.
+.TP
+.BR \-\-name= username ,\ \-\-name= groupname
+Name of the user account or group (required).  
+If the name does not exist in the specified output-file, an entry will be created
+for it. Otherwise, the given fields will be updated.
+.TP
+.BR \-\-shell= path
+Shell for the user (required).  Recommended: 
+.I /bin/false
+.TP
+.BR \-\-change-password 
+Update only the password field for a user.  This option
+requires that the 
+.BR --name 
+option be used, but no others.
+This also double-checks the given password against the
+user's current password in the existing passwd file, and
+requests that a new password be given if the entered password
+is the same as the current password.
+.TP
+.BR --not-system-password
+Double-checks the given password against the system password
+for the user, and requests that a new password be given if
+the entered password is the same as the system password.  This
+helps to enforce different passwords for different types of
+access.
+.TP
+.BR --stdin
+Read the password directly from standard in rather than
+prompting for it.  This is useful for writing scripts that
+automate use of ftpasswd.
+.TP
+.BR --use-cracklib\fR[ =path \fR]
+Causes ftpasswd to use Alec Muffet's cracklib routines in
+order to determine and prevent the use of bad or weak
+passwords.  The optional path to this option specifies
+the path to the dictionary files to use -- default path
+is 
+.IR /usr/lib/cracklib_dict .
+This requires the Perl Crypt::Cracklib module to be installed on your system.
+.TP
+.BR --enable-group-passwd
+Prompt for a group password.  This is disabled by default,
+as group passwords are not usually a good idea at all.
+.TP
+.BR \-m \ username ,\ \-\-member= username
+user to be a member of the group.  This argument may be used
+This argument may be used multiple times to specify the full list 
+of users to be members of this group.
+
+.SH BUGS
+No known bugs at this time.
+If you discover any bugs, please contact the author.
+
+.SH AUTHOR
+This program has been written by TJ Saunders <tj@castaglia.org>
+as a contributed software for ProFTPD.
+.P
+.SH "SEE ALSO"
+.BR proftpd (8), 
+.BR passwd (5), 
+.BR group (5),
+.BR ftpusers (8), 
+.BR ftpstats (8),
+.BR proftpd.conf (5)
+
+.SH CREDITS
+This manual page was written by
+Francesco Paolo Lovergine <frankie@debian.org> 
+for the Debian GNU/Linux system (but may be used by others).
--- proftpd-1.2.9.orig/debian/ftpstats.8
+++ proftpd-1.2.9/debian/ftpstats.8
@@ -0,0 +1,101 @@
+.\" Copyright (C) 1999 Darren Benham
+.\"
+.\" This manual page is free software.  It is distributed under the
+.\" terms of the GNU General Public License as published by the Free
+.\" Software Foundation; either version 2 of the License, or (at your
+.\" option) any later version.
+.\"
+.\" This manual page 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 manual page; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+.\" USA
+.\"
+.TH FTPSTATS 8 "October 30, 2002" "Debian GNU/Linux"
+
+.SH NAME
+ftpstats \- FTP Log summarizer
+.SH SYNOPSIS
+.B ftpstats
+.RI [ options ] 
+.SH DESCRIPTION
+.PP
+Ftpstats dissects the defined ftp log and reports various 
+statistics as requested.
+This manual page was written for the Debian GNU/Linux distribution
+because the original program does not have a manual page.
+.P
+.SH OPTIONS
+.P
+.TP
+.BR \-f " filename"
+Use
+.IR filename
+rather than the default
+.IR /var/log/xferlog
+.
+.TP
+.BR \-r
+Include real users.
+.TP
+.BR \-a
+Include anonymous users.
+.TP
+.BR \-h
+Include report on hourly traffic.
+.TP
+.BR \-d
+Include report on domain traffic.
+.TP
+.BR \-t
+Report on total traffic by section.
+.TP
+.BR \-i
+Report on incoming traffic only (uploads).
+.TP
+.BR \-o
+Report on outgoing traffic only (downloads).
+.TP
+.BR \-D "domain"
+Report only on traffic from
+.IR domain
+.  This option leads to problems with the local domain:  e.g. test.com is
+encountered under test and not recognized under com, -D com will give you only
+stats about com excluding test.com!  Use -A com for correct results.
+
+.TP
+.BR \-A "address"
+Report only on traffic from addresses whose end matches
+.IR address
+.  e.g. -A test.domain.com will report on address ending with test.domain.com
+
+.TP
+.BR \-l "depth"
+Depth of path detail for sections
+
+.TP
+.BR \-s "section"
+Section to report on.  e.g. -s /pub will report only on paths under /pub
+.SH BUGS
+No known bugs at this time.
+If you discover any bugs, please report at http://bugs.proftpd.org/
+For help/support, try the ProFTPD mailing lists, detailed on
+http://www.proftpd.org/lists.html
+.br
+.SH SEE ALSO
+.BR proftpd (8), proftpd.conf (5), xferlog (5)
+.SH AUTHORS
+ProFTPD is written and maintained by a number of people, full credits
+can be found on http://www.proftpd.org/credits.html
+.br
+.SH CREDITS
+This manual page was written by
+Francesco P. Lovergine <frankie@debian.org> and other Debian developers,
+for the Debian GNU/Linux system (but may be used by others).
+.br
+Please use the most appropriate mailing list listed on
+http://www.proftpd.org/lists.html for ftpstats related comments.
--- proftpd-1.2.9.orig/debian/ftpusers
+++ proftpd-1.2.9/debian/ftpusers
@@ -0,0 +1,14 @@
+# /etc/ftpusers: list of users disallowed FTP access. See ftpusers(5).
+
+root
+daemon
+bin
+sys
+sync
+games
+man
+lp
+mail
+news
+uucp
+nobody
--- proftpd-1.2.9.orig/debian/ftpusers.5
+++ proftpd-1.2.9/debian/ftpusers.5
@@ -0,0 +1,42 @@
+.\" Copyright (c) 1994 Peter Tobias (tobias@server.et-inf.fho-emden.de),
+.\"               2001 Ivo Timmermans <ivo@debian.org>
+.\" This file may be distributed under the GNU General Public License.
+.\"
+.Dd April 19, 2001
+.Dt FTPUSERS 5
+.Os "Debian proftpd"
+.Sh NAME
+.Nm ftpusers
+.Nd file which lists users who are not allowed to use ftp
+.Sh DESCRIPTION
+.Pa /etc/ftpusers
+is used by
+.Xr proftpd 8 ;
+the file contains a list of users who are not allowed to use the
+ftp command. For security reasons at least users like ``root'', ``bin'',
+``uucp'' and ``news'' should be listed in this file. 
+Blank lines and lines beginning with `#' are ignored.
+.Pp
+Note: a lines with `#' in the
+.Em middle
+is 
+.Em not
+a comment. Don't put `#' after a name to comment it; use another line,
+or things will silently fail on you.
+.Sh EXAMPLES
+.Pa /etc/ftpusers
+might contain the following entries:
+.Bd -literal
+#
+# /etc/ftpusers
+#
+root
+bin
+uucp
+news
+.Ed
+.Sh FILES
+.Pa /etc/ftpusers
+.Sh SEE ALSO
+.Xr ftp 1 ,
+.Xr proftpd 8
--- proftpd-1.2.9.orig/debian/html2man.pl
+++ proftpd-1.2.9/debian/html2man.pl
@@ -0,0 +1,137 @@
+#!/usr/bin/perl
+
+# This script tries to generate a manual page for proftpd.conf(5) out
+# of the file ../doc/Configuration.html.
+
+$date = `date +"%e %B %Y"`;
+$date =~ tr/\r\n//d;
+
+print <<EOF;
+.\" This file was automatically generated on $date from Configuration.html.
+.\" This file may be distributed under the GNU General Public License.
+.\"
+.TH PROFTPD.CONF 5 "$date" "proftpd.conf" "Debian proftpd"
+.SH NAME
+proftpd.conf \- Configuration file for ProFTPD
+.SH DESCRIPTION
+.PP
+\\fBWARNING: This file was automatically generated\\fR from the file
+\\fI/usr/share/doc/proftpd-doc/Configuration.html\\fR (from the
+package \\fIproftpd-doc\\fR).  It is very well possible that there are
+a few remaining conversion errors.  If in doubt, always consult the
+HTML version.
+.PP
+This manual page describes the configuration options that are
+available in the proftpd configuration file \\fI/etc/proftpd.conf\\fR.
+.SH SYNTAX
+.PP
+A list of available options follow.
+.PP
+EOF
+
+$header_started = 0;
+
+while (<STDIN>) {
+    s/&lt;/\</g;
+    s/&gt;/\>/g;
+    s/&amp;/&/g;
+    s/&quot;/"/g;
+    if(m%^<h2><a[^>]*>(.+)</a></h2>$%i) {
+	print ".TP\n\\fB$1\\fR\n";
+	$block_started = 1;
+    } else {
+	if($block_started) {
+	    if($header_started != 2 && m%^.*<strong>(.*):</strong>(.*)<[^>]*>$%i) {
+		if(!$header_started) {
+		    $header_started = 1;
+		    print "\n.TS\ntab(\@);\nl l.\n";
+		}
+		$field = $1;
+		$value = $2;
+		$value =~ s%<strong>%\\fB%gi;
+		$value =~ s%<em>%\\fI%gi;
+		$value =~ s%<i>%\\fI%gi;
+		$value =~ s%</strong>%\\fR%gi;
+		$value =~ s%</em>%\\fR%gi;
+		$value =~ s%</i>%\\fR%gi;
+		print "\\fB$field\\fR:\@$value\n";
+	    } else {
+		if(m%<hr>%i) {
+		    $block_started = 0;
+		    $header_started = 0;
+		} else {
+		    if($header_started == 1) {
+			$header_started = 2;
+			print ".TE\n\n";
+		    }
+		    s/^\s+//g;
+		    if(m%^<p>%i) {
+			print "\n";
+			s/^<p>//i;
+		    }
+		    if(s%^(<[^>]+>)*<code>%%gi) {
+			$code_started = 1;
+			print ".PP\n.sp\n.nf\n.in +10\n";
+			s%</p>%%i;
+			if(s%</code>$%%gi) {
+			    $code_started = 0;
+			    print;
+			    print ".fi\n.PP\n";
+			} else {
+			    s%<br>%%gi;
+			    print;
+			}
+		    } else {
+			s%</p>%%i;
+			s%<strong>%\\fB%gi;
+			s%<em>%\\fI%gi;
+			s%<i>%\\fI%gi;
+			s%</strong>%\\fR%gi;
+			s%</em>%\\fR%gi;
+			s%</i>%\\fR%gi;
+			if($link_started) {
+			    s%^[^>]*>(.*)</a>%\\fB$1\\fR%i;
+			    $link_started = 0;
+			}
+			s%<a[^>]*>(.*)</a>%\\fB$1\\fR%gi;
+			if($code_started) {
+			    s%<br>%%gi;
+			} else {
+			    s%<br>%\n%gi;
+			}
+			if(s%</code>$%%gi) {
+			    $code_started = 0;
+			    print;
+			    print ".fi\n.PP\n";
+			} else {
+			    if(s%<a[^>]*$%%i) {
+				$link_started = 1;
+			    }
+			    print;
+			}
+		    }
+		}
+	    }
+	}
+    }
+}
+
+print <<EOF;
+.PP
+.SH "SEE ALSO"
+\\fBproftpd\\fR(8)
+.PP
+The full documentation for
+.B proftpd.conf
+is maintained as a HTML file in the package
+.B proftpd-doc
+; if for example the
+.B lynx
+and
+.B proftpd-doc
+packages are properly installed at your site, the command
+.IP
+.B lynx /usr/share/doc/proftpd-doc/Configuration.html
+.PP
+should give you access to the complete manual.
+EOF
--- proftpd-1.2.9.orig/debian/mod_mysql.texi
+++ proftpd-1.2.9/debian/mod_mysql.texi
@@ -0,0 +1,19 @@
+This module is contained in the mod_mysql.c file, and is not compiled in
+by default.  It provides the backend support to connect to MySQL
+databases.
+
+@heading MySQL Database Directives
+
+@subheading @anchor{MySQLInfo} MySQLInfo
+
+@format
+Syntax: MySQLInfo host user pass dbname
+Default: none
+Context: server config, virtual host
+@end format
+
+Configures the MySQL database driver (the database may be remote).  A
+connection isn't made until use of a SQL feature requires it, after
+which it may be held open for the lifetime of the FTP session
+depending on the directives in use.  Use @kbd{""} to specify a null
+password.
--- proftpd-1.2.9.orig/debian/mod_mysql.txt
+++ proftpd-1.2.9/debian/mod_mysql.txt
@@ -0,0 +1,19 @@
+This module is contained in the mod_mysql.c file, and is not compiled in
+by default.  It provides the backend support to connect to MySQL
+databases.
+
+MySQL Database Directives
+=========================
+
+MySQLInfo
+---------
+
+Syntax: MySQLInfo host user pass dbname
+Default: none
+Context: server config, virtual host
+
+   Configures the MySQL database driver (the database may be remote).  A
+connection isn't made until use of a SQL feature requires it, after
+which it may be held open for the lifetime of the FTP session depending
+on the directives in use.  Use `""' to specify a null password.
+
--- proftpd-1.2.9.orig/debian/mod_pgsql.texi
+++ proftpd-1.2.9/debian/mod_pgsql.texi
@@ -0,0 +1,30 @@
+This module is contained in the mod_pgsql.c file, and is not compiled in
+by default.  It provides the backend support to connect to Postgresql
+databases.
+
+@heading Postgres Database Directives
+
+@subheading @anchor{PostgresInfo} PostgresInfo
+
+@format
+Syntax: PostgresInfo host user pass dbname
+Syntax: PostgresInfo host dbname
+Default: none
+Context: server config, virtual host
+@end format
+
+Configures the Posgresql database driver (the database may be remote).
+A connection isn't made until use of a SQL feature requires it, after
+which it may be held open for the lifetime of the FTP session depending
+on the directives in use.
+
+@subheading @anchor{PostgresPort} PostgresPort
+
+@format
+Syntax: PostgresPort [num]
+Default: 5432
+Context: server config, virtual host
+@end format
+
+Specifies which TCP/IP port to use for connecting.  Default is 5432, or
+UNIX socket for localhost.
--- proftpd-1.2.9.orig/debian/mod_pgsql.txt
+++ proftpd-1.2.9/debian/mod_pgsql.txt
@@ -0,0 +1,30 @@
+This module is contained in the mod_pgsql.c file, and is not compiled in
+by default.  It provides the backend support to connect to Postgresql
+databases.
+
+Postgres Database Directives
+============================
+
+PostgresInfo
+------------
+
+Syntax: PostgresInfo host user pass dbname
+Syntax: PostgresInfo host dbname
+Default: none
+Context: server config, virtual host
+
+   Configures the Posgresql database driver (the database may be
+remote).  A connection isn't made until use of a SQL feature requires
+it, after which it may be held open for the lifetime of the FTP session
+depending on the directives in use.
+
+PostgresPort
+------------
+
+Syntax: PostgresPort [num]
+Default: 5432
+Context: server config, virtual host
+
+   Specifies which TCP/IP port to use for connecting.  Default is 5432,
+or UNIX socket for localhost.
+
--- proftpd-1.2.9.orig/debian/proftpd.config
+++ proftpd-1.2.9/debian/proftpd.config
@@ -0,0 +1,19 @@
+#!/bin/sh -e
+
+# Source debconf library.
+. /usr/share/debconf/confmodule
+
+action=$1
+version=$2
+
+db_title ProFTPd configuration
+
+if dpkg --compare-versions "$version" lt "1.2.8-1" ; then
+    if test -f /etc/proftpd.conf ; then
+        db_input critical shared/proftpd/warning || true
+	db_go
+    fi
+fi
+
+db_input high shared/proftpd/inetd_or_standalone || true
+db_go
--- proftpd-1.2.9.orig/debian/proftpd.cron.monthly
+++ proftpd-1.2.9/debian/proftpd.cron.monthly
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# cron script to rotate the proftpd server logfile, based on the
+# wu-ftpd script by Peter Tobias <tobias@et-inf.fho-emden.de>.
+
+[ -x /usr/sbin/ftpstats ] || exit 0
+
+cd /var/log
+savelog -q -u root -g adm -m 640 -c 12 /var/log/xferreport 
+ftpstats -a -r -l 2 -d 2>/dev/null >/var/log/xferreport
+savelog -q -u root -g adm -m 640 -c 7 /var/log/xferlog 
--- proftpd-1.2.9.orig/debian/proftpd.init
+++ proftpd-1.2.9/debian/proftpd.init
@@ -0,0 +1,136 @@
+#!/bin/sh 
+
+# Start the proftpd FTP daemon.
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+DAEMON=/usr/sbin/proftpd
+NAME=proftpd
+
+# Defaults
+RUN="no"
+OPTIONS=""
+
+PIDFILE=`grep -i 'pidfile' /etc/proftpd.conf | sed -e 's/pidfile[\t ]\+//i'`
+if [ "x$PIDFILE" = "x" ];
+then
+	PIDFILE=/var/run/proftpd.pid
+fi
+
+# Read config (will override defaults)
+[ -r /etc/default/proftpd ] && . /etc/default/proftpd
+
+trap "" 1
+trap "" 15
+
+test -f $DAEMON || exit 0
+
+if ! egrep -qi "^[[:space:]]*ServerType.*standalone" /etc/proftpd.conf
+then
+    RUN="no"
+    INETD="yes"
+fi
+
+start()
+{
+    if start-stop-daemon --start --quiet --pidfile "$PIDFILE" \
+        --exec $DAEMON -- $OPTIONS ; then
+        echo "$NAME."
+    else
+        echo "."
+    fi
+}
+
+signal()
+{
+    if [ "$1" = "stop" ]; then
+	SIGNAL="TERM"
+    else
+	if [ "$1" = "reload" ]; then
+	    SIGNAL="HUP"
+	else
+	    echo "ERR: wrong parameter given to signal()"
+	fi
+    fi
+    if start-stop-daemon --stop --signal $SIGNAL --quiet --pidfile "$PIDFILE"; then
+        echo "$NAME."
+    else
+	SIGNAL="KILL"
+	if start-stop-daemon --stop --signal $SIGNAL --quiet --pidfile "$PIDFILE"; then
+		echo "$NAME."
+	else
+        	echo "."
+	fi
+    fi
+    if [ "$SIGNAL" = "KILL" ]; then
+	    rm -f "$PIDFILE"
+    fi
+}
+
+case "$1" in
+    start)
+	if [ "x$RUN" = "xyes" ] ; then
+	    echo -n "Starting ProFTPD ftp daemon: "
+	    start
+	else
+	    if [ "x$INETD" = "xyes" ] ; then
+		echo "ProFTPd is started from inetd."
+	    fi
+	fi
+	;;
+
+    force-start)
+	if [ "x$INETD" = "xyes" ] ; then
+	    echo "Warning: ProFTPd is started from inetd (trying to start anyway)."
+	fi
+	echo -n "Starting ProFTPD ftp daemon: "
+	start
+	;;	
+    
+    stop)
+	if [ "x$RUN" = "xyes" ] ; then
+	    echo -n "Stopping ProFTPD ftp daemon: "
+	    signal stop
+	else
+	    if [ "x$INETD" = "xyes" ] ; then
+		echo "ProFTPd is started from inetd."
+	    fi
+	fi
+	;;
+
+    force-stop)
+	if [ "x$INETD" = "xyes" ] ; then
+	    echo "Warning: ProFTPd is started from inetd (trying to kill anyway)."
+	fi
+	echo -n "Stopping ProFTPD ftp daemon: "
+	signal stop
+	;;
+
+    reload)
+	echo -n "Reloading $NAME configuration..."
+	signal reload
+	echo " done."
+	;;
+
+    force-reload|restart)
+	if [ "x$RUN" = "xyes" ] ; then
+	    echo -n "Restarting ProFTPD ftp daemon."
+	    signal stop
+	    echo -n "."
+	    sleep 2
+	    echo -n "."
+	    start
+	    echo " done."
+	else
+	    if [ "x$INETD" = "xyes" ] ; then
+		echo "ProFTPd is started from inetd."
+	    fi
+	fi
+	;;
+
+    *)
+	echo "Usage: /etc/init.d/$NAME {start|force-start|stop|force-stop|reload|restart|force-reload}"
+	exit 1
+	;;
+esac
+
+exit 0
--- proftpd-1.2.9.orig/debian/proftpd.pam
+++ proftpd-1.2.9/debian/proftpd.pam
@@ -0,0 +1,11 @@
+#%PAM-1.0
+auth       required	pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
+auth       required	pam_unix.so nullok
+
+# This is disabled because anonymous logins will fail otherwise,
+# unless you give the 'ftp' user a valid shell, or /bin/false and add
+# /bin/false to /etc/shells.
+#auth       required	pam_shells.so
+
+account    required	pam_unix.so
+session    required	pam_unix.so
--- proftpd-1.2.9.orig/debian/proftpd.postinst
+++ proftpd-1.2.9/debian/proftpd.postinst
@@ -0,0 +1,155 @@
+#!/bin/sh -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see /usr/share/doc/packaging-manual/
+#
+# quoting from the policy:
+#     Any necessary prompting should almost always be confined to the
+#     post-installation script, and should be protected with a conditional
+#     so that unnecessary prompting doesn't happen if a package's
+#     installation fails and the `postinst' is called with `abort-upgrade',
+#     `abort-remove' or `abort-deconfigure'.
+
+
+CONF="/etc/proftpd.conf"
+CONF_NEW="/etc/proftpd.conf.proftpd-new"
+
+installftp()
+{
+	if ! grep -q "^ftp:" /etc/passwd
+	    then
+	    adduser --system ftp || true
+            if [ -f /usr/share/doc/proftpd/examples/welcome.msg -a -d ~ftp ] ; then
+                cp -p -v /usr/share/doc/proftpd/examples/welcome.msg ~ftp/welcome.msg.proftpd-new || true
+                do_update ~ftp/welcome.msg || true
+	    fi
+	fi
+}
+
+list_options()
+{
+    if [ -f $CONF_NEW ] ; then
+	sed -e "s/lsdefaultoptions/ListOptions/i" $CONF_NEW > $CONF_NEW.tmp
+	mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+tcpwin_options()
+{
+    if [ -f $CONF_NEW ] ; then
+        sed -e "s/tcpreceivewindow/SocketOptions rcvbuf/i" \
+            -e "s/tcpsendwindow/SocketOptions sndbuf/i" \
+                                                $CONF_NEW > $CONF_NEW.tmp
+        mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+                                                                                         
+scoreboard()
+{
+    if [ -f $CONF_NEW ] ; then
+        sed -e "s/\(scoreboardpath.*\)/#\n#ScoreboardPath is deprecated in 1.2.9, use ScoreboardFile instead\n#\1\n#\n#ScoreboardFile\t\/var\/run\/proftpd.scoreboard\n#/i" \
+                                                $CONF_NEW > $CONF_NEW.tmp
+        mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+
+switch_on()
+{
+    if [ -f $CONF_NEW ] ; then
+	sed -e 's/^\(ServerType.*\)inetd/\1standalone/' $CONF_NEW >$CONF_NEW.tmp
+	mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+switch_off()
+{
+    if [ -f $CONF_NEW ] ; then
+	sed -e 's/^\(ServerType.*\)standalone/\1inetd/' $CONF_NEW >$CONF_NEW.tmp
+	mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+replace_file () {
+    file=$1
+    if [ ! -f ${file} ] ; then
+	mv ${file}.proftpd-new ${file}
+    else
+	cp $file ${file}.proftpd-old
+	ucf ${file}.proftpd-new $file 
+    fi
+}
+
+do_update () {
+    file=$1
+    if diff -q ${file} ${file}.proftpd-new >/dev/null 2>&1; then
+	# Old file and new file are identical
+	rm -f ${file}.proftpd-new
+    else
+	replace_file $file
+    fi
+}
+
+DONTSTART=0
+
+. /usr/share/debconf/confmodule
+
+if [ "$1" = "configure" ]; then
+    
+    # use current configuration or generate a new one from scratch
+    if [ ! -f /etc/proftpd.conf ] ; then
+       cp /usr/share/doc/proftpd/examples/proftpd.conf $CONF_NEW
+    else
+       cp $CONF $CONF_NEW
+    fi
+    
+    update-inetd --group STANDARD --add 'ftp	stream	tcp	nowait	root	/usr/sbin/tcpd /usr/sbin/proftpd' 
+
+    db_get shared/proftpd/inetd_or_standalone
+    if [ "$RET" = "inetd" ] ; then
+	    update-inetd --enable ftp
+	    switch_off
+    else
+	    update-inetd --disable ftp
+	    switch_on
+    fi
+
+    # Proftpd could not close all of its fd nicely
+    db_stop
+
+    installftp
+
+    # do mandatory changes
+    list_options
+    tcpwin_options
+    scoreboard
+
+    # propose maintainer changes to user
+    do_update /etc/proftpd.conf
+
+
+    # clean run files (pidfile and scoreboard)
+    rm -f /var/run/proftpd/proftpd* /var/run/proftpd.pid 
+
+fi
+
+if [ -e "/etc/init.d/proftpd" ]; then
+    update-rc.d proftpd defaults 50 >/dev/null
+    if [ $DONTSTART -eq 0 ] ; then
+        set +e; /usr/sbin/proftpd -t >/dev/null 2>&1; set -e
+    	if [ $? = 0 ]; then
+		invoke-rc.d proftpd start
+	else
+		echo "Cannot start proftpd, please check syntax of your configuration file $CONF"
+	fi
+    fi
+fi
+
+#DEBHELPER#
+
--- proftpd-1.2.9.orig/debian/proftpd.postrm
+++ proftpd-1.2.9/debian/proftpd.postrm
@@ -0,0 +1,22 @@
+#!/bin/sh -e
+
+if [ "$1" = "purge" ] ; then
+    rm -f /etc/proftpd.conf
+    rm -f /etc/proftpd.conf.proftpd-new
+    rm -f /etc/proftpd.conf.proftpd-old
+fi
+
+if [ "$1" = "purge" -o "$1" = "remove" ]
+then
+    update-inetd --disable ftp
+fi
+
+if [ "$1" = "purge" ] ; then
+        update-rc.d proftpd remove >/dev/null
+	update-inetd --remove "^.*ftp.*/usr/sbin/proftpd$" 
+	ucf --purge /etc/proftpd.conf
+	rm -rf /var/run/proftpd /var/run/proftpd.pid
+fi
+
+#DEBHELPER#
+
--- proftpd-1.2.9.orig/debian/proftpd.preinst
+++ proftpd-1.2.9/debian/proftpd.preinst
@@ -0,0 +1,34 @@
+#!/bin/sh -e
+
+# summary of how this script can be called:
+#        * <new-preinst> `install'
+#        * <new-preinst> `install' <old-version>
+#        * <new-preinst> `upgrade' <old-version>
+#        * <old-preinst> `abort-upgrade' <new-version>
+#
+
+if [ "$1" = "upgrade" ]; then
+	 if [ -e /usr/sbin/invoke-rc.d ]; then
+         	invoke-rc.d proftpd stop >/dev/null 2>&1 || true 
+	 else
+	 	/etc/init.d/proftpd stop >/dev/null 2>&1 || true
+	 fi
+
+         # Scoreboard file format changed in 1.2.9
+         # Now stopping all inetd sessions and removing it to ensure
+         # a clean upgrade
+         if dpkg --compare-versions "$2" lt "1.2.9-1"; then
+                if [ `pgrep proftpd|wc -l` -ne 0 ]; then
+                        pkill proftpd
+                        sleep 2
+                fi
+                rm -f /var/run/proftpd/proftpd.scoreboard
+         fi
+fi
+
+exit 0
+
+#DEBHELPER#
+
+
+
--- proftpd-1.2.9.orig/debian/proftpd.prerm
+++ proftpd-1.2.9/debian/proftpd.prerm
@@ -0,0 +1,11 @@
+#! /bin/sh
+
+if [ -x "/usr/sbin/invoke-rc.d" ]; then
+    invoke-rc.d proftpd stop
+else 
+	if [ -x "/etc/init.d/proftpd" ]; then
+		/etc/init.d/proftpd stop
+	fi
+fi
+
+#DEBHELPER#
--- proftpd-1.2.9.orig/debian/proftpd.templates
+++ proftpd-1.2.9/debian/proftpd.templates
@@ -0,0 +1,26 @@
+Template: shared/proftpd/inetd_or_standalone
+Type: select
+_Choices: inetd, standalone
+Default: standalone
+_Description: Run proftpd from inetd or standalone?
+ ProFTPd can be run either as a service from inetd, or as a standalone
+ server.  Eeach choice has its own benefits.  If you have only a few ftp
+ connections per day, it may not be worth the resources to keep proftpd
+ running at all times.
+ .
+ On the other hand, if your ftp site is visited frequently, inetd is not a
+ good choice, because each time a connection is opened, a new process is
+ spawned.
+
+Template: shared/proftpd/warning
+Type: note
+_Description: Warning on syntax changes in ProFTPd configuration.
+ You are upgrading from a pre-1.2.8 version. Probably you will need
+ to revise your previous configuration to be compliant with
+ current directives. Please, consult documentation available
+ in proftpd-doc and change /etc/proftpd.conf as needed.
+ .
+ Unfortunately, it is near impossible for me to convert your setup
+ automatically, but for some elementary issues. You will have to do 
+ it yourself. ProFTPd could also be unable to use the resulting 
+ configuration, and it will not restart after upgrading.
--- proftpd-1.2.9.orig/debian/rules
+++ proftpd-1.2.9/debian/rules
@@ -0,0 +1,221 @@
+#!/usr/bin/make -f
+# -*- makefile -*- made with the aid of debmake, by Christoph Lameter,
+
+package = proftpd
+
+SHELL = /bin/bash
+CC = gcc
+CFLAGS := -O3 -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+IE := install -m755 -s
+ID := install -m644
+
+# Some special build options
+ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
+  CFLAGS += -g
+  ifneq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+    IE := install -m755
+  endif
+endif
+
+DH_COMPAT=3
+export DH_COMPAT
+
+# the dbs rules
+TAR_DIR := proftpd-1.2.9
+include debian/scripts/dbs-build.mk
+
+# dpkg-arch rules
+ifeq (,$(DEB_BUILD_GNU_TYPE))
+  include debian/scripts/dpkg-arch.mk
+endif
+
+DOC = usr/share/doc
+MAN = usr/share/man
+
+# This is the suite of modules maintained in debian/, not upstream CVS.
+# To enable mod_pgsql, put it after or in place of mod_mysql.
+#EXTRAMODS = mod_mysql:mod_ratio:
+QUOTAMOD  = mod_quotatab:
+EXTRAMODS = mod_ratio:mod_tls:mod_rewrite:mod_radius:mod_wrap:mod_quotatab_file:
+MYSQLMODS = mod_sql:mod_sql_mysql:mod_quotatab_sql:
+PGSQLMODS = mod_sql:mod_sql_postgres:mod_quotatab_sql:
+LDAPMODS  = mod_ldap:mod_quotatab_ldap:
+
+# This should be commented out for the build to succeed.
+#DEBUG = -DDEBUG_NOFORK -g3 
+
+configure_args := --prefix=/usr --cache-file=../config.cache		\
+	--sysconfdir=/etc --localstatedir=/var/run --enable-autoshadow  \
+	--srcdir=../.. --enable-ipv6
+
+ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
+  configure_args += --build $(DEB_HOST_GNU_TYPE)
+else
+  configure_args += --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE)
+endif
+	
+#$(BUILD_TREE)/configure: $(BUILD_TREE)/configure.in
+#	cd $(BUILD_TREE) && autoconf
+
+
+proftpd.conf.5: build-tree/$(TAR_DIR)/doc/Configuration.html
+	chmod +x debian/html2man.pl
+	debian/html2man.pl <build-tree/$(TAR_DIR)/doc/Configuration.html >proftpd.conf.5
+
+stampdir/build: stampdir/configure proftpd.conf.5 $(dh_mak_deps) 
+	dh_testdir
+	# The -DLINUX bit is cause ./configure doesnt detect alpha
+	( cd build-tree/$(TAR_DIR)/build/pam && $(MAKE) all PLATFORM=-DLINUX )
+	( cd build-tree/$(TAR_DIR)/build/mysql && $(MAKE) proftpd PLATFORM=-DLINUX )
+	( cd build-tree/$(TAR_DIR)/build/pgsql && $(MAKE) proftpd PLATFORM=-DLINUX )
+	( cd build-tree/$(TAR_DIR)/build/ldap && $(MAKE) proftpd PLATFORM=-DLINUX )
+	touch stampdir/build
+
+build: stampdir/build
+
+stampdir/configure: $(unpacked) $(patched)
+	for d in pam mysql pgsql ldap ; do mkdir -p build-tree/$(TAR_DIR)/build/$$d/contrib/dist/rpm ; done
+	cd build-tree/$(TAR_DIR)/modules ; for m in mod_{ratio,sql,sqlpw,mysql,pgsql}.c ; do if [ ! -e $$m ] ; then ln -s ../contrib/$$m . ; fi ; done
+
+	( cd build-tree/$(TAR_DIR)/build/pam && CC="$(CC) -Wall $(CFLAGS) $(DEBUG) -I.. -I../../.." \
+		../../configure $(configure_args) --with-modules=$(QUOTAMOD)$(EXTRAMODS)mod_readme )
+	( cd build-tree/$(TAR_DIR)/build/mysql && CC="$(CC) -Wall $(CFLAGS) $(DEBUG) -I.. -I../../.." \
+		../../configure $(configure_args) --with-modules=$(QUOTAMOD)$(MYSQLMODS)$(EXTRAMODS)mod_readme )
+	( cd build-tree/$(TAR_DIR)/build/pgsql && CC="$(CC) -Wall $(CFLAGS) $(DEBUG) -I.. -I../../.." \
+		../../configure $(configure_args) --with-modules=$(QUOTAMOD)$(PGSQLMODS)$(EXTRAMODS)mod_readme )
+	( cd build-tree/$(TAR_DIR)/build/ldap && CC="$(CC) -Wall $(CFLAGS) $(DEBUG) -I.. -I../../.." \
+		../../configure $(configure_args) --with-modules=$(QUOTAMOD)$(LDAPMODS)$(EXTRAMODS)mod_readme )
+	touch stampdir/configure
+
+clean:
+	dh_testdir
+	dh_clean
+
+	-test -r /usr/share/misc/config.sub && \
+		cp -f /usr/share/misc/config.sub config.sub
+	-test -r /usr/share/misc/config.guess && \
+		cp -f /usr/share/misc/config.guess config.guess
+
+	rm -rf stampdir build-tree
+	rm -f stamp-build stamp-configure debian/files.saved debian/files
+	rm -rf build
+	rm -f $$(find . -type l) $$(find . -name "*~" -o -name "*.o")
+	rm -f proftpd config.cache config.log lib/*.a ftpshut Make.rules
+	rm -rf debian/proftpd debian/proftpd-{doc,common,ldap,pgsql,mysql}
+	rm -rf debian/{files*,*substvars*,*.gz} core
+	rm -f debian/proftpd-{mysql,pgsql,ldap}.{postinst,postrm,prerm,config,init}
+	rm -f $$(find * -name "*.orig") modules/mod_ratio.c
+	rm -f contrib/dist/rpm/proftpd.spec
+	rm -f proftpd.conf.5
+
+binary-indep:	checkroot build
+	dh_testdir
+	dh_clean -k -i
+	dh_installdirs -i $(DOC) -pproftpd-doc
+	dh_installdocs -i debian/copyright
+	dh_installchangelogs -i build-tree/$(TAR_DIR)/ChangeLog
+	dh_installdocs -i build-tree/$(TAR_DIR)/README* \
+		debian/*.txt \
+		$$(find build-tree/$(TAR_DIR)/doc/* -type f -maxdepth 0 | egrep -v "Get|Show|license") \
+		$$(find build-tree/$(TAR_DIR)/contrib -name "*.html" -type f -maxdepth 1) \
+		build-tree/$(TAR_DIR)/contrib/README.mod_wrap \
+		build-tree/$(TAR_DIR)/contrib/README.ratio build-tree/$(TAR_DIR)/contrib/UPGRADE.mod_sql
+	dh_installexamples -i build-tree/$(TAR_DIR)/sample-configurations/*
+	dh_compress -i
+	dh_fixperms -i
+	dh_installdeb -i
+	dh_gencontrol -i -u-isp
+	dh_md5sums -i
+	dh_fixperms -i
+	dh_builddeb -i
+
+binary-arch:	checkroot build
+	dh_testdir
+	dh_clean -k -i
+	dh_installdirs -a $(DOC) $(MAN)
+	dh_installdocs -a debian/copyright
+	dh_installchangelogs -a build-tree/$(TAR_DIR)/ChangeLog
+
+	for t in mysql pgsql ldap ; do \
+		for d in postinst postrm prerm config init ; do \
+			sed -e "s,usr/share/doc/proftpd,usr/share/doc/proftpd-$$t,g" \
+				< debian/proftpd.$$d > debian/proftpd-$$t.$$d ; \
+		done ; \
+		ln -sf proftpd.templates debian/proftpd-$$t.templates ; \
+	done
+
+	for d in pam mysql pgsql ldap ; do \
+		case $$d in \
+			pam) \
+				packagename="proftpd" ;\
+			;; \
+			*) \
+				packagename="proftpd-$$d" ;\
+			;; \
+		esac ;\
+		cwd=`pwd` ; \
+		set -e ; \
+		dh_installdirs -p$$packagename etc/pam.d etc/init.d etc/default ;\
+		( cd build-tree/$(TAR_DIR)/build/$$d && $(MAKE) install-proftpd \
+			rundir=var/run/proftpd \
+			mandir=usr/share/man \
+			sbindir=usr/sbin \
+			bindir=usr/bin \
+			sysconfdir=etc INSTALL=install DESTDIR=$$cwd/debian/$$packagename/ ) ;\
+		rm -f debian/$$packagename/usr/sbin/in.proftpd ;\
+		mkdir -p debian/$$packagename/usr/share/doc/$$packagename/examples ;\
+		cp debian/basic.conf debian/$$packagename/usr/share/doc/$$packagename/examples/proftpd.conf ;\
+		cp debian/welcome.msg debian/$$packagename/usr/share/doc/$$packagename/examples/welcome.msg ;\
+		cp debian/ftpusers debian/$$packagename/etc ;\
+		install -m 755 debian/proftpd.init debian/$$packagename/etc/init.d/proftpd ;\
+		install -m 644 debian/proftpd.pam debian/$$packagename/etc/pam.d/proftpd ;\
+		install -m 644 debian/default debian/$$packagename/etc/default/proftpd ;\
+	done
+
+	dh_installdirs -pproftpd-common usr/bin \
+					usr/share/man usr/share/man/man1 usr/share/man/man5 usr/share/man/man8
+	cwd=`pwd` ;\
+	( cd build-tree/$(TAR_DIR)/build/pam && $(MAKE) install-utils install-man \
+		rundir=var/run/proftpd \
+		mandir=usr/share/man \
+		sbindir=usr/sbin \
+		bindir=usr/bin \
+		sysconfdir=etc INSTALL=install DESTDIR=$$cwd/debian/proftpd-common/ )
+
+	dh_installdirs -pproftpd-common usr/sbin etc/cron.monthly
+	install debian/ftpusers.5 debian/proftpd-common/usr/share/man/man5/ftpusers.5
+	install proftpd.conf.5 debian/proftpd-common/usr/share/man/man5/proftpd.conf.5
+	install debian/ftpasswd.8 debian/proftpd-common/usr/share/man/man8/ftpasswd.8
+	install build-tree/$(TAR_DIR)/contrib/xferstats.holger-preiss \
+		debian/proftpd-common/usr/sbin/ftpstats
+
+	install -m 755 build-tree/$(TAR_DIR)/contrib/ftpasswd debian/proftpd-common/usr/sbin/ftpasswd
+	install -m 755 debian/proftpd.cron.monthly debian/proftpd-common/etc/cron.monthly/proftpd
+	cp debian/ftpstats.8 debian/proftpd-common/usr/share/man/man8
+
+	dh_installdebconf -a
+	dh_compress -a
+	dh_fixperms -a
+	dh_installdeb -a
+	dh_shlibdeps -a
+	dh_perl -a
+	dh_gencontrol -a -u-isp
+	dh_strip -a
+	dh_md5sums -a
+	dh_fixperms -a
+	dh_builddeb -a
+	if egrep "^DEBUG" debian/rules; then false; fi
+
+binary:	binary-indep binary-arch
+
+checkroot:
+	dh_testdir
+	dh_testroot
+
+.PHONY: binary binary-arch binary-indep clean checkroot
+
+tidy:
+	rm -f o *~ debian/*~
+	- cd debian && indent -v mod_mysql.c mod_pgsql.c mod_ratio.c
+	cd debian && makeinfo --no-headers -o mod_mysql.txt mod_mysql.texi
+	cd debian && makeinfo --no-headers -o mod_pgsql.txt mod_pgsql.texi
--- proftpd-1.2.9.orig/debian/welcome.msg
+++ proftpd-1.2.9/debian/welcome.msg
@@ -0,0 +1,7 @@
+Welcome, archive user %U@%R !
+
+The local time is: %T
+
+This is an experimental FTP server.  If have any unusual problems,
+please report them via e-mail to <root@%L>.
+
--- proftpd-1.2.9.orig/debian/po/CVS/Root
+++ proftpd-1.2.9/debian/po/CVS/Root
@@ -0,0 +1 @@
+:ext:frankie@cvs.alioth.debian.org:/cvsroot/pkg-proftpd
--- proftpd-1.2.9.orig/debian/po/CVS/Repository
+++ proftpd-1.2.9/debian/po/CVS/Repository
@@ -0,0 +1 @@
+debian/po
--- proftpd-1.2.9.orig/debian/po/CVS/Entries
+++ proftpd-1.2.9/debian/po/CVS/Entries
@@ -0,0 +1,11 @@
+/POTFILES.in/1.1.1.1/Sun Sep 14 10:55:47 2003//
+/de.po/1.2/Mon Nov  3 14:52:48 2003//
+/es.po/1.2/Mon Nov  3 14:52:48 2003//
+/fr.po/1.2/Mon Nov  3 14:52:48 2003//
+/it.po/1.2/Mon Nov  3 14:52:48 2003//
+/ja.po/1.2/Mon Nov  3 14:52:48 2003//
+/nl.po/1.2/Mon Nov  3 14:52:48 2003//
+/pt_BR.po/1.2/Mon Nov  3 14:52:48 2003//
+/ru.po/1.3/Mon Nov  3 14:52:48 2003//
+/templates.pot/1.2/Mon Nov  3 14:52:48 2003//
+D
--- proftpd-1.2.9.orig/debian/po/POTFILES.in
+++ proftpd-1.2.9/debian/po/POTFILES.in
@@ -0,0 +1 @@
+[type: gettext/rfc822deb] proftpd.templates
--- proftpd-1.2.9.orig/debian/po/de.po
+++ proftpd-1.2.9/debian/po/de.po
@@ -0,0 +1,145 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#    Translators, please read /usr/share/doc/po-debconf/README-trans
+#         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-11-03 14:11+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: select
+#. Choices
+#: ../proftpd.templates:3
+#, fuzzy
+msgid "inetd, standalone"
+msgstr "inetd, Daemon"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+#, fuzzy
+msgid "Run proftpd from inetd or standalone?"
+msgstr "ProFTPd über inetd oder als Daemon starten?"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+#, fuzzy
+msgid ""
+"ProFTPd can be run either as a service from inetd, or as a standalone "
+"server.  Eeach choice has its own benefits.  If you have only a few ftp "
+"connections per day, it may not be worth the resources to keep proftpd "
+"running at all times."
+msgstr ""
+"ProFTPd kann entweder als Dienst über inetd oder als einzelner Daemon "
+"gestartet werden. Jede der zwei Startarten hat ihre Vorteile. Wenn der FTP-"
+"Server nur sehr wenig genutzt werden wird. ist es sinnvoller, ihn inetd "
+"laufen zu lassen."
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+#, fuzzy
+msgid ""
+"On the other hand, if your ftp site is visited frequently, inetd is not a "
+"good choice, because each time a connection is opened, a new process is "
+"spawned."
+msgstr ""
+"Wenn der FTP-Server jedoch sehr oft genutzt werden wird, ist es nicht "
+"sinnvoll, ihn über inetd laufen zu lassen, da bei jeder Verbindung eine "
+"eigene Instanz des Programmes gestartet werden würde."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid "Warning on syntax changes in ProFTPd configuration."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"You are upgrading from a pre-1.2.8 version. Probably you will need to revise "
+"your previous configuration to be compliant with current directives. Please, "
+"consult documentation available in proftpd-doc and change /etc/proftpd.conf "
+"as needed."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+#, fuzzy
+msgid ""
+"Unfortunately, it is near impossible for me to convert your setup "
+"automatically, but for some elementary issues. You will have to do  it "
+"yourself. ProFTPd could also be unable to use the resulting  configuration, "
+"and it will not restart after upgrading."
+msgstr ""
+"Es ist nicht möglich, die SQL-Konfiguration automatisch in die neue Version "
+"zu übernehmen."
+
+#, fuzzy
+#~ msgid "Enable anonymous access?"
+#~ msgstr "Anonymen Zugriff zulassen?"
+
+#, fuzzy
+#~ msgid ""
+#~ "Enabling anonymous access grants access to your ftp site by any user, "
+#~ "without being a system user.  This is probably not a good idea for "
+#~ "paranoid sysadmins.  Only enable if you know what it does."
+#~ msgstr ""
+#~ "Ein anonymer Zugriff auf Ihren FTP-Server erlaubt jedem den Zugang zu "
+#~ "Ihrem FTP-Server. Dies ist keine gute Idee für sicherheitsrelevante "
+#~ "Systeme. Aktivieren Sie den anonymen Zugang nur, wenn Sie es wirklich "
+#~ "wollen."
+
+#, fuzzy
+#~ msgid "Using SQL with ProFTPd."
+#~ msgstr "SQL mit ProFTPd nutzen?"
+
+#, fuzzy
+#~ msgid ""
+#~ "I found some old sql directives in /etc/proftpd.conf.  This release of "
+#~ "proftpd doesn't know many of the old sql-related configuration options.  "
+#~ "Many new ones were introduced, and old ones aren't recognized."
+#~ msgstr ""
+#~ "Es wurden einige SQL-Direktiven in /etc/proftpd.conf gefunden. Diese "
+#~ "Version von ProFTPd kennt jedoch nur wenige der alten SQL-"
+#~ "Konfigurationsvariablen."
+
+#, fuzzy
+#~ msgid ""
+#~ "Luckily, it is well documented.  Therefore I refer you to the "
+#~ "documentation in /usr/share/doc/proftpd/README.mod_sql.  I will not start "
+#~ "proftpd; do that yourself when you edited the configuration."
+#~ msgstr ""
+#~ "In der Datei /usr/share/doc/proftpd/README.mod_sql finden Sie eine sehr "
+#~ "gut dokumentierte Anleitung zum Einsatz von SQL in ProFTPd. ProFTPd wird "
+#~ "jetzt nicht gestartet. Passen Sie bitte die Konfiguration an, und starten "
+#~ "Sie ProFTPd danach von Hand."
+
+#, fuzzy
+#~ msgid "Edit configuration file ${file}?"
+#~ msgstr "Die Konfigurationsdatei ${file} anpassen?"
+
+#, fuzzy
+#~ msgid ""
+#~ "You did not install any debconf-enabled versions of the proftpd yet. This "
+#~ "means that I shall ask you some questions about the way to start proftpd "
+#~ "and anonymous access."
+#~ msgstr ""
+#~ "Es wurde bisher keine debconf-kompatible Version von ProFTPd verwendet.  "
+#~ "Dies bedeutet, das Sie jetzt ein paar Fragen zur Konfiguration von "
+#~ "ProFTPd beantworten sollten, um die Installation zu vervollständigen."
--- proftpd-1.2.9.orig/debian/po/es.po
+++ proftpd-1.2.9/debian/po/es.po
@@ -0,0 +1,135 @@
+#
+#    Translators, if you are not familiar with the PO format, gettext
+#    documentation is worth reading, especially sections dedicated to
+#    this format, e.g. by running:
+#         info -n '(gettext)PO Files'
+#         info -n '(gettext)Header Entry'
+#
+#    Some information specific to po-debconf are available at
+#            /usr/share/doc/po-debconf/README-trans
+#         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+#    Developers do not need to manually edit POT or PO files.
+#
+# Carlos Valdivia Yagüe <valyag@dat.etsit.upm.es>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: proftpd 1.2.8-8\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-11-03 14:11+0100\n"
+"PO-Revision-Date: 2003-07-12 18:40+0200\n"
+"Last-Translator: Carlos Valdivia Yagüe <valyag@dat.etsit.upm.es>\n"
+"Language-Team: Debian L10n Spanish <debian-l10n-spanish@lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: select
+#. Choices
+#: ../proftpd.templates:3
+msgid "inetd, standalone"
+msgstr "inetd, independiente"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid "Run proftpd from inetd or standalone?"
+msgstr "¿Ejecutar proftpd desde inetd o independientemente?"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"ProFTPd can be run either as a service from inetd, or as a standalone "
+"server.  Eeach choice has its own benefits.  If you have only a few ftp "
+"connections per day, it may not be worth the resources to keep proftpd "
+"running at all times."
+msgstr ""
+"ProFTPd puede ejecutarse como servicio desde inetd o como servidor "
+"independiente. Ambas opciones tienen sus ventajas. Si recibe solamente unas "
+"pocas conexiones ftp diarias, puede que no merezca la pena mantener proftpd "
+"funcionando constantemente con el consiguiente consumo de recursos."
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"On the other hand, if your ftp site is visited frequently, inetd is not a "
+"good choice, because each time a connection is opened, a new process is "
+"spawned."
+msgstr ""
+"Por otro lado, si su sitio ftp recibe muchas visitas, inetd no es una buena "
+"elección, porque cada vez que se abre una conexión se crea un nuevo proceso."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid "Warning on syntax changes in ProFTPd configuration."
+msgstr "Aviso de cambios de sintaxis en la configuración de ProFTPd."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"You are upgrading from a pre-1.2.8 version. Probably you will need to revise "
+"your previous configuration to be compliant with current directives. Please, "
+"consult documentation available in proftpd-doc and change /etc/proftpd.conf "
+"as needed."
+msgstr ""
+"Está actualizando desde una versión de ProFTPd anterior a la 1.2.8. Es muy "
+"posible que necesite revisar la configuración anterior para que se adecue a "
+"las directivas actuales. Por favor, consulte la documentación disponible en "
+"proftpd-doc y modifique apropiadamente /etc/proftpd.conf."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"Unfortunately, it is near impossible for me to convert your setup "
+"automatically, but for some elementary issues. You will have to do  it "
+"yourself. ProFTPd could also be unable to use the resulting  configuration, "
+"and it will not restart after upgrading."
+msgstr ""
+"Desgraciadamente, es casi imposible convertir su configuración de forma "
+"automática, salvo algunas cuestiones elementales, por lo que tendrá que "
+"hacerlo manualmente. ProFTPd podría tener problemas para usar la nueva "
+"configuración y no arrancar después de actualizar."
+
+#~ msgid "Enable anonymous access?"
+#~ msgstr "¿Permitir acceso anónimo?"
+
+#~ msgid ""
+#~ "Enabling anonymous access grants access to your ftp site by any user, "
+#~ "without being a system user.  This is probably not a good idea for "
+#~ "paranoid sysadmins.  Only enable if you know what it does."
+#~ msgstr ""
+#~ "Permitir acceso anónimo ofrece acceso a su sitio ftp a cualquier usuario "
+#~ "aunque no lo sea del sistema. Probablemente no sea una buena idea para "
+#~ "administradores paranoicos. Sólo permítalo si sabe lo que hace."
+
+#~ msgid "Manage ProFTPd configuration with debconf?"
+#~ msgstr "¿Gestionar la configuración de ProFTPd con debconf?"
+
+#~ msgid ""
+#~ "If you accept here, some aspect of ProFTPd will be automatically managed "
+#~ "by debconf. ProFTPd is quite complicated and flexible, so this kind of "
+#~ "management could be useful for newbies, or very simple kinds of "
+#~ "configuration."
+#~ msgstr ""
+#~ "Si acepta, algunos aspectos de ProFTPd se gestionarán automáticamente con "
+#~ "debconf. ProFTPd es muy complicado y flexible, por lo que puede resultar "
+#~ "útil a usuarios noveles o para configuraciones muy sencillas."
+
+#~ msgid ""
+#~ "If you refuse here, all aspects of ProFTPd configuration will be under "
+#~ "your responsability. If this is your first installation, I'll create a "
+#~ "very basic default configuration in /etc/proftpd.conf, else I'll try "
+#~ "create an updated configuration on the basis of your current one and some "
+#~ "known conversion issues."
+#~ msgstr ""
+#~ "En caso contrario, todos los aspectos de la configuración quedarán bajo "
+#~ "su responsabilidad. Si es su primera instalación se creará una "
+#~ "configuración predeterminada muy básica en /etc/proftpd.conf, sino se "
+#~ "intentará actualizar la configuración existente teniendo en cuenta "
+#~ "ciertos problemas conocidos en la conversión."
--- proftpd-1.2.9.orig/debian/po/fr.po
+++ proftpd-1.2.9/debian/po/fr.po
@@ -0,0 +1,134 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#    Translators, please read /usr/share/doc/po-debconf/README-trans
+#         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: proftpd 1.2.8-6\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-11-03 14:11+0100\n"
+"PO-Revision-Date: 2003-05-08 09:37+0100\n"
+"Last-Translator: Christian Perrier <bubulle@debian.org>\n"
+"Language-Team: Debian french translation team <debian-l10n-french@lists."
+"debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: select
+#. Choices
+#: ../proftpd.templates:3
+msgid "inetd, standalone"
+msgstr "inetd, indépendamment"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid "Run proftpd from inetd or standalone?"
+msgstr "Lancer proftpd à partir d'inetd ou indépendamment ?"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"ProFTPd can be run either as a service from inetd, or as a standalone "
+"server.  Eeach choice has its own benefits.  If you have only a few ftp "
+"connections per day, it may not be worth the resources to keep proftpd "
+"running at all times."
+msgstr ""
+"ProFTPd peut être lancé soit à partir d'inetd, soit comme un serveur "
+"indépendant. Chaque méthode a ses avantages. Pour quelques connexions par "
+"jour, il n'est peut-être pas nécessaire de laisser proftpd tourner en "
+"permanence."
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"On the other hand, if your ftp site is visited frequently, inetd is not a "
+"good choice, because each time a connection is opened, a new process is "
+"spawned."
+msgstr ""
+"Par contre, si votre site ftp est assez fréquenté, inetd n'est pas un choix "
+"judicieux, car chaque ouverture de connexion lance un nouveau processus."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid "Warning on syntax changes in ProFTPd configuration."
+msgstr ""
+"Avertissement pour changement de syntaxe dans la configuration de ProFTPd"
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"You are upgrading from a pre-1.2.8 version. Probably you will need to revise "
+"your previous configuration to be compliant with current directives. Please, "
+"consult documentation available in proftpd-doc and change /etc/proftpd.conf "
+"as needed."
+msgstr ""
+"Vous effectuez une mise à jour depuis une version inférieure à 1.2.8. Il "
+"vous sera probablement nécessaire de revoir votre configuration antérieure "
+"afin d'être conforme aux nouvelles directives. Veuillez, s'il vous plait, "
+"consulter la documentation disponible dans le paquet proftpd-doc et "
+"modifier /etc/proftpd.conf en conséquence."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"Unfortunately, it is near impossible for me to convert your setup "
+"automatically, but for some elementary issues. You will have to do  it "
+"yourself. ProFTPd could also be unable to use the resulting  configuration, "
+"and it will not restart after upgrading."
+msgstr ""
+"Malheureusement, il est à peu près impossible de convertir votre "
+"configuration automatiquement, sauf pour des points particulièrement "
+"simples. Vous devrez le faire vous-même. ProFTPd pourrait être incapable "
+"d'utiliser le fichier de configuration résultant et ne redémarrera donc pas "
+"après la mise à jour."
+
+#~ msgid "Enable anonymous access?"
+#~ msgstr "Autoriser les connexions anonymes ?"
+
+#~ msgid ""
+#~ "Enabling anonymous access grants access to your ftp site by any user, "
+#~ "without being a system user.  This is probably not a good idea for "
+#~ "paranoid sysadmins.  Only enable if you know what it does."
+#~ msgstr ""
+#~ "Autoriser les connexions anonymes donne l'accès au serveur ftp à toute "
+#~ "personne (même inconnue de la machine). Les administrateurs système "
+#~ "paranoïaques pensent que ce n'est probablement pas une bonne idée. Ne "
+#~ "l'activez que si vous savez ce que vous faites."
+
+#~ msgid "Manage ProFTPd configuration with debconf?"
+#~ msgstr "Gérer la configuration de ProFTPd avec debconf ?"
+
+#~ msgid ""
+#~ "If you accept here, some aspect of ProFTPd will be automatically managed "
+#~ "by debconf. ProFTPd is quite complicated and flexible, so this kind of "
+#~ "management could be useful for newbies, or very simple kinds of "
+#~ "configuration."
+#~ msgstr ""
+#~ "Si vous acceptez ici, certains aspects de ProFTPd seront gérés "
+#~ "automatiquement par debconf. ProFTPd est relativement complexe et "
+#~ "souple : ce type de gestion peut simplifier la tâche pour les débutants "
+#~ "ou pour les configurations très simples."
+
+#~ msgid ""
+#~ "If you refuse here, all aspects of ProFTPd configuration will be under "
+#~ "your responsability. If this is your first installation, I'll create a "
+#~ "very basic default configuration in /etc/proftpd.conf, else I'll try "
+#~ "create an updated configuration on the basis of your current one and some "
+#~ "known conversion issues."
+#~ msgstr ""
+#~ "Si vous refusez, l'ensemble de la configuration de ProFTPd sera de votre "
+#~ "responsabilité. S'il s'agit de votre première installation, je vais créer "
+#~ "un fichier de configuration très simplifié sous le nom /etc/proftpd.conf. "
+#~ "Si un fichier de configuration existe, je vais tenter de le convertir à "
+#~ "l'aide de méthodes de conversion connues."
--- proftpd-1.2.9.orig/debian/po/it.po
+++ proftpd-1.2.9/debian/po/it.po
@@ -0,0 +1,133 @@
+# This is the italian debconf template for proftpd.
+# Copyright (C) 2003 Francesco P.Lovergine <frankie@debian.org>
+# This file is distributed under the same license as the proftpd package.
+# Francesco P.Lovergine <frankie@debian.org>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: proftpd 1.2.6\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-11-03 14:11+0100\n"
+"PO-Revision-Date: 2003-05-06 20:35+0100\n"
+"Last-Translator: Francesco Paolo Lovergine <frankie@debian.org>\n"
+"Language-Team: Italian <debian-l10n-italian@lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: select
+#. Choices
+#: ../proftpd.templates:3
+msgid "inetd, standalone"
+msgstr "inetd, autonomo"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid "Run proftpd from inetd or standalone?"
+msgstr "Vuoi eseguire proftpd da inetd o in modo autonomo?"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"ProFTPd can be run either as a service from inetd, or as a standalone "
+"server.  Eeach choice has its own benefits.  If you have only a few ftp "
+"connections per day, it may not be worth the resources to keep proftpd "
+"running at all times."
+msgstr ""
+"ProFTPd può essere eseguito come servizio da inetd o come server autonomo. "
+"Ogni scelta ha i suoi benefici. Se hai poche connessioni ftp al giorno, "
+"potrebbe essere uno spreco di risorse mantenere proftpd in esecuzione tutto "
+"il tempo."
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"On the other hand, if your ftp site is visited frequently, inetd is not a "
+"good choice, because each time a connection is opened, a new process is "
+"spawned."
+msgstr ""
+"D'altronde, se il tuo sito ftp è visitato di frequente, inetd non è una "
+"buona scelta, perchè ogni volta che viene aperta una connessione viene "
+"caricato un nuovo processo."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid "Warning on syntax changes in ProFTPd configuration."
+msgstr ""
+"Attenzione alle variazioni di sintassi nella configurazione di ProFTPd."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+#, fuzzy
+msgid ""
+"You are upgrading from a pre-1.2.8 version. Probably you will need to revise "
+"your previous configuration to be compliant with current directives. Please, "
+"consult documentation available in proftpd-doc and change /etc/proftpd.conf "
+"as needed."
+msgstr ""
+"Stai aggiornando da una versione pre-1.2.8. Probabilmente avrai bisogno di "
+"rivedere la tua configurazione precedente per renderal compatibile con le "
+"direttive attuali. Consulta la documentazione disponibile in proftpd-doc e "
+"modifica /etc/proftpd.conf come necessario."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+#, fuzzy
+msgid ""
+"Unfortunately, it is near impossible for me to convert your setup "
+"automatically, but for some elementary issues. You will have to do  it "
+"yourself. ProFTPd could also be unable to use the resulting  configuration, "
+"and it will not restart after upgrading."
+msgstr ""
+"Sfortunatamente, è quasi impossibile per me convertire la tua configurazione "
+"automaticamente tranne per alcuni aspetti elementari. Dovrai farlo da solo "
+"ProFTPd potrebbe anche non essere in grado di utilizzare la configurazione "
+"risultante, e non ripartirà dopo l'aggiornamento."
+
+#~ msgid "Enable anonymous access?"
+#~ msgstr "Abilito l'accesso anonimo?"
+
+#~ msgid ""
+#~ "Enabling anonymous access grants access to your ftp site by any user, "
+#~ "without being a system user.  This is probably not a good idea for "
+#~ "paranoid sysadmins.  Only enable if you know what it does."
+#~ msgstr ""
+#~ "L'attivazione dell'accesso anonimo concede l'accesso al tuo sito ftp a "
+#~ "qualsiasi utente, senza essere un utente del sistema. Questa "
+#~ "probabilmente non è una buona idea per gli amministratori di sistema "
+#~ "'paranoici'. Abilitalo solo se sai cosa stai facendo. "
+
+#~ msgid "Manage ProFTPd configuration with debconf?"
+#~ msgstr "Gestisco la configurazione di ProFTPd con debconf?"
+
+#, fuzzy
+#~ msgid ""
+#~ "If you accept here, some aspect of ProFTPd will be automatically managed "
+#~ "by debconf. ProFTPd is quite complicated and flexible, so this kind of "
+#~ "management could be useful for newbies, or very simple kinds of "
+#~ "configuration."
+#~ msgstr ""
+#~ "Se accetti, alcuni aspetti di ProFTPd saranno automaticamente gestiti con "
+#~ "debconf. ProFTPd è piuttosto complesso e flessibile, per cui questo "
+#~ "genere di gestione può essere utile solo per i principianti, o tipi "
+#~ "elementari di configurazione."
+
+#, fuzzy
+#~ msgid ""
+#~ "If you refuse here, all aspects of ProFTPd configuration will be under "
+#~ "your responsability. If this is your first installation, I'll create a "
+#~ "very basic default configuration in /etc/proftpd.conf, else I'll try "
+#~ "create an updated configuration on the basis of your current one and some "
+#~ "known conversion issues."
+#~ msgstr ""
+#~ "Se rifiuti, tutti gli aspetti della configurazione di ProFTPd saranno "
+#~ "sotto la tua responsabilità. Se questa è la tua prima installazione, "
+#~ "verrà creata una configurazione di base in /etc/proftpd.conf, altrimenti "
+#~ "proverò a creare una configurazione aggiornata sulla base di quella "
+#~ "corrente e alcune note problematiche di conversione."
--- proftpd-1.2.9.orig/debian/po/ja.po
+++ proftpd-1.2.9/debian/po/ja.po
@@ -0,0 +1,133 @@
+#
+#    Translators, if you are not familiar with the PO format, gettext
+#    documentation is worth reading, especially sections dedicated to
+#    this format, e.g. by running:
+#         info -n '(gettext)PO Files'
+#         info -n '(gettext)Header Entry'
+#
+#    Some information specific to po-debconf are available at
+#            /usr/share/doc/po-debconf/README-trans
+#         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+#    Developers do not need to manually edit POT or PO files.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: proftpd 1.2.8-6\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-11-03 14:11+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Tomohiro KUBOTA <kubota@debian.org>\n"
+"Language-Team: Japanese <debian-doc@debian.or.jp>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=EUC-JP\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: select
+#. Choices
+#: ../proftpd.templates:3
+msgid "inetd, standalone"
+msgstr "inetd, ¥¹¥¿¥ó¥É¥¢¥í¡¼¥ó"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid "Run proftpd from inetd or standalone?"
+msgstr "proftpd ¤Î¼Â¹Ô¤Ï inetd ·ÐÍ³¤È¥¹¥¿¥ó¥É¥¢¥í¡¼¥ó¤Î¤É¤Á¤é¤Ë¤·¤Þ¤¹¤«"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"ProFTPd can be run either as a service from inetd, or as a standalone "
+"server.  Eeach choice has its own benefits.  If you have only a few ftp "
+"connections per day, it may not be worth the resources to keep proftpd "
+"running at all times."
+msgstr ""
+"ProFTPd ¤Ï¡¢inetd ·ÐÍ³¤Î¥µ¡¼¥Ó¥¹¤È¤·¤Æ¼Â¹Ô¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¤·¡¢ ¥¹¥¿¥ó¥É¥¢"
+"¥í¡¼¥ó¤Î¥µ¡¼¥Ð¤È¤·¤Æ¤â¼Â¹Ô¤Ç¤­¤Þ¤¹¡£¤É¤Á¤é¤Ë¤â¤½¤ì¤¾¤ì ¤ÎÍøÅÀ¤¬¤¢¤ê¤Þ¤¹¡£1Æü"
+"¤Ë¿ô²ó¤Î¥¢¥¯¥»¥¹¤·¤«¤Ê¤¤¾ì¹ç¤Ï¡¢proftpd ¤ò ¾ï»þ¼Â¹Ô¤·¤Æ¤ª¤¯¤Î¤Ï»ñ¸»¤ÎÌµÂÌ¤«¤â"
+"ÃÎ¤ì¤Þ¤»¤ó¡£"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"On the other hand, if your ftp site is visited frequently, inetd is not a "
+"good choice, because each time a connection is opened, a new process is "
+"spawned."
+msgstr ""
+"°ìÊý¡¢ÉÑÈË¤Ê¥¢¥¯¥»¥¹¤¬¤¢¤ë¾ì¹ç¤Ï¡¢inetd ¤ÏÎÉ¤¤ÁªÂò¤È¤Ï¸À¤¨¤Þ¤»¤ó¡£ ¤Ê¤¼¤Ê¤é¡¢"
+"ÀÜÂ³¤´¤È¤Ë¿·µ¬¥×¥í¥»¥¹¤¬À¸À®¤µ¤ì¤ë¤«¤é¤Ç¤¹¡£"
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid "Warning on syntax changes in ProFTPd configuration."
+msgstr "ProFTPd ÀßÄê¤ÎÊ¸Ë¡¤ÎÊÑ²½¤Ë´Ø¤¹¤ë·Ù¹ð"
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"You are upgrading from a pre-1.2.8 version. Probably you will need to revise "
+"your previous configuration to be compliant with current directives. Please, "
+"consult documentation available in proftpd-doc and change /etc/proftpd.conf "
+"as needed."
+msgstr ""
+"º£²ó¤Ï¡¢1.2.8 °ÊÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤«¤é¤Î¥¢¥Ã¥×¥°¥ì¡¼¥É¤È¤Ê¤ê¤Þ¤¹¡£¶²¤é ¤¯¸½ºß¤ÎÊ¸"
+"Ë¡¤ËÅ¬¹ç¤¹¤ë¤è¤¦¤ËÀßÄê¥Õ¥¡¥¤¥ë¤ò¸«Ä¾¤¹É¬Í×¤¬¤¢¤ê¤Þ¤¹¡£ proftpd-doc ¤ÎÊ¸½ñ¤ò»²"
+"¾È¤·¤Æ /etc/proftpd.conf ¤ò½¤Àµ¤·¤Æ²¼¤µ¤¤¡£"
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"Unfortunately, it is near impossible for me to convert your setup "
+"automatically, but for some elementary issues. You will have to do  it "
+"yourself. ProFTPd could also be unable to use the resulting  configuration, "
+"and it will not restart after upgrading."
+msgstr ""
+"ÉÔ¹¬¤Ë¤â¡¢ÀßÄê¥Õ¥¡¥¤¥ë¤ò¼«Æ°Åª¤ËÊÑ´¹¤¹¤ë¤³¤È¤Ï¡¢¿ô¸Ä¤Î´ðËÜÅª¤ÊÀßÄê °Ê³°¤Ï¤Û¤È"
+"¤ó¤ÉÉÔ²ÄÇ½¤Ç¤¹¡£¤´¼«Ê¬¤ÇÊÑ´¹¤¹¤ëÉ¬Í×¤¬¤¢¤ê¤Þ¤¹¡£¼«Æ°ÊÑ´¹ ¸å¤ÎÀßÄê¤ò»È¤¦¤³¤È¤Ï"
+"¶²¤é¤¯¤Ç¤­¤Þ¤»¤ó¤Î¤Ç¡¢¥¢¥Ã¥×¥°¥ì¡¼¥É¸å¤Ë ProFTPd ¤òºÆµ¯Æ°¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤»"
+"¤ó¡£"
+
+#~ msgid "Enable anonymous access?"
+#~ msgstr "Æ¿Ì¾ (anonymous) ¥¢¥¯¥»¥¹¤òµö²Ä¤·¤Þ¤¹¤«?"
+
+#~ msgid ""
+#~ "Enabling anonymous access grants access to your ftp site by any user, "
+#~ "without being a system user.  This is probably not a good idea for "
+#~ "paranoid sysadmins.  Only enable if you know what it does."
+#~ msgstr ""
+#~ "Æ¿Ì¾ (anonymous) ¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë¤È¡¢¤½¤Î¥·¥¹¥Æ¥à¤Î¥æ¡¼¥¶¤Ç¤Ê¤¤ Ç¤°Õ¤Î"
+#~ "¥æ¡¼¥¶¤¬¤¢¤Ê¤¿¤Î ftp ¥µ¥¤¥È¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ ¿À·Ð¼Á¤Ê´ÉÍý¼Ô"
+#~ "¤Ë¤È¤Ã¤ÆÎÉ¤¤ÁªÂò¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤´¼«Ê¬¤Ç²¿¤ò¤ä¤Ã¤Æ ¤¤¤ë¤«Íý²ò¤·¤Æ¤¤¤ë¾ì¹ç"
+#~ "¤Î¤ß¡¢µö²Ä¤·¤Æ¤¯¤À¤µ¤¤¡£"
+
+#~ msgid "Manage ProFTPd configuration with debconf?"
+#~ msgstr "ProFTPd ¤ÎÀßÄê¤ò debconf ¤Ç´ÉÍý¤·¤Þ¤¹¤«?"
+
+#~ msgid ""
+#~ "If you accept here, some aspect of ProFTPd will be automatically managed "
+#~ "by debconf. ProFTPd is quite complicated and flexible, so this kind of "
+#~ "management could be useful for newbies, or very simple kinds of "
+#~ "configuration."
+#~ msgstr ""
+#~ "¤³¤³¤Ç¡Ö¤Ï¤¤¡×¤ÈÅú¤¨¤ë¤È¡¢ProFTPd ¤ÎÀßÄê¤Î°ìÉô¤Ï debconf ¤Ë¤è¤Ã¤Æ ¼«Æ°Åª¤Ë"
+#~ "´ÉÍý¤µ¤ì¤Þ¤¹¡£ProFTPd ¤Ï¶Ë¤á¤ÆÊ£»¨¤Ç½ÀÆð¤Ê¤Î¤Ç¡¢¤³¤Î¤è¤¦ ¤Ê´ÉÍý¤Ï½é¿´¼Ô¤Ë"
+#~ "¤È¤Ã¤Æ¡¢¤Þ¤¿¤Ï¤´¤¯Ã±½ã¤ÊÀßÄê¤ò¤·¤¿¤¤¾ì¹ç¤Ë¤Ï¡¢ÊØ Íø¤«¤âÃÎ¤ì¤Þ¤»¤ó¡£"
+
+#~ msgid ""
+#~ "If you refuse here, all aspects of ProFTPd configuration will be under "
+#~ "your responsability. If this is your first installation, I'll create a "
+#~ "very basic default configuration in /etc/proftpd.conf, else I'll try "
+#~ "create an updated configuration on the basis of your current one and some "
+#~ "known conversion issues."
+#~ msgstr ""
+#~ "¤³¤³¤Ç¡Ö¤¤¤¤¤¨¡×¤ÈÅú¤¨¤ë¤È¡¢ProFTPd ¤ÎÀßÄê¤Ï¤¹¤Ù¤Æ¤´¼«Ê¬¤Ç¹Ô¤¦É¬Í× ¤¬¤¢¤ê"
+#~ "¤Þ¤¹¡£º£²ó½é¤á¤Æ ProFTPd ¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¤Î¤Ç¤·¤¿¤é¡¢Èó¾ï ¤Ë´ðËÜÅª¤Ê¥Ç"
+#~ "¥Õ¥©¥ë¥È¤ÎÀßÄê¤¬ /etc/proftpd.conf ¤Ë¹Ô¤ï¤ì¤Þ¤¹¡£¤½¤¦ ¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¸½ºß"
+#~ "¤ÎÀßÄê¤¬¥¢¥Ã¥×¥Ç¡¼¥È¤µ¤ì¤Þ¤¹¤¬¡¢ÊÑ´¹¤ÎºÝ¤Ë´ûÃÎ ¤ÎÌäÂê¤¬¤¤¤¯¤Ä¤«¤¢¤ê¤Þ¤¹¡£"
--- proftpd-1.2.9.orig/debian/po/nl.po
+++ proftpd-1.2.9/debian/po/nl.po
@@ -0,0 +1,134 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#    Translators, please read /usr/share/doc/po-debconf/README-trans
+#         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-11-03 14:11+0100\n"
+"PO-Revision-Date: 2003-08-08 16:07+0100\n"
+"Last-Translator: Bart Cornelis <cobaco@linux.be>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: select
+#. Choices
+#: ../proftpd.templates:3
+msgid "inetd, standalone"
+msgstr "inetd, losstaand"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid "Run proftpd from inetd or standalone?"
+msgstr "ProFTPd losstaand, of vanuit inetd opstarten?"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"ProFTPd can be run either as a service from inetd, or as a standalone "
+"server.  Eeach choice has its own benefits.  If you have only a few ftp "
+"connections per day, it may not be worth the resources to keep proftpd "
+"running at all times."
+msgstr ""
+"ProFTPd kan als een losstaande server, of als een dienst via inetd gedraait "
+"worden. Elke keuze heeft z'n eigen voordeel. Als u relatief weinig ftp "
+"verbindingen binnenkrijgt is hetwaarschijnlijk niet aan te raden om proftpd "
+"altijd draaiende te houden."
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"On the other hand, if your ftp site is visited frequently, inetd is not a "
+"good choice, because each time a connection is opened, a new process is "
+"spawned."
+msgstr ""
+"Daar staat tegenover dat inetd niet zo'n goede keuze is wanneer uw ftp side "
+"druk-bezocht wordt. Inetd start namelijk bij iedere verbinding een nieuw "
+"proces."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid "Warning on syntax changes in ProFTPd configuration."
+msgstr ""
+"Waarschuwing betreffende syntax veranderingen in de ProFTPd configuratie."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"You are upgrading from a pre-1.2.8 version. Probably you will need to revise "
+"your previous configuration to be compliant with current directives. Please, "
+"consult documentation available in proftpd-doc and change /etc/proftpd.conf "
+"as needed."
+msgstr ""
+"U voert een actualizatie uit van een pre-1.2.8 versie. U zult waarschijnlijk "
+"uw bestaande configuratie moeten aanpassen om te voldoen aan de huidige "
+"richtlijnen. Gelieve de documentatie beschikbaar in proftpd-doc te "
+"consulteren en de noodzakelijke aanpassingen in /etc/proftpd.conf door te "
+"voeren."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"Unfortunately, it is near impossible for me to convert your setup "
+"automatically, but for some elementary issues. You will have to do  it "
+"yourself. ProFTPd could also be unable to use the resulting  configuration, "
+"and it will not restart after upgrading."
+msgstr ""
+"Het is voor mij helaas bijna onmogelijk om uw instelling automatisch om te "
+"schakelen. Ik zal dit proberen, maar afgezien van eenvoudige opzetten, zult "
+"u zelf nog aanpassingen moeten uitvoeren. Het is mogelijk dat ProFTPd de "
+"door mij gemaakte configuratie niet kan gebruiken, waardoor deze niet zal "
+"herstarten."
+
+#~ msgid "Enable anonymous access?"
+#~ msgstr "Anonieme toegang mogelijk maken?"
+
+#~ msgid ""
+#~ "Enabling anonymous access grants access to your ftp site by any user, "
+#~ "without being a system user.  This is probably not a good idea for "
+#~ "paranoid sysadmins.  Only enable if you know what it does."
+#~ msgstr ""
+#~ "Het activeren van anonieme toegang, geeft niet-systeem gebruikers de "
+#~ "mogelijkheid om uw ftp site te bezoeken. Dit is geen goed idee voor "
+#~ "paranoïde systeembeheerders. Activeer dit enkel als u beseft wat dit "
+#~ "betekend."
+
+#~ msgid "Manage ProFTPd configuration with debconf?"
+#~ msgstr "Wilt u dat debconf de ProFTPd configuratie beheert?"
+
+#~ msgid ""
+#~ "If you accept here, some aspect of ProFTPd will be automatically managed "
+#~ "by debconf. ProFTPd is quite complicated and flexible, so this kind of "
+#~ "management could be useful for newbies, or very simple kinds of "
+#~ "configuration."
+#~ msgstr ""
+#~ "Indien u dit aanvaard zullen sommige aspecten van ProFTPd automatisch "
+#~ "door debconf beheerd worden. Voor beginners en eenvoudige opzetten is "
+#~ "dit, omdat ProFTPd vrij ingewikkeld en flexibel is, aan te raden."
+
+#~ msgid ""
+#~ "If you refuse here, all aspects of ProFTPd configuration will be under "
+#~ "your responsability. If this is your first installation, I'll create a "
+#~ "very basic default configuration in /etc/proftpd.conf, else I'll try "
+#~ "create an updated configuration on the basis of your current one and some "
+#~ "known conversion issues."
+#~ msgstr ""
+#~ "Als u hier Nee zegt, dan zult u alle aspecten van de ProFTPd configuratie "
+#~ "persoonlijk moeten beheren. Indien dit uw eerste installatie is zal ik "
+#~ "een eenvoudige standaard versievan het configuratie bestand /etc/proftpd."
+#~ "conf aanmaken, zoniet probeer ik om een geactualizeerde configuratie op "
+#~ "te stellen op basis van uw huidige configuratie en bekende "
+#~ "omschakelknelpunten."
--- proftpd-1.2.9.orig/debian/po/pt_BR.po
+++ proftpd-1.2.9/debian/po/pt_BR.po
@@ -0,0 +1,155 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#    Translators, please read /usr/share/doc/po-debconf/README-trans
+#         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-11-03 14:11+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: select
+#. Choices
+#: ../proftpd.templates:3
+msgid "inetd, standalone"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid "Run proftpd from inetd or standalone?"
+msgstr "Executar o proftpd em modo inetd ou standalone?"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+#, fuzzy
+msgid ""
+"ProFTPd can be run either as a service from inetd, or as a standalone "
+"server.  Eeach choice has its own benefits.  If you have only a few ftp "
+"connections per day, it may not be worth the resources to keep proftpd "
+"running at all times."
+msgstr ""
+"O Proftpd pode ser executado como um serviço do inetd ou como um servidor "
+"standalone.  Cada escolha tem seus próprios benefícios.  Se voce recebe "
+"poucas conexões ftp por dia, pode não ser compensativo em termos de consumo "
+"de recursos manter o proftpd rodando o tempo todo."
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"On the other hand, if your ftp site is visited frequently, inetd is not a "
+"good choice, because each time a connection is opened, a new process is "
+"spawned."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid "Warning on syntax changes in ProFTPd configuration."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"You are upgrading from a pre-1.2.8 version. Probably you will need to revise "
+"your previous configuration to be compliant with current directives. Please, "
+"consult documentation available in proftpd-doc and change /etc/proftpd.conf "
+"as needed."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+#, fuzzy
+msgid ""
+"Unfortunately, it is near impossible for me to convert your setup "
+"automatically, but for some elementary issues. You will have to do  it "
+"yourself. ProFTPd could also be unable to use the resulting  configuration, "
+"and it will not restart after upgrading."
+msgstr ""
+"Infelizmente, é quase impossível converter sua configuração antiga "
+"automaticamente.  Voce terá que fazer isso manualmente."
+
+#~ msgid "Enable anonymous access?"
+#~ msgstr "Habilitar acesso anônimo?"
+
+#~ msgid ""
+#~ "Enabling anonymous access grants access to your ftp site by any user, "
+#~ "without being a system user.  This is probably not a good idea for "
+#~ "paranoid sysadmins.  Only enable if you know what it does."
+#~ msgstr ""
+#~ "Habilitar acesso anônimo garante que qualquer usuário, mesmo não sendo "
+#~ "usuário do sistema, acesse seu site ftp. Essa provavelmente não é uma boa "
+#~ "para administradores de sistemas paranóicos. Somente habilite essa opção "
+#~ "se voce realmente sabe o que isso pode acarretar."
+
+#~ msgid "Using SQL with ProFTPd."
+#~ msgstr "Usando SQL com ProFTPd."
+
+#~ msgid ""
+#~ "I found some old sql directives in /etc/proftpd.conf.  This release of "
+#~ "proftpd doesn't know many of the old sql-related configuration options.  "
+#~ "Many new ones were introduced, and old ones aren't recognized."
+#~ msgstr ""
+#~ "Algumas diretrizes SQL antigas foram encontradas em /etc/proftpd.conf. "
+#~ "Essa versão do proftpd não reconhece muitas das opções de configuração "
+#~ "antigas relacionadas à SQL. Muitas novas diretrizes foram incluídas e "
+#~ "antigas opções não são reconhecidas."
+
+#~ msgid ""
+#~ "Luckily, it is well documented.  Therefore I refer you to the "
+#~ "documentation in /usr/share/doc/proftpd/README.mod_sql.  I will not start "
+#~ "proftpd; do that yourself when you edited the configuration."
+#~ msgstr ""
+#~ "Porém, este processo é bem documentado.  Entretanto é aconselhado a "
+#~ "leitura da documentação presente em /usr/share/doc/proftpd/README."
+#~ "mod_sql. O proftpd não será iniciado; faça isso manualmente depois de "
+#~ "editar as configurações."
+
+#, fuzzy
+#~ msgid "Edit configuration file ${file}?"
+#~ msgstr " Editar arquivo de configuração /etc/proftpd.conf ?"
+
+#, fuzzy
+#~ msgid ""
+#~ "You did not install any debconf-enabled versions of the proftpd yet. This "
+#~ "means that I shall ask you some questions about the way to start proftpd "
+#~ "and anonymous access."
+#~ msgstr ""
+#~ "Nenhuma versão anterior do pacote proftpd com suporte debconf foi "
+#~ "instalada em seu sistema. Isso significa que eu devo lhe fazer algumas "
+#~ "perguntas sobre a maneira de iniciar o proftpd e sobre acesso anônimo."
+
+#, fuzzy
+#~ msgid ""
+#~ "However, since you had proftpd installed before, I need to know if it is "
+#~ "ok for me to edit ${file} to actually make those changes.  Only answer "
+#~ "yes if you did not change much.  You will have a chance to review the "
+#~ "changes later on."
+#~ msgstr ""
+#~ "Porém, uma vez que você possuía o proftpd instalado anteriormente, é "
+#~ "preciso saber se você permite que o arquivo /etc/proftpd.conf seja "
+#~ "editado para relizar algumas mudanças. Somente responda sim se você não "
+#~ "muda muito sua configuração."
+
+#, fuzzy
+#~ msgid ""
+#~ "If you answer `no' here, I will not ask questions that may require me to "
+#~ "edit the file."
+#~ msgstr ""
+#~ "Caso você responda `não' aqui, questões que requeiram a edição desse "
+#~ "arquivo não serão perguntadas."
--- proftpd-1.2.9.orig/debian/po/ru.po
+++ proftpd-1.2.9/debian/po/ru.po
@@ -0,0 +1,163 @@
+# translation of proftpd_1.2.8-14.po to russian
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#    Translators, please read /usr/share/doc/po-debconf/README-trans
+#         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: proftpd_1.2.8-14\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-11-03 14:11+0100\n"
+"PO-Revision-Date: 2003-10-05 00:04+0600\n"
+"Last-Translator: Ilgiz Kalmetev <translator@ilgiz.pp.ru>\n"
+"Language-Team: russian <debian-russian@lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=KOI8-R\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.0.1\n"
+
+#. Type: select
+#. Choices
+#: ../proftpd.templates:3
+msgid "inetd, standalone"
+msgstr "ÞÅÒÅÚ inetd, ÓÁÍÏÓÔÏÑÔÅÌØÎÏ"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid "Run proftpd from inetd or standalone?"
+msgstr "úÁÐÕÓËÁÔØ proftpd ÓÁÍÏÓÔÏÑÔÅÌØÎÏ ÉÌÉ ÞÅÒÅÚ inetd?"
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"ProFTPd can be run either as a service from inetd, or as a standalone "
+"server.  Eeach choice has its own benefits.  If you have only a few ftp "
+"connections per day, it may not be worth the resources to keep proftpd "
+"running at all times."
+msgstr ""
+"ProFTPd ÍÏÖÅÔ ÂÙÔØ ÚÁÐÕÝÅÎ ÌÉÂÏ ËÁË ÓÅÒ×ÉÓ ÞÅÒÅÚ inetd, ÌÉÂÏ ËÁË "
+"ÓÁÍÏÓÔÏÑÔÅÌØÎÙÊ ÓÅÒ×ÅÒ. ëÁÖÄÙÊ ÉÚ ÓÐÏÓÏÂÏ× ÉÍÅÅÔ Ó×ÏÉ ÐÒÅÉÍÕÝÅÓÔ×Á. åÓÌÉ Ó "
+"×ÁÛÉÍ ftp ÓÅÒ×ÅÒÏÍ ÚÁ ÄÅÎØ ÐÒÏÉÓÈÏÄÉÔ ÌÉÛØ ÎÅÓËÏÌØËÏ ÓÅÁÎÓÏ× Ó×ÑÚÉ, ÔÏ ÎÅÔ "
+"ÐÒÉÞÉÎÙ ÚÁÇÒÕÖÁÔØ ÒÅÓÕÒÓÙ ÐÏÓÔÏÑÎÎÏ ÒÁÂÏÔÁÀÝÉÍ proftpd."
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"On the other hand, if your ftp site is visited frequently, inetd is not a "
+"good choice, because each time a connection is opened, a new process is "
+"spawned."
+msgstr ""
+"ó ÄÒÕÇÏÊ ÓÔÏÒÏÎÙ, ÅÓÌÉ ×ÁÛ ÓÁÊÔ ÞÁÓÔÏ ÐÏÓÅÝÁÅÔÓÑ, ÔÏ inetd ÎÅ ÓÌÉÛËÏÍ "
+"ÐÏÄÈÏÄÉÔ, ÐÏÓËÏÌØËÕ ÐÒÉ ËÁÖÄÏÍ ÎÏ×ÏÍ ÓÏÅÄÉÎÅÎÉÉ ÓÏÚÄÁÅÔÓÑ ÎÏ×ÙÊ ÐÒÏÃÅÓÓ."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid "Warning on syntax changes in ProFTPd configuration."
+msgstr "ðÒÅÄÕÐÒÅÖÄÅÎÉÅ: × ÓÉÎÔÁËÓÉÓÅ ÎÁÓÔÒÏÊËÉ ProFTPd ÅÓÔØ ÉÚÍÅÎÅÎÉÑ."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"You are upgrading from a pre-1.2.8 version. Probably you will need to revise "
+"your previous configuration to be compliant with current directives. Please, "
+"consult documentation available in proftpd-doc and change /etc/proftpd.conf "
+"as needed."
+msgstr ""
+"÷Ù ÏÂÎÏ×ÌÑÅÔÅ ×ÅÒÓÉÀ pre-1.2.8. ÷ÏÚÍÏÖÎÏ ÷ÁÍ ÎÕÖÎÏ ÐÒÏ×ÅÒÉÔØ ÉÍÅÀÝÉÅÓÑ "
+"ÎÁÓÔÒÏÊËÉ ÎÁ ÓÏ×ÍÅÓÔÉÍÏÓÔØ Ó ÔÅËÕÝÅÊ ×ÅÒÓÉÅÊ. îÅÏÂÈÏÄÉÍÕÀ ÄÏËÕÍÅÎÔÁÃÉÀ ÷Ù "
+"ÍÏÖÅÔÅ ÎÁÊÄÅÔÅ × ÐÁËÅÔÅ proftpd-doc É ÉÓÐÒÁ×ØÔÅ ÆÁÊÌ /etc/proftpd.conf ÔÁË, "
+"ËÁË ÷ÁÍ ÎÕÖÎÏ."
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"Unfortunately, it is near impossible for me to convert your setup "
+"automatically, but for some elementary issues. You will have to do  it "
+"yourself. ProFTPd could also be unable to use the resulting  configuration, "
+"and it will not restart after upgrading."
+msgstr ""
+"ë ÎÅÓÞÁÓÔØÀ, ÐÏÌÎÁÑ Á×ÔÏÍÁÔÉÞÅÓËÁÑ ËÏÎ×ÅÒÔÁÃÉÑ ÎÅ×ÏÚÍÏÖÎÁ, ËÒÏÍÅ ÎÅËÏÔÏÒÙÈ "
+"ÜÌÅÍÅÎÔÁÒÎÙÈ ×ÅÝÅÊ. ÷Ù ÄÏÌÖÎÙ ÓÄÅÌÁÔØ ÜÔÏ ÓÁÍÉ. ProFTPd ÎÅ ÓÍÏÖÅÔ "
+"ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÌÕÞÉ×ÛÉÅÓÑ ÎÁÓÔÒÏÊËÉ É ÎÅ ÓÍÏÖÅÔ ÐÅÒÅÚÁÐÕÓÔÉÔØÓÑ ÐÏÓÌÅ "
+"ÏÂÎÏ×ÌÅÎÉÑ."
+
+#, fuzzy
+#~ msgid "Enable anonymous access?"
+#~ msgstr "òÁÚÒÅÛÉÔØ ÁÎÏÎÉÍÎÙÊ ÄÏÓÔÕÐ?"
+
+#, fuzzy
+#~ msgid ""
+#~ "Enabling anonymous access grants access to your ftp site by any user, "
+#~ "without being a system user.  This is probably not a good idea for "
+#~ "paranoid sysadmins.  Only enable if you know what it does."
+#~ msgstr ""
+#~ "òÁÚÒÅÛÅÎÉÅ ÁÎÏÎÉÍÎÏÇÏ ÄÏÓÔÕÐÁ ÇÁÒÁÎÔÉÒÕÅÔ ÄÏÓÔÕÐ Ë ×ÁÛÅÍÕ ftp-ÓÁÊÔÕ "
+#~ "ÌÀÂÏÇÏ ÐÏÌØÚÏ×ÁÔÅÌÑ, ÄÁÖÅ ÅÓÌÉ ÏÎ ÎÅ Ñ×ÌÑÅÔÓÑ ÐÏÌØÚÏ×ÁÔÅÌÅÍ ÓÉÓÔÅÍÙ. äÌÑ "
+#~ "ÓÉÓÔÅÍÎÙÈ ÁÄÍÉÎÉÓÔÒÁÔÏÒÏ×-ÐÁÒÁÎÏÉËÏ× ÜÔÏ ×ÉÄÉÍÏ ÎÅ ÏÞÅÎØ ÈÏÒÏÛÁÑ ÉÄÅÑ. "
+#~ "òÁÚÒÅÛÁÊÔÅ ÔÁËÏÊ ÄÏÓÔÕÐ ÔÏÌØËÏ × ÔÏÍ ÓÌÕÞÁÅ, ÅÓÌÉ ×Ù ÚÎÁÅÔÅ, ÞÔÏ ÄÅÌÁÅÔÅ."
+
+#, fuzzy
+#~ msgid "Using SQL with ProFTPd."
+#~ msgstr "éÓÐÏÌØÚÏ×ÁÎÉÅ SQL Ó ProFTPd."
+
+#, fuzzy
+#~ msgid ""
+#~ "I found some old sql directives in /etc/proftpd.conf.  This release of "
+#~ "proftpd doesn't know many of the old sql-related configuration options.  "
+#~ "Many new ones were introduced, and old ones aren't recognized."
+#~ msgstr ""
+#~ "ñ ÏÂÎÁÒÕÖÉÌ ÎÅÓËÏÌØËÏ sql-ÄÉÒÅËÔÉ× × ÆÁÊÌÅ /etc/proftpd.conf. üÔÏÔ ×ÙÐÕÓË "
+#~ "proftpd ÎÅ ÚÎÁÅÔ ÍÎÏÇÉÅ ÉÚ ÏÔÎÏÓÑÝÉÈÓÑ Ë sql ÏÐÃÉÊ ÎÁÓÔÒÏÅË. âÙÌÏ ××ÅÄÅÎÏ "
+#~ "ÍÎÏÇÏ ÎÏ×ÙÈ, Á ÎÅËÏÔÏÒÙÅ ÓÔÁÒÙÅ ÏÐÃÉÉ ÂÏÌØÛÅ ÎÅ ÒÁÓÐÏÚÎÁÀÔÓÑ."
+
+#, fuzzy
+#~ msgid ""
+#~ "Luckily, it is well documented.  Therefore I refer you to the "
+#~ "documentation in /usr/share/doc/proftpd/README.mod_sql.  I will not start "
+#~ "proftpd; do that yourself when you edited the configuration."
+#~ msgstr ""
+#~ "ë ÓÞÁÓÔØÀ, ÜÔÏ ÈÏÒÏÛÏ ÄÏËÕÍÅÎÔÉÒÏ×ÁÎÏ. ðÏÜÔÏÍÕ Ñ ÏÔÓÙÌÁÀ ×ÁÓ Ë "
+#~ "ÄÏËÕÍÅÎÔÁÃÉÉ × ÆÁÊÌÅ /usr/share/doc/proftpd/README.mod_sql. ñ ÎÅ ÂÕÄÕ "
+#~ "ÚÁÐÕÓËÁÔØ proftpd; ÓÄÅÌÁÊÔÅ ÜÔÏ ÓÁÍÉ ÐÏÓÌÅ ÔÏÇÏ, ËÁË ÏÔÒÅÄÁËÔÉÒÕÅÔÅ ÆÁÊÌ "
+#~ "ÎÁÓÔÒÏÅË."
+
+#, fuzzy
+#~ msgid "Edit configuration file ${file}?"
+#~ msgstr "ðÏÐÒÁ×ÉÔØ ÎÁÓÔÒÏÅÞÎÙÊ ÆÁÊÌ /etc/proftpd.conf?"
+
+#, fuzzy
+#~ msgid ""
+#~ "You did not install any debconf-enabled versions of the proftpd yet. This "
+#~ "means that I shall ask you some questions about the way to start proftpd "
+#~ "and anonymous access."
+#~ msgstr ""
+#~ "õ ×ÁÓ ÐÏËÁ ÎÅ ÕÓÔÁÎÏ×ÌÅÎÁ ÎÉ ÏÄÎÁ ÉÓÐÏÌØÚÕÀÝÁÑ debconf ×ÅÒÓÉÑ proftpd. "
+#~ "üÔÏ ÏÚÎÁÞÁÅÔ, ÞÔÏ Ñ ÚÁÄÁÍ ×ÁÍ ÎÅÓËÏÌØËÏ ×ÏÐÒÏÓÏ× Ï ÍÅÔÏÄÅ ÚÁÐÕÓËÁ proftpd "
+#~ "É ÁÎÏÎÉÍÎÏÍ ÄÏÓÔÕÐÅ."
+
+#, fuzzy
+#~ msgid ""
+#~ "However, since you had proftpd installed before, I need to know if it is "
+#~ "ok for me to edit ${file} to actually make those changes.  Only answer "
+#~ "yes if you did not change much.  You will have a chance to review the "
+#~ "changes later on."
+#~ msgstr ""
+#~ "ïÄÎÁËÏ, ÔÁË ËÁË Õ ×ÁÓ ÕÖÅ ÂÙÌ ÕÓÔÁÎÏ×ÌÅÎ proftpd, ÐÏÚ×ÏÌÉÔÅ ÌÉ ×Ù ÍÎÅ "
+#~ "×ÎÅÓÔÉ ÐÏÌÕÞÅÎÎÙÅ Ó×ÅÄÅÎÉÑ × ÆÁÊÌ /etc/proftpd.conf. ïÔ×ÅÔØÔÅ ÄÁ ÔÏÌØËÏ × "
+#~ "ÔÏÍ ÓÌÕÞÁÅ, ÅÓÌÉ ×Ù ÎÅ ×ÎÏÓÉÌÉ ÍÎÏÇÏ ÉÚÍÅÎÅÎÉÊ."
+
+#, fuzzy
+#~ msgid ""
+#~ "If you answer `no' here, I will not ask questions that may require me to "
+#~ "edit the file."
+#~ msgstr ""
+#~ "åÓÌÉ ×Ù ÏÔ×ÅÔÉÔÅ ÚÄÅÓØ ÎÅÔ, ÔÏ Ñ ÎÅ ÂÕÄÕ ÚÁÄÁ×ÁÔØ ×ÏÐÒÏÓÙ, ÏÔ×ÅÔÙ ÎÁ "
+#~ "ËÏÔÏÒÙÅ ÍÎÅ ÎÕÖÎÏ ÂÕÄÅÔ ×ÎÏÓÉÔØ × ÆÁÊÌ."
--- proftpd-1.2.9.orig/debian/po/templates.pot
+++ proftpd-1.2.9/debian/po/templates.pot
@@ -0,0 +1,82 @@
+#
+#    Translators, if you are not familiar with the PO format, gettext
+#    documentation is worth reading, especially sections dedicated to
+#    this format, e.g. by running:
+#         info -n '(gettext)PO Files'
+#         info -n '(gettext)Header Entry'
+#
+#    Some information specific to po-debconf are available at
+#            /usr/share/doc/po-debconf/README-trans
+#         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+#    Developers do not need to manually edit POT or PO files.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-11-03 14:11+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: select
+#. Choices
+#: ../proftpd.templates:3
+msgid "inetd, standalone"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid "Run proftpd from inetd or standalone?"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"ProFTPd can be run either as a service from inetd, or as a standalone "
+"server.  Eeach choice has its own benefits.  If you have only a few ftp "
+"connections per day, it may not be worth the resources to keep proftpd "
+"running at all times."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../proftpd.templates:5
+msgid ""
+"On the other hand, if your ftp site is visited frequently, inetd is not a "
+"good choice, because each time a connection is opened, a new process is "
+"spawned."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid "Warning on syntax changes in ProFTPd configuration."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"You are upgrading from a pre-1.2.8 version. Probably you will need to revise "
+"your previous configuration to be compliant with current directives. Please, "
+"consult documentation available in proftpd-doc and change /etc/proftpd.conf "
+"as needed."
+msgstr ""
+
+#. Type: note
+#. Description
+#: ../proftpd.templates:17
+msgid ""
+"Unfortunately, it is near impossible for me to convert your setup "
+"automatically, but for some elementary issues. You will have to do  it "
+"yourself. ProFTPd could also be unable to use the resulting  configuration, "
+"and it will not restart after upgrading."
+msgstr ""
--- proftpd-1.2.9.orig/debian/scripts/CVS/Root
+++ proftpd-1.2.9/debian/scripts/CVS/Root
@@ -0,0 +1 @@
+:ext:frankie@cvs.alioth.debian.org:/cvsroot/pkg-proftpd
--- proftpd-1.2.9.orig/debian/scripts/CVS/Repository
+++ proftpd-1.2.9/debian/scripts/CVS/Repository
@@ -0,0 +1 @@
+debian/scripts
--- proftpd-1.2.9.orig/debian/scripts/CVS/Entries
+++ proftpd-1.2.9/debian/scripts/CVS/Entries
@@ -0,0 +1,4 @@
+/dbs-build.mk/1.1.1.1/Sun Sep 14 10:55:47 2003//
+/dpkg-arch.mk/1.1.1.1/Sun Sep 14 10:55:47 2003//
+/file2cat/1.1.1.1/Sun Sep 14 10:55:47 2003//
+D
--- proftpd-1.2.9.orig/debian/scripts/dbs-build.mk
+++ proftpd-1.2.9/debian/scripts/dbs-build.mk
@@ -0,0 +1,87 @@
+#!/usr/bin/make -f
+# Separate tarball/patch build system by Adam Heath <doogie@debian.org>
+# Modified by Ben Collins <bcollins@debian.org>
+
+SHELL		:= /bin/bash -e
+SOURCE_DIR	:= build-tree
+STAMP_DIR	:= stampdir
+PATCH_DIR	:= debian/patches
+
+patched		:= $(STAMP_DIR)/patch
+unpacked	:= $(STAMP_DIR)/unpack
+
+ifdef TAR_DIR
+  BUILD_TREE	:= $(SOURCE_DIR)/$(TAR_DIR)
+else
+  BUILD_TREE	:= $(SOURCE_DIR)
+endif
+
+
+setup: $(dh_mak_deps)
+	dh_testdir
+	@-up-scripts
+	$(MAKE) -f debian/rules $(unpacked) $(patched)
+
+$(patched)/: $(STAMP_DIR)/created $(unpacked)
+	test -d $(STAMP_DIR)/patches || mkdir -p $(STAMP_DIR)/patches
+	@if [ -d "$(PATCH_DIR)" ]; then \
+	  mkdir -p $(STAMP_DIR)/log/patches; \
+	  for f in `(cd $(PATCH_DIR); find -type f ! -name 'chk-*' ! -path "./CVS/*") | sort | \
+	      sed s,'\./',,g`; do \
+	    stampfile=$(STAMP_DIR)/patches/$$f; \
+	    log=$(STAMP_DIR)/log/patches/$$f; \
+	    if [ ! -e $$stampfile ]; then \
+	      echo -n "Applying patch $(PATCH_DIR)/$$f ... "; \
+	      if $(SHELL) debian/scripts/file2cat $(PATCH_DIR)/$$f | \
+		(cd $(BUILD_TREE);patch -p1 --no-backup-if-mismatch) > $$log 2>&1; then \
+		echo successful.; \
+		touch $$stampfile; \
+	      else \
+		echo "failed! (check $$log for reason)"; \
+		exit 1; \
+	      fi; \
+	    else \
+	      echo Already applied $(PATCH_DIR)/$$f.; \
+	    fi; \
+	  done; \
+	fi
+	touch $@
+
+$(unpacked): $(STAMP_DIR)/created
+	mkdir -p $(STAMP_DIR)/sources $(SOURCE_DIR) $(STAMP_DIR)/log/sources
+	@for f in `find upstream/tarballs -type f -maxdepth 1 -name \*.tgz -o -name \*.tar.gz -o \
+		-name \*.tar.bz -o -name \*.tar.bz2 | sort | sed s,'\./',,g`; do \
+	  stampfile=$(STAMP_DIR)/sources/`basename $$f`; \
+	  log=$(STAMP_DIR)/log/sources/`basename $$f`; \
+	  if [ ! -e $$stampfile ]; then \
+	    echo -n "Extracting source $$f ... "; \
+	    if $(SHELL) debian/scripts/file2cat $$f | \
+		(cd $(SOURCE_DIR); tar xv) > $$log 2>&1; then \
+	      echo successful.; \
+	      touch $$stampfile; \
+	    else \
+	      echo failed!; \
+	      exit 1; \
+	    fi; \
+	  else \
+	    echo Already unpacked $$f.; \
+	  fi; \
+	done
+	touch $@
+
+make_patch:
+	mv $(BUILD_TREE) $(BUILD_TREE).new
+	rm -rf $(STAMP_DIR)
+	$(MAKE) -f debian/rules $(unpacked) $(patched)
+ifndef TAR_DIR
+	diff -urN $(BUILD_TREE) $(BUILD_TREE).new > new.diff
+else
+	(cd $(SOURCE_DIR) && diff -urN $(TAR_DIR) $(TAR_DIR).new || true) > new.diff
+endif
+	rm -rf $(BUILD_TREE)
+	mv $(BUILD_TREE).new $(BUILD_TREE)
+	@echo; ls -l new.diff
+
+$(STAMP_DIR)/created:
+	test -d $(STAMP_DIR) || mkdir $(STAMP_DIR)
+	touch $(STAMP_DIR)/created
--- proftpd-1.2.9.orig/debian/scripts/dpkg-arch.mk
+++ proftpd-1.2.9/debian/scripts/dpkg-arch.mk
@@ -0,0 +1,7 @@
+# see dpkg-architecture(8)
+DEB_BUILD_ARCH		:= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
+DEB_BUILD_GNU_CPU	:= $(shell dpkg-architecture -qDEB_BUILD_GNU_CPU)
+DEB_BUILD_GNU_SYSTEM	:= $(shell dpkg-architecture -qDEB_BUILD_GNU_SYSTEM)
+DEB_BUILD_GNU_TYPE	:= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+DEB_HOST_GNU_SYSTEM	:= $(shell dpkg-architecture -qDEB_HOST_GNU_SYSTEM)
+DEB_HOST_GNU_TYPE	:= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
--- proftpd-1.2.9.orig/debian/scripts/file2cat
+++ proftpd-1.2.9/debian/scripts/file2cat
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+if [ "$1" = "" ]; then
+	echo "Usage: file2cat <file>"
+	exit 1
+fi
+
+case "$1" in
+	*.gz|*.Z|*.tgz)	cmd=zcat;;
+	*.bz|*.bz2)	cmd=bzcat;;
+	*.uue)		cmd="uudecode -o -";;
+	*)		cmd=cat;;
+esac
+$cmd $1
--- proftpd-1.2.9.orig/debian/.#changelog.1.7
+++ proftpd-1.2.9/debian/.#changelog.1.7
@@ -0,0 +1,1309 @@
+proftpd (1.2.9-3) unstable; urgency=low
+
+  * New patch 15.mod_quotatab_sql.c.diff. (Thanks Jerome Walters)
+    Bug found by Christian Schulte <cs@schulte.it>: delta values are signed,
+    and can be negative.
+  * Now use --debconf-ok for ucf, but needs versioning depends on ucf >= 0.30
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 26 Feb 2004 00:11:09 +0100
+
+proftpd (1.2.9-2) unstable; urgency=low
+
+  * Using basic.conf from 1.2.8 series, instead of the old one with prefixed
+    anonymous section.
+  * Added libncurses5-dev build-dep for ftptop.
+  * Policy bumped to 3.6.1 (no changes).
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon, 17 Nov 2003 13:59:24 +0100
+
+proftpd (1.2.9-1) unstable; urgency=low
+
+  * The first post-Halloween release now moving to sid. 
+    Now using upstream tarball.
+  * CVS repository enabled: tagging appropriately.
+  * Removed patch 14.manpages.diff: manpages are integrated in upstream
+    tarballs, even if not present in CVS.
+  * New patch: 14.mod_quotatab.diff: mod_quotatab 1.2.11 contributed module
+    now replaces the old 1.2.7.
+  * Removed 13.manpages.diff patch which is not due in off-cvs releases.
+  * Tries to manage upgrades from pre-1.2.9 series in a soft way:
+        - The scoreboard file format changed, so all inetd sessions need to be killed
+          and file moved before restarting the service. The file needs to be
+          moved for a standalone configuration, anyway.
+        - SocketOptions directive replaces and deprecates the following
+          directives: tcpReceiveWindow, and tcpSendWindow.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon,  3 Nov 2003 14:14:00 +0100
+
+proftpd (1.2.8+cvs20031020-1) experimental; urgency=low
+
+  * A new CVS snapshot (post 1.2.9rc3).
+  * Merged stuff from unstable branch
+  	- New russian template.
+  	- Added a versioned dependency from debianutils to proftpd-common
+   	- Removed RFCs
+        - Changed order in module loading for dependencies
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon, 20 Oct 2003 23:36:58 +0200
+
+proftpd (1.2.8+cvs20030927-1) experimental; urgency=high
+
+  * A new CVS snapshot (post 2003-9-24 exploit).
+  * Merged stuff from unstable branch (>= -9):
+         - Now using case insensitive egrep in init files
+         - Patches renumbered sequentially
+         - Removing anonymous access enabling/disabling. A well commented basic
+           configuration, to be modified by hand is much more effective and secure.
+           Also that code is completely failing if admin changed configuration on his
+           own, as generally done by everyone. So, debconf configuration is much less
+           intrusive, and it's performed anyway. User 'ftp' is also added by
+           default if not present, being a considered a 'system' one.
+
+           Added a NEWS.Debian file to explain the new policy.
+           Changed templates as consequence.
+         - International templates revised.
+         - Added strict version source dependency for proftpd-common.
+         - Use proftpd.org instead of .net in control file descriptions.
+         - Added NEWS.Debian as kept in unstable branch.
+         - Removed 05.ftpstats.diff (unuseful).
+         - Postinst revised to manage welcome.msg nicely.
+  * Bugs fixed at this time (see below):
+    (closes: #192590,#204157,#192590,#203230,#186074,#212416)
+    (closes: #145669 see http://www.castaglia.org/proftpd/patches/README.require-valid-user)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sun, 28 Sep 2003 17:52:31 +0200
+
+proftpd (1.2.8+cvs20030818-1) experimental; urgency=low
+
+  * A new CVS snapshot. IPV6 is now integrated.
+  * Removed previous patches 01.ipv6_rollback.diff and 00.ipv6.diff all IPv6
+    related.
+  * Changed patch 20.contrib.mod_ldap.c.diff to reflect modifications in
+    inet.h
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 19 Aug 2003 09:19:19 +0200
+
+proftpd (1.2.8+cvs20030805-1) experimental; urgency=low
+
+  * A new CVS snapshot. See NEWS file for a list of bugs solved.
+    All Debian patches applies but some hacks on the first one.
+  * Policy updated to 3.6.0
+  * Bugs closed at this time: #204157,#192590,#203230
+  * Added IPV6 support.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue,  5 Aug 2003 20:57:31 +0200
+
+proftpd (1.2.8+cvs20030620-1) experimental; urgency=low
+
+  * This is based on cvs tree at the date. It's not prime time ready.
+  * Removed duplicated tarball: fixes #192590
+  * Removed patches already in CVS:
+       AB.fixes_handling_of_contexts_to_use_proper_pool.diff
+       B2.mod_sql_postgres.c.diff
+       10.mod_cap.c.diff
+  * Added patches:
+       91.autoconf.diff - move configure.in to configure.ac to force use of autoconf2.50
+       B2.mod_sql_mysql.c.diff - use <mysql/mysql.h> instead of <mysql.h>
+       B3.manpages.diff - add man pages that are missing in the cvs tree
+  * Added autoconf build-dep.
+  * Policy updated to 3.5.10.
+  * Minor changes in rules file in order to build correctly.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sat, 21 Jun 2003 17:31:36 +0200
+
+proftpd (1.2.8-8) unstable; urgency=high
+
+  * Added a set +e before testing proftpd configuration.
+    Proftpd could crash in some cases when testing.
+    (closes: #197585)
+  * Added AB.fixes_handling_of_contexts_to_use_proper_pool.diff:
+    fixes handling of contexts to use properpool, by patching src/dirtree.c and src/sets.c.
+    This is from current CVS tree.
+    (closes: #197586)
+  * Security: added B2.mod_sql_postgres.c.diff:
+    See http://bugs.proftpd.org/show_bug.cgi?id=2087 for information. This
+    has been created using diff among mod_sql_postgres.c-1.16 and mod_sql_postgres.c-1.10.
+    This is from current CVS tree.
+    (closes: #197984)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 19 Jun 2003 13:50:29 +0200
+
+proftpd (1.2.8-7) unstable; urgency=high
+
+  * Added an input (</dev/tty) redirection for ucf in maint scripts.
+    (closes: #194359). This is a workaround for #193694 which is a
+    debconf/ucf interaction problem.
+  * Japanese podebconf template
+    (closes: #194646)
+  * Updated french podebconf template
+    (closes: #192406)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 27 May 2003 12:49:50 +0200
+
+proftpd (1.2.8-6) unstable; urgency=low
+
+  * Added missing HTML documentation to proftpd-doc. This also clarify misbehaving for mod_tls.
+    (closes: #150694)
+  * Added mod_rewrite, mod_radius, mod_wrap to all packages. So added
+    libwrap0-dev among build-deps.
+    (closes: #158305)
+  * Added more README files and removed a couple of obsoleted ones.
+  * debconf template and it.po revised as suggested.
+    (closes: #190821)
+  * New fr.po integrated.
+    (closes: #191227)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue,  6 May 2003 20:56:06 +0200
+
+proftpd (1.2.8-5) unstable; urgency=high
+
+  * Explicitly depends on libmysqlclient10-dev, which is the last LGPL licensed.
+    Also, current sql module is not tested with mysql4, so the conservative
+    approach is the safest one.
+  * Introduced Replaces in control/proftpd-common against old packages.
+    (closes: #188114)
+  * Policy updated.
+  * Maintainer script totally revised. Wow! Some more hints in basic.conf
+    added too. Also a new warning note is displayed when upgrading.
+    (closes: #168305, #145662, #187695, #186646, #187695)
+    Debconf IS NOT a configuration tool. Now I use it only for minimal
+    config interactions. We absolutely needed a more powerful config editor
+    for proftpd.conf, but I seriously doubt it can be really written.
+  * Introduced -q for savelog instead of stdout/stderr redirect, in
+    cron.monthly.
+    (closes: #188722)
+  * Now truly install ftpasswd.8 among proftpd-common man pages :-/
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 24 Apr 2003 12:31:26 +0200
+
+proftpd (1.2.8-4) unstable; urgency=medium
+
+  * Init file revised to use current default pidfile or PidFile directive.
+    Scoreboard file name no more has the daemon pid bundled.
+    (closes: #186312)
+  * Now postinst changes obsolete LsDefaultOptions in ListOptions directive.
+    That's needed in moving from 1.2.6 basic.conf. Added a list_options()
+    function for this.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 27 Mar 2003 11:09:00 +0100
+
+proftpd (1.2.8-3) unstable; urgency=high
+
+  * Removed dh_undocumented which is no more used.
+  * Added a new patch:
+  	10.mod_cap.c.diff - solves a double free in mod_cap which caused #185030.
+  * Re-added mod_cap thanks to previous patch. So readded libcap-dev.
+  * Patch 20.contrib.mod_ldap.c.diff revised.
+    (closes: #185125, #175581,#185567)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sat, 22 Mar 2003 11:56:53 +0100
+
+proftpd (1.2.8-2) unstable; urgency=high
+
+  * Removed mod_cap. It needs more investigation.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 18 Mar 2003 13:27:24 +0100
+
+proftpd (1.2.8-1) unstable; urgency=high
+
+  * New upstream release, merging with my experimental 1.2.7 pkg...
+    (closes: #185084)
+    This also solve a potential seriuous license bug as stated
+    in http://lists.debian.org/debian-legal/2003/debian-legal-200303/msg00287.html
+    and http://lists.debian.org/debian-legal/2003/debian-legal-200301/msg00287.html.
+  * IPv6 removed. It will be available in 1.2.9 anyway. It was also disabled in all
+    releases before 1.2.6-5, so I guess it's not a high-requested feature :)
+  * configure updated to 2.57.
+  * added config.(sub|guess) cleaning.
+  * Paul asked to become co-maintainer.
+  * Removed patches:
+  	30.libcap.change.build.dir.diff
+        32.libcap.compilation.fix.diff.uue
+        50.proftpd-1.2.6rc1-tls.2002.07.11.patch
+        AE.mod_tls.c.no.certificates.found.diff
+        91.mod_tls.diff
+        AF.ipv6.diff
+        B0.mod_ls.c.fsmatch.diff
+  * Added patches:
+  	90.man.diff
+  * Changed fr.po: now truly closes: #182889.
+  * Policy update.
+  * Added dep/build-dep from libcap2(-dev). It does not work with stable libcap.
+    (closes: #185030, hopefully #185125)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 18 Mar 2003 12:34:58 +0100
+                                                                                           
+proftpd (1.2.6-5) unstable; urgency=low
+
+  * Only restart the daemon if runlevels allow, in accordance with
+    policy section 10.3.3.2. (Closes: #166907)
+  * Revised contents of ftpstats.8 (frankie)
+  * Added ftpasswd.8 (frankie)
+  * Removed obsolete proftpd libcap building. Now uses standard one. (frankie)
+    (Closes: #168953)
+  * fr.po updated (frankie) (Closes: #182889)
+  * pt_BR.po updated (frankie) (Closes: #177226)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon,  3 Mar 2003 10:39:59 +0100
+
+proftpd (1.2.6-4) unstable; urgency=low
+
+  * debian/control: put proftpd-doc in section "doc".
+  * Now uses po-debconf templates (frankie).
+  * Added Italian template (frankie).
+  * debian/control: added frankie@debian.org as co-maintainer.
+  * debian/control: added build-depend on sharutils, as we now need
+    uudecode because of...
+  * debian/patches: two of the patches contain RCS Id tags in their
+    context, which got mangled by CVS, so they're now uuencoded, which
+    required changes to...
+  * debian/scripts/file2cat: now uudecodes files with .uue extension
+  * debian/scripts/dbs-build.mk: ignore CVS directories when applying
+    patches.
+  * debian/rules: use $$m instead of $m for loop variable.
+    (Closes: #166205)
+  * debian/patches/AC.mod_unixpw.c.ldap.fix.diff: if getpwnam/getpwuid
+    return NULL, revert to original method of getting pw entries.
+    (Closes: #165188)
+  * debian/rules: remove incorrect logic for detecting kernel version
+    which was causing linuxprivs never to be compiled in. Thanks to 
+    frankie for tracing this one. (Closes: #166215)
+
+ -- Paul Martin <pm@debian.org>  Mon, 28 Oct 2002 14:24:28 +0000
+
+proftpd (1.2.6-3) unstable; urgency=low
+
+  * debian/proftpd.config: unfortunately Ivo's patch had a bug in it.
+    Fixed this and another problematic conditional pointed out by Andrew
+    Suffield. (Closes: #164556,#164556)
+  * debian/proftpd.config: more compare-versions fixes. (Closes: #165677)
+
+ -- Paul Martin <pm@debian.org>  Mon, 21 Oct 2002 12:27:08 +0100
+
+proftpd (1.2.6-2) unstable; urgency=low
+
+  * New maintainer. (Closes: #163632)
+  * debian/proftpd.config: fix version test (Closes: #164556)
+  * debian/patches/B0.mod_ls.c.fsmatch.diff: Fixes the "virtual
+    filesystem" abstraction. Only contrib/mod_test.c would be
+    affected, if we built it.
+  * debian/rules: added undocumented.7 link to ftpasswd.8.
+    (Bug: #150101) Bug left open until proper manpage is written.
+  * debian/patches/B1.ftpasswd.cracklib.location.diff: Change the
+    default location of the cracklib dictionaries to match their
+    Debian location. (Closes: #159365)
+
+ -- Paul Martin <pm@debian.org>  Fri, 18 Oct 2002 18:12:59 +0100
+
+proftpd (1.2.6-1) unstable; urgency=low
+
+  * New upstream release.
+  * debian/patches/20.contrib.mod_ldap.c.diff: Updated.
+  * debian/patches/AF.ipv6.diff: Updated.
+  * debian/patches/AG.mod_ratio.c.3.3.diff: Removed.
+  * debian/patches/AH.mod_ldap.c.HEAD.diff: Removed.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat,  7 Sep 2002 14:49:52 +0200
+
+proftpd (1.2.5+1.2.6rc2-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/control: Change section from non-US to net.
+  * debian/copyright: Change licenses for mod_ldap.c and mod_ratio.c.
+  * Take advantage of the required new source upload to create an
+    .orig.tar.gz and a .diff.gz.
+  * debian/proftpd.postinst: Call db_stop before replace_file.
+  * debian/patches/33.mod_quota.c.exemption.fix.diff: Removed (upstream
+    has removed mod_quota.c).
+  * debian/rules: Don't include mod_quota.c in compilation.
+  * debian/patches/50proftpd-1.2.5-tls.2002.05.30.patch: Replaced by
+    50.proftpd-1.2.6rc1-tls.2002.07.11.patch.
+  * debian/patches/AB.mod_ls.c.large.files.support.diff: Removed (upstream
+    has included LFS).
+  * debian/patches/AF.ipv6.diff: Updated.
+  * debian/patches/AG.mod_ratio.c.3.3.diff: Update mod_ratio.c to version
+    3.3.
+  * debian/patches/AH.mod_ldap.c.HEAD.diff: Update mod_ldap.c to CVS HEAD.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun,  1 Sep 2002 17:06:41 +0200
+
+proftpd (1.2.5-3) unstable; urgency=low
+
+  * debian/proftpd.init:
+      - Remove bashism;
+      - signal(): remove superfluous "proftpd" in the find statement;
+        (Closes: #156878)
+      - Added new option "force-stop", which will try to kill proftpd even
+        though the config file says it is started from inetd (like
+        force-start). (Closes: #153922)
+  * debian/proftpd.config: Stop any running proftpd when the old setting
+    was to be run standalone, and the new setting to run from inetd.
+    (Closes: #144882, #151362)
+  * debian/proftpd.postrm: Remove debconf calls.
+    (Closes: #148727, #156464)
+  * debian/copyright:
+      - Include the license exception the ProFTPd team has given (long
+        ago) to allow binaries linked against OpenSSL to be distributed.
+      - Include licenses for contributed modules.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun, 18 Aug 2002 20:25:11 +0200
+
+proftpd (1.2.5-2) unstable; urgency=low
+
+  * debian/proftpd.init: Let the init script get the location of the
+    scoreboard from the config. (Closes: #150162)
+  * debian/patches/AE.mod_tls.c.no.certificates.found.diff: Don't try to
+    check certificate files on startup. (Closes: #153992, #154238)
+  * debian/patches/20.contrib.mod_ldap.diff: Fix segfault in uid-lookup in
+    proftpd-ldap. (Closes: #150525)
+  * debian/control: Changed sections from non-US/main to non-US.
+  * debian/patches/AF.ipv6.diff: IPv6 patch from Jan Rekorajski, Amand
+    TIHON and others.
+
+ -- Ivo Timmermans <ivo@debian.org>  Tue, 13 Aug 2002 23:23:54 +0200
+
+proftpd (1.2.5-1) unstable; urgency=low
+
+  * New upstream version. (Closes: #146839)
+  * Updated TLS patch.
+  * Upstream now includes ftpasswd, deleted it from 99.misc.diff.
+  * Deleted the patch to delete doc/rfc/draft-murray-auth-ftp-ssl-08.txt,
+    which has been deleted upstream.
+  * Updated AB.mod_ls.c.large.files.support.diff.
+  * Removed one "ShowSymlinks on" from basic.conf. (Closes: #148358)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 13 Jun 2002 17:16:10 +0200
+
+proftpd (1.2.4+1.2.5rc1-6) unstable; urgency=high
+
+  * One more try...
+  * /etc/proftpd.conf is no longer marked as a conffile.  Instead, we
+    verify its existence every time postinst is ran, possibly copying it
+    over from our default version in
+    /usr/share/doc/<package>/examples/proftpd.conf.  If we need to change
+    it, ucf is called to let the user merge in any changes he
+    made. (Closes: #143351)
+  * Rephrased the shared/proftpd/replace_file_install debconf question.
+    (Closes: #144715)
+  * Removed mention of obsolete proftpd-sql in package description.
+    (Closes: #144365)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun, 28 Apr 2002 10:22:42 +0200
+
+proftpd (1.2.4+1.2.5rc1-5) unstable; urgency=high
+
+  * Reworked postinst to handle configuration files better; allow the user
+    to review the changes before committing them.  Thanks to Roland Mas
+    for the help. (Closes: #143351)
+  * Stop proftpd from prerm. (Closes: #143376)
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon, 22 Apr 2002 13:50:50 +0200
+
+proftpd (1.2.4+1.2.5rc1-4) unstable; urgency=high
+
+  * Configuring proftpd-ldap, proftpd-*sql with debconf was broken, now
+    uses shared debconf templates.  This fixes a release critical bug
+    nobody reported.
+  * Properly mention that support for mysql or postgresql is included in
+    proftpd-{my,pg}sql package descriptions.
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed, 17 Apr 2002 12:07:20 +0200
+
+proftpd (1.2.4+1.2.5rc1-3) unstable; urgency=medium
+
+  * Use CFLAGS when running configure.
+  * Large file support (partially by Petr Cech, thank you).
+    (Closes: #139325)
+  * Fix typo in postinst. (Closes: #140498)
+  * Correct == to = in init script. (Closes: #140896)
+  * Apply fix for proftpd-ldap by Steve Langasek, which makes mod_unixpw
+    use getpwnam if pwdfname isn't /etc/passwd. (Closes: #141275)
+  * Fix crash of proftpd-*sql when user shell field is NULL.
+    (Closes: #140141)
+  * Updated debconf template for Brazilian Portugese. (Closes: #141690)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 11 Apr 2002 19:25:53 +0200
+
+proftpd (1.2.4+1.2.5rc1-2) unstable; urgency=low
+
+  * Changelog entry for 1.2.4-2 got lost, readded.
+  * Changed build dependency for postgresql-dev to 7.2 or higher.
+  * Added build dependency on bzip2.
+  * Patch, probably from Ignacy Gawedzki, to prevent server crash when
+    using REST+GET on unaccessible source. (Closes: #136696)
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon,  4 Mar 2002 19:37:21 +0100
+
+proftpd (1.2.4+1.2.5rc1-1) unstable; urgency=low
+
+  * New upstream version. (Closes: #125829)
+  * Switch to dbs.
+  * Updated TLS patch. (Closes: #118804)
+  * Fix ftpstats (see bugreport for details). (Closes: #133647)
+  * Updated init.d script, use /etc/defaults.  Thanks to Marc Haber for
+    the patch. (Closes: #120324, #128805)
+  * Fixed a typo in postinst which might have caused problems when
+    upgrading.
+  * Renamed the English debconf template, added French translation.
+    (Closes: #136104)
+  * Redirect stderr to /dev/null in cron.monthly. (Closes: #136309)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun,  3 Mar 2002 18:37:41 +0100
+
+proftpd (1.2.4-2) unstable; urgency=high
+
+  * Fix segfault on ls /////////// (Closes: 125829)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun, 23 Dec 2001 23:00:43 +0100
+
+proftpd (1.2.4-1) unstable; urgency=low
+
+  * New upstream release
+  * Added Russian debconf templates.
+    (Closes: #114953, #114954, #114955, #114957)
+  * Fixed small error in build script that prevented the German debconf
+    templates from being installed.
+  * Updated standards version.
+  * Make proftpd suggest proftpd-doc instead of recommend.
+    (Closes: #113673)
+  * Allow two extra digits for total number of bytes sent in the xferstat
+    script. (Closes: #107387)
+  * Link in mod_wrap. (Closes: #111454)
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon, 22 Oct 2001 01:45:19 +0200
+
+proftpd (1.2.2-1) unstable; urgency=high
+
+  * New upstream release (Closes: #109070):
+     - Doesn't use ifdef's inside a printf call.
+       (Closes: #104402, #104948)
+  * Don't log `No certificates found' message for each connection, only
+    print it on startup. (Closes: #103318)
+  * Change documentation for HideGroup. (Closes: #106548)
+  * Add new directives for proftpd-ldap: LDAPCheckAllow, LDAPCheckDeny,
+    LDAPHomedirOnDemandScript
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat, 18 Aug 2001 17:29:31 +0200
+
+proftpd (1.2.1+1.2.2rc3-3) unstable; urgency=low
+
+  * Depend on adduser. (Closes: #102944)
+  * Updated the Spanish debconf template. (Closes: #102135)
+  * Include genuser.pl and ftpasswd in the proftpd-common package.
+    (Closes: #102489)
+
+ -- Ivo Timmermans <ivo@debian.org>  Tue,  3 Jul 2001 01:01:44 +0200
+
+proftpd (1.2.1+1.2.2rc3-2) unstable; urgency=low
+
+  * Added -r to rm -f /var/run/proftpd in postrm.
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon,  2 Jul 2001 00:48:16 +0200
+
+proftpd (1.2.1+1.2.2rc3-1) unstable; urgency=low
+
+  * New upstream release.
+  * Applied the TLS patch by Peter Runestig.
+  * Included new config.sub and config.guess. (Closes: #99862)
+  * Fixed regexp in proftpd.init. (Closes: #98078)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 28 Jun 2001 11:57:49 +0200
+
+proftpd (1.2.1-9) unstable; urgency=low
+
+  * Changed sections now that postgresql is in non-US. (Closes: #97124)
+  * Kill any references to /usr/doc and /usr/man from debian/rules.
+
+ -- Ivo Timmermans <ivo@debian.org>  Fri, 11 May 2001 11:16:51 +0200
+
+proftpd (1.2.1-8) unstable; urgency=low
+
+  * Fixed the logic that determines how to handle
+    /etc/proftpd.conf. (Closes: #96593)
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed,  9 May 2001 10:57:32 +0200
+
+proftpd (1.2.1-7) unstable; urgency=low
+
+  * Check that /etc/proftpd.conf exists before calculating the md5sum
+    (doh).
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun,  6 May 2001 14:06:32 +0200
+
+proftpd (1.2.1-6) unstable; urgency=low
+
+  * Make proftpd-doc suggest proftpd-common. (Closes: #95724)
+  * Added tests to see if /etc/proftpd.conf exists. (Closes: #95650)
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed,  2 May 2001 15:09:40 +0200
+
+proftpd (1.2.1-5) unstable; urgency=low
+
+  * Include German debconf templates. (Closes: #93770, #93989)
+  * Redirect update-inetd stdout and stdin to /dev/tty.
+    (Closes: #93152)
+  * Include ftpusers(5) manual page, originally from the ftpd package.
+    (Closes: #94348)
+  * Automatically generate a proftpd.conf(5) manual page from the file
+    doc/Configuration.html; add perl-base to build dependencies.
+    (Closes: #65354)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 19 Apr 2001 03:13:02 +0200
+
+proftpd (1.2.1-4) unstable; urgency=low
+
+  * Make proftpd-common and -doc replace proftpd. (Closes: #93230)
+  * Don't edit /etc/init.d/proftpd from postinst, as this is already
+    handled correctly with a grep. (Closes: #93331)
+  * Split proftpd-sql into proftpd-mysql and proftpd-pgsql.  This is ugly,
+    but necessary. (Closes: #72347, #93150)
+  * proftpd-ldap no longer conflicts with itself.
+  * All the configure scripts use the same config.cache file.
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon,  9 Apr 2001 02:34:26 +0200
+
+proftpd (1.2.1-3) unstable; urgency=low
+
+  * `Let's split up' -- Created a separate package for SQL authentication,
+    drop mod_sql from the standard package.
+  * Created a separate package with mod_ldap for LDAP authentication
+    (untested!). (Closes: #60458)
+  * Check md5sum of /etc/proftpd.conf or ask user before asking questions
+    that mean we have to edit the file. (Closes: #90673)
+  * Needs debhelper 3.0 or later.
+  * Include Brazilian, Dutch and Spanish debconf templates.
+    (Closes: #92143, #92318)
+  * Move all debconf related stuff out of postinst into config.  This
+    makes update-inetd work correctly if it needs to ask something.
+    (Closes: #91931, #91987; addresses #90676)
+  * Also edit the ServerType directive in /etc/proftpd.conf when switching
+    to/from inetd mode. (Closes: #91931, #91987)
+  * Use /etc/pam.d/proftpd (fix typo). (Closes: #91745)
+  * Drop manual.uue from the source, delete sharutils from build depends.
+  * Remove the contents from /var/run/proftpd in postrm and postinst.
+    (Closes: #90675, #91262)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat, 24 Mar 2001 23:32:58 +0100
+
+proftpd (1.2.1-2) unstable; urgency=low
+
+  * Added postgresql-dev and sharutils to the build dependencies.
+    (Closes: #90650)
+  * Run proftpd as root from inetd.  proftpd switches to the user/group
+    that is given in the configuration file after startup anyway.
+    (Closes: #90643, #90645)
+  * Set priority to optional.
+  * In cron.monthly, test for ftpstats in the right directory
+    (/usr/sbin). (Closes: #90669)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 22 Mar 2001 18:21:46 +0100
+
+proftpd (1.2.1-1) unstable; urgency=low
+
+  * New upstream release.  (Closes: #49742, #60188, #62589, #64926,
+    Closes: #66784, #66785, #68848, #74153, #74545, #74758, #77701,
+    Closes: #76453, #78922, #80220, #81757, #82921, #83822, #85561,
+    Closes: #86175, #86855)
+  * New maintainer. (Closes: #66783, #67343, #68356, #72841, #75487,
+    Closes: #76258, #85259, #85589, #85710, #85724, #85940, #86011,
+    Closes: #86519, #87194, #90299)
+  * Send savelog output from cron.monthly to /dev/null.
+    (Closes: #72894, #88150)
+  * Applied a patch submitted by me that fixes segfaults due to using
+    a nonexistant postgres connection. (Closes: #76710)
+  * Fixed a small error. (Closes: #77701)
+  * Check for the presence of any SQL* directives in proftpd.conf on
+    upgrade, refer to README.mod_sql. (Closes: #77701)
+  * Added /etc/ftpusers file. (Closes: #79062, #87568)
+  * Changed modules/mod_pam.c to use /etc/pam.d/proftpd by default.
+  * Replace pam_unix_password by pam_unix and remove the shadow option
+    from /etc/pam.d/proftpd. (Closes: #81753)
+  * Ask whether proftpd should start from inetd or standalone.
+    (Closes: #67720)
+  * Test if ftpstats exists on the system before executing it in
+    cron.monthly. (Closes: #86773)
+  * postinst: Call cp in a separate shell to prevent ~ftp caching trouble.
+    (Closes: #44530)
+  * Made changes to contrib/mod_sql*.c to allow both mysql and postgres
+    modules to be linked in.
+  * Fixed small but obvious mistake in mod_sqlpw.c. (Closes: #76723)
+  * Apply fix from ftp://ftp.urbanrage.com/pub/c/mod_quota.c (by Dmitry
+    Alyabyev) for QuotaExempt.
+  * Added a line with PersistentPasswd to basic.conf, to please NIS and
+    LDAP users bugging about proftpd not finding their dynamic
+    users. (Closes: #62197)
+  * Set DenyFilter in basic.conf to prevent a DoS posted to bugtraq
+    (proftpd bug id 1066). (Closes: #89871)
+  * Move Umask to the <Directory> blocks.
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed,  7 Mar 2001 02:52:26 +0100
+
+proftpd (1.2.0pre10-2.1) unstable; urgency=high
+
+  * Non-Maintainer upload.
+  * Applied patch against string format buffer attack.
+  * Removed extra User/Group pair from basic.conf, server now runs as
+    user/group nobody by default.
+  * Added build dependencies on libmysqlclient-dev (instead of
+    mysql-dev), zlib1g-dev, debhelper and libpam-dev.
+  * In contrib/libcap/libcap.h: moved the capability.h include to just
+    below sys/types.h to fix horrible build errors.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat, 24 Feb 2001 02:32:02 +0100
+
+proftpd (1.2.0pre10-2) frozen unstable; urgency=high
+
+  * Use setproctitle(%s,foo) in main.c, lamagra@DIGIBEL.ORG advisory.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed,  5 Jul 2000 18:50:07 -0500
+
+proftpd (1.2.0pre10-1) unstable; urgency=low
+
+  * New upstream version (CVS), closes: #59851, #58043, #58149, #41090.
+  * Included lines in default config which make files overwritable,
+    closes: #58258.
+  * Added patch from Gerhard Poul to create xferreport in cron.daily,
+    closes: #57935.
+  * Added patch from Christian Hammers so the init.d script reliably kills
+    the daemon even in inetd mode, and without using killall, closes:
+    #48487, #45853.
+  * Added directory umask to default config, closes: #42279.
+  * Included more documentation and READMEs.
+  * Disabled mod_pgsql and statically linked to library for mod_mysql,
+    closes: #51120, #50342.
+  * Enabled new module mod_quota.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  7 Mar 2000 14:54:10 -0600
+
+proftpd (1.2.0pre9-7) unstable; urgency=low
+
+  * New upstream version (CVS), fixes TYPE L, closes: #58043.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 16 Feb 2000 16:17:00 -0600
+
+proftpd (1.2.0pre9-6) unstable; urgency=low
+
+  * Uploaded for the correct dist (unstable).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 20 Dec 1999 05:19:47 -0600
+
+proftpd (1.2.0pre9-5) unstable; urgency=low
+
+  * Included ftpstats manpage by Darren Benham (gecko), closes: #51867,
+    #39508.
+  * Changed xferstats to ftpstats in example crontab, closes: #50027.
+  * Slink version updated as of 2.1r4, closes: #33193, #36829, #34564.
+  * No longer asks debconf questions in the postinst, closes: #48353,
+    #46695.
+  * Included compile fixes from slink version, closes: #49170.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 17 Dec 1999 21:01:02 -0600
+
+proftpd (1.2.0pre9-4) stable; urgency=low
+
+  * Included compile fixes from slink version.
+  * Changed xferstats to ftpstats in example crontab, closes: #50027.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  8 Nov 1999 22:12:13 -0600
+
+proftpd (1.2.0pre9-3) stable; urgency=high
+
+  * Really really important security upload for slink.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  8 Nov 1999 19:35:58 -0600
+
+proftpd (1.2.0pre9-2) unstable; urgency=low
+
+  * New upstream version, closes: #49170 (have_sendfile on m68k).
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 30 Oct 1999 20:51:00 -0500
+
+proftpd (1.2.0pre9-1) unstable; urgency=low
+
+  * New upstream version, closes: #43842, #38203, #48274, #46407, #40085, #33206.
+  * Included patch from Madarasz Gergely so it works on 2.0 kernels again
+    (adopted upstream), closes: #47138.
+  * Database client libraries are linked dynamically, closes: #47147.
+  * Split of netbase ends inetd.conf problems, closes: #17514.
+  * Starting in standalone mode removes ftp from inetd.conf, closes: #29734.
+  * Changed PAM service class to 'ftp'.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 30 Oct 1999 20:44:31 -0500
+
+proftpd (1.2.0pre7-3) unstable; urgency=low
+
+  * New upstream version (pre8 beta).
+  * Added detection of slink (ancient non-FHS) system during build.
+  * Changed awkward name xferstats.proftpd to ftpstats.
+  * Debconfified install question.
+  * Updated SQL support.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  4 Oct 1999 13:32:59 -0500
+
+proftpd (1.2.0pre7-2) unstable; urgency=low
+
+  * Turned off debugging feature, closes: #46309.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 30 Sep 1999 09:49:00 -0500
+
+proftpd (1.2.0pre7-1) unstable; urgency=low
+
+  * New upstream version.
+  * Fixed pam configuration error, closes: #45775, #45769
+  * Split mod_sql out of mod_mysql; added mod_pgsql.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 27 Sep 1999 00:51:11 -0500
+
+proftpd (1.2.0pre6-3) unstable; urgency=low
+
+  * Updated mod_mysql module, updated CVS, added docs.
+  * Closing old bugs:
+    * Authentication (PAM) works, closes: #38229, #22894, #10360.
+    * Kills on upgrade, closes: #44531.  
+    * Restarts on upgrade, closes: #38560, #33540, #33205.
+    * But only if ServerType standalone, closes: #32950.
+    * No killall to fail, closes: #38260.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 18 Sep 1999 01:48:47 -0500
+
+proftpd (1.2.0pre6-2) unstable; urgency=high
+
+  * New upstream security update.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 16 Sep 1999 13:14:32 -0500
+
+proftpd (1.2.0pre6-1) unstable; urgency=low
+
+  * New upstream version.
+  * Separate PAM configuration file; PersistentPasswd defaults to off to
+    allow NIS and PAM auth to work.
+  * Reactivated linuxprivs module, fixed upstream.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 13 Sep 1999 02:50:19 -0500
+
+proftpd (1.2.0pre5-1) unstable; urgency=low
+
+  * New upstream version.
+  * ARM support (1.1.7r3-4 NMU, #29805), mod_mysql, and all debian patches
+    are now included upstream.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 10 Sep 1999 03:58:40 -0500
+
+proftpd (1.2.0pre4-3) unstable; urgency=low
+
+  * Updated to Standards-Version 3.0.1.1 (FHS).
+  * Purging proftpd will stop the daemon, closes: #44531.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun,  5 Sep 1999 09:50:48 -0500
+
+proftpd (1.2.0pre4-2) unstable; urgency=high
+
+  * More security fixes.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun,  5 Sep 1999 09:38:01 -0500
+
+proftpd (1.2.0pre4-1) unstable; urgency=high
+
+  * New upstream version, fixing remote root exploit.
+  * Prepared with the PAM of glibc 2.1, closes: #36742, #38562.
+  * Note: the README.Solaris2.5x is included as humor, illustrating how
+    bad non-free OSes can be, closes: #36540.
+  * Fixed segfault possibility in mysql module.
+  * Updated to Standards-Version 3.0.1.0.
+  * Conflicts with and provides ftp-server, closes: #42407.
+  * Added dependency on libpam-modules.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 30 Aug 1999 11:52:18 -0500
+
+proftpd (1.2.0pre2-7) unstable; urgency=low
+
+  * Added useful undocumented features to mod_ratio and mod_mysql.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  3 May 1999 12:23:18 -0400
+
+proftpd (1.2.0pre2-6) unstable; urgency=low
+
+  * Activated PAM support, closes: #24115, #24524.
+  * Also closes: #35292, fixed in 1.20pre2-4.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 23 Apr 1999 11:04:57 -0400
+
+proftpd (1.2.0pre2-5) unstable; urgency=low
+
+  * Changed default (undocumented) TimeoutStalled from 0 to 300.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 10 Apr 1999 17:53:29 -0400
+
+proftpd (1.2.0pre2-4) unstable; urgency=low
+
+  * Conflicts with wu-ftpd-academ, closes: #35036.
+  * The postrm no longer dies if proftpd is not currently running, closes:
+    #35292.
+  * Updated mod_ratio to 2.0beta, added experimental and utterly
+    undocumented mod_mysql 0.1.
+  * Updated to Standards-Version 2.5.0.0.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  8 Apr 1999 12:01:42 -0400
+
+proftpd (1.2.0pre2-3) unstable; urgency=low (high for glibc 2.1)
+
+  * New upstream version (1.2.0pre2)
+      * Fixes root priv problem with glibc 2.1 (mod_linuxprivs disabled),
+        closes: #34604.
+      * Fixes ls -lR again, closes: #34521, #33671, #33494
+      * Returns 550 instead of 553 when retrieving dir, closes: #29498.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 19 Mar 1999 10:29:43 -0500
+
+proftpd (1.2.0pre2-2) frozen unstable; urgency=medium
+
+  * Uploaded for frozen.  Fixes ls -alR looping bug discovered by Jim
+    Pick, closes: #33494.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  4 Mar 1999 08:11:14 -0500
+
+proftpd (1.2.0pre2-1) unstable; urgency=medium
+
+  * New upstream version, closes: #33494 (ls -alR looping bug discovered
+    by Jim Pick).
+  * Debugging turned off by default, closes: #33396.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 17 Feb 1999 12:46:15 -0500
+
+proftpd (1.2.0pre1-2) stable frozen unstable; urgency=high
+
+  * Uploaded for stable by request of Wichert Akkerman.  This fixes the
+    Palmetto bug discovered by netect.com.  Upgrade.  Now.
+  * Bug also fixed in slink and potato on Feb 4, closes: #32686, #33173.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 10 Feb 1999 09:26:18 -0500
+
+proftpd (1.2.0pre1-1) frozen unstable; urgency=medium
+
+  * Include path exploit fix (closes: #32686, important).
+  * Rehashing (-HUP) now properly discards old LogFormat logs, and
+    recreates from the conf file, closes: #28641.
+  * Fixed division by 0 in xferstats.proftp, closes: #26946.
+  * No longer complains to stderr when capababilities (a 2.2.x feature)
+    aren't supported by the kernel, closes: #27861.
+  * Includes ARM support (1.1.7r3-4 NMU), closes: #29805.
+  * Module mod_ls fixed so ncftp -R works, closes: #29520.
+  * Removing package kills proftpd, closes: #30157, #32331, #32607.
+  * No longer slow (846.68 kB/s over ethernet), closes: #29396.
+  * Tweaked regex in /etc/init.d/proftpd.
+  * Daemon is not pointlessly stopped during upgrade: #28900.
+  * Updated documentation from upstream website.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  4 Feb 1999 13:37:17 -0500
+
+proftpd (1.1.7r3-4) unstable; urgency=low
+
+  * Only queries about installing anonymous ftp once (#27873 and #25432).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 12 Oct 1998 18:24:59 -0400
+
+proftpd (1.1.7r3-3) unstable; urgency=low
+
+  * Merged fix from Alpha release by Paul Slootman (#27823).
+  * Bugs fixed prior to this release, or non-bugs: #20130, #24675, #25158,
+    #25162.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 12 Oct 1998 17:16:53 -0400
+
+proftpd (1.1.7r3-2) unstable; urgency=low
+
+  * New upstream version (CVS).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 12 Oct 1998 12:53:14 -0400
+
+proftpd (1.1.7r3-1.1) unstable; urgency=low
+
+  * non-maintainer (binary-only) upload for Alpha
+  * invoke "make install" with some modified parameters, else it tries to
+    create directories outside the source directory.
+
+ -- Paul Slootman <paul@debian.org>  Mon, 12 Oct 1998 21:07:12 +0200
+
+proftpd (1.1.7r3-1) unstable; urgency=low
+
+  * New upstream version (pristine).
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 10 Oct 1998 13:11:38 -0400
+
+proftpd (1.1.7r2-2) unstable; urgency=low
+
+  * New upstream version (CVS).
+  * Module linuxprivs is now compiled in for better security, on
+    architectures with kernel source newer than 2.1.103.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed,  7 Oct 1998 10:55:38 -0400
+
+proftpd (1.1.7r2-1) unstable; urgency=low, closes=26839
+
+  * New upstream version (pristine).
+  * Removal will not run init.d script if script doesn't exist (#26839).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  6 Oct 1998 14:17:08 -0400
+
+proftpd (1.1.7r1-1) unstable; urgency=low
+
+  * New upstream version 1.1.7pl1 (CVS).
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 23 Sep 1998 11:29:21 -0400
+
+proftpd (1.1.7pre1-1) unstable; urgency=low, closes=25168 16502 20868 26638 23485 25272
+
+  * New upstream version (CVS) includes ability to diable wtmp logging
+    (#16502) and a correct implementation of %L (#20868).
+  * Fixed xferstats conflict with hylafax-server (#26638).
+  * Removing proftpd now stops the running daemon (#25272).
+  * Bugs fixed prior to this release, by other packages, or non-bugs:
+    #25168, #23485.
+  * Updated to Standards-Version 2.4.1.4.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 12 Sep 1998 17:16:53 -0400
+
+proftpd (1.1.6r2-3) unstable; urgency=low
+
+  * Ratio support is accepted by upstream author as a "contrib" module,
+    and now fully documented.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Sep 1998 22:30:45 -0400
+
+proftpd (1.1.6r2-2) unstable; urgency=low, closes=26089 25133
+
+  * New upstream version (CVS), fixing symlink Bug (#26089) and general
+    slowness when used with 2.1.x kernels (#25133).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Sep 1998 14:54:59 -0400
+
+proftpd (1.1.6r2-1) unstable; urgency=low, closes=26167 26305 23156 17488
+
+  * New upstream version (CVS).
+  * Modified for new debhelper behavior (#26167, #26305).
+  * Closes #17488, as ls -lat is now supported.
+  * Added xferstats manpage and program wu-ftpd-academ, as modified by
+    Holger Preiss (TU Dresden) (#23156).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Sep 1998 12:29:25 -0400
+
+proftpd (1.1.6r-1.1) unstable; urgency=low
+
+  * non-maintainer upload for Alpha
+  * don't use wildcards in debian/examples, as that fails with debhelper_1.1.9
+
+ -- Paul Slootman &lt;paul@debian.org&gt;  Wed, 26 Aug 1998 22:37:29 +0200
+
+proftpd (1.1.6r-1) unstable; urgency=low
+
+  * New upstream version (CVS).
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 20 Aug 1998 10:51:04 -0400
+
+proftpd (1.1.6pre4-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  4 Aug 1998 12:25:14 -0400
+
+proftpd (1.1.6pre2-1) unstable; urgency=low
+
+  * New upstream version (fixes ident timeouts).
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 31 Jul 1998 11:51:32 -0400
+
+proftpd (1.1.6pre1-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 30 Jul 1998 14:29:27 -0400
+
+proftpd (1.1.5r-3) unstable; urgency=low
+
+  * New upstream version (1.1.5pl3).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 20 Jul 1998 23:04:08 -0400
+
+proftpd (1.1.5r-2) unstable; urgency=low
+
+  * Tweaked syslog logging: CWD command, initial connect, etc.
+  * Added HostRatio directive.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 14 Jul 1998 12:09:35 -0400
+
+proftpd (1.1.5r-1) unstable; urgency=low
+
+  * New upstream version.
+  * Removed extraneous debugging output from mod_ratio.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 14 Jul 1998 11:00:58 -0400
+
+proftpd (1.1.5pre3-2) unstable; urgency=low
+
+  * Added custom-written ratio module.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 14 Jul 1998 01:23:00 -0400
+
+proftpd (1.1.5pre3-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun, 12 Jul 1998 22:11:05 -0400
+
+proftpd (1.1.5pre1-1) unstable; urgency=low, closes=23568 17765 18589
+
+  * New upstream version.
+  * Source code uses correct FSF address (#23568).
+  * Recursive directory listings (ls -lR) now supported (#17765).
+  * No longer possible to crash/spin server with huge dirs (#18589).
+  * Probably fixes 10360, 16502, 18855, 20130, 22894, 23485, and 23875,
+    but more testing is needed.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun,  5 Jul 1998 18:24:45 -0400
+
+proftpd (1.0.3-1) unstable; urgency=low, closes=22207 22437 14447 21808
+
+  * New upstream version.
+  * ProFTPD now uses port 20 for outgoing data instead of "wierd ports"
+    (#14447).
+  * Pre-install script will not fail if init.d script is missing (#22207).
+  * Closes Bug #22437 against ncftp, incorrect handling of multiline
+    responses, actually due to proftpd's incorrect multiline response.
+  * Includes example configurations (#21808).
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 22 May 1998 17:17:20 -0400
+
+proftpd (1.0.2-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 21 May 1998 15:21:06 -0400
+
+proftpd (1.0.1-1) unstable; urgency=low
+
+  * New (somewhat unreleased) upstrem version, fixing potential segfault
+    problem.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 19 May 1998 13:48:26 -0400
+
+proftpd (1.0.0unoff1-2) unstable; urgency=low
+
+  * Real-time ratio levels are now logged for each user, at the higher
+    debugging levels (>= 3).
+  * Ratios are calculated at session start in addition to during chdir
+    commands.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun, 19 Apr 1998 20:06:01 -0400
+
+proftpd (1.0.0unoff1-1) unstable; urgency=low
+
+  * Now includes current directories in status output.
+  * The ftpwho command now shows the entire command being executed.
+  * Remoted commands logged separate from malloc debugging: most at level
+    3, STOR, RETR and CWD at level 2.
+  * Now logs the rough bandwidth of each transfer to syslog.
+  * Disabled NEED_PERSISTENT_PASSWORD so NIS works (#18144, #14916).
+  * Converted from debmake to debhelper packaging technology.
+  * Undocumented support for upload/download ratios added.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 18 Apr 1998 23:24:15 -0400
+
+proftpd (1.0.0-8) unstable; urgency=low
+
+  * Priority is now extra.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 18 Mar 1998 17:01:21 -0500
+
+proftpd (1.0.0-7) unstable; urgency=low
+
+  * Corrected spelling of proftpd in init.d message output.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 14 Mar 1998 19:47:23 -0500
+
+proftpd (1.0.0-6) unstable; urgency=low
+
+  * Included force-reload target in help text returned by init.d script,
+    and switched to the unofficial official downcase style.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri,  6 Feb 1998 23:43:19 -0500
+
+proftpd (1.0.0-5) unstable; urgency=low
+
+  * Corrected year and URL info in copyright file.
+  * Added reload and force-reload targets to init.d script.
+  * Updated to Standards-Version 2.4.0.0.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Feb 1998 15:05:51 -0500
+
+proftpd (1.0.0-4) unstable; urgency=low, closes=17489
+
+  * Applied proftpd-1.0.0-chmod.patch, fixing behavior of the SITE CHMOD
+    command when octal numbers do not begin with 0.
+  * Default config now shows symlinks as symlinks (#17489).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Feb 1998 13:14:10 -0500
+
+proftpd (1.0.0-3) unstable; urgency=low
+
+  * Built with new version of debmake to correct md5sum error.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 21 Jan 1998 13:33:39 -0500
+
+proftpd (1.0.0-2) unstable; urgency=low, closes=14234
+
+  * Setting up anonymous FTP now sets up an example welcome.msg (#14234).
+  
+ -- Johnie Ingram <johnie@debian.org>  Thu,  1 Jan 1998 14:02:50 -0500
+
+proftpd (1.0.0-1) unstable; urgency=low, closes=12753
+
+  * New upstream version, fixes MDTM and NOOP commands.
+  * Closed #12753, as install now asks to set up anonymous FTP.
+  * Init script modified for better compliance with policy 2.3.0.1 section
+    3.6.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 31 Dec 1997 23:43:20 -0500
+
+proftpd (0.99.0pl11-2) unstable; urgency=low
+
+  * Fixed bug in preinst discovered on powerpc architecture -- the preinst
+    script could fail with some versions of bash.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  9 Dec 1997 20:11:07 -0500
+
+proftpd (0.99.0pl11-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 11 Nov 1997 13:53:58 -0500
+
+proftpd (0.99.0pl10-1) unstable; urgency=low, closes=14725
+
+  * New upstream version, supporting md5 passwords (#14725).
+  * Fixed bug where proftpd would not start automatically after upgrade if
+    anonymous FTP was enabled.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 11 Nov 1997 12:36:52 -0500
+
+proftpd (0.99.0pl9-2) unstable; urgency=low
+
+  * Fixed errors in default proftpd.conf pointed out by Scott K. Ellis.
+  * Configuration script no longer asks if anonymous FTP should be
+    enabled, if anonymous FTP is enabled.
+  * Closed #10360, as proftpd now works correctly on both shadow and
+    non-shadow systems.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 29 Oct 1997 14:54:31 -0500
+
+proftpd (0.99.0pl9-1) unstable; urgency=low
+
+  * New upstream version.
+  * Features support for the SIZE command (#13963).
+  
+ -- Johnie Ingram <johnie@debian.org>  Wed, 29 Oct 1997 14:05:12 -0500
+
+proftpd (0.99.0pl8-1) unstable; urgency=low
+
+  * New upstream version.
+  * Includes support for the MDTM command used by the ftp method of dpkg
+    (#13959).
+  * Added code from Christoph Lameter to set up anonymous ftp (#13334).
+  * Removed patch to fix non-shadow support, as this feature has been
+    added to the configuration script.
+  * Added SHELL=/bin/bash to debian rules.
+  * Updated to Standards-Version 2.3.0.0 and debmake 3.4.2..
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 20 Oct 1997 16:11:05 -0400
+
+proftpd (0.99.0pl7-1) unstable; urgency=medium
+
+  * New upstream version.
+  * Fixes wtmp corruption program (#12013, #12483).
+  * Added patch to fix non-shadow support.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 24 Sep 1997 14:10:51 -0400
+
+proftpd (0.99.0pl6-5) unstable; urgency=low
+
+  * Tweaked packaging for better multi-architecture support.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun, 31 Aug 1997 00:38:31 -0400
+
+proftpd (0.99.0pl6-4) unstable; urgency=low
+
+  * Updated to Standards-Version 2.2.0.0 and debmake 3.3.11.
+  * Removed "Evil" code to auto-fetch HTML manual during package build
+    reported by James Troup (#11598).
+  * Switched to pristine upstream tar archive.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat,  9 Aug 1997 14:59:24 -0400
+
+proftpd (0.99.0pl6-3) unstable; urgency=low
+
+  * Linked against libc6 again on Intel architecture.
+  * Fixed errors in default proftpd.conf pointed out by Rob Browning.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 28 Jul 1997 04:26:05 -0400
+
+proftpd (0.99.0pl6-2) unstable; urgency=low
+
+  * Updated HTML manual, modifed build script to mirror automatically.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 10 Jul 1997 11:14:33 -0400
+
+proftpd (0.99.0pl6-1) unstable; urgency=low
+
+  * New upstream version.
+  * Added complete HTML manual and FAQ to package.
+  * Updated to Standards-Version 2.1.3.3 and debmake 3.3.4.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Jul 1997 23:46:06 -0400
+
+proftpd (0.99.0pl5-1) unstable; urgency=low
+
+  * New upstream version.
+  * No longer unnecessarily edits /etc/inetd.conf during upgrades,
+    and /etc/init.d/proftpd script now automatically detects when proftpd
+    is being run out of inetd instead (Bug #10462).
+  * Closed Bug #10373.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 11 Jun 1997 02:46:55 -0400
+
+proftpd (0.99.0pl4-3) unstable; urgency=low
+
+  * Built with libc5 (on i386 systems) in another attempt to fix Bug
+    #10373 (corruption of utmp and wtmp).
+  * Some tweaks to debian "clean" target.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat,  7 Jun 1997 11:47:45 -0400
+
+proftpd (0.99.0pl4-2) unstable; urgency=low
+
+  * Added TODO file and upstream changelog to package.
+  * Temporarily disabled wtmp logging since this corrupts the log on
+    libc5/libc6 systems (Bug #10373).
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  5 Jun 1997 20:14:17 -0400
+
+proftpd (0.99.0pl4-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  5 Jun 1997 13:28:13 -0400
+
+proftpd (0.99.0pl3-2) unstable; urgency=low
+
+  * Added patch from author to fix premature termination of the control
+    connection during MPUT commands.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Jun 1997 15:59:42 -0400
+
+proftpd (0.99.0pl3-1) unstable; urgency=low
+
+  * Initial Release.
+  * Contains two additional patches from the author to fix compilation on
+    libc6, and to log the full pathname in the xferlog.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Jun 1997 09:41:41 -0400
+
+
--- proftpd-1.2.9.orig/debian/.#changelog.1.9
+++ proftpd-1.2.9/debian/.#changelog.1.9
@@ -0,0 +1,1330 @@
+proftpd (1.2.9-5) unstable; urgency=high
+
+  * Reverted redirection of stdin and stdout for update-inetd. Also reverted
+    netbase versioning dependency. Apparently workaround in current
+    update-inetd does not work as it should.
+    (closes: #239528)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Wed, 24 Mar 2004 20:14:55 +0100
+
+proftpd (1.2.9-4) unstable; urgency=high
+
+  * Typo introduced in postrm (closes: #236963)
+  * Removed redirection workaround for update-inetd (already builtin in netbase >=4.13).
+    Changed version dependency for netbase as consequence.
+    (closes: #236595)
+  * Security problem (although conf dependent) fixed in patch 16.dirtree.c.diff. (Thanks iSteve)
+    See http://bugs.proftpd.org/show_bug.cgi?id=2267 for hint and patch.
+  * Typo in ftpstats.8 corrected (Thanks iSteve)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue,  9 Mar 2004 11:50:36 +0100
+
+proftpd (1.2.9-3) unstable; urgency=low
+
+  * New patch 15.mod_quotatab_sql.c.diff. (Thanks Jerome Walters)
+    Bug found by Christian Schulte <cs@schulte.it>: delta values are signed,
+    and can be negative.
+  * Now use --debconf-ok for ucf, but needs versioning depends on ucf >= 0.30
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 26 Feb 2004 00:11:09 +0100
+
+proftpd (1.2.9-2) unstable; urgency=low
+
+  * Using basic.conf from 1.2.8 series, instead of the old one with prefixed
+    anonymous section.
+  * Added libncurses5-dev build-dep for ftptop.
+  * Policy bumped to 3.6.1 (no changes).
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon, 17 Nov 2003 13:59:24 +0100
+
+proftpd (1.2.9-1) unstable; urgency=low
+
+  * The first post-Halloween release now moving to sid. 
+    Now using upstream tarball.
+  * CVS repository enabled: tagging appropriately.
+  * Removed patch 14.manpages.diff: manpages are integrated in upstream
+    tarballs, even if not present in CVS.
+  * New patch: 14.mod_quotatab.diff: mod_quotatab 1.2.11 contributed module
+    now replaces the old 1.2.7.
+  * Removed 13.manpages.diff patch which is not due in off-cvs releases.
+  * Tries to manage upgrades from pre-1.2.9 series in a soft way:
+        - The scoreboard file format changed, so all inetd sessions need to be killed
+          and file moved before restarting the service. The file needs to be
+          moved for a standalone configuration, anyway.
+        - SocketOptions directive replaces and deprecates the following
+          directives: tcpReceiveWindow, and tcpSendWindow.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon,  3 Nov 2003 14:14:00 +0100
+
+proftpd (1.2.8+cvs20031020-1) experimental; urgency=low
+
+  * A new CVS snapshot (post 1.2.9rc3).
+  * Merged stuff from unstable branch
+  	- New russian template.
+  	- Added a versioned dependency from debianutils to proftpd-common
+   	- Removed RFCs
+        - Changed order in module loading for dependencies
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon, 20 Oct 2003 23:36:58 +0200
+
+proftpd (1.2.8+cvs20030927-1) experimental; urgency=high
+
+  * A new CVS snapshot (post 2003-9-24 exploit).
+  * Merged stuff from unstable branch (>= -9):
+         - Now using case insensitive egrep in init files
+         - Patches renumbered sequentially
+         - Removing anonymous access enabling/disabling. A well commented basic
+           configuration, to be modified by hand is much more effective and secure.
+           Also that code is completely failing if admin changed configuration on his
+           own, as generally done by everyone. So, debconf configuration is much less
+           intrusive, and it's performed anyway. User 'ftp' is also added by
+           default if not present, being a considered a 'system' one.
+
+           Added a NEWS.Debian file to explain the new policy.
+           Changed templates as consequence.
+         - International templates revised.
+         - Added strict version source dependency for proftpd-common.
+         - Use proftpd.org instead of .net in control file descriptions.
+         - Added NEWS.Debian as kept in unstable branch.
+         - Removed 05.ftpstats.diff (unuseful).
+         - Postinst revised to manage welcome.msg nicely.
+  * Bugs fixed at this time (see below):
+    (closes: #192590,#204157,#192590,#203230,#186074,#212416)
+    (closes: #145669 see http://www.castaglia.org/proftpd/patches/README.require-valid-user)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sun, 28 Sep 2003 17:52:31 +0200
+
+proftpd (1.2.8+cvs20030818-1) experimental; urgency=low
+
+  * A new CVS snapshot. IPV6 is now integrated.
+  * Removed previous patches 01.ipv6_rollback.diff and 00.ipv6.diff all IPv6
+    related.
+  * Changed patch 20.contrib.mod_ldap.c.diff to reflect modifications in
+    inet.h
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 19 Aug 2003 09:19:19 +0200
+
+proftpd (1.2.8+cvs20030805-1) experimental; urgency=low
+
+  * A new CVS snapshot. See NEWS file for a list of bugs solved.
+    All Debian patches applies but some hacks on the first one.
+  * Policy updated to 3.6.0
+  * Bugs closed at this time: #204157,#192590,#203230
+  * Added IPV6 support.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue,  5 Aug 2003 20:57:31 +0200
+
+proftpd (1.2.8+cvs20030620-1) experimental; urgency=low
+
+  * This is based on cvs tree at the date. It's not prime time ready.
+  * Removed duplicated tarball: fixes #192590
+  * Removed patches already in CVS:
+       AB.fixes_handling_of_contexts_to_use_proper_pool.diff
+       B2.mod_sql_postgres.c.diff
+       10.mod_cap.c.diff
+  * Added patches:
+       91.autoconf.diff - move configure.in to configure.ac to force use of autoconf2.50
+       B2.mod_sql_mysql.c.diff - use <mysql/mysql.h> instead of <mysql.h>
+       B3.manpages.diff - add man pages that are missing in the cvs tree
+  * Added autoconf build-dep.
+  * Policy updated to 3.5.10.
+  * Minor changes in rules file in order to build correctly.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sat, 21 Jun 2003 17:31:36 +0200
+
+proftpd (1.2.8-8) unstable; urgency=high
+
+  * Added a set +e before testing proftpd configuration.
+    Proftpd could crash in some cases when testing.
+    (closes: #197585)
+  * Added AB.fixes_handling_of_contexts_to_use_proper_pool.diff:
+    fixes handling of contexts to use properpool, by patching src/dirtree.c and src/sets.c.
+    This is from current CVS tree.
+    (closes: #197586)
+  * Security: added B2.mod_sql_postgres.c.diff:
+    See http://bugs.proftpd.org/show_bug.cgi?id=2087 for information. This
+    has been created using diff among mod_sql_postgres.c-1.16 and mod_sql_postgres.c-1.10.
+    This is from current CVS tree.
+    (closes: #197984)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 19 Jun 2003 13:50:29 +0200
+
+proftpd (1.2.8-7) unstable; urgency=high
+
+  * Added an input (</dev/tty) redirection for ucf in maint scripts.
+    (closes: #194359). This is a workaround for #193694 which is a
+    debconf/ucf interaction problem.
+  * Japanese podebconf template
+    (closes: #194646)
+  * Updated french podebconf template
+    (closes: #192406)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 27 May 2003 12:49:50 +0200
+
+proftpd (1.2.8-6) unstable; urgency=low
+
+  * Added missing HTML documentation to proftpd-doc. This also clarify misbehaving for mod_tls.
+    (closes: #150694)
+  * Added mod_rewrite, mod_radius, mod_wrap to all packages. So added
+    libwrap0-dev among build-deps.
+    (closes: #158305)
+  * Added more README files and removed a couple of obsoleted ones.
+  * debconf template and it.po revised as suggested.
+    (closes: #190821)
+  * New fr.po integrated.
+    (closes: #191227)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue,  6 May 2003 20:56:06 +0200
+
+proftpd (1.2.8-5) unstable; urgency=high
+
+  * Explicitly depends on libmysqlclient10-dev, which is the last LGPL licensed.
+    Also, current sql module is not tested with mysql4, so the conservative
+    approach is the safest one.
+  * Introduced Replaces in control/proftpd-common against old packages.
+    (closes: #188114)
+  * Policy updated.
+  * Maintainer script totally revised. Wow! Some more hints in basic.conf
+    added too. Also a new warning note is displayed when upgrading.
+    (closes: #168305, #145662, #187695, #186646, #187695)
+    Debconf IS NOT a configuration tool. Now I use it only for minimal
+    config interactions. We absolutely needed a more powerful config editor
+    for proftpd.conf, but I seriously doubt it can be really written.
+  * Introduced -q for savelog instead of stdout/stderr redirect, in
+    cron.monthly.
+    (closes: #188722)
+  * Now truly install ftpasswd.8 among proftpd-common man pages :-/
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 24 Apr 2003 12:31:26 +0200
+
+proftpd (1.2.8-4) unstable; urgency=medium
+
+  * Init file revised to use current default pidfile or PidFile directive.
+    Scoreboard file name no more has the daemon pid bundled.
+    (closes: #186312)
+  * Now postinst changes obsolete LsDefaultOptions in ListOptions directive.
+    That's needed in moving from 1.2.6 basic.conf. Added a list_options()
+    function for this.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Thu, 27 Mar 2003 11:09:00 +0100
+
+proftpd (1.2.8-3) unstable; urgency=high
+
+  * Removed dh_undocumented which is no more used.
+  * Added a new patch:
+  	10.mod_cap.c.diff - solves a double free in mod_cap which caused #185030.
+  * Re-added mod_cap thanks to previous patch. So readded libcap-dev.
+  * Patch 20.contrib.mod_ldap.c.diff revised.
+    (closes: #185125, #175581,#185567)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Sat, 22 Mar 2003 11:56:53 +0100
+
+proftpd (1.2.8-2) unstable; urgency=high
+
+  * Removed mod_cap. It needs more investigation.
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 18 Mar 2003 13:27:24 +0100
+
+proftpd (1.2.8-1) unstable; urgency=high
+
+  * New upstream release, merging with my experimental 1.2.7 pkg...
+    (closes: #185084)
+    This also solve a potential seriuous license bug as stated
+    in http://lists.debian.org/debian-legal/2003/debian-legal-200303/msg00287.html
+    and http://lists.debian.org/debian-legal/2003/debian-legal-200301/msg00287.html.
+  * IPv6 removed. It will be available in 1.2.9 anyway. It was also disabled in all
+    releases before 1.2.6-5, so I guess it's not a high-requested feature :)
+  * configure updated to 2.57.
+  * added config.(sub|guess) cleaning.
+  * Paul asked to become co-maintainer.
+  * Removed patches:
+  	30.libcap.change.build.dir.diff
+        32.libcap.compilation.fix.diff.uue
+        50.proftpd-1.2.6rc1-tls.2002.07.11.patch
+        AE.mod_tls.c.no.certificates.found.diff
+        91.mod_tls.diff
+        AF.ipv6.diff
+        B0.mod_ls.c.fsmatch.diff
+  * Added patches:
+  	90.man.diff
+  * Changed fr.po: now truly closes: #182889.
+  * Policy update.
+  * Added dep/build-dep from libcap2(-dev). It does not work with stable libcap.
+    (closes: #185030, hopefully #185125)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Tue, 18 Mar 2003 12:34:58 +0100
+                                                                                           
+proftpd (1.2.6-5) unstable; urgency=low
+
+  * Only restart the daemon if runlevels allow, in accordance with
+    policy section 10.3.3.2. (Closes: #166907)
+  * Revised contents of ftpstats.8 (frankie)
+  * Added ftpasswd.8 (frankie)
+  * Removed obsolete proftpd libcap building. Now uses standard one. (frankie)
+    (Closes: #168953)
+  * fr.po updated (frankie) (Closes: #182889)
+  * pt_BR.po updated (frankie) (Closes: #177226)
+
+ -- Francesco Paolo Lovergine <frankie@debian.org>  Mon,  3 Mar 2003 10:39:59 +0100
+
+proftpd (1.2.6-4) unstable; urgency=low
+
+  * debian/control: put proftpd-doc in section "doc".
+  * Now uses po-debconf templates (frankie).
+  * Added Italian template (frankie).
+  * debian/control: added frankie@debian.org as co-maintainer.
+  * debian/control: added build-depend on sharutils, as we now need
+    uudecode because of...
+  * debian/patches: two of the patches contain RCS Id tags in their
+    context, which got mangled by CVS, so they're now uuencoded, which
+    required changes to...
+  * debian/scripts/file2cat: now uudecodes files with .uue extension
+  * debian/scripts/dbs-build.mk: ignore CVS directories when applying
+    patches.
+  * debian/rules: use $$m instead of $m for loop variable.
+    (Closes: #166205)
+  * debian/patches/AC.mod_unixpw.c.ldap.fix.diff: if getpwnam/getpwuid
+    return NULL, revert to original method of getting pw entries.
+    (Closes: #165188)
+  * debian/rules: remove incorrect logic for detecting kernel version
+    which was causing linuxprivs never to be compiled in. Thanks to 
+    frankie for tracing this one. (Closes: #166215)
+
+ -- Paul Martin <pm@debian.org>  Mon, 28 Oct 2002 14:24:28 +0000
+
+proftpd (1.2.6-3) unstable; urgency=low
+
+  * debian/proftpd.config: unfortunately Ivo's patch had a bug in it.
+    Fixed this and another problematic conditional pointed out by Andrew
+    Suffield. (Closes: #164556,#164556)
+  * debian/proftpd.config: more compare-versions fixes. (Closes: #165677)
+
+ -- Paul Martin <pm@debian.org>  Mon, 21 Oct 2002 12:27:08 +0100
+
+proftpd (1.2.6-2) unstable; urgency=low
+
+  * New maintainer. (Closes: #163632)
+  * debian/proftpd.config: fix version test (Closes: #164556)
+  * debian/patches/B0.mod_ls.c.fsmatch.diff: Fixes the "virtual
+    filesystem" abstraction. Only contrib/mod_test.c would be
+    affected, if we built it.
+  * debian/rules: added undocumented.7 link to ftpasswd.8.
+    (Bug: #150101) Bug left open until proper manpage is written.
+  * debian/patches/B1.ftpasswd.cracklib.location.diff: Change the
+    default location of the cracklib dictionaries to match their
+    Debian location. (Closes: #159365)
+
+ -- Paul Martin <pm@debian.org>  Fri, 18 Oct 2002 18:12:59 +0100
+
+proftpd (1.2.6-1) unstable; urgency=low
+
+  * New upstream release.
+  * debian/patches/20.contrib.mod_ldap.c.diff: Updated.
+  * debian/patches/AF.ipv6.diff: Updated.
+  * debian/patches/AG.mod_ratio.c.3.3.diff: Removed.
+  * debian/patches/AH.mod_ldap.c.HEAD.diff: Removed.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat,  7 Sep 2002 14:49:52 +0200
+
+proftpd (1.2.5+1.2.6rc2-1) unstable; urgency=low
+
+  * New upstream version.
+  * debian/control: Change section from non-US to net.
+  * debian/copyright: Change licenses for mod_ldap.c and mod_ratio.c.
+  * Take advantage of the required new source upload to create an
+    .orig.tar.gz and a .diff.gz.
+  * debian/proftpd.postinst: Call db_stop before replace_file.
+  * debian/patches/33.mod_quota.c.exemption.fix.diff: Removed (upstream
+    has removed mod_quota.c).
+  * debian/rules: Don't include mod_quota.c in compilation.
+  * debian/patches/50proftpd-1.2.5-tls.2002.05.30.patch: Replaced by
+    50.proftpd-1.2.6rc1-tls.2002.07.11.patch.
+  * debian/patches/AB.mod_ls.c.large.files.support.diff: Removed (upstream
+    has included LFS).
+  * debian/patches/AF.ipv6.diff: Updated.
+  * debian/patches/AG.mod_ratio.c.3.3.diff: Update mod_ratio.c to version
+    3.3.
+  * debian/patches/AH.mod_ldap.c.HEAD.diff: Update mod_ldap.c to CVS HEAD.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun,  1 Sep 2002 17:06:41 +0200
+
+proftpd (1.2.5-3) unstable; urgency=low
+
+  * debian/proftpd.init:
+      - Remove bashism;
+      - signal(): remove superfluous "proftpd" in the find statement;
+        (Closes: #156878)
+      - Added new option "force-stop", which will try to kill proftpd even
+        though the config file says it is started from inetd (like
+        force-start). (Closes: #153922)
+  * debian/proftpd.config: Stop any running proftpd when the old setting
+    was to be run standalone, and the new setting to run from inetd.
+    (Closes: #144882, #151362)
+  * debian/proftpd.postrm: Remove debconf calls.
+    (Closes: #148727, #156464)
+  * debian/copyright:
+      - Include the license exception the ProFTPd team has given (long
+        ago) to allow binaries linked against OpenSSL to be distributed.
+      - Include licenses for contributed modules.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun, 18 Aug 2002 20:25:11 +0200
+
+proftpd (1.2.5-2) unstable; urgency=low
+
+  * debian/proftpd.init: Let the init script get the location of the
+    scoreboard from the config. (Closes: #150162)
+  * debian/patches/AE.mod_tls.c.no.certificates.found.diff: Don't try to
+    check certificate files on startup. (Closes: #153992, #154238)
+  * debian/patches/20.contrib.mod_ldap.diff: Fix segfault in uid-lookup in
+    proftpd-ldap. (Closes: #150525)
+  * debian/control: Changed sections from non-US/main to non-US.
+  * debian/patches/AF.ipv6.diff: IPv6 patch from Jan Rekorajski, Amand
+    TIHON and others.
+
+ -- Ivo Timmermans <ivo@debian.org>  Tue, 13 Aug 2002 23:23:54 +0200
+
+proftpd (1.2.5-1) unstable; urgency=low
+
+  * New upstream version. (Closes: #146839)
+  * Updated TLS patch.
+  * Upstream now includes ftpasswd, deleted it from 99.misc.diff.
+  * Deleted the patch to delete doc/rfc/draft-murray-auth-ftp-ssl-08.txt,
+    which has been deleted upstream.
+  * Updated AB.mod_ls.c.large.files.support.diff.
+  * Removed one "ShowSymlinks on" from basic.conf. (Closes: #148358)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 13 Jun 2002 17:16:10 +0200
+
+proftpd (1.2.4+1.2.5rc1-6) unstable; urgency=high
+
+  * One more try...
+  * /etc/proftpd.conf is no longer marked as a conffile.  Instead, we
+    verify its existence every time postinst is ran, possibly copying it
+    over from our default version in
+    /usr/share/doc/<package>/examples/proftpd.conf.  If we need to change
+    it, ucf is called to let the user merge in any changes he
+    made. (Closes: #143351)
+  * Rephrased the shared/proftpd/replace_file_install debconf question.
+    (Closes: #144715)
+  * Removed mention of obsolete proftpd-sql in package description.
+    (Closes: #144365)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun, 28 Apr 2002 10:22:42 +0200
+
+proftpd (1.2.4+1.2.5rc1-5) unstable; urgency=high
+
+  * Reworked postinst to handle configuration files better; allow the user
+    to review the changes before committing them.  Thanks to Roland Mas
+    for the help. (Closes: #143351)
+  * Stop proftpd from prerm. (Closes: #143376)
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon, 22 Apr 2002 13:50:50 +0200
+
+proftpd (1.2.4+1.2.5rc1-4) unstable; urgency=high
+
+  * Configuring proftpd-ldap, proftpd-*sql with debconf was broken, now
+    uses shared debconf templates.  This fixes a release critical bug
+    nobody reported.
+  * Properly mention that support for mysql or postgresql is included in
+    proftpd-{my,pg}sql package descriptions.
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed, 17 Apr 2002 12:07:20 +0200
+
+proftpd (1.2.4+1.2.5rc1-3) unstable; urgency=medium
+
+  * Use CFLAGS when running configure.
+  * Large file support (partially by Petr Cech, thank you).
+    (Closes: #139325)
+  * Fix typo in postinst. (Closes: #140498)
+  * Correct == to = in init script. (Closes: #140896)
+  * Apply fix for proftpd-ldap by Steve Langasek, which makes mod_unixpw
+    use getpwnam if pwdfname isn't /etc/passwd. (Closes: #141275)
+  * Fix crash of proftpd-*sql when user shell field is NULL.
+    (Closes: #140141)
+  * Updated debconf template for Brazilian Portugese. (Closes: #141690)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 11 Apr 2002 19:25:53 +0200
+
+proftpd (1.2.4+1.2.5rc1-2) unstable; urgency=low
+
+  * Changelog entry for 1.2.4-2 got lost, readded.
+  * Changed build dependency for postgresql-dev to 7.2 or higher.
+  * Added build dependency on bzip2.
+  * Patch, probably from Ignacy Gawedzki, to prevent server crash when
+    using REST+GET on unaccessible source. (Closes: #136696)
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon,  4 Mar 2002 19:37:21 +0100
+
+proftpd (1.2.4+1.2.5rc1-1) unstable; urgency=low
+
+  * New upstream version. (Closes: #125829)
+  * Switch to dbs.
+  * Updated TLS patch. (Closes: #118804)
+  * Fix ftpstats (see bugreport for details). (Closes: #133647)
+  * Updated init.d script, use /etc/defaults.  Thanks to Marc Haber for
+    the patch. (Closes: #120324, #128805)
+  * Fixed a typo in postinst which might have caused problems when
+    upgrading.
+  * Renamed the English debconf template, added French translation.
+    (Closes: #136104)
+  * Redirect stderr to /dev/null in cron.monthly. (Closes: #136309)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun,  3 Mar 2002 18:37:41 +0100
+
+proftpd (1.2.4-2) unstable; urgency=high
+
+  * Fix segfault on ls /////////// (Closes: 125829)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun, 23 Dec 2001 23:00:43 +0100
+
+proftpd (1.2.4-1) unstable; urgency=low
+
+  * New upstream release
+  * Added Russian debconf templates.
+    (Closes: #114953, #114954, #114955, #114957)
+  * Fixed small error in build script that prevented the German debconf
+    templates from being installed.
+  * Updated standards version.
+  * Make proftpd suggest proftpd-doc instead of recommend.
+    (Closes: #113673)
+  * Allow two extra digits for total number of bytes sent in the xferstat
+    script. (Closes: #107387)
+  * Link in mod_wrap. (Closes: #111454)
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon, 22 Oct 2001 01:45:19 +0200
+
+proftpd (1.2.2-1) unstable; urgency=high
+
+  * New upstream release (Closes: #109070):
+     - Doesn't use ifdef's inside a printf call.
+       (Closes: #104402, #104948)
+  * Don't log `No certificates found' message for each connection, only
+    print it on startup. (Closes: #103318)
+  * Change documentation for HideGroup. (Closes: #106548)
+  * Add new directives for proftpd-ldap: LDAPCheckAllow, LDAPCheckDeny,
+    LDAPHomedirOnDemandScript
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat, 18 Aug 2001 17:29:31 +0200
+
+proftpd (1.2.1+1.2.2rc3-3) unstable; urgency=low
+
+  * Depend on adduser. (Closes: #102944)
+  * Updated the Spanish debconf template. (Closes: #102135)
+  * Include genuser.pl and ftpasswd in the proftpd-common package.
+    (Closes: #102489)
+
+ -- Ivo Timmermans <ivo@debian.org>  Tue,  3 Jul 2001 01:01:44 +0200
+
+proftpd (1.2.1+1.2.2rc3-2) unstable; urgency=low
+
+  * Added -r to rm -f /var/run/proftpd in postrm.
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon,  2 Jul 2001 00:48:16 +0200
+
+proftpd (1.2.1+1.2.2rc3-1) unstable; urgency=low
+
+  * New upstream release.
+  * Applied the TLS patch by Peter Runestig.
+  * Included new config.sub and config.guess. (Closes: #99862)
+  * Fixed regexp in proftpd.init. (Closes: #98078)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 28 Jun 2001 11:57:49 +0200
+
+proftpd (1.2.1-9) unstable; urgency=low
+
+  * Changed sections now that postgresql is in non-US. (Closes: #97124)
+  * Kill any references to /usr/doc and /usr/man from debian/rules.
+
+ -- Ivo Timmermans <ivo@debian.org>  Fri, 11 May 2001 11:16:51 +0200
+
+proftpd (1.2.1-8) unstable; urgency=low
+
+  * Fixed the logic that determines how to handle
+    /etc/proftpd.conf. (Closes: #96593)
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed,  9 May 2001 10:57:32 +0200
+
+proftpd (1.2.1-7) unstable; urgency=low
+
+  * Check that /etc/proftpd.conf exists before calculating the md5sum
+    (doh).
+
+ -- Ivo Timmermans <ivo@debian.org>  Sun,  6 May 2001 14:06:32 +0200
+
+proftpd (1.2.1-6) unstable; urgency=low
+
+  * Make proftpd-doc suggest proftpd-common. (Closes: #95724)
+  * Added tests to see if /etc/proftpd.conf exists. (Closes: #95650)
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed,  2 May 2001 15:09:40 +0200
+
+proftpd (1.2.1-5) unstable; urgency=low
+
+  * Include German debconf templates. (Closes: #93770, #93989)
+  * Redirect update-inetd stdout and stdin to /dev/tty.
+    (Closes: #93152)
+  * Include ftpusers(5) manual page, originally from the ftpd package.
+    (Closes: #94348)
+  * Automatically generate a proftpd.conf(5) manual page from the file
+    doc/Configuration.html; add perl-base to build dependencies.
+    (Closes: #65354)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 19 Apr 2001 03:13:02 +0200
+
+proftpd (1.2.1-4) unstable; urgency=low
+
+  * Make proftpd-common and -doc replace proftpd. (Closes: #93230)
+  * Don't edit /etc/init.d/proftpd from postinst, as this is already
+    handled correctly with a grep. (Closes: #93331)
+  * Split proftpd-sql into proftpd-mysql and proftpd-pgsql.  This is ugly,
+    but necessary. (Closes: #72347, #93150)
+  * proftpd-ldap no longer conflicts with itself.
+  * All the configure scripts use the same config.cache file.
+
+ -- Ivo Timmermans <ivo@debian.org>  Mon,  9 Apr 2001 02:34:26 +0200
+
+proftpd (1.2.1-3) unstable; urgency=low
+
+  * `Let's split up' -- Created a separate package for SQL authentication,
+    drop mod_sql from the standard package.
+  * Created a separate package with mod_ldap for LDAP authentication
+    (untested!). (Closes: #60458)
+  * Check md5sum of /etc/proftpd.conf or ask user before asking questions
+    that mean we have to edit the file. (Closes: #90673)
+  * Needs debhelper 3.0 or later.
+  * Include Brazilian, Dutch and Spanish debconf templates.
+    (Closes: #92143, #92318)
+  * Move all debconf related stuff out of postinst into config.  This
+    makes update-inetd work correctly if it needs to ask something.
+    (Closes: #91931, #91987; addresses #90676)
+  * Also edit the ServerType directive in /etc/proftpd.conf when switching
+    to/from inetd mode. (Closes: #91931, #91987)
+  * Use /etc/pam.d/proftpd (fix typo). (Closes: #91745)
+  * Drop manual.uue from the source, delete sharutils from build depends.
+  * Remove the contents from /var/run/proftpd in postrm and postinst.
+    (Closes: #90675, #91262)
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat, 24 Mar 2001 23:32:58 +0100
+
+proftpd (1.2.1-2) unstable; urgency=low
+
+  * Added postgresql-dev and sharutils to the build dependencies.
+    (Closes: #90650)
+  * Run proftpd as root from inetd.  proftpd switches to the user/group
+    that is given in the configuration file after startup anyway.
+    (Closes: #90643, #90645)
+  * Set priority to optional.
+  * In cron.monthly, test for ftpstats in the right directory
+    (/usr/sbin). (Closes: #90669)
+
+ -- Ivo Timmermans <ivo@debian.org>  Thu, 22 Mar 2001 18:21:46 +0100
+
+proftpd (1.2.1-1) unstable; urgency=low
+
+  * New upstream release.  (Closes: #49742, #60188, #62589, #64926,
+    Closes: #66784, #66785, #68848, #74153, #74545, #74758, #77701,
+    Closes: #76453, #78922, #80220, #81757, #82921, #83822, #85561,
+    Closes: #86175, #86855)
+  * New maintainer. (Closes: #66783, #67343, #68356, #72841, #75487,
+    Closes: #76258, #85259, #85589, #85710, #85724, #85940, #86011,
+    Closes: #86519, #87194, #90299)
+  * Send savelog output from cron.monthly to /dev/null.
+    (Closes: #72894, #88150)
+  * Applied a patch submitted by me that fixes segfaults due to using
+    a nonexistant postgres connection. (Closes: #76710)
+  * Fixed a small error. (Closes: #77701)
+  * Check for the presence of any SQL* directives in proftpd.conf on
+    upgrade, refer to README.mod_sql. (Closes: #77701)
+  * Added /etc/ftpusers file. (Closes: #79062, #87568)
+  * Changed modules/mod_pam.c to use /etc/pam.d/proftpd by default.
+  * Replace pam_unix_password by pam_unix and remove the shadow option
+    from /etc/pam.d/proftpd. (Closes: #81753)
+  * Ask whether proftpd should start from inetd or standalone.
+    (Closes: #67720)
+  * Test if ftpstats exists on the system before executing it in
+    cron.monthly. (Closes: #86773)
+  * postinst: Call cp in a separate shell to prevent ~ftp caching trouble.
+    (Closes: #44530)
+  * Made changes to contrib/mod_sql*.c to allow both mysql and postgres
+    modules to be linked in.
+  * Fixed small but obvious mistake in mod_sqlpw.c. (Closes: #76723)
+  * Apply fix from ftp://ftp.urbanrage.com/pub/c/mod_quota.c (by Dmitry
+    Alyabyev) for QuotaExempt.
+  * Added a line with PersistentPasswd to basic.conf, to please NIS and
+    LDAP users bugging about proftpd not finding their dynamic
+    users. (Closes: #62197)
+  * Set DenyFilter in basic.conf to prevent a DoS posted to bugtraq
+    (proftpd bug id 1066). (Closes: #89871)
+  * Move Umask to the <Directory> blocks.
+
+ -- Ivo Timmermans <ivo@debian.org>  Wed,  7 Mar 2001 02:52:26 +0100
+
+proftpd (1.2.0pre10-2.1) unstable; urgency=high
+
+  * Non-Maintainer upload.
+  * Applied patch against string format buffer attack.
+  * Removed extra User/Group pair from basic.conf, server now runs as
+    user/group nobody by default.
+  * Added build dependencies on libmysqlclient-dev (instead of
+    mysql-dev), zlib1g-dev, debhelper and libpam-dev.
+  * In contrib/libcap/libcap.h: moved the capability.h include to just
+    below sys/types.h to fix horrible build errors.
+
+ -- Ivo Timmermans <ivo@debian.org>  Sat, 24 Feb 2001 02:32:02 +0100
+
+proftpd (1.2.0pre10-2) frozen unstable; urgency=high
+
+  * Use setproctitle(%s,foo) in main.c, lamagra@DIGIBEL.ORG advisory.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed,  5 Jul 2000 18:50:07 -0500
+
+proftpd (1.2.0pre10-1) unstable; urgency=low
+
+  * New upstream version (CVS), closes: #59851, #58043, #58149, #41090.
+  * Included lines in default config which make files overwritable,
+    closes: #58258.
+  * Added patch from Gerhard Poul to create xferreport in cron.daily,
+    closes: #57935.
+  * Added patch from Christian Hammers so the init.d script reliably kills
+    the daemon even in inetd mode, and without using killall, closes:
+    #48487, #45853.
+  * Added directory umask to default config, closes: #42279.
+  * Included more documentation and READMEs.
+  * Disabled mod_pgsql and statically linked to library for mod_mysql,
+    closes: #51120, #50342.
+  * Enabled new module mod_quota.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  7 Mar 2000 14:54:10 -0600
+
+proftpd (1.2.0pre9-7) unstable; urgency=low
+
+  * New upstream version (CVS), fixes TYPE L, closes: #58043.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 16 Feb 2000 16:17:00 -0600
+
+proftpd (1.2.0pre9-6) unstable; urgency=low
+
+  * Uploaded for the correct dist (unstable).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 20 Dec 1999 05:19:47 -0600
+
+proftpd (1.2.0pre9-5) unstable; urgency=low
+
+  * Included ftpstats manpage by Darren Benham (gecko), closes: #51867,
+    #39508.
+  * Changed xferstats to ftpstats in example crontab, closes: #50027.
+  * Slink version updated as of 2.1r4, closes: #33193, #36829, #34564.
+  * No longer asks debconf questions in the postinst, closes: #48353,
+    #46695.
+  * Included compile fixes from slink version, closes: #49170.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 17 Dec 1999 21:01:02 -0600
+
+proftpd (1.2.0pre9-4) stable; urgency=low
+
+  * Included compile fixes from slink version.
+  * Changed xferstats to ftpstats in example crontab, closes: #50027.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  8 Nov 1999 22:12:13 -0600
+
+proftpd (1.2.0pre9-3) stable; urgency=high
+
+  * Really really important security upload for slink.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  8 Nov 1999 19:35:58 -0600
+
+proftpd (1.2.0pre9-2) unstable; urgency=low
+
+  * New upstream version, closes: #49170 (have_sendfile on m68k).
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 30 Oct 1999 20:51:00 -0500
+
+proftpd (1.2.0pre9-1) unstable; urgency=low
+
+  * New upstream version, closes: #43842, #38203, #48274, #46407, #40085, #33206.
+  * Included patch from Madarasz Gergely so it works on 2.0 kernels again
+    (adopted upstream), closes: #47138.
+  * Database client libraries are linked dynamically, closes: #47147.
+  * Split of netbase ends inetd.conf problems, closes: #17514.
+  * Starting in standalone mode removes ftp from inetd.conf, closes: #29734.
+  * Changed PAM service class to 'ftp'.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 30 Oct 1999 20:44:31 -0500
+
+proftpd (1.2.0pre7-3) unstable; urgency=low
+
+  * New upstream version (pre8 beta).
+  * Added detection of slink (ancient non-FHS) system during build.
+  * Changed awkward name xferstats.proftpd to ftpstats.
+  * Debconfified install question.
+  * Updated SQL support.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  4 Oct 1999 13:32:59 -0500
+
+proftpd (1.2.0pre7-2) unstable; urgency=low
+
+  * Turned off debugging feature, closes: #46309.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 30 Sep 1999 09:49:00 -0500
+
+proftpd (1.2.0pre7-1) unstable; urgency=low
+
+  * New upstream version.
+  * Fixed pam configuration error, closes: #45775, #45769
+  * Split mod_sql out of mod_mysql; added mod_pgsql.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 27 Sep 1999 00:51:11 -0500
+
+proftpd (1.2.0pre6-3) unstable; urgency=low
+
+  * Updated mod_mysql module, updated CVS, added docs.
+  * Closing old bugs:
+    * Authentication (PAM) works, closes: #38229, #22894, #10360.
+    * Kills on upgrade, closes: #44531.  
+    * Restarts on upgrade, closes: #38560, #33540, #33205.
+    * But only if ServerType standalone, closes: #32950.
+    * No killall to fail, closes: #38260.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 18 Sep 1999 01:48:47 -0500
+
+proftpd (1.2.0pre6-2) unstable; urgency=high
+
+  * New upstream security update.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 16 Sep 1999 13:14:32 -0500
+
+proftpd (1.2.0pre6-1) unstable; urgency=low
+
+  * New upstream version.
+  * Separate PAM configuration file; PersistentPasswd defaults to off to
+    allow NIS and PAM auth to work.
+  * Reactivated linuxprivs module, fixed upstream.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 13 Sep 1999 02:50:19 -0500
+
+proftpd (1.2.0pre5-1) unstable; urgency=low
+
+  * New upstream version.
+  * ARM support (1.1.7r3-4 NMU, #29805), mod_mysql, and all debian patches
+    are now included upstream.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 10 Sep 1999 03:58:40 -0500
+
+proftpd (1.2.0pre4-3) unstable; urgency=low
+
+  * Updated to Standards-Version 3.0.1.1 (FHS).
+  * Purging proftpd will stop the daemon, closes: #44531.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun,  5 Sep 1999 09:50:48 -0500
+
+proftpd (1.2.0pre4-2) unstable; urgency=high
+
+  * More security fixes.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun,  5 Sep 1999 09:38:01 -0500
+
+proftpd (1.2.0pre4-1) unstable; urgency=high
+
+  * New upstream version, fixing remote root exploit.
+  * Prepared with the PAM of glibc 2.1, closes: #36742, #38562.
+  * Note: the README.Solaris2.5x is included as humor, illustrating how
+    bad non-free OSes can be, closes: #36540.
+  * Fixed segfault possibility in mysql module.
+  * Updated to Standards-Version 3.0.1.0.
+  * Conflicts with and provides ftp-server, closes: #42407.
+  * Added dependency on libpam-modules.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 30 Aug 1999 11:52:18 -0500
+
+proftpd (1.2.0pre2-7) unstable; urgency=low
+
+  * Added useful undocumented features to mod_ratio and mod_mysql.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon,  3 May 1999 12:23:18 -0400
+
+proftpd (1.2.0pre2-6) unstable; urgency=low
+
+  * Activated PAM support, closes: #24115, #24524.
+  * Also closes: #35292, fixed in 1.20pre2-4.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 23 Apr 1999 11:04:57 -0400
+
+proftpd (1.2.0pre2-5) unstable; urgency=low
+
+  * Changed default (undocumented) TimeoutStalled from 0 to 300.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 10 Apr 1999 17:53:29 -0400
+
+proftpd (1.2.0pre2-4) unstable; urgency=low
+
+  * Conflicts with wu-ftpd-academ, closes: #35036.
+  * The postrm no longer dies if proftpd is not currently running, closes:
+    #35292.
+  * Updated mod_ratio to 2.0beta, added experimental and utterly
+    undocumented mod_mysql 0.1.
+  * Updated to Standards-Version 2.5.0.0.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  8 Apr 1999 12:01:42 -0400
+
+proftpd (1.2.0pre2-3) unstable; urgency=low (high for glibc 2.1)
+
+  * New upstream version (1.2.0pre2)
+      * Fixes root priv problem with glibc 2.1 (mod_linuxprivs disabled),
+        closes: #34604.
+      * Fixes ls -lR again, closes: #34521, #33671, #33494
+      * Returns 550 instead of 553 when retrieving dir, closes: #29498.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 19 Mar 1999 10:29:43 -0500
+
+proftpd (1.2.0pre2-2) frozen unstable; urgency=medium
+
+  * Uploaded for frozen.  Fixes ls -alR looping bug discovered by Jim
+    Pick, closes: #33494.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  4 Mar 1999 08:11:14 -0500
+
+proftpd (1.2.0pre2-1) unstable; urgency=medium
+
+  * New upstream version, closes: #33494 (ls -alR looping bug discovered
+    by Jim Pick).
+  * Debugging turned off by default, closes: #33396.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 17 Feb 1999 12:46:15 -0500
+
+proftpd (1.2.0pre1-2) stable frozen unstable; urgency=high
+
+  * Uploaded for stable by request of Wichert Akkerman.  This fixes the
+    Palmetto bug discovered by netect.com.  Upgrade.  Now.
+  * Bug also fixed in slink and potato on Feb 4, closes: #32686, #33173.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 10 Feb 1999 09:26:18 -0500
+
+proftpd (1.2.0pre1-1) frozen unstable; urgency=medium
+
+  * Include path exploit fix (closes: #32686, important).
+  * Rehashing (-HUP) now properly discards old LogFormat logs, and
+    recreates from the conf file, closes: #28641.
+  * Fixed division by 0 in xferstats.proftp, closes: #26946.
+  * No longer complains to stderr when capababilities (a 2.2.x feature)
+    aren't supported by the kernel, closes: #27861.
+  * Includes ARM support (1.1.7r3-4 NMU), closes: #29805.
+  * Module mod_ls fixed so ncftp -R works, closes: #29520.
+  * Removing package kills proftpd, closes: #30157, #32331, #32607.
+  * No longer slow (846.68 kB/s over ethernet), closes: #29396.
+  * Tweaked regex in /etc/init.d/proftpd.
+  * Daemon is not pointlessly stopped during upgrade: #28900.
+  * Updated documentation from upstream website.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  4 Feb 1999 13:37:17 -0500
+
+proftpd (1.1.7r3-4) unstable; urgency=low
+
+  * Only queries about installing anonymous ftp once (#27873 and #25432).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 12 Oct 1998 18:24:59 -0400
+
+proftpd (1.1.7r3-3) unstable; urgency=low
+
+  * Merged fix from Alpha release by Paul Slootman (#27823).
+  * Bugs fixed prior to this release, or non-bugs: #20130, #24675, #25158,
+    #25162.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 12 Oct 1998 17:16:53 -0400
+
+proftpd (1.1.7r3-2) unstable; urgency=low
+
+  * New upstream version (CVS).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 12 Oct 1998 12:53:14 -0400
+
+proftpd (1.1.7r3-1.1) unstable; urgency=low
+
+  * non-maintainer (binary-only) upload for Alpha
+  * invoke "make install" with some modified parameters, else it tries to
+    create directories outside the source directory.
+
+ -- Paul Slootman <paul@debian.org>  Mon, 12 Oct 1998 21:07:12 +0200
+
+proftpd (1.1.7r3-1) unstable; urgency=low
+
+  * New upstream version (pristine).
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 10 Oct 1998 13:11:38 -0400
+
+proftpd (1.1.7r2-2) unstable; urgency=low
+
+  * New upstream version (CVS).
+  * Module linuxprivs is now compiled in for better security, on
+    architectures with kernel source newer than 2.1.103.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed,  7 Oct 1998 10:55:38 -0400
+
+proftpd (1.1.7r2-1) unstable; urgency=low, closes=26839
+
+  * New upstream version (pristine).
+  * Removal will not run init.d script if script doesn't exist (#26839).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  6 Oct 1998 14:17:08 -0400
+
+proftpd (1.1.7r1-1) unstable; urgency=low
+
+  * New upstream version 1.1.7pl1 (CVS).
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 23 Sep 1998 11:29:21 -0400
+
+proftpd (1.1.7pre1-1) unstable; urgency=low, closes=25168 16502 20868 26638 23485 25272
+
+  * New upstream version (CVS) includes ability to diable wtmp logging
+    (#16502) and a correct implementation of %L (#20868).
+  * Fixed xferstats conflict with hylafax-server (#26638).
+  * Removing proftpd now stops the running daemon (#25272).
+  * Bugs fixed prior to this release, by other packages, or non-bugs:
+    #25168, #23485.
+  * Updated to Standards-Version 2.4.1.4.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 12 Sep 1998 17:16:53 -0400
+
+proftpd (1.1.6r2-3) unstable; urgency=low
+
+  * Ratio support is accepted by upstream author as a "contrib" module,
+    and now fully documented.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Sep 1998 22:30:45 -0400
+
+proftpd (1.1.6r2-2) unstable; urgency=low, closes=26089 25133
+
+  * New upstream version (CVS), fixing symlink Bug (#26089) and general
+    slowness when used with 2.1.x kernels (#25133).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Sep 1998 14:54:59 -0400
+
+proftpd (1.1.6r2-1) unstable; urgency=low, closes=26167 26305 23156 17488
+
+  * New upstream version (CVS).
+  * Modified for new debhelper behavior (#26167, #26305).
+  * Closes #17488, as ls -lat is now supported.
+  * Added xferstats manpage and program wu-ftpd-academ, as modified by
+    Holger Preiss (TU Dresden) (#23156).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Sep 1998 12:29:25 -0400
+
+proftpd (1.1.6r-1.1) unstable; urgency=low
+
+  * non-maintainer upload for Alpha
+  * don't use wildcards in debian/examples, as that fails with debhelper_1.1.9
+
+ -- Paul Slootman &lt;paul@debian.org&gt;  Wed, 26 Aug 1998 22:37:29 +0200
+
+proftpd (1.1.6r-1) unstable; urgency=low
+
+  * New upstream version (CVS).
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 20 Aug 1998 10:51:04 -0400
+
+proftpd (1.1.6pre4-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  4 Aug 1998 12:25:14 -0400
+
+proftpd (1.1.6pre2-1) unstable; urgency=low
+
+  * New upstream version (fixes ident timeouts).
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 31 Jul 1998 11:51:32 -0400
+
+proftpd (1.1.6pre1-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 30 Jul 1998 14:29:27 -0400
+
+proftpd (1.1.5r-3) unstable; urgency=low
+
+  * New upstream version (1.1.5pl3).
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 20 Jul 1998 23:04:08 -0400
+
+proftpd (1.1.5r-2) unstable; urgency=low
+
+  * Tweaked syslog logging: CWD command, initial connect, etc.
+  * Added HostRatio directive.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 14 Jul 1998 12:09:35 -0400
+
+proftpd (1.1.5r-1) unstable; urgency=low
+
+  * New upstream version.
+  * Removed extraneous debugging output from mod_ratio.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 14 Jul 1998 11:00:58 -0400
+
+proftpd (1.1.5pre3-2) unstable; urgency=low
+
+  * Added custom-written ratio module.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 14 Jul 1998 01:23:00 -0400
+
+proftpd (1.1.5pre3-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun, 12 Jul 1998 22:11:05 -0400
+
+proftpd (1.1.5pre1-1) unstable; urgency=low, closes=23568 17765 18589
+
+  * New upstream version.
+  * Source code uses correct FSF address (#23568).
+  * Recursive directory listings (ls -lR) now supported (#17765).
+  * No longer possible to crash/spin server with huge dirs (#18589).
+  * Probably fixes 10360, 16502, 18855, 20130, 22894, 23485, and 23875,
+    but more testing is needed.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun,  5 Jul 1998 18:24:45 -0400
+
+proftpd (1.0.3-1) unstable; urgency=low, closes=22207 22437 14447 21808
+
+  * New upstream version.
+  * ProFTPD now uses port 20 for outgoing data instead of "wierd ports"
+    (#14447).
+  * Pre-install script will not fail if init.d script is missing (#22207).
+  * Closes Bug #22437 against ncftp, incorrect handling of multiline
+    responses, actually due to proftpd's incorrect multiline response.
+  * Includes example configurations (#21808).
+
+ -- Johnie Ingram <johnie@debian.org>  Fri, 22 May 1998 17:17:20 -0400
+
+proftpd (1.0.2-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 21 May 1998 15:21:06 -0400
+
+proftpd (1.0.1-1) unstable; urgency=low
+
+  * New (somewhat unreleased) upstrem version, fixing potential segfault
+    problem.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 19 May 1998 13:48:26 -0400
+
+proftpd (1.0.0unoff1-2) unstable; urgency=low
+
+  * Real-time ratio levels are now logged for each user, at the higher
+    debugging levels (>= 3).
+  * Ratios are calculated at session start in addition to during chdir
+    commands.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun, 19 Apr 1998 20:06:01 -0400
+
+proftpd (1.0.0unoff1-1) unstable; urgency=low
+
+  * Now includes current directories in status output.
+  * The ftpwho command now shows the entire command being executed.
+  * Remoted commands logged separate from malloc debugging: most at level
+    3, STOR, RETR and CWD at level 2.
+  * Now logs the rough bandwidth of each transfer to syslog.
+  * Disabled NEED_PERSISTENT_PASSWORD so NIS works (#18144, #14916).
+  * Converted from debmake to debhelper packaging technology.
+  * Undocumented support for upload/download ratios added.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 18 Apr 1998 23:24:15 -0400
+
+proftpd (1.0.0-8) unstable; urgency=low
+
+  * Priority is now extra.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 18 Mar 1998 17:01:21 -0500
+
+proftpd (1.0.0-7) unstable; urgency=low
+
+  * Corrected spelling of proftpd in init.d message output.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat, 14 Mar 1998 19:47:23 -0500
+
+proftpd (1.0.0-6) unstable; urgency=low
+
+  * Included force-reload target in help text returned by init.d script,
+    and switched to the unofficial official downcase style.
+
+ -- Johnie Ingram <johnie@debian.org>  Fri,  6 Feb 1998 23:43:19 -0500
+
+proftpd (1.0.0-5) unstable; urgency=low
+
+  * Corrected year and URL info in copyright file.
+  * Added reload and force-reload targets to init.d script.
+  * Updated to Standards-Version 2.4.0.0.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Feb 1998 15:05:51 -0500
+
+proftpd (1.0.0-4) unstable; urgency=low, closes=17489
+
+  * Applied proftpd-1.0.0-chmod.patch, fixing behavior of the SITE CHMOD
+    command when octal numbers do not begin with 0.
+  * Default config now shows symlinks as symlinks (#17489).
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Feb 1998 13:14:10 -0500
+
+proftpd (1.0.0-3) unstable; urgency=low
+
+  * Built with new version of debmake to correct md5sum error.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 21 Jan 1998 13:33:39 -0500
+
+proftpd (1.0.0-2) unstable; urgency=low, closes=14234
+
+  * Setting up anonymous FTP now sets up an example welcome.msg (#14234).
+  
+ -- Johnie Ingram <johnie@debian.org>  Thu,  1 Jan 1998 14:02:50 -0500
+
+proftpd (1.0.0-1) unstable; urgency=low, closes=12753
+
+  * New upstream version, fixes MDTM and NOOP commands.
+  * Closed #12753, as install now asks to set up anonymous FTP.
+  * Init script modified for better compliance with policy 2.3.0.1 section
+    3.6.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 31 Dec 1997 23:43:20 -0500
+
+proftpd (0.99.0pl11-2) unstable; urgency=low
+
+  * Fixed bug in preinst discovered on powerpc architecture -- the preinst
+    script could fail with some versions of bash.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  9 Dec 1997 20:11:07 -0500
+
+proftpd (0.99.0pl11-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 11 Nov 1997 13:53:58 -0500
+
+proftpd (0.99.0pl10-1) unstable; urgency=low, closes=14725
+
+  * New upstream version, supporting md5 passwords (#14725).
+  * Fixed bug where proftpd would not start automatically after upgrade if
+    anonymous FTP was enabled.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue, 11 Nov 1997 12:36:52 -0500
+
+proftpd (0.99.0pl9-2) unstable; urgency=low
+
+  * Fixed errors in default proftpd.conf pointed out by Scott K. Ellis.
+  * Configuration script no longer asks if anonymous FTP should be
+    enabled, if anonymous FTP is enabled.
+  * Closed #10360, as proftpd now works correctly on both shadow and
+    non-shadow systems.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 29 Oct 1997 14:54:31 -0500
+
+proftpd (0.99.0pl9-1) unstable; urgency=low
+
+  * New upstream version.
+  * Features support for the SIZE command (#13963).
+  
+ -- Johnie Ingram <johnie@debian.org>  Wed, 29 Oct 1997 14:05:12 -0500
+
+proftpd (0.99.0pl8-1) unstable; urgency=low
+
+  * New upstream version.
+  * Includes support for the MDTM command used by the ftp method of dpkg
+    (#13959).
+  * Added code from Christoph Lameter to set up anonymous ftp (#13334).
+  * Removed patch to fix non-shadow support, as this feature has been
+    added to the configuration script.
+  * Added SHELL=/bin/bash to debian rules.
+  * Updated to Standards-Version 2.3.0.0 and debmake 3.4.2..
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 20 Oct 1997 16:11:05 -0400
+
+proftpd (0.99.0pl7-1) unstable; urgency=medium
+
+  * New upstream version.
+  * Fixes wtmp corruption program (#12013, #12483).
+  * Added patch to fix non-shadow support.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 24 Sep 1997 14:10:51 -0400
+
+proftpd (0.99.0pl6-5) unstable; urgency=low
+
+  * Tweaked packaging for better multi-architecture support.
+
+ -- Johnie Ingram <johnie@debian.org>  Sun, 31 Aug 1997 00:38:31 -0400
+
+proftpd (0.99.0pl6-4) unstable; urgency=low
+
+  * Updated to Standards-Version 2.2.0.0 and debmake 3.3.11.
+  * Removed "Evil" code to auto-fetch HTML manual during package build
+    reported by James Troup (#11598).
+  * Switched to pristine upstream tar archive.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat,  9 Aug 1997 14:59:24 -0400
+
+proftpd (0.99.0pl6-3) unstable; urgency=low
+
+  * Linked against libc6 again on Intel architecture.
+  * Fixed errors in default proftpd.conf pointed out by Rob Browning.
+
+ -- Johnie Ingram <johnie@debian.org>  Mon, 28 Jul 1997 04:26:05 -0400
+
+proftpd (0.99.0pl6-2) unstable; urgency=low
+
+  * Updated HTML manual, modifed build script to mirror automatically.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu, 10 Jul 1997 11:14:33 -0400
+
+proftpd (0.99.0pl6-1) unstable; urgency=low
+
+  * New upstream version.
+  * Added complete HTML manual and FAQ to package.
+  * Updated to Standards-Version 2.1.3.3 and debmake 3.3.4.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  8 Jul 1997 23:46:06 -0400
+
+proftpd (0.99.0pl5-1) unstable; urgency=low
+
+  * New upstream version.
+  * No longer unnecessarily edits /etc/inetd.conf during upgrades,
+    and /etc/init.d/proftpd script now automatically detects when proftpd
+    is being run out of inetd instead (Bug #10462).
+  * Closed Bug #10373.
+
+ -- Johnie Ingram <johnie@debian.org>  Wed, 11 Jun 1997 02:46:55 -0400
+
+proftpd (0.99.0pl4-3) unstable; urgency=low
+
+  * Built with libc5 (on i386 systems) in another attempt to fix Bug
+    #10373 (corruption of utmp and wtmp).
+  * Some tweaks to debian "clean" target.
+
+ -- Johnie Ingram <johnie@debian.org>  Sat,  7 Jun 1997 11:47:45 -0400
+
+proftpd (0.99.0pl4-2) unstable; urgency=low
+
+  * Added TODO file and upstream changelog to package.
+  * Temporarily disabled wtmp logging since this corrupts the log on
+    libc5/libc6 systems (Bug #10373).
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  5 Jun 1997 20:14:17 -0400
+
+proftpd (0.99.0pl4-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Johnie Ingram <johnie@debian.org>  Thu,  5 Jun 1997 13:28:13 -0400
+
+proftpd (0.99.0pl3-2) unstable; urgency=low
+
+  * Added patch from author to fix premature termination of the control
+    connection during MPUT commands.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Jun 1997 15:59:42 -0400
+
+proftpd (0.99.0pl3-1) unstable; urgency=low
+
+  * Initial Release.
+  * Contains two additional patches from the author to fix compilation on
+    libc6, and to log the full pathname in the xferlog.
+
+ -- Johnie Ingram <johnie@debian.org>  Tue,  3 Jun 1997 09:41:41 -0400
+
+
--- proftpd-1.2.9.orig/debian/.#control.1.4
+++ proftpd-1.2.9/debian/.#control.1.4
@@ -0,0 +1,131 @@
+Source: proftpd
+Section: net
+Priority: optional
+Maintainer: Francesco Paolo Lovergine <frankie@debian.org>
+Uploaders: Paul Martin <pm@debian.org>
+Standards-Version: 3.6.1
+Build-Depends: libmysqlclient10-dev, libpam-dev, debhelper (>=4.1.16), zlib1g-dev, postgresql-dev (>= 7.2), libldap2-dev, perl-base, libssl-dev, libwrap0-dev, patch, bzip2, sharutils, libcap-dev, libwrap0-dev, autoconf, libncurses5-dev
+
+Package: proftpd
+Architecture: any
+Depends: netbase (>= 2.0), ${shlibs:Depends}, debconf (>= 0.5.00), proftpd-common (= ${Source-Version}), adduser, ucf (>= 0.30)
+Conflicts: wu-ftpd, wu-ftpd-academ, ftp-server, proftpd-mysql, proftpd-pgsql, proftpd-ldap
+Provides: ftp-server
+Suggests: proftpd-doc
+Description: Versatile, virtual-hosting FTP daemon
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package contains only the basic functionality of proftpd and PAM
+ authentication.  If you need SQL, use proftpd-mysql or proftpd-pgsql
+ and if you need LDAP, use proftpd-ldap.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-common
+Architecture: any
+Depends: netbase (>= 2.0), ${perl:Depends}, ${shlibs:Depends}, debconf (>= 0.5.00), proftpd|proftpd-mysql|proftpd-pgsql|proftpd-ldap, debianutils (>= 1.21.0)
+Suggests: proftpd-doc
+Replaces: proftpd (<< 1.2.8-1), proftpd-mysql (<< 1.2.8-1), proftpd-pgsql (<< 1.2.8-1), proftpd-ldap (<< 1.2.8-1)
+Description: Versatile, virtual-hosting FTP daemon
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package provides the common administrative programs.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-doc
+Architecture: all
+Suggests: proftpd-common
+Replaces: proftpd (<= 1.2.1-2)
+Section: doc
+Description: Versatile, virtual-hosting FTP daemon (Documentation)
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-mysql
+Architecture: any
+Depends: netbase (>= 2.0), ${shlibs:Depends}, debconf (>= 0.5.00), proftpd-common (= ${Source-Version}), adduser, ucf (>= 0.30)
+Conflicts: wu-ftpd, wu-ftpd-academ, ftp-server, proftpd, proftpd-pgsql, proftpd-ldap
+Provides: ftp-server
+Description: Versatile, virtual-hosting FTP daemon (with SQL support)
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package contains the proftpd daemon compiled with support for
+ MySQL user authentication.  It also supports PAM authentication.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-pgsql
+Architecture: any
+Depends: netbase (>= 2.0), ${shlibs:Depends}, debconf (>= 0.5.00), proftpd-common (= ${Source-Version}), adduser, ucf (>= 0.30)
+Conflicts: wu-ftpd, wu-ftpd-academ, ftp-server, proftpd, proftpd-mysql, proftpd-ldap
+Provides: ftp-server
+Description: Versatile, virtual-hosting FTP daemon (with SQL support)
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package contains the proftpd daemon compiled with support for
+ PostgreSQL user authentication.  It also supports PAM authentication.
+ .
+ More information can be found at http://www.proftpd.org/.
+
+Package: proftpd-ldap
+Architecture: any
+Depends: netbase (>= 2.0), ${shlibs:Depends}, debconf (>= 0.5.00), proftpd-common (= ${Source-Version}), adduser, ucf (>= 0.30)
+Conflicts: wu-ftpd, wu-ftpd-academ, ftp-server, proftpd, proftpd-mysql, proftpd-pgsql
+Provides: ftp-server
+Description: Versatile, virtual-hosting FTP daemon (with LDAP support)
+ A powerful replacement for wu-ftpd, this File Transfer Protocol
+ daemon supports hidden directories, virtual hosts, and per-directory
+ ".ftpaccess" files.  It uses a single main configuration file, with a
+ syntax similar to Apache.
+ .
+ Because of the advanced design, anonymous-FTP directories can have
+ an arbitrary internal structure (bin, lib, etc, and special files are
+ not needed).  Advanced features like multiple password files and
+ upload/download ratios are also supported.
+ .
+ This package contains the proftpd daemon compiled with support for
+ LDAP user authentication.  It also supports PAM authentication.
+ .
+ More information can be found at http://www.proftpd.org/.
--- proftpd-1.2.9.orig/debian/.#proftpd.postinst.1.3
+++ proftpd-1.2.9/debian/.#proftpd.postinst.1.3
@@ -0,0 +1,156 @@
+#!/bin/sh -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see /usr/share/doc/packaging-manual/
+#
+# quoting from the policy:
+#     Any necessary prompting should almost always be confined to the
+#     post-installation script, and should be protected with a conditional
+#     so that unnecessary prompting doesn't happen if a package's
+#     installation fails and the `postinst' is called with `abort-upgrade',
+#     `abort-remove' or `abort-deconfigure'.
+
+
+CONF="/etc/proftpd.conf"
+CONF_NEW="/etc/proftpd.conf.proftpd-new"
+
+installftp()
+{
+	if ! grep -q "^ftp:" /etc/passwd
+	    then
+	    adduser --system ftp || true
+            if [ -f /usr/share/doc/proftpd/examples/welcome.msg -a -d ~ftp ] ; then
+                cp -p -v /usr/share/doc/proftpd/examples/welcome.msg ~ftp/welcome.msg.proftpd-new
+                do_update ~ftp/welcome.msg || true
+	    fi
+	fi
+}
+
+list_options()
+{
+    if [ -f $CONF_NEW ] ; then
+	sed -e "s/lsdefaultoptions/ListOptions/i" $CONF_NEW > $CONF_NEW.tmp
+	mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+tcpwin_options()
+{
+    if [ -f $CONF_NEW ] ; then
+        sed -e "s/tcpreceivewindow/SocketOptions rcvbuf/i" \
+            -e "s/tcpsendwindow/SocketOptions sndbuf/i" \
+                                                $CONF_NEW > $CONF_NEW.tmp
+        mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+                                                                                         
+scoreboard()
+{
+    if [ -f $CONF_NEW ] ; then
+        sed -e "s/\(scoreboardpath.*\)/#\n#ScoreboardPath is deprecated in 1.2.9, use ScoreboardFile instead\n#\1\n#\n#ScoreboardFile\t\/var\/run\/proftpd.scoreboard\n#/i" \
+                                                $CONF_NEW > $CONF_NEW.tmp
+        mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+
+switch_on()
+{
+    if [ -f $CONF_NEW ] ; then
+	sed -e 's/^\(ServerType.*\)inetd/\1standalone/' $CONF_NEW >$CONF_NEW.tmp
+	mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+switch_off()
+{
+    if [ -f $CONF_NEW ] ; then
+	sed -e 's/^\(ServerType.*\)standalone/\1inetd/' $CONF_NEW >$CONF_NEW.tmp
+	mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+replace_file () {
+    file=$1
+    if [ ! -f ${file} ] ; then
+	mv ${file}.proftpd-new ${file}
+    else
+	cp $file ${file}.proftpd-old
+	ucf --debconf-ok ${file}.proftpd-new $file 
+    fi
+}
+
+do_update () {
+    file=$1
+    if diff -q ${file} ${file}.proftpd-new >/dev/null 2>&1; then
+	# Old file and new file are identical
+	rm -f ${file}.proftpd-new
+    else
+	replace_file $file
+    fi
+}
+
+DONTSTART=0
+
+. /usr/share/debconf/confmodule
+
+if [ "$1" = "configure" ]; then
+    
+    # use current configuration or generate a new one from scratch
+    if [ ! -f /etc/proftpd.conf ] ; then
+       cp /usr/share/doc/proftpd/examples/proftpd.conf $CONF_NEW
+    else
+       cp $CONF $CONF_NEW
+    fi
+    
+    if ! egrep -qi "^.*ftp.*/usr/sbin/proftpd$" /etc/inetd.conf >/dev/null 2>&1; then
+           update-inetd --group STANDARD --add 'ftp	stream 	tcp	nowait	root	/usr/sbin/tcpd /usr/sbin/proftpd' </dev/tty >/dev/tty
+    fi
+    update-inetd --group STANDARD --add 'ftp	stream	tcp	nowait	root	/usr/sbin/tcpd /usr/sbin/proftpd' </dev/tty >/dev/tty
+    db_get shared/proftpd/inetd_or_standalone
+    if [ "$RET" = "inetd" ] ; then
+	    update-inetd --enable ftp </dev/tty >/dev/tty
+	    switch_off
+    else
+	    update-inetd --disable ftp </dev/tty >/dev/tty
+	    switch_on
+    fi
+
+    installftp
+
+    # Proftpd could not close all of its fd nicely
+    db_stop
+
+    # do mandatory changes
+    list_options
+    tcpwin_options
+    scoreboard
+
+    # propose maintainer changes to user
+    do_update /etc/proftpd.conf
+
+    # clean run files (pidfile and scoreboard)
+    rm -f /var/run/proftpd/proftpd* /var/run/proftpd.pid 
+
+fi
+
+if [ -e "/etc/init.d/proftpd" ]; then
+    update-rc.d proftpd defaults 50 >/dev/null
+    if [ $DONTSTART -eq 0 ] ; then
+        set +e; /usr/sbin/proftpd -t >/dev/null 2>&1; set -e
+    	if [ $? = 0 ]; then
+		invoke-rc.d proftpd start
+	else
+		echo "Cannot start proftpd, please check syntax of your configuration file $CONF"
+	fi
+    fi
+fi
+
+#DEBHELPER#
+
--- proftpd-1.2.9.orig/debian/.#proftpd.postrm.1.1.1.1
+++ proftpd-1.2.9/debian/.#proftpd.postrm.1.1.1.1
@@ -0,0 +1,25 @@
+#!/bin/sh -e
+
+if [ "$1" = "purge" ] ; then
+    rm -f /etc/proftpd.conf
+    rm -f /etc/proftpd.conf.proftpd-new
+    rm -f /etc/proftpd.conf.proftpd-old
+fi
+
+if [ "$1" = "purge" -o "$1" = "remove" ]
+then
+    update-inetd --disable ftp
+fi
+
+if [ "$1" = "purge" ] ; then
+        update-rc.d proftpd remove >/dev/null
+	update-inetd --remove "^.*ftp.*/usr/sbin/proftpd$"
+	ucf --purge /etc/proftpd.conf
+:q
+
+
+	rm -rf /var/run/proftpd /var/run/proftpd.pid
+fi
+
+#DEBHELPER#
+
--- proftpd-1.2.9.orig/debian/.#proftpd.postinst.1.5
+++ proftpd-1.2.9/debian/.#proftpd.postinst.1.5
@@ -0,0 +1,156 @@
+#!/bin/sh -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see /usr/share/doc/packaging-manual/
+#
+# quoting from the policy:
+#     Any necessary prompting should almost always be confined to the
+#     post-installation script, and should be protected with a conditional
+#     so that unnecessary prompting doesn't happen if a package's
+#     installation fails and the `postinst' is called with `abort-upgrade',
+#     `abort-remove' or `abort-deconfigure'.
+
+
+CONF="/etc/proftpd.conf"
+CONF_NEW="/etc/proftpd.conf.proftpd-new"
+
+installftp()
+{
+	if ! grep -q "^ftp:" /etc/passwd
+	    then
+	    adduser --system ftp || true
+            if [ -f /usr/share/doc/proftpd/examples/welcome.msg -a -d ~ftp ] ; then
+                cp -p -v /usr/share/doc/proftpd/examples/welcome.msg ~ftp/welcome.msg.proftpd-new
+                do_update ~ftp/welcome.msg || true
+	    fi
+	fi
+}
+
+list_options()
+{
+    if [ -f $CONF_NEW ] ; then
+	sed -e "s/lsdefaultoptions/ListOptions/i" $CONF_NEW > $CONF_NEW.tmp
+	mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+tcpwin_options()
+{
+    if [ -f $CONF_NEW ] ; then
+        sed -e "s/tcpreceivewindow/SocketOptions rcvbuf/i" \
+            -e "s/tcpsendwindow/SocketOptions sndbuf/i" \
+                                                $CONF_NEW > $CONF_NEW.tmp
+        mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+                                                                                         
+scoreboard()
+{
+    if [ -f $CONF_NEW ] ; then
+        sed -e "s/\(scoreboardpath.*\)/#\n#ScoreboardPath is deprecated in 1.2.9, use ScoreboardFile instead\n#\1\n#\n#ScoreboardFile\t\/var\/run\/proftpd.scoreboard\n#/i" \
+                                                $CONF_NEW > $CONF_NEW.tmp
+        mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+
+switch_on()
+{
+    if [ -f $CONF_NEW ] ; then
+	sed -e 's/^\(ServerType.*\)inetd/\1standalone/' $CONF_NEW >$CONF_NEW.tmp
+	mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+switch_off()
+{
+    if [ -f $CONF_NEW ] ; then
+	sed -e 's/^\(ServerType.*\)standalone/\1inetd/' $CONF_NEW >$CONF_NEW.tmp
+	mv -f $CONF_NEW.tmp $CONF_NEW
+    fi
+}
+
+replace_file () {
+    file=$1
+    if [ ! -f ${file} ] ; then
+	mv ${file}.proftpd-new ${file}
+    else
+	cp $file ${file}.proftpd-old
+	ucf --debconf-ok ${file}.proftpd-new $file 
+    fi
+}
+
+do_update () {
+    file=$1
+    if diff -q ${file} ${file}.proftpd-new >/dev/null 2>&1; then
+	# Old file and new file are identical
+	rm -f ${file}.proftpd-new
+    else
+	replace_file $file
+    fi
+}
+
+DONTSTART=0
+
+. /usr/share/debconf/confmodule
+
+if [ "$1" = "configure" ]; then
+    
+    # use current configuration or generate a new one from scratch
+    if [ ! -f /etc/proftpd.conf ] ; then
+       cp /usr/share/doc/proftpd/examples/proftpd.conf $CONF_NEW
+    else
+       cp $CONF $CONF_NEW
+    fi
+    
+    if ! egrep -qi "^.*ftp.*/usr/sbin/proftpd$" /etc/inetd.conf >/dev/null 2>&1; then
+           update-inetd --group STANDARD --add 'ftp	stream 	tcp	nowait	root	/usr/sbin/tcpd /usr/sbin/proftpd' </dev/tty >/dev/tty
+    fi
+    update-inetd --group STANDARD --add 'ftp	stream	tcp	nowait	root	/usr/sbin/tcpd /usr/sbin/proftpd' </dev/tty >/dev/tty
+    db_get shared/proftpd/inetd_or_standalone
+    if [ "$RET" = "inetd" ] ; then
+	    update-inetd --enable ftp </dev/tty >/dev/tty
+	    switch_off
+    else
+	    update-inetd --disable ftp </dev/tty >/dev/tty
+	    switch_on
+    fi
+
+    installftp
+
+    # Proftpd could not close all of its fd nicely
+    db_stop
+
+    # do mandatory changes
+    list_options
+    tcpwin_options
+    scoreboard
+
+    # propose maintainer changes to user
+    do_update /etc/proftpd.conf
+
+    # clean run files (pidfile and scoreboard)
+    rm -f /var/run/proftpd/proftpd* /var/run/proftpd.pid 
+
+fi
+
+if [ -e "/etc/init.d/proftpd" ]; then
+    update-rc.d proftpd defaults 50 >/dev/null
+    if [ $DONTSTART -eq 0 ] ; then
+        set +e; /usr/sbin/proftpd -t >/dev/null 2>&1; set -e
+    	if [ $? = 0 ]; then
+		invoke-rc.d proftpd start
+	else
+		echo "Cannot start proftpd, please check syntax of your configuration file $CONF"
+	fi
+    fi
+fi
+
+#DEBHELPER#
+
--- proftpd-1.2.9.orig/config.sub
+++ proftpd-1.2.9/config.sub
@@ -0,0 +1,1537 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2004-01-05'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m68000 | m68k | m88k | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| msp430-* \
+	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nv1)
+		basic_machine=nv1-cray
+		os=-unicosmp
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
