summaryrefslogtreecommitdiff
path: root/packaging/utils/patcher
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/utils/patcher')
-rwxr-xr-xpackaging/utils/patcher188
1 files changed, 188 insertions, 0 deletions
diff --git a/packaging/utils/patcher b/packaging/utils/patcher
new file mode 100755
index 000000000..ba31bdd26
--- /dev/null
+++ b/packaging/utils/patcher
@@ -0,0 +1,188 @@
+#! /bin/sh
+# smart patch applier
+# Copyright (C) 1999, 2001 Henry Spencer.
+#
+# 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+#
+# 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.
+#
+# patcher [-v] [-c] targetdir target [ key patchfile ] ...
+# In targetdir, patch target from patchfile unless it already contains
+# key and it appears to have been patched with the same patch. (If the
+# patch has changed, undo the old one and then put the new one in.) Save
+# original as target.preipsec, and patched copy as target.wipsec, with
+# patch md5sum stored as target.ipsecmd5. If the patch doesn't work,
+# put the original back and save the patch attempt as target.mangled.
+# If there are no key+patchfile pairs, undo any old patch and leave it
+# at that.
+# -v means verbose
+# -c means do "patching" by appending rather than by using patch(1)
+#
+# RCSID $Id: patcher,v 1.1 2004/03/15 20:35:27 as Exp $
+
+PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
+export PATH
+umask 022
+
+verbose=
+modifier=patch
+for dummy
+do
+ case "$1" in
+ -v) verbose=yes ;;
+ -c) modifier=cat ;;
+ --) shift ; break ;;
+ -*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
+ *) break ;;
+ esac
+ shift
+done
+if test $# -lt 2
+then
+ echo "Usage: $0 [-v] [-c] targetdir target [ key patchfile ] ..." >&2
+ exit 2
+fi
+
+need() {
+ if test ! -f $1
+ then
+ echo "$0: cannot find file \`$1'" >&2
+ exit 1
+ fi
+}
+
+note() {
+ if test "$verbose"
+ then
+ echo "* $1"
+ fi
+}
+
+dir="$1"
+target="$2"
+shift ; shift
+it=$dir/$target
+need $it
+
+
+
+patches=
+if test ! -s $it.ipsecmd5
+then
+ # no records of patching...
+ while test $# -ge 2
+ do
+ key="$1"
+ patchfile="$2"
+ shift ; shift
+ need $patchfile
+
+ if egrep -q "$key" $it
+ then
+ # patched but no record of how
+ note "$it no longer needs patch $patchfile"
+ else
+ patches="$patches $patchfile"
+ fi
+ done
+elif test ! -f $it.preipsec -o ! -f $it.wipsec
+then
+ echo "$0: $it.preipsec or .wipsec is missing!" >&2
+ exit 1
+else
+ # determine whether patches have changed
+ tmp=/tmp/patcher.$$
+ >$tmp
+ while test $# -ge 2
+ do
+ key="$1"
+ patchfile="$2"
+ shift ; shift
+ need $patchfile
+ md5sum $patchfile | awk '{print $1}' >>$tmp
+
+ if egrep -q "$key" $it.preipsec
+ then
+ note "$it no longer needs patch $patchfile"
+ else
+ patches="$patches $patchfile"
+ fi
+ done
+ if cmp -s $tmp $it.ipsecmd5
+ then
+ note "$it already fully patched"
+ rm -f $tmp
+ exit 0
+ fi
+ rm -f $tmp
+
+ # must undo old patch(es)
+ note "$it old patches must be undone, undoing them..."
+ if ! cmp -s $it $it.wipsec
+ then
+ note "$it has changed, cannot undo old patches!"
+ echo "$0: cannot unpatch $it, it has changed since patching" >&2
+ exit 1
+ fi
+ rm $it
+ mv $it.preipsec $it
+ rm $it.wipsec $it.ipsecmd5
+fi
+
+# if no necessary patches, we're done
+if test " $patches" = " "
+then
+ note "$it no longer needs patching"
+ exit 0
+fi
+
+# try to figure out patch options
+if test " $modifier" = " patch"
+then
+ if patch --help >/dev/null 2>/dev/null
+ then
+ # looks like a modern version
+ popts='-p1 -b'
+ else
+ # looks like an old one
+ popts='-p1'
+ fi
+fi
+
+# do it
+>$it.ipsecmd5
+for patchfile in $patches
+do
+ note "applying $patchfile to $it..."
+
+ # make local copy - this defeats hard and soft links
+ mv $it $it.preipsec || exit 0
+ rm -f $it
+ cp -p $it.preipsec $it
+
+ case "$modifier" in
+ patch) ( cd $dir ; patch $popts ) <$patchfile ;;
+ cat) cat $patchfile >>$it ;;
+ esac
+ status=$?
+ if test $status -ne 0
+ then
+ note "$it patch failed, restoring original"
+ echo "$0: patch on $it failed!" >&2
+ echo "$0: restoring original $it," >&2
+ echo "$0: leaving patch attempt in $it.mangled" >&2
+ mv $it $it.mangled
+ mv $it.preipsec $it
+ rm -f $it.ipsecmd5
+ exit 1
+ fi
+ rm -f $it.orig # some patch versions leave debris
+ md5sum $patchfile | awk '{print $1}' >>$it.ipsecmd5
+done
+cp -p $it $it.wipsec