]> jfr.im git - irc/quakenet/snircd.git/blob - ircd-patch
Need to step back here too
[irc/quakenet/snircd.git] / ircd-patch
1 #!/bin/sh
2 #
3 # IRC - Internet Relay Chat, ircd-patch
4 # Copyright (C) 2002 Alex Badea <vampire@p16.pub.ro>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 1, or (at your option)
9 # any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #
20 # $Id: ircd-patch,v 1.5.2.1 2005/12/29 03:41:56 entrope Exp $
21 #
22 #
23 # Experimental centralized patch system for ircu
24 # Run with no arguments to get help.
25 #
26 # Return codes:
27 # 0 - success
28 # 1 - at least one live patch failed
29 # 2 - at least one simulation (dry run) failed
30 # 3 - invalid arguments (i.e. no such patch)
31 # 4 - invalid operation (i.e. tried to apply when already applied)
32 #
33
34 DIFFS=patches/diffs
35 MARKS=patches/marks
36 PLIST_FILE=include/patchlist.h
37
38 retcode=0
39 force=0
40
41
42 PLIST=""
43 for fname in $DIFFS/*.diff ; do
44 name=`basename $fname | sed -e 's/\.diff//'`
45 PLIST="$PLIST $name"
46 done
47
48 update_patchlist() {
49 list=""
50 for name in $PLIST ; do
51 test -f $MARKS/$name && list="$list.$name"
52 done
53 echo "/* This file was automatically generated by ircd-patch */" > $PLIST_FILE
54 echo "#define PATCHLIST \"$list\"" >> $PLIST_FILE
55 echo "Updated $PLIST_FILE"
56 }
57
58 test -d $DIFFS || (echo "*** Missing $DIFFS, creating it" ; mkdir -p $DIFFS)
59 test -d $MARKS || (echo "*** Missing $MARKS, creating it" ; mkdir -p $MARKS)
60
61 dry_run() {
62 rejects=`patch -p0 -N -t --dry-run $2 < $1 | grep "hunk FAILED" | sed -e 's/.*to file / /;s/\.rej$//'`
63 test -z "$rejects"
64 }
65
66 patch_list() {
67 echo "Available patches (* marks applied patches):"
68 for name in $PLIST ; do
69 test -f $MARKS/$name && echo -n " * " || echo -n " "
70 echo $name
71 done
72 echo "Done."
73 }
74
75 patch_test() {
76 echo "Testing patches:"
77 list="$*"
78 test "z$list" = "z" && list=$PLIST
79 for name in $list ; do
80 fname=$DIFFS/$name.diff
81 echo -ne " $name\t"
82 if test ! -f $MARKS/$name ; then
83 if dry_run "$fname" ; then
84 echo -n " OK"
85 else
86 echo -n " PATCH FAILED"
87 retcode=2
88 fi
89 else
90 echo -n " APPLIED"
91 if dry_run "$fname" -R ; then
92 echo -n " OK"
93 else
94 echo -n " REVERSE FAILED"
95 retcode=2
96 fi
97 fi
98 echo
99 done
100 echo "Done."
101 }
102
103 patch_add() {
104 name=$1
105 fname="$DIFFS/$name.diff"
106 if test ! -f $fname ; then
107 echo "Patch $name ($fname) does not exist"
108 retcode=3
109 return
110 fi
111
112 if test $force -lt 2 -a -f $MARKS/$name ; then
113 echo "Patch $name seems already applied"
114 retcode=4
115 return
116 fi
117
118 if test $force -lt 1 ; then
119 echo -n "Testing $fname... "
120 if ! dry_run $fname ; then
121 echo "Failed (use -f to force)."
122 echo "The following files failed patching:"
123 echo "$rejects"
124 retcode=2
125 return
126 fi
127 echo "seems ok."
128 fi
129
130 echo "Applying $fname..."
131 if patch -p0 -N -t < $fname ; then
132 touch $MARKS/$name
133 echo "Done."
134 else
135 echo "Failed."
136 retcode=1
137 fi
138 }
139
140 patch_del() {
141 name=$1
142 fname="$DIFFS/$name.diff"
143 if test ! -f $fname ; then
144 echo "Patch $name ($fname) does not exist"
145 retcode=3
146 return
147 fi
148
149 if test $force -lt 2 -a ! -f $MARKS/$name ; then
150 echo "Patch $name doesn't seem to be applied"
151 retcode=4
152 return
153 fi
154
155 if test $force -lt 1 ; then
156 echo -n "Testing $fname... "
157 if ! dry_run $fname -R ; then
158 echo "Failed (use -f to force)."
159 echo "The following files failed patching:"
160 echo "$rejects"
161 retcode=2
162 return
163 fi
164 echo "seems ok."
165 fi
166
167 echo "Reversing $fname..."
168 if patch -p0 -R -t < $fname ; then
169 rm -f $MARKS/$name
170 echo "Done."
171 else
172 echo "Failed."
173 retcode=1
174 fi
175 }
176
177 do_help() {
178 echo "Usage: $0 [-f [-f]] [args]"
179 echo "Arguments may be:"
180 echo " help Prints this help"
181 echo " list List available patches"
182 echo " test [patch list] Tests whether patches can be (un)applied correctly"
183 echo " add <patch list> Applies a patch"
184 echo " del <patch list> Reverses a patch"
185 echo " update Updates $PLIST_FILE with the currently applied patches"
186 echo "The -f option forces patching even if a dry run fails (effective on 'add'"
187 echo "and 'del' commands only). Using it twice will also skip checking whether"
188 echo "a patch is already applied."
189 }
190
191 while test "$1" = "-f" ; do
192 force=`expr $force + 1`
193 shift
194 done
195
196 case "$1" in
197 add)
198 shift
199 for name in $* ; do
200 patch_add $name
201 done
202 update_patchlist
203 ;;
204 del)
205 shift
206 for name in $* ; do
207 patch_del $name
208 done
209 update_patchlist
210 ;;
211 test)
212 shift
213 patch_test $*
214 ;;
215 list)
216 patch_list
217 ;;
218 update)
219 update_patchlist
220 ;;
221 *)
222 do_help
223 ;;
224 esac
225
226 exit $retcode