root/floppyfw/patches/run-pom.sh

Revision 1, 26.1 KB (checked in by root, 6 years ago)

First post

Line 
1#! /bin/sh
2# Script to ask user if they want patches applied or reversed.
3# Sun 12 Nov 2000 Harald Welte <laforge@gnumonks.org>
4#               - added support for other protocols than ipv4
5# Tue 12 Feb 2002 Bob Hockney <zeus@ix.netcom.com>
6#               - added support for reverting patches out
7# Fri 22 Feb 2002 Fabrice MARIE <fabrice@netfilter.org>
8#               - added support for userspace/ patches
9# Sat 25 Jan 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
10#               - removed copying the source trees for testing
11# Fri 21 Feb 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
12#               - added dependecy support
13# Sat  5 Apr 2003 Martin Josefsson <gandalf@wlug.westbo.se>
14#               - added support for conflicting dependencies
15#               - readded partial support for sourcetree copying
16#               - fix support for userspace/ patches
17# Mon  7 Apr 2003 Martin Josefsson <gandalf@wlug.westbo.se>
18#               - add support for batch testing
19#
20
21#set -x
22
23printheader()
24{
25    clear 2> /dev/null
26    echo "Welcome to Rusty's Patch-o-matic!"
27    echo
28    echo "Kernel:    $KERNEL_DIR"
29    echo "Userspace: $NETFILTERDIR"
30    echo
31    echo "Each patch is a new feature: many have minimal impact, some do not."
32    echo "Almost every one has bugs, so I don't recommend applying them all!"
33    echo "-------------------------------------------------------"
34    if [ -n "$1" ]; then
35        if [ $MODE ]; then
36            echo -n "NOT applied:     "
37        else
38            echo -n "Already applied: "
39        fi
40        rest=${1# }
41        first=${rest%% *}
42        rest=${1#*$first}
43        echo $first
44        for x in $rest
45        do
46            echo "                 $x"
47        done
48        echo
49    fi 
50}
51
52entertocont()
53{
54        echo ""
55        echo "[Press enter to continue]"
56        read enter
57        echo
58}
59
60#
61# WARNING: this function could fail, always check the output.
62#
63tmpdirname()
64{
65        dd if=/dev/urandom bs=32 count=1 2>/dev/null | od -x -w32 -A n | tr -d ' '
66}
67
68alloc_ktmpdir()
69{
70        if [ "$KTMPDIR" == "$KERNEL_DIR" ]; then
71                KTMPDIR=`tmpdirname`
72                # I'm really paranoid.  What if there's no /dev/urandom?
73                if [ -z "$KTMPDIR" ]; then
74                   echo Failed to generate kernel tmpdirname: perhaps your /dev/urandom is broken >&2
75                   free_utmpdir
76                   exit 1
77                fi
78                KTMPDIR=$KERNEL_DIR/../$KTMPDIR
79                if cp -al $KERNEL_DIR/. $KTMPDIR
80                then :
81                else
82                   echo Failed to make copy of $KERNEL_DIR >&2
83                   free_ktmpdir
84                   free_utmpdir
85                   exit 1
86                fi
87        fi
88}
89
90free_ktmpdir()
91{
92        if [ "$KTMPDIR" != "$KERNEL_DIR" ]; then
93                rm -rf $KTMPDIR
94                KTMPDIR=$KERNEL_DIR
95        fi
96}
97
98alloc_utmpdir()
99{
100        if [ "$UTMPDIR" == "$NETFILTERDIR" ]; then
101                UTMPDIR=`tmpdirname`
102                # I'm really paranoid.  What if there's no /dev/urandom?
103                if [ -z "$UTMPDIR" ]; then
104                   echo Failed to generate userspace tmpdirname: perhaps your /dev/urandom is broken >&2
105                   free_ktmpdir
106                   exit 1
107                fi
108                UTMPDIR=$NETFILTERDIR/../$UTMPDIR
109                if cp -al $NETFILTERDIR/. $UTMPDIR
110                then :
111                else
112                   echo Failed to make copy of $NETFILTERDIR >&2
113                   free_utmpdir
114                   free_ktmpdir
115                   exit 1
116                fi
117        fi
118}
119
120free_utmpdir()
121{
122        if [ "$UTMPDIR" != "$NETFILTERDIR" ]; then
123                rm -rf $UTMPDIR
124                UTMPDIR=$NETFILTERDIR
125        fi
126}
127
128# Too many rejects from trying to patch Configure.help/Config.help and Config.in.
129# So we use special format: First line specifies entry we want to
130# follow, and rest of file is pasted in under that.
131
132# Args: "patch" file, directory, file to patch, test mode
133apply_change()
134{
135    PRIOR="`head -1 $1`"
136    LINE=`fgrep -x -n "$PRIOR" $2/$3 | cut -d: -f1 | head -1`
137    if [ -z "$LINE" ]
138    then
139        echo Could not find place to slot in $3 line >&2
140        return 1
141    fi
142    rm -f $2/${3}.tmp
143 
144    if [ $MODE ]; then
145        # Reverse "patch"
146
147        # Need to search for previously inserted lines
148        # Might not be immediately under $LINE
149        BEGIN=2
150        TESTLINE=$BEGIN
151        NUMLINES1=`sed -n \$= $1`
152        NUMLINES2=`sed -n \$= $2/$3`
153
154        while [ $TESTLINE -le $NUMLINES1 ]; do
155            NOMATCH=`awk "NR==$LINE + $TESTLINE - 1" $2/$3|\
156                    fgrep -vcx "\`sed -n -e ${TESTLINE}p $1\`"`;
157            if [ $NOMATCH -ne 0 ]; then
158                LINE=`expr $LINE + $TESTLINE - 1`
159                TESTLINE=$BEGIN
160                continue
161            fi;
162
163            TESTLINE=`expr $TESTLINE + 1`;
164
165        done;
166
167        if [ $LINE -lt $NUMLINES2 ] && \
168            (awk "NR==1,NR==$LINE" $2/$3 && awk "NR==$LINE + $NUMLINES1,NR=0" $2/$3) > $2/${3}.tmp
169        then
170            if [ "$4" = "test" ]
171            then
172                rm -f $2/${3}.tmp
173            else
174                mv $2/${3}.tmp $2/$3
175            fi
176            echo "   $3 updated"
177            return 0
178        else
179            echo Could not update $3 >&2
180            rm -f $2/${3}.tmp
181            return 1
182        fi
183    fi
184    # Apply "patch"
185    # Use awk to properly add newline if last line of code has only spaces
186    # Necessary to properly remove inserted code if patch is reversed
187    if (awk "NR==1,NR==$LINE" $2/$3 && awk "NR==2,NR==0" $1 && \
188        awk "NR==$LINE+1,NR==0" $2/$3) > $2/${3}.tmp
189    then
190        if [ "$4" = "test" ]
191        then
192            rm -f $2/${3}.tmp
193        else
194            mv $2/${3}.tmp $2/$3
195        fi
196    else
197        echo Could not slot in $3 line >&2
198        rm -f $2/${3}.tmp
199        return 1
200    fi
201    echo "   Placed new $3 line"
202    return 0
203}
204
205# Args: configure.help file, Documentation file to which to add it.
206apply_config_help_change()
207{
208    if [ "$2" = '/dev/null' ]; then
209        #return 0       #Use this one if you don't care that the config*.help file is not getting updated
210        return 1        #Fail
211    fi
212    BASEFILE=`basename $2`      #Configure.help or Config.help
213    PRIOR="`head -1 $1`"
214    LINE=`fgrep -x -n "$PRIOR" $2 | cut -d: -f1 | head -1`
215    if [ -z "$LINE" ] || [ "$LINE" -eq 0 ]
216    then
217        echo Could not find place to slot in $BASEFILE entry >&2
218        return 1
219    fi
220    rm -f $2.tmp
221
222    if [ $MODE ];
223    then
224        # Reverse "patch"
225
226        NUMLINES1=`sed -n \$= $1`
227        NUMLINES2=`sed -n \$= $2`
228        BEGIN=2
229
230        LINES=`fgrep -nx "\`sed -n 2p $1\`" $2 | cut -d: -f1`
231        if [ -z "$LINES" ]
232        then
233            echo $BASEFILE text not found >&2
234            return 1
235        fi
236
237        # First line of inserted text may appear more than once
238        # Check each occurance
239        MATCHES=
240        for x in $LINES; do
241            TESTLINE=$BEGIN
242            # Be paranoid and check for match on all lines
243            while `let "$TESTLINE <= $NUMLINES1"`; do
244                NOMATCH=`awk "NR==$x + $TESTLINE - $BEGIN" $2|\
245                        fgrep -xcv "\`sed -n -e ${TESTLINE}p $1\`"`;
246
247                if [ $NOMATCH -ne 0 ]; then continue 2; fi
248
249                TESTLINE=`expr $TESTLINE + 1`;
250
251            done; # while
252            MATCHES="$x $MATCHES"
253
254        done; # for
255
256        if [ ! "$MATCHES" ]; then
257            echo $BASEFILE text not found >&2
258            return 1
259        fi;
260
261        for x in $MATCHES; do
262#            if (head -`expr $x - 1` $2 && \
263#                tail -n +`expr $x + $NUMLINES1` $2) > $2.tmp
264            if (awk "NR==1,NR==$x - 1" $2 && \
265                awk "NR==$x + $NUMLINES1,NR=0" $2) > $2.tmp
266            then
267                if [ "$3" = "test" ]
268                then
269                    rm -f $2.tmp
270                else
271                    mv $2.tmp $2
272                fi
273            else
274                echo Could not update $BASEFILE >&2
275                rm -f $2.tmp
276                return 1
277            fi
278        done
279        echo "   $BASEFILE updated"
280        return 0
281    fi
282
283    #Apply "Patch"
284
285    # Use awk to force newline if last line of $1 has only spaces
286    # Necessary to properly remove inserted text if patch is reversed
287    if (awk "NR==1,NR==$LINE-2" $2 && awk "NR==2,NR==0" $1 && echo && \
288        awk "NR==$LINE-1,NR==0" $2) > $2.tmp
289    then
290        if [ "$3" = "test" ]
291        then
292            rm -f $2.tmp
293        else
294            mv $2.tmp $2
295        fi
296    else
297        echo Could not slot in $BASEFILE entry >&2
298        rm -f $2.tmp
299        return 1
300    fi
301    echo "   Placed new $BASEFILE entry"
302    return 0
303}
304
305# Don't like to use GLOBIGNORE stuff; can't use shopt (bash v1).
306expand_no_backups()
307{
308    for expansion in $1
309    do
310        case "$expansion"
311        in
312            "$1") ;;
313            *~) ;;
314            *) echo "$expansion";;
315        esac
316    done
317}
318
319apply_config_in_changes()
320{
321        ret=0
322
323        for x in `expand_no_backups "$1.config.in*"`
324        do
325            apply_change $x $2 Config.in $3 || ret=1
326        done
327
328        return $ret
329}
330
331apply_config_help_changes()
332{
333        ret=0
334
335        for x in `expand_no_backups "$1.configure.help*"`
336        do
337            apply_config_help_change $x $2 $3 || ret=1
338        done
339
340        return $ret
341}
342
343apply_makefile_changes()
344{
345        ret=0
346
347        for x in `expand_no_backups "$1.makefile*"`
348        do
349            apply_change $x $2 Makefile $3 || ret=1
350        done
351
352        return $ret
353}
354
355apply_conntrack_h_changes()
356{
357        ret=0
358        case $2 in
359                *ipv4)
360                        conntrack_h=ip_conntrack.h
361                        ;;
362                *ipv6)
363                        conntrack_h=ip6_conntrack.h
364                        ;;
365                *)
366                        return $ret
367                        ;;
368        esac
369
370        for x in `expand_no_backups "$1.${conntrack_h}*"`
371        do
372            apply_change $x $2 $conntrack_h $3 || ret=1
373        done
374
375        return $ret
376}
377
378# Args: patch filename, protocol.
379test_patch_depend()
380{
381    # Check the dependecy of the patch
382    if [ -f "$1.depend" -a -z "$MODE" ]; then
383        while read dep
384        do
385            if [ -z "${dep###*}" ]; then
386                continue
387            fi
388
389            not=0
390            if [ -z "${dep##not *}" ]; then
391                dep=${dep##not }
392                not=1
393            fi
394
395            if [ ! -f $dep ]; then
396                echo >&2
397                echo "patch $dep which $1 depends on doesn't exist." >&2
398                echo "Report the problem to the patch-o-matic maintainer." >&2
399                echo >&2
400                return 1
401            fi
402           
403            f=${dep%%.patch*}   # filename without .patch*
404            p=${dep##$f.patch}  # protocol, if exist
405            p=${p##.}
406            n=$f${p:+-$p}
407            if [ "`echo $PROCESSED | grep $n`" ]; then
408                if [ $not == 1 ]; then
409                        echo >&2
410                        echo "Conflicting dependency." >&2
411                        echo "   $1" >&2
412                        echo "is incompatible with" >&2
413                        echo "   $dep" >&2
414                        echo >&2
415                        return 1
416                else
417                        continue
418                fi
419            elif [ "`echo "$DEPEND" | grep " $dep "`" ]; then
420                echo >&2
421                echo "Circular dependency, patch $1 cannot be applied." >&2
422                echo "Report the problem to the patch-o-matic maintainer." >&2
423                echo >&2
424                return 1
425            fi
426            if [ $not == 1 ]; then
427                echo Patch $1 conflicts with $dep...
428            else
429                echo Patch $1 depends on $dep...
430            fi
431            DEPEND="$DEPEND $dep "
432            if ./isapplied $KTMPDIR $dep
433            then
434                if [ $not == 1 ]; then
435                        echo >&2
436                        echo "Conflicting dependency." >&2
437                        echo "   $1" >&2
438                        echo "is incompatible with" >&2
439                        echo "   $dep" >&2
440                        echo >&2
441                        return 1
442                fi
443            elif [ $not == 1 ] || apply_patch_depend $dep ${p:-"ipv4"} test
444            then :
445            else
446                return 1
447            fi
448        done < $1.depend
449    fi
450
451    echo Testing patch $1...
452
453    if [ -f "$KTMPDIR/net/$2/netfilter/Config.help" ]; then
454        DOCUMENTATIONFILE="net/$2/netfilter/Config.help"
455    elif [ -f "$KTMPDIR/Documentation/Configure.help" ]; then
456        DOCUMENTATIONFILE="Documentation/Configure.help"
457    else
458        echo Warning - no help text file could be found in either >&2
459        echo $KTMPDIR/net/$2/netfilter/Config.help >&2
460        echo or $KTMPDIR/Documentation/Configure.help >&2
461        DOCUMENTATIONFILE=/dev/null
462    fi
463
464    if apply_config_in_changes $1 $KTMPDIR/net/$2/netfilter test &&
465        apply_config_help_changes $1 $KTMPDIR/$DOCUMENTATIONFILE test &&
466        apply_makefile_changes $1 $KTMPDIR/net/$2/netfilter test &&
467        apply_conntrack_h_changes $1 $KTMPDIR/include/linux/netfilter_$2 test
468    then :
469    else
470        return 1
471    fi
472
473    if (cd $KTMPDIR &&
474        if [ $MODE ]; then
475                patch -R -p1 --dry-run
476        else
477                patch -p1 --dry-run
478        fi > /dev/null) < $1
479    then :
480    else
481        echo "Failed to patch copy of $KERNEL_DIR" >&2
482        return 1
483    fi
484
485    if [ ! -e $1.userspace ];
486    then
487        echo "   Patch $1 `modesense 2` cleanly."
488        return 0
489    fi
490
491    APPLIED=
492    if STATUS=`./isapplied $UTMPDIR $1.userspace`; then APPLIED=Y ; fi
493
494    if (cd $UTMPDIR &&
495        if [ $MODE ]; then
496                if [ $APPLIED ]; then
497                        patch -R -p1 --dry-run
498                else
499                        true
500                fi
501        else
502                if [ -z $APPLIED ]; then
503                        patch -p1 --dry-run
504                else
505                        true
506                fi
507        fi > /dev/null) < $1.userspace
508    then :
509    else
510        echo Failed to patch copy of $NETFILTERDIR >&2
511        return 1
512    fi 
513                                                       
514    echo "   Patch $1 `modesense 2` cleanly."
515    return 0
516}
517
518# I'm paranoid.  Test patch first.
519# Args: patch filename, protocol.
520test_patch()
521{
522    DEPEND=" $1 "
523
524    test_patch_depend $1 $2
525    ret=$?
526
527    free_ktmpdir
528    free_utmpdir
529
530    return $ret
531}
532
533# Args: patch filename, protocol.
534apply_patch_depend()
535{
536    # Are we testing?
537    if [ "$3" == "test" ]; then
538        alloc_ktmpdir
539    fi
540    # Check the dependecy of the patch
541    if [ "$3" != "force" -a -f "$1.depend" -a -z "$MODE" ]; then
542        while read dep
543        do
544            if [ -z "${dep###*}" ]; then
545                continue
546            fi
547
548            not=0
549            if [ -z "${dep##not *}" ]; then
550                dep=${dep##not }
551                not=1
552            fi
553
554            if [ ! -f $dep ]; then
555                echo >&2
556                echo "patch $dep which $1 depends on doesn't exist." >&2
557                echo "Report the problem to the patch-o-matic maintainer." >&2
558                echo >&2
559                return 1
560            fi
561
562            f=${dep%%.patch*}   # filename without .patch*
563            p=${dep##$f.patch}  # protocol, if exist
564            p=${p##.}
565            n=$f${p:+-$p}
566            if [ "`echo $PROCESSED | grep $n`" ]; then
567                if [ $not == 1 ]; then
568                        echo >&2
569                        echo "Conflicting dependency." >&2
570                        echo "   $1" >&2
571                        echo "is incompatible with" >&2
572                        echo "   $dep" >&2
573                        echo >&2
574                        return 1
575                else
576                        continue
577                fi
578            elif [ "`echo "$DEPEND" | grep " $dep "`" ]; then
579                echo >&2
580                echo "Circular dependency, patch $1 cannot be applied." >&2
581                echo "Report the problem to the patch-o-matic maintainer." >&2
582                echo >&2
583                return 1
584            fi
585            if [ $not == 1 ]; then
586                echo Patch $1 conflicts with $dep...
587            else
588                echo Patch $1 depends on $dep...
589            fi
590            DEPEND="$DEPEND $dep "
591            if ./isapplied $KTMPDIR $dep
592            then
593                if [ $not == 1 ]; then
594                        echo >&2
595                        echo "Conflicting dependency." >&2
596                        echo "   $1" >&2
597                        echo "is incompatible with" >&2
598                        echo "   $dep" >&2
599                        echo >&2
600                        return 1
601                fi
602            elif [ $not == 1 ] || apply_patch_depend $dep ${p:-"ipv4"} $3
603            then :
604            else
605                return 1
606            fi
607        done < $1.depend
608    fi
609
610    echo `modesense 3` patch $1...
611
612    if (cd $KTMPDIR &&
613        if [ $MODE ]; then
614                patch -R -p1
615        else
616                patch -p1
617        fi > /dev/null) < $1
618    then :
619    else
620        echo "Failed to patch copy of $KERNEL_DIR" >&2
621        return 1
622    fi
623
624    if [ -f "$KTMPDIR/net/$2/netfilter/Config.help" ]; then
625        DOCUMENTATIONFILE="net/$2/netfilter/Config.help"
626    elif [ -f "$KTMPDIR/Documentation/Configure.help" ]; then
627        DOCUMENTATIONFILE="Documentation/Configure.help"
628    else
629        echo Warning - no help text file could be found in either >&2
630        echo $KTMPDIR/net/$2/netfilter/Config.help >&2
631        echo or $KTMPDIR/Documentation/Configure.help >&2
632        DOCUMENTATIONFILE=/dev/null
633    fi
634
635    apply_config_in_changes $1 $KTMPDIR/net/$2/netfilter/
636    apply_config_help_changes $1 $KTMPDIR/$DOCUMENTATIONFILE
637    apply_makefile_changes $1 $KTMPDIR/net/$2/netfilter/
638    apply_conntrack_h_changes $1 $KTMPDIR/include/linux/netfilter_$2
639
640    if [ ! -e $1.userspace ];
641    then
642        echo "   Patch $1 `modesense 2` cleanly."
643        return 0
644    fi
645
646    # Are we testing?
647    if [ "$3" == "test" ]; then
648        alloc_utmpdir
649    fi
650
651    APPLIED=
652    if STATUS=`./isapplied $UTMPDIR $1.userspace`; then APPLIED=Y ; fi
653
654    if (cd $UTMPDIR &&
655        if [ $MODE ]; then
656                if [ $APPLIED ]; then
657                        patch -R -p1
658                else
659                        true
660                fi
661        else
662                if [ -z $APPLIED ]; then
663                        patch -p1
664                else
665                        true
666                fi
667        fi > /dev/null) < $1.userspace
668    then :
669    else
670        echo Failed to patch copy of $NETFILTERDIR >&2
671        return 1
672    fi 
673                                                       
674    echo "   Patch $1 `modesense 2` cleanly."
675    if [ "$UTMPDIR" == "$NETFILTERDIR" ]; then
676            echo "   *******************"
677            echo "   ***** WARNING ***** You have applied a userspace patch, so do not forget to recompile"
678            echo "   ******************* and re-install iptables."
679            echo "   *******************"
680    fi
681
682    return 0
683}
684
685# Args: patch filename, protocol.
686apply_patch()
687{
688    DEPEND=" $1 "
689
690    apply_patch_depend $1 $2 $3
691}
692
693# Reverse order of arguments.
694reverse_args()
695{
696    NUMARGS=$#
697    while [ $NUMARGS -gt 0 ]; do
698        eval "echo -n \${$NUMARGS}' '"
699        NUMARGS=`expr $NUMARGS - 1`
700    done
701}
702
703modesense()
704{
705    case $1 in
706        1)
707            if [ $MODE ]; then echo REVERSE; else echo apply; fi;
708            ;;
709        2)
710            if [ $MODE ]; then echo REVERSED; else echo applied; fi;
711            ;;
712        3)
713            if [ $MODE ]; then echo REVERSING; else echo Applying; fi;
714            ;;
715    esac
716}
717
718parse_filename()
719{
720    SUITE=${1%%/*}
721    FILE=${1##$SUITE/}
722    BASE=${FILE%%.patch*}       # filename without .patch*
723    PROTO=${FILE##$BASE.patch}
724    PROTO=${PROTO##.}
725}
726
727# Args: list of patches to process
728process_patches()
729{
730    CURRENT=0
731    while [ $CURRENT -le $# ];
732    do
733        CURRENT=`expr $CURRENT + 1`
734        if [ $CURRENT -gt $# ];
735        then
736    if [ $BATCH ] || [ $CHECKMODE ] || [ $TESTMODE ]; then
737        if [ $CHECKMODE ]
738        then
739           printheader "$PROCESSED"
740           printheader "$PROCESSED" > runme.out-check
741        fi
742        return
743    fi
744    printheader "$PROCESSED"
745    ANSWER=""
746    while [ ! $ANSWER ]
747    do
748        echo "-----------------------------------------------------------------"
749        echo -n "No more patches to `modesense 1`! Q to Quit or ? for options "'[Q/a/r/b/?] '
750        read ANSWER
751        case "$ANSWER" in
752            a*|A*)
753                WALK=
754                NEWMODE=
755                if ! [ "$NEWMODE" = "$MODE" ]; then PATCHES=`reverse_args $PATCHES`; fi;
756                MODE=$NEWMODE
757                continue 3
758                ;;
759            r*|R*)
760                WALK=
761                NEWMODE=UN
762                if ! [ "$NEWMODE" = "$MODE" ]; then PATCHES=`reverse_args $PATCHES`; fi;
763                MODE=$NEWMODE
764                continue 3
765                ;;
766            b*|B*)
767                WALK=1
768                BACK=1
769                SEEN=${SEEN%%$SUITE/$BASE${PROTO:+-$PROTO} }
770                PROCESSED=${PROCESSED%% $SUITE/$BASE${PROTO:+-$PROTO}}
771                if [ $CURRENT -gt 1 ]; then
772                    CURRENT=`expr $CURRENT - 2`
773                else
774                    CURRENT=0
775                fi
776                continue 2
777                ;;
778            Q*|q*|'')
779                ANSWER=Q
780                continue 2
781                ;;
782            *)
783                ANSWER=""
784                echo "Answer one of the following: "
785                echo "  A to restart patch-o-matic in apply mode"
786                echo "  R to restart patch-o-matic in REVERSE mode"
787                echo "  B to walk Back one patch in the list"
788                echo "  Q to quit immediately"
789                echo "  ? for help"
790                ;;
791        esac
792    done
793        fi
794
795        THIS_PATCH=`eval echo -n \\\${$CURRENT}` > /dev/null
796        parse_filename $THIS_PATCH # > /dev/null
797
798        printheader "$PROCESSED"
799        # Don't skip SEEN patches in REVERSE mode
800        if [ ! $MODE ] && [ ! $BACK ] && echo $SEEN | tr ' ' '\012' | grep -q "$BASE${PROTO:+-$PROTO}\$"
801        then
802            # Patches seen at previous suites are skipped
803            continue
804        else
805            if [ $MODE ] || ! echo $SEEN | tr ' ' '\012' | grep -q "$BASE${PROTO:+-$PROTO}\$"; then
806                SEEN="$SEEN$SUITE/$BASE${PROTO:+-$PROTO} "
807            elif [ $BACK ]; then
808                if [ $CURRENT -gt 1 ]; then
809                    parse_filename `eval echo -n \\\${\`expr $CURRENT - 1\`}` > /dev/null
810                    SEEN=${SEEN%%$SUITE/$BASE${PROTO:+-$PROTO} }
811                    PROCESSED=${PROCESSED%% $SUITE/$BASE${PROTO:+-$PROTO}}
812                    CURRENT=`expr $CURRENT - 2`
813                else
814                    CURRENT=0
815                fi
816                continue
817            fi
818
819            echo -n "Testing... "
820
821            APPLIED=
822            if STATUS=`./isapplied $KERNEL_DIR $THIS_PATCH`; then APPLIED=Y ; fi
823            if [ ! $WALK ] && ([ "$APPLIED" -a -z "$MODE" ] || [ ! "$APPLIED" -a -n "$MODE" ]);
824            then
825                PROCESSED="$PROCESSED $SUITE/$BASE${PROTO:+-$PROTO}"
826                continue
827            elif [ $CHECKMODE ]
828            then
829                continue
830            else
831                WALK=
832                BACK=
833                echo $STATUS
834                echo The $SUITE/$BASE ${PROTO:+$PROTO } patch:
835                if [ -f $THIS_PATCH.help ]; then while read LINE; do echo "   $LINE"; done < $THIS_PATCH.help; fi
836                ANSWER=""
837                if [ $BATCH ] || [ $TESTMODE ]
838                then
839                    if test_patch $THIS_PATCH ${PROTO:-"ipv4"}
840                    then
841                        if [ -z "$TESTMODE" ]; then
842                                apply_patch $THIS_PATCH ${PROTO:-"ipv4"}
843                                PROCESSED="$PROCESSED $SUITE/$BASE${PROTO:+-$PROTO}"
844                        fi
845                        ANSWER=Y
846                    else
847                        echo TEST FAILED: patch NOT `modesense 2`.
848                        exit 1
849                    fi
850                fi
851                while [ "$ANSWER" = "" ]
852                do
853                    echo "-----------------------------------------------------------------"
854                    echo -n "Do you want to `modesense 1` this patch "'[N/y/t/f/a/r/b/w/q/?] '
855                    read ANSWER
856                    case "$ANSWER" in
857                        y*|Y*)
858                            if test_patch $THIS_PATCH ${PROTO:-"ipv4"}
859                            then
860                                apply_patch $THIS_PATCH ${PROTO:-"ipv4"}
861                                PROCESSED="$PROCESSED $SUITE/$BASE${PROTO:+-$PROTO}"
862                            else
863                                echo TEST FAILED: patch NOT `modesense 2`.
864                                ANSWER=""
865                            fi
866                            entertocont # pause before screen is cleared by printheader
867                            ;;
868                        t*|T*)
869                            ANSWER=""
870                            test_patch $THIS_PATCH ${PROTO:-"ipv4"}
871                            ;;
872                        f*|F*)
873                            apply_patch $THIS_PATCH ${PROTO:-"ipv4"} force
874                            PROCESSED="$PROCESSED $SUITE/$BASE${PROTO:+-$PROTO}"
875                            entertocont # pause before screen is cleared by printheader
876                            ;;
877                        a*|A*)
878                            NEWMODE=
879                            if ! [ "$NEWMODE" = "$MODE" ]; then PATCHES=`reverse_args $PATCHES`; fi;
880                            MODE=$NEWMODE
881                            continue 3
882                            ;;
883                        r*|R*)
884                            NEWMODE=UN
885                            if ! [ "$NEWMODE" = "$MODE" ]; then PATCHES=`reverse_args $PATCHES`; fi;
886                            MODE=$NEWMODE
887                            continue 3
888                            ;;
889                        b*|B*)
890                            WALK=1
891                            BACK=1
892                            SEEN=${SEEN%%$SUITE/$BASE${PROTO:+-$PROTO} }
893                            PROCESSED=${PROCESSED%% $SUITE/$BASE${PROTO:+-$PROTO}}
894                            if [ $CURRENT -gt 1 ]; then
895                                parse_filename `eval echo -n \\\${\`expr $CURRENT - 1\`}` > /dev/null
896                                SEEN=${SEEN%%$SUITE/$BASE${PROTO:+-$PROTO} }
897                                PROCESSED=${PROCESSED%% $SUITE/$BASE${PROTO:+-$PROTO}}
898                                CURRENT=`expr $CURRENT - 2`
899                            else
900                                CURRENT=0
901                            fi
902                            continue 2
903                            ;;
904                        w*|W*)
905                            WALK=1
906                            if [ "$APPLIED" -a -z "$MODE" ] || [ ! "$APPLIED" -a -n "$MODE" ];
907                            then
908                                PROCESSED="$PROCESSED $SUITE/$BASE${PROTO:+-$PROTO}"
909                            fi
910                            continue 2
911                            ;;
912                        N*|n*|'')
913                            ANSWER=N
914                                if [ "$APPLIED" -a -z "$MODE" ] || [ ! "$APPLIED" -a -n "$MODE" ];
915                            then
916                                PROCESSED="$PROCESSED $SUITE/$BASE${PROTO:+-$PROTO}"
917                            fi
918                            ;;
919                        q*|Q*)
920                            echo Bye!
921                            exit 0 ;;
922                        *)
923                            ANSWER=""
924                            echo "Answer one of the following: "
925                            echo "  T to test that patch will `modesense 1` cleanly"
926                            echo "  Y to `modesense 1` patch"
927                            echo "  N to skip this patch"
928                            echo "  F to `modesense 1` patch even if test fails"
929                            echo "  A to restart patch-o-matic in apply mode"
930                            echo "  R to restart patch-o-matic in REVERSE mode"
931                            echo "  B to walk Back one patch in the list"
932                            echo "  W to Walk forward one patch in the list"
933                            echo "  Q to quit immediately"
934                            echo "  ? for help"
935                            ;;
936                    esac
937                done # while [ "$ANSWER" = "" ]
938            fi
939        fi
940    done # [ $CURRENT -le $# ]
941}
942
943# Make sure we are in the correct directory
944if [ ! -f ./isapplied ]
945then
946    echo
947    echo Please call $0 from the patch-o-matic directory!
948    exit 1
949fi
950
951if [ -z "$NETFILTERDIR" ]
952then
953        if [ -d ../userspace ]
954        then
955                export NETFILTERDIR=`cd ../userspace; pwd`
956        else
957                export NETFILTERDIR=`cd ..; pwd`
958        fi
959fi
960
961UTMPDIR=$NETFILTERDIR
962
963# Make sure we have 'patch'...
964if patch -v >/dev/null 2>&1
965then :
966else
967   echo program \'patch\' is missing, please install it!
968   exit 1
969fi
970
971# Check to see if we are running in batch mode
972BATCH=
973if [ "$1" = "--batch" ]; then
974    BATCH=1
975    shift
976fi
977
978TESTMODE=
979if [ "$1" = "--test" ]; then
980    TESTMODE=1
981    shift
982fi
983
984CHECKMODE=
985if [ "$1" = "--check" ]; then
986    CHECKMODE=1
987    shift
988fi
989
990# Check to see if we are applying or reversing patches
991MODE=
992if [ "$1" = "--reverse" ]; then
993    shift
994    MODE=UN
995fi
996
997# Check to see if there is excluded patches
998EXCLUDED=
999while [ "$1" = "--exclude" ]; do
1000    EXCLUDED="$EXCLUDED $2"
1001    shift
1002    shift
1003done
1004
1005# Script arg: suite name or a single patch file
1006PATCHES=""
1007for arg; do
1008if [ -d "$arg" -a -e $arg/SUITE ]
1009then
1010    for x in `cat $arg/SUITE`
1011    do
1012        PATCHES="$PATCHES `ls $x/*.patch $x/*.patch.ipv6 2>/dev/null`"
1013    done
1014elif [ -e "$arg" -a -n "${arg%%.patch*}" ]
1015then
1016        PATCHES="$PATCHES $arg"
1017else
1018    echo "ERROR: Invalid option $arg"
1019    exit 1
1020fi
1021done
1022
1023if [ -z "$PATCHES" ]; then
1024    echo
1025    echo "Usage: $0 [--batch] [--reverse] [--exclude suite/patch-file ...] suite|suite/patch-file"
1026    echo
1027    echo "  --batch     batch mode, automatically applying patches"
1028    echo "  --test      test mode, automatically test patches"
1029    echo "  --check     check mode, automatically checks if patches are already applied"
1030    echo "              produces a logfile: runme.out-check"
1031    echo "  --reverse   back out the selected patches"
1032    echo "  --exclude   excludes the named patches"
1033    echo
1034
1035    echo Possible patch-o-matic suites:
1036    echo
1037    for x in */SUITE; do
1038        suite=${x%%/*}
1039        echo ${suite}:
1040        fold -s -w 56 $suite/DESCRIPTION | sed 's/^/    /'
1041    done
1042    exit 1
1043fi
1044
1045if [ $MODE ]; then
1046    PATCHES=`reverse_args $PATCHES`
1047fi
1048
1049if [ -z "$KERNEL_DIR" ]
1050then
1051    echo Hey\! KERNEL_DIR is not set.
1052    echo -n "Where is your kernel? [/usr/src/linux] "
1053    read KERNEL_DIR
1054    if (cd $KERNEL_DIR )
1055    then :
1056    else
1057        echo "Failed to change directory to the kernel source dir $KERNEL_DIR" >&2
1058        exit 1
1059    fi
1060fi
1061
1062echo "Examining kernel in $KERNEL_DIR"
1063echo "-----------------------------------------------------------------"
1064
1065if [ ! -f ${KERNEL_DIR:=/usr/src/linux}/Makefile ]
1066then
1067    echo $KERNEL_DIR doesn\'t look like a kernel tree to me. >&2
1068    exit 1
1069fi
1070VERSION=`grep '^VERSION' $KERNEL_DIR/Makefile | cut -d= -f2`
1071PATCHLEVEL=`grep '^PATCHLEVEL' $KERNEL_DIR/Makefile | cut -d= -f2`
1072if [ "$VERSION" -lt 2 -o "$PATCHLEVEL" -lt 4 ]
1073then
1074    echo $KERNEL_DIR looks like a $VERSION.$PATCHLEVEL kernel tree to me. >&2
1075    echo I expect a 2.4 kernel or above. >&2
1076    exit 1
1077fi
1078
1079KTMPDIR=$KERNEL_DIR
1080
1081DONE=
1082until [ $DONE ];
1083do
1084    PROCESSED=
1085    SEEN="${EXCLUDED//.patch/} "
1086    process_patches $PATCHES
1087    DONE=1
1088done
1089
1090echo
1091echo Excellent\!  Kernel is now ready for compilation.
1092exit 0
Note: See TracBrowser for help on using the browser.