Author: Alex Badea <vampire@p16.pub.ro>
[ircu2.10.12-pk.git] / ircd-patch
1 #!/bin/sh
2 #
3 # ircd-patch
4 # Copyright (C) 2002 Alex Badea <vampire@p16.pub.ro>
5 #
6 # $Id: ircd-patch,v 1.3 2002-04-02 11:24:29 isomer Exp $
7 #
8 # Experimental centralized patch system for ircu
9 #
10 # Return codes:
11 #   0 - success
12 #   1 - at least one live patch failed
13 #   2 - at least one simulation (dry run) failed 
14 #   3 - invalid arguments (i.e. no such patch)
15 #   4 - invalid operation (i.e. tried to apply when already applied)
16 #
17
18 DIFFS=patches/diffs
19 MARKS=patches/marks
20 PLIST_FILE=include/patchlist.h
21
22 retcode=0
23 force=0
24
25
26 PLIST=""
27 for fname in $DIFFS/*.diff ; do
28         name=`basename $fname | sed -e 's/\.diff//'`
29         PLIST="$PLIST $name"
30 done
31
32 update_patchlist() {
33         list=""
34         for name in $PLIST ; do
35                 [ -f $MARKS/$name ] && list="$list.$name"
36         done
37         echo "/* This file was automatically generated by ircd-patch */" > $PLIST_FILE
38         echo "#define PATCHLIST \"$list\"" >> $PLIST_FILE
39         echo "Updated $PLIST_FILE"
40 }
41
42 [ ! -d $DIFFS ] && (echo "*** Missing $DIFFS, creating it" ; mkdir -p $DIFFS)
43 [ ! -d $MARKS ] && (echo "*** Missing $MARKS, creating it" ; mkdir -p $MARKS)
44
45 dry_run() {
46         patch -p0 -N -t --dry-run $2 >/dev/null < $1
47 }
48
49 patch_list() {
50         echo "Available patches (* marks applied patches):"
51         for name in $PLIST ; do
52                 [ -f $MARKS/$name ] && echo -n " * " || echo -n "   "
53                 echo $name
54         done
55         echo "Done."
56 }
57
58 patch_test() {
59         echo "Testing patches:"
60         list="$*"
61         [ -z "$list" ] && list=$PLIST
62         for name in $list ; do
63                 fname=$DIFFS/$name.diff
64                 echo -ne "  $name\t"
65                 if [ ! -f $MARKS/$name ] ; then
66                         if dry_run "$fname" ; then
67                                 echo -n " OK"
68                         else
69                                 echo -n " PATCH FAILED"
70                                 retcode=2
71                         fi
72                 else
73                         echo -n " APPLIED"
74                         if dry_run "$fname" -R ; then
75                                 echo -n " OK"
76                         else
77                                 echo -n " REVERSE FAILED"
78                                 retcode=2
79                         fi
80                 fi
81                 echo
82         done
83         echo "Done."
84 }
85
86 patch_add() {
87         name=$1
88         fname="$DIFFS/$name.diff"
89         if [ ! -f $fname ]; then
90                 echo "Patch $name ($fname) does not exist"
91                 retcode=3
92                 return
93         fi
94
95         if [ $force -lt 2 -a -f $MARKS/$name ] ; then
96                 echo "Patch $name seems already applied"
97                 retcode=4
98                 return
99         fi
100
101         if [ $force -lt 1 ]; then
102                 echo -n "Testing $fname... "
103                 if ! dry_run $fname ; then
104                         echo "Failed (use -f to force)."
105                         retcode=2
106                         return
107                 fi
108                 echo "seems ok."
109         fi
110
111         echo "Applying $fname..."
112         if patch -p0 -N -t < $fname ; then
113                 touch $MARKS/$name
114                 echo "Done."
115         else
116                 echo "Failed."
117                 retcode=1
118         fi
119 }
120
121 patch_del() {
122         name=$1
123         fname="$DIFFS/$name.diff"
124         if [ ! -f $fname ]; then
125                 echo "Patch $name ($fname) does not exist"
126                 retcode=3
127                 return
128         fi
129
130         if [ $force -lt 2 -a ! -f $MARKS/$name ] ; then
131                 echo "Patch $name doesn't seem to be applied"
132                 retcode=4
133                 return
134         fi
135
136         if [ $force -lt 1 ]; then
137                 echo -n "Testing $fname... "
138                 if ! dry_run $fname -R ; then
139                         echo "Failed (use -f to force)."
140                         retcode=2
141                         return
142                 fi
143                 echo "seems ok."
144         fi
145         
146         echo "Reversing $fname..."
147         if patch -p0 -R -t < $fname ; then
148                 rm -f $MARKS/$name
149                 echo "Done."
150         else
151                 echo "Failed."
152                 retcode=1
153         fi
154 }
155
156 do_help() {
157         echo "Usage: $0 [-f [-f]] [args]"
158         echo "Arguments may be:"
159         echo "  help                Prints this help"
160         echo "  list                List available patches"
161         echo "  test [patch list]   Tests whether patches can be (un)applied correctly"
162         echo "  add  <patch list>   Applies a patch"
163         echo "  del  <patch list>   Reverses a patch"
164         echo "  update              Updates $PLIST_FILE with the currently applied patches"
165         echo "The -f option forces patching even if a dry run fails (effective on 'add'"
166         echo "and 'del' commands only). Using it twice will also skip checking whether"
167         echo "a patch is already applied."
168 }
169
170 while [ "$1" == "-f" ]; do
171         force=$[$force + 1]
172         shift
173 done
174
175 case "$1" in
176         add)
177                 shift
178                 for name in $* ; do
179                         patch_add $name
180                 done
181                 update_patchlist
182                 ;;
183         del)
184                 shift
185                 for name in $* ; do
186                         patch_del $name
187                 done
188                 update_patchlist
189                 ;;
190         test)
191                 shift
192                 patch_test $*
193                 ;;
194         list)
195                 patch_list
196                 ;;
197         update)
198                 update_patchlist
199                 ;;
200         *)
201                 do_help
202                 ;;
203 esac
204
205 exit $retcode