aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/patch-kernel
blob: 43af01075612a5b663616c468930b401c972e0fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#! /bin/sh
# Script to apply kernel patches.
#   usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
#     The source directory defaults to /usr/src/linux, and the patch
#     directory defaults to the current directory.
# e.g.
#   scripts/patch-kernel . ..
#      Update the kernel tree in the current directory using patches in the
#      directory above to the latest Linus kernel
#   scripts/patch-kernel . .. -ac
#      Get the latest Linux kernel and patch it with the latest ac patch
#   scripts/patch-kernel . .. 2.4.9
#      Gets standard kernel 2.4.9
#   scripts/patch-kernel . .. 2.4.9 -ac
#      Gets 2.4.9 with latest ac patches
#   scripts/patch-kernel . .. 2.4.9 -ac11
#      Gets 2.4.9 with ac patch ac11
#   Note: It uses the patches relative to the Linus kernels, not the
#   ac to ac relative patches
#
# It determines the current kernel version from the top-level Makefile.
# It then looks for patches for the next sublevel in the patch directory.
# This is applied using "patch -p1 -s" from within the kernel directory.
# A check is then made for "*.rej" files to see if the patch was
# successful.  If it is, then all of the "*.orig" files are removed.
#
#       Nick Holloway <Nick.Holloway@alfie.demon.co.uk>, 2nd January 1995.
#
# Added support for handling multiple types of compression. What includes
# gzip, bzip, bzip2, zip, compress, and plaintext. 
#
#       Adam Sulmicki <adam@cfar.umd.edu>, 1st January 1997.
#
# Added ability to stop at a given version number
# Put the full version number (i.e. 2.3.31) as the last parameter
#       Dave Gilbert <linux@treblig.org>, 11th December 1999.

# Fixed previous patch so that if we are already at the correct version
# not to patch up.
#
# Added -ac option, use -ac or -ac9 (say) to stop at a particular version
#       Dave Gilbert <linux@treblig.org>, 29th September 2001.
#
# Add support for (use of) EXTRAVERSION (to support 2.6.8.x, e.g.);
# update usage message;
# fix some whitespace damage;
# be smarter about stopping when current version is larger than requested;
#	Randy Dunlap <rddunlap@osdl.org>, 2004-AUG-18.

# Set directories from arguments, or use defaults.
sourcedir=${1-/usr/src/linux}
patchdir=${2-.}
stopvers=${3-default}

if [ "$1" == -h -o "$1" == --help -o ! -r "$sourcedir/Makefile" ]; then
cat << USAGE
usage: patch-kernel [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
  source directory defaults to /usr/src/linux,
  patch directory defaults to the current directory,
  stopversion defaults to <all in patchdir>.
USAGE
exit 1
fi

# See if we have any -ac options
for PARM in $*
do
  case $PARM in
	  -ac*)
		  gotac=$PARM;

	esac;
done

# ---------------------------------------------------------------------------
# Find a file, first parameter is basename of file
# it tries many compression mechanisms and sets variables to say how to get it
findFile () {
  filebase=$1;

  if [ -r ${filebase}.gz ]; then
		ext=".gz"
		name="gzip"
		uncomp="gunzip -dc"
  elif [ -r ${filebase}.bz  ]; then
		ext=".bz"
		name="bzip"
		uncomp="bunzip -dc"
  elif [ -r ${filebase}.bz2 ]; then
		ext=".bz2"
		name="bzip2"
		uncomp="bunzip2 -dc"
  elif [ -r ${filebase}.zip ]; then
		ext=".zip"
		name="zip"
		uncomp="unzip -d"
  elif [ -r ${filebase}.Z ]; then
		ext=".Z"
		name="uncompress"
		uncomp="uncompress -c"
  elif [ -r ${filebase} ]; then
		ext=""
		name="plaintext"
		uncomp="cat"
  else
	return 1;
  fi

  return 0;
}

# ---------------------------------------------------------------------------
# Apply a patch and check it goes in cleanly
# First param is patch name (e.g. patch-2.4.9-ac5) - without path or extension

