From 21a15e55a81ea4bd2bc21729ceebe6be6a9ccd9b Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Fri, 31 Jan 2003 12:45:37 +0000 Subject: Install binary backup-files into /usr/lib/quilt and the remaining scripts under /usr/share/quilt/scripts. --- scripts/rpatch.in | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100755 scripts/rpatch.in (limited to 'scripts/rpatch.in') diff --git a/scripts/rpatch.in b/scripts/rpatch.in new file mode 100755 index 0000000..afdf230 --- /dev/null +++ b/scripts/rpatch.in @@ -0,0 +1,254 @@ +#! @BASH@ + +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# See the COPYING and AUTHORS files for more details. + +# Read in library functions +if [ "$(type -t patch_file_name)" != function ] +then + if ! [ -r @SCRIPTS@/patchfns ] + then + echo "Cannot read library @SCRIPTS@/patchfns" >&2 + exit 1 + fi + . @SCRIPTS@/patchfns +fi + +usage() +{ + echo "Usage: $0 [-fRq] patchname" + exit 1 +} + +verify_removal() +{ + local patch=$1 + local bup file status=0 + local dir=$(basename $PWD) suffix=${patch//\//_} + + # Check if all changes of the patch are undone + for file in $(files_in_patch $patch) + do + bup=$(backup_file_name $patch $file) + if ! [ -s $file -o -s $bup ] || \ + cmp $file $bup > /dev/null 2> /dev/null + then + continue + fi + + if [ $status -eq 0 ] + then + echo "Patch does not remove changes:" + fi + + @DIFF@ -Nu $DIFF_OPTS $bup $file \ + | sed -e 's:^--- [^ \t]*:--- '"$dir/$file.orig"':' \ + -e 's:^+++ [^ \t]*:+++ '"$dir/$file"':' + + status=1 + done + return $status +} + +files_may_have_changed() +{ + local patch=$1 file + local patch_file=$(patch_file_name $patch) + local pc_file=$(pc_file_name $patch) + + if ! [ -e $pc_file ] + then + return 1 + fi + + local apply_ts=$(date -r $pc_file '+%s') ts + + if [ -e "$patch_file" -a $pc_file -ot "$patch_file" ] + then + return 0 + fi + + for file in $(files_in_patch $patch) + do + if ! [ -e $file ] + then + return 0 # file is missing + fi + + ts=$(date -r $file '+%s') + if [ $? -ne 0 -o $ts -gt $apply_ts ] + then + return 0 # file has changed + fi + done + return 1 +} + +rollback_patch() +{ + local patch=$1 pc_file=$(pc_file_name $patch) + @LIB@/backup-files $silent_unless_verbose \ + -f $pc_file -z ~rpatch -r + rm -f $(files_in_patch $patch | sed -e 's/$/\.rej/') +} + +interrupt() +{ + local patch=$1 + rollback_patch $patch + echo "Interrupted by user; patch $patch was not removed." + exit 1 +} + +reverse_patch() +{ + local patch=$1 + local patch_file=$(patch_file_name $patch) + + if ! [ -s $patch_file ] + then + echo "Patch file $patch_file appears to be empty" + return 0 + fi + + if [ "x${patch_file:(-3)}" = "x.gz" ] + then + gzip -cd $patch_file \ + | @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ + -R -E $silent + elif [ "x${patch_file:(-4)}" = "x.bz2" ] + then + bzip2 -cd $patch_file \ + | @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ + -R -E $silent + else + @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ + -R -E $silent -i $patch_file + fi +} + +rpatch() +{ + local patch=$1 pc_file=$(pc_file_name $patch) + + if ! [ -e $pc_file ] + then + echo "Patch $patch appears to be empty, removed" + remove_from_db $patch + return 0 + fi + + trap "" SIGINT + if [ -n "$opt_force" ] || \ + ( [ -z "$opt_remove" ] && ! files_may_have_changed $patch ) + then + # Optimize: Force remove if the patch has not been + # modified since it was applied. (Forced remove is + # faster!) + + @LIB@/backup-files $silent -f $pc_file -B .pc/$patch/ -r + status=$? + remove_from_db $patch + rm -f $pc_file~refresh + if [ $status != 0 ] + then + exit $status + fi + else + if ! @LIB@/backup-files $silent_unless_verbose \ + -f $pc_file -z ~rpatch + then + echo "Failed to create temporary files" >&2 + return 1 + fi + + trap "interrupt $patch" SIGINT + + reverse_patch $patch + status=$? + + trap "" SIGINT + + if [ $status -eq 0 ] && verify_removal $patch + then + @LIB@/backup-files $silent_unless_verbose \ + -f $pc_file -z ~rpatch -x + @LIB@/backup-files $silent_unless_verbose \ + -f $pc_file -B .pc/$patch/ -x + + remove_from_db $patch + else + rollback_patch $patch + echo "Patch $patch does not remove (enforce with -f)" + return 1 + fi + fi + trap - SIGINT + + local top=$(top_patch) where + if [ -z "$top" ] + then + where="no patches applied" + else + where="now at $top" + fi + echo "Removed $patch, $where" +} + +options=`getopt -o fRqvh -- "$@"` + +if [ $? -ne 0 ] +then + usage +fi + +eval set -- "$options" + +while true +do + case "$1" in + -f) + opt_force=1 + shift ;; + -R) + opt_remove=1 # remove properly with patch -R; no tricks + unset opt_force + shift ;; + -q) + opt_quiet=1 + shift ;; + -v) + opt_verbose=1 + shift ;; + -h) + usage -h ;; + --) + shift + break ;; + esac +done + +if [ $# -ne 1 ] +then + usage +fi + +patch=$(stripit $1) +[ -n "$opt_quiet" ] && silent=-s +[ -z "$opt_verbose" ] && silent_unless_verbose=-s + +top=$(top_patch) +if [ -n "$top" -a -e $(pc_file_name $top)~refresh -a -z "$opt_force" ] +then + echo "The topmost patch $top needs to be refreshed first." + exit 1 +fi + +rpatch "$patch" || exit 1 +### Local Variables: +### mode: shell-script +### End: +# vim:filetype=sh -- cgit