OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / utils / patcher
1 #! /bin/sh
2 # smart patch applier
3 # Copyright (C) 1999, 2001  Henry Spencer.
4
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2 of the License, or (at your
8 # option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 # for more details.
14 #
15 # patcher [-v] [-c] targetdir target [ key patchfile ] ...
16 # In targetdir, patch target from patchfile unless it already contains
17 # key and it appears to have been patched with the same patch.  (If the
18 # patch has changed, undo the old one and then put the new one in.)  Save
19 # original as target.preipsec, and patched copy as target.wipsec, with
20 # patch md5sum stored as target.ipsecmd5.  If the patch doesn't work,
21 # put the original back and save the patch attempt as target.mangled.
22 # If there are no key+patchfile pairs, undo any old patch and leave it
23 # at that.
24 # -v means verbose
25 # -c means do "patching" by appending rather than by using patch(1)
26 #
27 # RCSID $Id: patcher,v 1.13 2001/08/15 04:28:04 henry Exp $
28
29 PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
30 export PATH
31 umask 022
32
33 verbose=
34 modifier=patch
35 for dummy
36 do
37         case "$1" in
38         -v)     verbose=yes             ;;
39         -c)     modifier=cat            ;;
40         --)     shift ; break           ;;
41         -*)     echo "$0: unknown option \`$1'" >&2 ; exit 2    ;;
42         *)      break                   ;;
43         esac
44         shift
45 done
46 if test $# -lt 2
47 then
48         echo "Usage: $0 [-v] [-c] targetdir target [ key patchfile ] ..." >&2
49         exit 2
50 fi
51
52 need() {
53         if test ! -f $1
54         then
55                 echo "$0: cannot find file \`$1'" >&2
56                 exit 1
57         fi
58 }
59
60 note() {
61         if test "$verbose"
62         then
63                 echo "* $1"
64         fi
65 }
66
67 dir="$1"
68 target="$2"
69 shift ; shift
70 it=$dir/$target
71 need $it
72
73
74
75 patches=
76 if test ! -s $it.ipsecmd5
77 then
78         # no records of patching...
79         while test $# -ge 2
80         do
81                 key="$1"
82                 patchfile="$2"
83                 shift ; shift
84                 need $patchfile
85
86                 if egrep -q "$key" $it
87                 then
88                         # patched but no record of how
89                         note "$it no longer needs patch $patchfile"
90                 else
91                         patches="$patches $patchfile"
92                 fi
93         done
94 elif test ! -f $it.preipsec -o ! -f $it.wipsec
95 then
96         echo "$0: $it.preipsec or .wipsec is missing!" >&2
97         exit 1
98 else
99         # determine whether patches have changed
100         tmp=/tmp/patcher.$$
101         >$tmp
102         while test $# -ge 2
103         do
104                 key="$1"
105                 patchfile="$2"
106                 shift ; shift
107                 need $patchfile
108                 md5sum $patchfile | awk '{print $1}' >>$tmp
109
110                 if egrep -q "$key" $it.preipsec
111                 then
112                         note "$it no longer needs patch $patchfile"
113                 else
114                         patches="$patches $patchfile"
115                 fi
116         done
117         if cmp -s $tmp $it.ipsecmd5
118         then
119                 note "$it already fully patched"
120                 rm -f $tmp
121                 exit 0
122         fi
123         rm -f $tmp
124
125         # must undo old patch(es)
126         note "$it old patches must be undone, undoing them..."
127         if ! cmp -s $it $it.wipsec
128         then
129                 note "$it has changed, cannot undo old patches!"
130                 echo "$0: cannot unpatch $it, it has changed since patching" >&2
131                 exit 1
132         fi
133         rm $it
134         mv $it.preipsec $it
135         rm $it.wipsec $it.ipsecmd5
136 fi
137
138 # if no necessary patches, we're done
139 if test " $patches" = " "
140 then
141         note "$it no longer needs patching"
142         exit 0
143 fi
144
145 # try to figure out patch options
146 if test " $modifier" = " patch"
147 then
148         if patch --help >/dev/null 2>/dev/null
149         then
150                 # looks like a modern version
151                 popts='-p0 -b'
152         else
153                 # looks like an old one
154                 popts='-p0'
155         fi
156 fi
157
158 # do it
159 cp -p $it $it.preipsec || exit 0
160 >$it.ipsecmd5
161 for patchfile in $patches
162 do
163         note "applying $patchfile to $it..."
164         case "$modifier" in
165         patch)  ( cd $dir ; patch $popts ) <$patchfile  ;;
166         cat)    cat $patchfile >>$it                    ;;
167         esac
168         status=$?
169         if test $status -ne 0
170         then
171                 note "$it patch failed, restoring original"
172                 echo "$0: patch on $it failed!" >&2
173                 echo "$0: restoring original $it," >&2
174                 echo "$0: leaving patch attempt in $it.mangled" >&2
175                 mv $it $it.mangled
176                 mv $it.preipsec $it
177                 rm -f $it.ipsecmd5
178                 exit 1
179         fi
180         rm -f $it.orig          # some patch versions leave debris
181         md5sum $patchfile | awk '{print $1}' >>$it.ipsecmd5
182 done
183 cp -p $it $it.wipsec