applyPatch () {
  echo -n "Applying $1 (${name})... "
  if $uncomp ${patchdir}/$1${ext} | patch -p1 -s -N -E -d $sourcedir
  then
    echo "done."
  else
    echo "failed.  Clean up yourself."
    return 1;
  fi
  if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ]
  then
    echo "Aborting.  Reject files found."
    return 1;
  fi
  # Remove backup files
  find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \;
 
  return 0;
}

# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
TMPFILE=`mktemp .tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; }
grep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE
tr -d [:blank:] < $TMPFILE > $TMPFILE.1
source $TMPFILE.1
rm -f $TMPFILE*
if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
then
    echo "unable to determine current kernel version" >&2
    exit 1
fi

NAME=`grep ^NAME $sourcedir/Makefile`
NAME=${NAME##*=}

echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} ($NAME)"

# strip EXTRAVERSION to just a number (drop leading '.' and trailing additions)
EXTRAVER=
if [ x$EXTRAVERSION != "x" ]
then
	if [ ${EXTRAVERSION:0:1} == "." ]; then
		EXTRAVER=${EXTRAVERSION:1}
	else
		EXTRAVER=$EXTRAVERSION
	fi
	EXTRAVER=${EXTRAVER%%[[:punct:]]*}
	#echo "patch-kernel: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER"
fi

#echo "stopvers=$stopvers"
if [ $stopvers != "default" ]; then
	STOPSUBLEVEL=`echo $stopvers | cut -d. -f3`
	STOPEXTRA=`echo $stopvers | cut -d. -f4`
	#echo "STOPSUBLEVEL=$STOPSUBLEVEL, STOPEXTRA=$STOPEXTRA"
else
	STOPSUBLEVEL=9999
	STOPEXTRA=9999
fi

while :				# incrementing SUBLEVEL (s in v.p.s)
do
    if [ x$EXTRAVER != "x" ]; then
	CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
    else
	CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
    fi

    if [ $stopvers == $CURRENTFULLVERSION ]; then
        echo "Stopping at $CURRENTFULLVERSION base as requested."
        break
    fi

    while :			# incrementing EXTRAVER (x in v.p.s.x)
    do
	EXTRAVER=$((EXTRAVER + 1))
	FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
	#echo "... trying $FULLVERSION ..."

	patch=patch-$FULLVERSION

	# See if the file exists and find extension
	findFile $patchdir/${patch} || break

	# Apply the patch and check all is OK
	applyPatch $patch || break

	continue 2
    done

    EXTRAVER=
    SUBLEVEL=$((SUBLEVEL + 1))
    FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
    #echo "___ trying $FULLVERSION ___"

    if [ $((SUBLEVEL)) -gt $((STOPSUBLEVEL)) ]; then
	echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)"
	exit 1
    fi

    patch=patch-$FULLVERSION

    # See if the file exists and find extension
    findFile $patchdir/${patch} || break

    # Apply the patch and check all is OK
    applyPatch $patch || break
done
#echo "base all done"

if [ x$gotac != x ]; then
  # Out great user wants the -ac patches
	# They could have done -ac (get latest) or -acxx where xx=version they want
	if [ $gotac == "-ac" ]; then
	  # They want the latest version
		HIGHESTPATCH=0
		for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.*
		do
			ACVALUE=`echo $PATCHNAMES | sed -e 's/^.*patch-[0-9.]*-ac\([0-9]*\).*/\1/'`
			# Check it is actually a recognised patch type
			findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${ACVALUE} || break

		  if [ $ACVALUE -gt $HIGHESTPATCH ]; then
			  HIGHESTPATCH=$ACVALUE
		  fi
		done

		if [ $HIGHESTPATCH -ne 0 ]; then
			findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} || break
			applyPatch patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH}
		else
		  echo "No -ac patches found"
		fi
	else
	  # They want an exact version
		findFile $patchdir/patch-${CURRENTFULLVERSION}${gotac} || {
		  echo "Sorry, I couldn't find the $gotac patch for $CURRENTFULLVERSION.  Hohum."
			exit 1
		}
		applyPatch patch-${CURRENTFULLVERSION}${gotac}
	fi
fi