  * Make backup-files a shell script instead of a binary, so we can make
    quilt arch: all [Steve Langasek, thanks so much]
    (Closes: #363659)
    
Upstream status: Submitted 060427

---
 Makefile.in                   |   30 --
 bin/quilt.in                  |    4 
 lib/backup-files.c            |  601 ------------------------------------------
 quilt/add.in                  |    2 
 quilt/pop.in                  |    6 
 quilt/push.in                 |    2 
 quilt/scripts/backup-files.in |  289 ++++++++++++++++++++
 quilt/scripts/patchfns.in     |    2 
 quilt/snapshot.in             |    2 
 9 files changed, 304 insertions(+), 634 deletions(-)

--- a/Makefile.in
+++ b/Makefile.in
@@ -6,7 +6,6 @@ PACKAGE_BUGREPORT := @PACKAGE_BUGREPORT@
 prefix :=	@prefix@
 exec_prefix :=	@exec_prefix@
 bindir :=	@bindir@
-libdir :=	@libdir@
 datarootdir :=	@datarootdir@
 datadir :=	@datadir@
 docdir :=	@docdir@
@@ -51,11 +50,6 @@ LDFLAGS +=	@LDFLAGS@
 LIBS :=		@LIBS@
 EXEEXT :=	@EXEEXT@
 
-LIBOBJS :=	$(filter $(patsubst lib/%.c,lib/%.o,$(wildcard lib/*.c)), $(patsubst %,lib/%,@LIBOBJS@))
-ifneq ($(LIBOBJS),)
-CFLAGS += -Ilib
-endif
-
 COMPAT_SYMLINKS	:= @COMPAT_SYMLINKS@
 COMPAT_PROGRAMS	:= @COMPAT_PROGRAMS@
 
@@ -83,7 +77,7 @@ SRC +=		$(QUILT_SRC:%=quilt/%)
 DIRT +=		$(QUILT_IN:%=quilt/%)
 
 SCRIPTS_IN :=	patchfns parse-patch inspect dependency-graph edmail	\
-		remove-trailing-ws
+		remove-trailing-ws backup-files
 
 SCRIPTS_SRC :=	$(SCRIPTS_IN:%=%.in)
 SCRIPTS :=	$(SCRIPTS_IN)
@@ -94,10 +88,8 @@ COMPAT :=	$(COMPAT_PROGRAMS:%=compat/%)
 SRC +=		$(wildcard compat/*.in) $(wildcard compat/*.sh)
 DIRT +=		$(patsubst %.in,%,$(wildcard compat/*.in)) $(COMPAT_SYMLINKS:%=compat/%)
 
-LIB_SRC :=	backup-files.c quilt.el
-LIB :=		backup-files$(EXEEXT)
+LIB_SRC :=	quilt.el
 SRC +=		$(LIB_SRC:%=lib/%)
-DIRT +=		lib/backup-files$(EXEEXT) $(LIB_SRC:%.c=lib/%.o)
 
 DOC_IN :=	README
 DOC_SRC :=	$(DOC_IN:%=doc/%.in)
@@ -131,16 +123,13 @@ DIRT +=		test/.depend $(wildcard test/.*
 # Settings for running the uninstalled version of quilt in the source tree:
 PATH :=		$(CURDIR)/bin:$(CURDIR)/compat:$(PATH)
 QUILT_DIR :=	$(CURDIR)/quilt
-QUILT_LIB :=	$(CURDIR)/lib
 QUILTRC :=	$(CURDIR)/test/test.quiltrc
-export QUILT_DIR QUILT_LIB QUILTRC
+export QUILT_DIR QUILTRC
 
 #-----------------------------------------------------------------------
 
 all : configure scripts compat $(DOC:%=doc/%) $(MAN1) mofiles
 
-$(LIB:%=lib/%) :: $(LIBOBJS)
-
 ifeq ($(USE_NLS),yes)
 mofiles : $(LINGUAS:%=po/%.mo)
 else
@@ -154,7 +143,7 @@ endif
 	$(MSGMERGE) -o $@ $@ $^
 
 scripts : $(BIN:%=bin/%) $(QUILT:%=quilt/%) 				\
-	  $(SCRIPTS:%=quilt/scripts/%) $(LIB:%=lib/%)			\
+	  $(SCRIPTS:%=quilt/scripts/%) 					\
 	  $(if $(PATCH_WRAPPER),bin/patch-wrapper)
 
 dist : clean $(PACKAGE)-$(VERSION).tar.gz
@@ -259,8 +248,7 @@ $(PACKAGE).spec : $(PACKAGE).spec.in $(P
 $(patsubst %.in,%,$(wildcard bin/*.in quilt/*.in quilt/scripts/*.in)) :: Makefile
 % :: %.in
 	@echo "$< -> $@" >&2
-	@$(SED) -e 's:@QUILT_LIB''@:$(libdir)/$(PACKAGE):g'		\
-		-e 's:@QUILT_DIR''@:$(datadir)/$(PACKAGE):g'		\
+	@$(SED) -e 's:@QUILT_DIR''@:$(datadir)/$(PACKAGE):g'		\
 		-e 's:@PERL''@:$(PERL):g'				\
 		-e 's:@BASH''@:$(BASH):g'				\
 		-e 's:@PATCH''@:$(PATCH):g'				\
@@ -272,8 +260,6 @@ $(patsubst %.in,%,$(wildcard bin/*.in qu
 		$< > $@
 	@$(if $(filter-out $<,$(NON_EXEC_IN)),chmod +x $@)
 
-lib/backup-files.o :: Makefile
-
 configure : configure.ac aclocal.m4
 	autoconf
 	@echo "Please run ./configure"
@@ -324,9 +310,6 @@ ifneq ($(PATCH_WRAPPER),)
 		   $(BUILD_ROOT)$(datadir)/$(PACKAGE)/wrapper/patch
 endif
 	
-	$(INSTALL) -d $(BUILD_ROOT)$(libdir)/$(PACKAGE)
-	$(INSTALL) -m 755 $(LIB:%=lib/%) $(BUILD_ROOT)$(libdir)/$(PACKAGE)/
-
 	$(INSTALL) -d $(BUILD_ROOT)$(docdir)/$(PACKAGE)-$(VERSION)/
 	$(INSTALL) -m 644 doc/README					\
 		   $(BUILD_ROOT)$(docdir)/$(PACKAGE)-$(VERSION)/
@@ -363,7 +346,6 @@ install: install-main install-compat
 
 uninstall ::
 	rm -rf $(BIN:%=$(BUILD_ROOT)$(bindir)/%)			\
-	       $(BUILD_ROOT)$(libdir)/$(PACKAGE)			\
 	       $(BUILD_ROOT)$(datadir)/$(PACKAGE)			\
 	       $(patsubst %,$(BUILD_ROOT)$(mandir)/man1/%,		\
 		   $(notdir $(MAN1)))					\
@@ -387,7 +369,7 @@ test/.patch-wrapper.ok : bin/patch-wrapp
 
 # Include a run-time generated list of dependencies for each test case
 test/.depend : Makefile $(TESTS)
-	@(  printf "%s : bin/quilt quilt/scripts/patchfns $(LIB:%=lib/%) $(COMPAT)\n" $(TESTS); \
+	@(  printf "%s : bin/quilt quilt/scripts/patchfns quilt/scripts/backup-files $(COMPAT)\n" $(TESTS); \
 	    $(AWK) 'sub(/.*\$$ *quilt /, "")				\
 			{ print FILENAME, ":", "quilt/"$$1}' $(TESTS); \
 	    $(AWK) 'sub(/.*\<quilt_command /, "") && ($$1 !~ /[^a-z]/)	\
--- a/quilt/add.in
+++ b/quilt/add.in
@@ -121,7 +121,7 @@ do
 		continue
 	fi
 
-	if ! $QUILT_LIB/backup-files -b -s -L -B $QUILT_PC/$patch/ "$SUBDIR$file"
+	if ! $QUILT_DIR/scripts/backup-files -b -s -L -B $QUILT_PC/$patch/ "$SUBDIR$file"
 	then
 		printf $"Failed to back up file %s\n" "$SUBDIR$file" >&2
 		status=1
--- a/quilt/pop.in
+++ b/quilt/pop.in
@@ -95,7 +95,7 @@ check_for_pending_changes()
 		local prefix=$QUILT_PC/$patch/
 		[ ${prefix:0:1} == / ] || prefix=$PWD/$prefix
 		if ! ( cd $workdir && \
-		       $QUILT_LIB/backup-files -B $prefix -rks - )
+		       $QUILT_DIR/scripts/backup-files -B $prefix -r -k -s - )
 		then
 			printf $"Failed to copy files to temporary directory\n" >&2
 			rm -rf $workdir
@@ -162,7 +162,7 @@ remove_patch()
 			status=$?
 		else
 			printf $"Removing patch %s\n" "$(print_patch $patch)"
-			$QUILT_LIB/backup-files $silent -r -t -B $QUILT_PC/$patch/ -
+			$QUILT_DIR/scripts/backup-files $silent -r -t -B $QUILT_PC/$patch/ -
 			status=$?
 		fi
 		remove_from_db $patch
@@ -264,7 +264,7 @@ else
 	# of one: This will automatically be the case in the usual
 	# situations, but we don't want to risk file corruption in weird
 	# corner cases such as files added to a patch but not modified.
-	$QUILT_LIB/backup-files -L -s -B $QUILT_PC/$patch/ -
+	$QUILT_DIR/scripts/backup-files -L -s -B $QUILT_PC/$patch/ -
 	printf $"Now at patch %s\n" "$(print_patch $patch)"
 fi
 ### Local Variables:
--- a/quilt/push.in
+++ b/quilt/push.in
@@ -140,7 +140,7 @@ rollback_patch()
 {
 	local patch=$1
 
-	$QUILT_LIB/backup-files $silent_unless_verbose -r -B $QUILT_PC/$patch/ -
+	$QUILT_DIR/scripts/backup-files $silent_unless_verbose -r -B $QUILT_PC/$patch/ -
 }
 
 cleanup_patch_output() {
--- a/quilt/snapshot.in
+++ b/quilt/snapshot.in
@@ -86,7 +86,7 @@ done \
 	}
 	{ print }
 ' \
-| $QUILT_LIB/backup-files -b -s -L -f - -B "$QUILT_PC/$snap_subdir/"
+| $QUILT_DIR/scripts/backup-files -b -s -L -f - -B "$QUILT_PC/$snap_subdir/"
 
 ### Local Variables:
 ### mode: shell-script
--- /dev/null
+++ b/quilt/scripts/backup-files.in
@@ -0,0 +1,289 @@
+#! @BASH@
+
+set -e
+
+# File: backup-files.sh
+
+# Copyright (C) 2006 Steve Langasek <vorlon@debian.org>
+# portions Copyright (C) 2003, 2004, 2005, 2006 Andreas Gruenbacher
+# <agruen@suse.de>, SuSE Labs
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 dated June, 1991.
+
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program;  if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+
+# Create backup files of a list of files similar to GNU patch. A path
+# name prefix and suffix for the backup file can be specified with the
+# -B and -z options.
+
+usage () {
+	local progname="$1"
+	echo "Usage: $progname [-B prefix] [-z suffix] [-f {file|-}] [-s] [-k] [-t] [-L] [-b|-r|-x] {file|-} ...
+
+	Create hard linked backup copies of a list of files
+	read from standard input.
+
+	-b	Create backup
+	-r	Restore the backup
+	-x	Remove backup files and empty parent directories
+	-k	When doing a restore, keep the backup files
+	-B	Path name prefix for backup files
+	-z	Path name suffix for backup files
+	-s	Silent operation; only print error messages
+	-f	Read the filenames to process from file (- = standard input)
+	-t	Touch original files after restore (update their mtimes)
+
+	-L	Ensure that when finished, the source file has a link count of 1
+"
+}
+
+copy_file() {
+	local from="$1"
+	local to="$2"
+	cp -dp --remove-destination "$from" "$to"
+}
+
+link_or_copy_file() {
+	local from="$1"
+	local to="$2"
+	if ! ln "$from" "$to" 2>/dev/null ; then
+		copy_file "$from" "$to"
+	fi
+}
+
+ensure_nolinks() {
+	local filename="$1"
+	local link_count dirname basename tmpname
+
+	link_count=$(stat -c '%h' "$filename")
+	if [ -z "$link_count" ] || [ "$link_count" -gt 1 ]; then
+		dirname=$(dirname "$filename")
+		basename=$(basename "$filename")
+		# Temp file name is "path/to/.file.XXXXXX"
+		tmpname=$(mktemp "${dirname}/.${basename}.XXXXXX")
+		cp -dp "$filename" "$tmpname"
+		mv "$tmpname" "$filename"
+	fi
+}
+
+process_file() {
+	local file="$1"
+	local backup="${OPT_PREFIX}${file}${OPT_SUFFIX}"
+
+	if [ "$OPT_WHAT" == "backup" ]; then
+		if [ -e "$backup" ]; then
+			rm "$backup"
+		else
+			mkdir -p "$(dirname "$backup")"
+		fi
+		if [ ! -e "$file" ]; then
+			$ECHO "New file $file"
+			touch "$backup"
+		else
+			$ECHO "Copying $file"
+			if [ -n "$OPT_NOLINKS" -a "$(stat -c '%h' "$file")" = "1" ]; then
+				copy_file "$file" "$backup"
+			else
+				link_or_copy_file "$file" "$backup"
+				if [ -n "$OPT_NOLINKS" ]; then
+					ensure_nolinks "$file"
+				fi
+			fi
+			if [ -n "$OPT_TOUCH" ]; then
+				touch "$backup"
+			fi
+		fi
+	elif [ "$OPT_WHAT" == "restore" ]; then
+		mkdir -p "$(dirname "$file")"
+
+		if [ ! -e "$backup" ]; then
+			return 1
+		fi
+		if [ ! -s "$backup" ]; then
+			if [ -e "$file" ]; then
+				rm "$file"
+			fi
+			$ECHO "Removing $file"
+			if [ -z "$OPT_KEEP_BACKUP" ]; then
+				rm "$backup"
+				while [ -d "${backup%/*}" ] && ! [ -L "${backup%/*}" ]
+				do
+					backup="${backup%/*}"
+					rmdir --ignore-fail-on-non-empty "$backup" 2>/dev/null
+					if [ -d "$backup" ]; then
+						break
+					fi
+				done
+			fi
+		else
+			$ECHO "Restoring $file"
+			if [ -e "$file" ]; then
+				rm "$file"
+			fi
+			if [ -n "$OPT_NOLINKS" -a "$(stat -c '%h' "$backup")" != "1" ]; then
+				copy_file "$backup" "$file"
+			else
+                        	link_or_copy_file "$backup" "$file"
+				if [ -n "$OPT_NOLINKS" ]; then
+					ensure_nolinks "$file"
+				fi
+			fi
+
+			if [ -z "$OPT_KEEP_BACKUP" ]; then
+				rm "$backup"
+				while [ -d "${backup%/*}" ] && ! [ -L "${backup%/*}" ]
+				do
+					backup="${backup%/*}"
+					rmdir --ignore-fail-on-non-empty "$backup" 2>/dev/null
+					if [ -d "$backup" ]; then
+						break
+					fi
+				done
+			fi
+			if [ -n "$OPT_TOUCH" ]; then
+				touch "$file"
+			fi
+		fi
+	elif [ "$OPT_WHAT" == "remove" ]; then
+		if [ -e "$backup" ]; then
+			rm "$backup"
+		fi
+		while [ -d "${backup%/*}" ] && ! [ -L "${backup%/*}" ]
+		do
+			backup="${backup%/*}"
+			rmdir --ignore-fail-on-non-empty "$backup" 2>/dev/null
+			if [ -d "$backup" ]; then
+				break
+			fi
+		done
+	elif [ -z "$OPT_WHAT" ]; then
+		if [ -e "$file" ] && [ -n "$OPT_NOLINKS" ]; then
+			ensure_nolinks "$file"
+		fi
+	else
+		return 1
+	fi
+}
+
+walk() {
+	local path="$1"
+	if [ ! -f "$path" ]; then
+		return 0
+	fi
+
+	if [ "${path#$OPT_PREFIX}" == "$path" ]
+	then
+		# prefix does not match
+		return 0
+	fi
+	path="${path#$OPT_PREFIX}"
+
+	if [ -n "$OPT_SUFFIX" ] && [ "${path%$OPT_SUFFIX}" == "$path" ]
+	then
+		# suffix does not match
+		return 0
+	fi
+	path="${path%$OPT_SUFFIX}"
+
+	process_file "$path"
+}
+
+
+ECHO=echo
+declare -a FILELIST
+progname="$0"
+while [ $# -gt 0 ]; do
+	case $1 in
+	-b)	OPT_WHAT=backup
+		;;
+	-r)	OPT_WHAT=restore
+		;;
+	-x)	OPT_WHAT=remove
+		;;
+	-B)	OPT_PREFIX=$2
+		shift
+		;;
+	-f)	OPT_FILE=$2
+		shift
+		;;
+	-z)	OPT_SUFFIX=$2
+		shift
+		;;
+	-s)	ECHO=:
+		;;
+	-k)	OPT_KEEP_BACKUP=1
+		;;
+	-L)	OPT_NOLINKS=1
+		;;
+	-t)	OPT_TOUCH=1
+		;;
+	-?*)	usage "$progname"
+		exit 0
+		;;
+	*)	FILELIST=("$@")
+		break
+		;;
+	esac
+
+        shift
+done
+
+if [ -z "${OPT_PREFIX}${OPT_SUFFIX}" ]; then
+	usage "$progname"
+	exit 1
+fi
+if [ ${#FILELIST[@]} == 0 ] && [ -z "$OPT_FILE" ]; then
+	usage "$progname"
+	exit 1
+fi
+
+if [ -n "$OPT_FILE" ]; then
+	cat "$OPT_FILE" \
+	| while read nextfile; do
+		process_file "$nextfile"
+	done
+fi
+
+I=0
+while [ $I -lt ${#FILELIST[@]} ]; do
+
+	case "${FILELIST[$I]}" in
+	-)
+		path="${OPT_PREFIX%/*}"
+
+		find "$path" -mindepth 1 \( -type f -o -type d \) -print 2>/dev/null \
+		| while read
+		do
+			if [ -d "$REPLY" ]
+			then
+				if ! [ -r "$REPLY" ] || ! [ -x "$REPLY" ]
+				then
+					echo "$REPLY: Permission denied"
+					exit 1
+				fi
+			else
+				walk "$REPLY"
+			fi
+		done
+		if [ $? != 0 ]; then
+			exit 1
+		fi
+		;;
+	*)
+		process_file "${FILELIST[$I]}"
+		;;
+	esac
+
+	I=$(($I+1))
+done
--- a/bin/quilt.in
+++ b/bin/quilt.in
@@ -9,8 +9,8 @@
 export TEXTDOMAIN=quilt
 export TEXTDOMAINDIR=@LOCALEDIR@
 
-: ${QUILT_DIR=@QUILT_DIR@} ${QUILT_LIB=@QUILT_LIB@}
-export QUILT_DIR QUILT_LIB
+: ${QUILT_DIR=@QUILT_DIR@}
+export QUILT_DIR
 
 if [ -z "$QUILTRC" ]
 then
--- a/quilt/scripts/patchfns.in
+++ b/quilt/scripts/patchfns.in
@@ -914,7 +914,7 @@ apply_patch_temporarily()
 	local prefix=$QUILT_PC/$patch/
 	[ ${prefix:0:1} == / ] || prefix=$PWD/$prefix
 	if ! ( cd $workdir && \
-	       $QUILT_LIB/backup-files -B $prefix -rks ${@:--} )
+	       $QUILT_DIR/scripts/backup-files -B $prefix -r -k -s ${@:--} )
 	then
 		printf $"Failed to copy files to temporary directory\n" >&2
 		return 1
--- a/lib/backup-files.c
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
-  File: backup-files.c
-
-  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
-  Andreas Gruenbacher <agruen@suse.de>, SuSE Labs
-
-  This program is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Library 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
-  Library General Public License for more details.
-
-  You should have received a copy of the GNU Library General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-/*
- * Create backup files of a list of files similar to GNU patch. A path
- * name prefix and suffix for the backup file can be specified with the
- * -B and -z options.
- */
-
-#define _GNU_SOURCE 1
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <utime.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <dirent.h>
-
-#if !defined(HAVE_MKSTEMP) && defined(HAVE_MKTEMP)
-# define mkstemp(x) creat(mktemp(x), 0600)
-#endif
-
-#ifndef PATH_MAX
-# define PATH_MAX 4096
-#endif
-
-#ifdef __MINGW32__
-#define mkdir(x,y) mkdir(x)
-/* Symlinks are not supported */
-#define lstat stat
-static int link(const char *oldpath, const char *newpath)
-{
-	errno = ENOSYS;
-	return -1;
-}
-#endif
-
-const char *progname;
-
-enum { what_noop, what_backup, what_restore, what_remove };
-
-const char *opt_prefix="", *opt_suffix="", *opt_file;
-int opt_silent, opt_what=what_noop;
-int opt_nolinks, opt_touch;
-int opt_keep_backup;
-
-#define LINE_LENGTH 1024
-
-
-static void
-usage(void)
-{
-	printf("Usage: %s [-B prefix] [-z suffix] [-f {file|-}] [-sktL] [-b|-r|-x] {file|-} ...\n"
-	       "\n"
-	       "\tCreate hard linked backup copies of a list of files\n"
-	       "\tread from standard input.\n"
-	       "\n"
-	       "\t-b\tCreate backup\n"
-	       "\t-r\tRestore the backup\n"
-	       "\t-x\tRemove backup files and empty parent directories\n"
-	       "\t-k\tWhen doing a restore, keep the backup files\n"
-	       "\t-B\tPath name prefix for backup files\n"
-	       "\t-z\tPath name suffix for backup files\n"
-	       "\t-s\tSilent operation; only print error messages\n"
-	       "\t-f\tRead the filenames to process from file (- = standard input)\n"
-	       "\t-t\tTouch original files after restore (update their mtimes)\n\n"
-	       "\t-L\tEnsure that when finished, the source file has a link count of 1\n\n",
-	       progname);
-}
-
-static void *
-malloc_nofail(size_t size)
-{
-	void *p = malloc(size);
-	if (!p) {
-		perror(progname);
-		exit(1);
-	}
-	return p;
-}
-
-static void
-create_parents(const char *filename)
-{
-	struct stat st;
-	int rv = -1;
-	char *fn = malloc_nofail(strlen(filename) + 1), *f;
-
-	strcpy(fn, filename);
-
-	f = strrchr(fn, '/');
-	if (f == NULL)
-		goto out;
-	*f = '\0';
-	if (stat(fn, &st) == 0)
-		goto out;
-	*f = '/';
-
-	f = strchr(fn, '/');
-	while (f != NULL) {
-		*f = '\0';
-		if (!rv || (rv = stat(fn, &st)) != 0) {
-			mkdir(fn, 0777);
-		}
-		*f = '/';
-		f = strchr(f+1, '/');
-	}
-out:
-	free(fn);
-}
-
-static void
-remove_parents(const char *filename)
-{
-	char *fn = malloc_nofail(strlen(filename) + 1), *f;
-
-	strcpy(fn, filename);
-
-	f = strrchr(fn, '/');
-	if (f == NULL)
-		goto out;
-	do {
-		*f = '\0';
-		if (rmdir(fn) == -1)
-			goto out;
-	} while ((f = strrchr(fn, '/')) != NULL);
-	rmdir(fn);
-out:
-	free(fn);
-}
-
-static int
-copy_fd(int from_fd, int to_fd)
-{
-	char buffer[16384];
-	char *wbuf;
-	ssize_t len, l;
-
-	for ( ;; ) {
-		len = read(from_fd, buffer, sizeof(buffer));
-		if (len == 0)
-			return 0;
-		if (len < 0) {
-			if (errno == EINTR || errno == EAGAIN)
-				continue;
-			return 1;
-		}
-		for (wbuf = buffer; len != 0; ) {
-			l = write(to_fd, wbuf, len);
-			if (l < 0) {
-				if (errno == EINTR || errno == EAGAIN)
-					continue;
-				return 1;
-			}
-			wbuf += l;
-			len -= l;
-		}
-	}
-}
-
-static int
-copy_file(const char *from, const struct stat *st, const char *to)
-{
-	int from_fd, to_fd, error = 1;
-
-	if ((from_fd = open(from, O_RDONLY)) == -1) {
-		perror(from);
-		return 1;
-	}
-	unlink(to);  /* make sure we don't inherit this file's mode. */
-	if ((to_fd = creat(to, st->st_mode)) < 0) {
-		perror(to);
-		close(from_fd);
-		return 1;
-	}
-#if defined(HAVE_FCHMOD)
-	(void) fchmod(to_fd, st->st_mode);
-#elif defined(HAVE_CHMOD)
-	(void) chmod(to, st->st_mode);
-#endif
-	if (copy_fd(from_fd, to_fd)) {
-		fprintf(stderr, "%s -> %s: %s\n", from, to, strerror(errno));
-		unlink(to);
-		goto out;
-	}
-
-	error = 0;
-out:
-	close(from_fd);
-	close(to_fd);
-
-	return error;
-}
-
-static int
-link_or_copy_file(const char *from, const struct stat *st, const char *to)
-{
-	if (link(from, to) == 0)
-		return 0;
-	if (errno != EXDEV && errno != EPERM &&
-	    errno != EMLINK && errno != ENOSYS) {
-		fprintf(stderr, "Could not link file `%s' to `%s': %s\n",
-		       from, to, strerror(errno));
-		return 1;
-	}
-	return copy_file(from, st, to);
-}
-
-static int
-ensure_nolinks(const char *filename)
-{
-	struct stat st;
-
-	if (stat(filename, &st) != 0) {
-		perror(filename);
-		return 1;
-	}
-	if (st.st_nlink > 1) {
-		char *tmpname = malloc(1 + strlen(filename) + 7 + 1), *c;
-		int from_fd = -1, to_fd = -1;
-		int error = 1;
-
-		if (!tmpname)
-			goto fail;
-		from_fd = open(filename, O_RDONLY);
-		if (from_fd == -1)
-			goto fail;
-
-		/* Temp file name is "path/to/.file.XXXXXX" */
-		strcpy(tmpname, filename);
-		strcat(tmpname, ".XXXXXX");
-		c = strrchr(tmpname, '/');
-		if (c == NULL)
-			c = tmpname;
-		else
-			c++;
-		memmove(c + 1, c, strlen(c) + 1);
-		*c = '.';
-
-		to_fd = mkstemp(tmpname);
-		if (to_fd == -1)
-			goto fail;
-		if (copy_fd(from_fd, to_fd))
-			goto fail;
-#if defined(HAVE_FCHMOD)
-		(void) fchmod(to_fd, st.st_mode);
-#elif defined(HAVE_CHMOD)
-		(void) chmod(tmpname, st.st_mode);
-#endif
-		close(from_fd);
-		from_fd = -1;
-		close(to_fd);
-		to_fd = -1;
-		if (rename(tmpname, filename))
-			goto fail;
-
-		error = 0;
-	fail:
-		if (error)
-			perror(filename);
-		if (from_fd != -1)
-			close(from_fd);
-		if (to_fd != -1)
-			close(to_fd);
-		free(tmpname);
-		return error;
-	} else
-		return 0;
-}
-
-static int
-process_file(const char *file)
-{
-	char *backup = malloc_nofail(
-		strlen(opt_prefix) + strlen(file) + strlen(opt_suffix) + 1);
-
-	sprintf(backup, "%s%s%s", opt_prefix, file, opt_suffix);
-
-	if (opt_what == what_backup) {
-		struct stat st;
-		int missing_file = (stat(file, &st) == -1 && errno == ENOENT);
-
-		unlink(backup);
-		create_parents(backup);
-		if (missing_file) {
-			int fd;
-
-			if (!opt_silent)
-				printf("New file %s\n", file);
-			/* Old versions of GNU patch create new files with mode==0.
-			   (This has been changed/fixed in patch version 2.6.)  */
-			if ((fd = creat(backup, 0666)) == -1) {
-				perror(backup);
-				goto fail;
-			}
-			close(fd);
-		} else {
-			if (!opt_silent)
-				printf("Copying %s\n", file);
-			if (opt_nolinks && st.st_nlink == 1) {
-				if (copy_file(file, &st, backup))
-					goto fail;
-			} else {
-				if (link_or_copy_file(file, &st, backup))
-					goto fail;
-				if (opt_nolinks && ensure_nolinks(file))
-					goto fail;
-			}
-			if (opt_touch)
-				(void) utime(backup, NULL);
-			else {
-				struct utimbuf ut;
-				ut.actime = ut.modtime = st.st_mtime;
-				(void) utime(backup, &ut);
-			}
-		}
-	} else if (opt_what == what_restore) {
-		struct stat st;
-
-		create_parents(file);
-		if (stat(backup, &st) != 0) {
-			perror(backup);
-			goto fail;
-		}
-		if (st.st_size == 0) {
-			if (unlink(file) == 0 || errno == ENOENT) {
-				if (!opt_silent)
-					printf("Removing %s\n", file);
-			} else {
-				perror(file);
-				goto fail;
-			}
-			if (!opt_keep_backup) {
-				unlink(backup);
-				remove_parents(backup);
-			}
-		} else {
-			if (!opt_silent)
-				printf("Restoring %s\n", file);
-			unlink(file);
-			if (opt_nolinks && st.st_nlink != 1) {
-				if (copy_file(backup, &st, file))
-					goto fail;
-			} else {
-				if (link_or_copy_file(backup, &st, file))
-					goto fail;
-				if (opt_nolinks && ensure_nolinks(file))
-					goto fail;
-			}
-			if (!opt_keep_backup) {
-				unlink(backup);
-				remove_parents(backup);
-			}
-			if (opt_touch)
-				(void) utime(file, NULL);
-			else {
-				struct utimbuf ut;
-				ut.actime = ut.modtime = st.st_mtime;
-				(void) utime(file, &ut);
-			}
-		}
-	} else if (opt_what == what_remove) {
-		unlink(backup);
-		remove_parents(backup);
-	} else if (opt_what == what_noop) {
-		struct stat st;
-		int missing_file = (stat(file, &st) == -1 && errno == ENOENT);
-
-		if (!missing_file && opt_nolinks) {
-			if (ensure_nolinks(file))
-				goto fail;
-		}
-	} else
-		goto fail;
-
-	free(backup);
-	return 0;
-
-fail:
-	free(backup);
-	return 1;
-}
-
-static int
-foreachdir_rec(const char *path, struct stat *st,
-	       int (*walk)(const char *, const struct stat *))
-{
-	DIR *dir;
-	struct dirent *dp;
-	int failed = 0;
-
-	struct path {
-		char *name;
-		struct path *next;
-	};
-	struct path *paths = NULL, *last_path = NULL;
-
-	if (access(path, R_OK|X_OK) || !(dir = opendir(path)))
-		return walk(path, NULL);
-	while ((dp = readdir(dir))) {
-		struct path *p;
-		size_t size;
-
-		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
-			continue;
-
-		p = malloc_nofail(sizeof(*p));
-		if (!last_path)
-			paths = p;
-		else
-			last_path->next = p;
-		p->next = NULL;
-		last_path = p;
-
-		size = strlen(path) + 1 + strlen(dp->d_name) + 1;
-		p->name = malloc_nofail(size);
-		sprintf(p->name, "%s/%s", path, dp->d_name);
-	}
-	if (closedir(dir) != 0)
-		failed = -1;
-
-	while (paths != NULL) {
-		struct path *next;
-
-		if (lstat(paths->name, st))
-			continue;  /* file has disappeared meanwhile */
-		if (S_ISDIR(st->st_mode)) {
-			failed = foreachdir_rec(paths->name, st, walk);
-			if (failed)
-				goto out;
-		} else {
-			failed = walk(paths->name, st);
-			if (failed)
-				goto out;
-		}
-		next = paths->next;
-		free(paths->name);
-		free(paths);
-		paths = next;
-	}
-
-out:
-	return failed;
-}
-
-static int
-foreachdir(const char *path,
-	   int (*walk)(const char *, const struct stat *))
-{
-	struct stat st;
-
-	if (lstat(path, &st))
-		return walk(path, NULL);
-	return foreachdir_rec(path, &st, walk);
-}
-
-static int
-walk(const char *path, const struct stat *st)
-{
-	size_t prefix_len=strlen(opt_prefix), suffix_len=strlen(opt_suffix);
-	size_t len = strlen(path);
-	char *p;
-	int ret;
-
-	if (!st) {
-		perror(path);
-		return 1;
-	}
-	if (!S_ISREG(st->st_mode))
-		return 0;
-	if (strncmp(opt_prefix, path, prefix_len))
-		return 0;  /* prefix does not match */
-	if (len < suffix_len || strcmp(opt_suffix, path + len - suffix_len))
-		return 0;  /* suffix does not match */
-
-	p = malloc_nofail(len - prefix_len - suffix_len + 1);
-	memcpy(p, path + prefix_len, len - prefix_len - suffix_len);
-	p[len - prefix_len - suffix_len] = '\0';
-	ret = process_file(p);
-	free(p);
-	return ret;
-}
-
-int
-main(int argc, char *argv[])
-{
-	int opt, status = 0;
-
-	progname = argv[0];
-
-	while ((opt = getopt(argc, argv, "brkxB:z:f:shLt")) != -1) {
-		switch(opt) {
-			case 'b':
-				opt_what = what_backup;
-				break;
-
-			case 'r':
-				opt_what = what_restore;
-				break;
-
-			case 'k':
-				opt_keep_backup = 1;
-				break;
-
-			case 'x':
-				opt_what = what_remove;
-				break;
-
-			case 'B':
-				opt_prefix = optarg;
-				break;
-
-			case 'f':
-				opt_file = optarg;
-				break;
-
-			case 'z':
-				opt_suffix = optarg;
-				break;
-
-			case 's':
-				opt_silent = 1;
-				break;
-
-			case 'L':
-				opt_nolinks = 1;
-				break;
-
-			case 't':
-				opt_touch = 1;
-				break;
-
-			case 'h':
-			default:
-				usage();
-				return 0;
-		}
-	}
-
-	if ((*opt_prefix == '\0' && *opt_suffix == '\0') ||
-	    (opt_file == NULL && optind == argc)) {
-		usage();
-		return 1;
-	}
-
-	if (opt_file != NULL) {
-		FILE *file;
-		char line[LINE_LENGTH];
-
-		if (!strcmp(opt_file, "-")) {
-			file = stdin;
-		} else {
-			if ((file = fopen(opt_file, "r")) == NULL) {
-				perror(opt_file);
-				return 1;
-			}
-		}
-
-		while (fgets(line, sizeof(line), file)) {
-			char *l = strchr(line, '\0');
-
-			if (l > line && *(l-1) == '\n')
-				*(l-1) = '\0';
-			if (*line == '\0')
-				continue;
-
-			if ((status = process_file(line)) != 0)
-				return status;
-		}
-
-		if (file != stdin) {
-			fclose(file);
-		}
-	}
-	for (; optind < argc; optind++) {
-		if (strcmp(argv[optind], "-") == 0) {
-			struct stat st;
-			char *dir = strdup(opt_prefix), *d = strrchr(dir, '/');
-			if (d)
-				*d = '\0';
-			else
-				d = ".";
-			if (stat(dir, &st) == 0) {
-				status = foreachdir(dir, walk);
-				if (status == -1)
-					perror(dir);
-			}
-			free(dir);
-		} else
-			status = process_file(argv[optind]);
-		if (status)
-			return status;
-	}
-
-	return status;
-}
--- a/quilt/remove.in
+++ b/quilt/remove.in
@@ -86,7 +86,7 @@ do
 	fi
 
 	# Restore file from backup
-	if ! $QUILT_LIB/backup-files -r -t -s -B $QUILT_PC/$patch/ "$SUBDIR$file"
+	if ! $QUILT_DIR/scripts/backup-files -r -t -s -B $QUILT_PC/$patch/ "$SUBDIR$file"
 	then
 		printf $"Failed to remove file %s from patch %s\n" \
 		       "$SUBDIR$file" "$(print_patch $patch)" >&2
