-
Notifications
You must be signed in to change notification settings - Fork 0
/
autopatch
executable file
·206 lines (189 loc) · 6.56 KB
/
autopatch
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
#!/bin/bash
# This script checks to see if there is a newer patch version of the Linux
# kernel you're already tracking, and eases the toil of these minor updates.
# It is intended for use with an LTS series such as 3.2, 3.4, or 3.18
# CURRENTLY UPDATING -RT PATCH IS POORLY TESTED! -----------------
# If you have already applied the -rt patch, this script will also
# update it. It does not support both at the same time.
# ----------------------------------------------------------------
# Copyright (C) 2011-2017 Nicholas D Steeves <[email protected]>
# Distributed under the terms of the GPLv2 license.
#
# Requires coretools, curl, grep, patch, bzip2, and xzutils
# TODO --cron
# "autopatch --cron" does not patch anything, but it will check for a new
# version, and silently exit if you are up to date. If you are not up to
# date, it will notify you of the new version.
#
mirror="https://www.kernel.org/pub/linux/kernel"
if [ -x "$(command -v pager)" ]; then
pager=pager
else
pager=less
fi
autopatch=`basename $0`
get_local_version() {
for i in VERSION PATCHLEVEL SUBLEVEL NAME CKVERSION; do
i_scratch=`grep ^$i Makefile | sed 's/^.*=\ //'`
export $i="$i_scratch"
done
if [ -n "$CKVERSION" ]; then
# ck="-ck"
echo "-ck patch is unsupported"
echo "exiting"
exit 1
fi
if [ -e localversion-rt ]; then
rt="-rt"
rtversion=`sed 's/[^0-9]*//g' < localversion-rt`
fi
if [ -n $CKVERSION ] && [ -e localversion-rt ]; then
echo "You have patched $PWD with both -ck and -rt"
echo "$autopatch will probably fail..."
sleep 3
echo "Aborting. Please choose -ck or -rt before trying again"
exit 1
fi
}
get_latest_versions() {
target=`curl -s $mirror/v$VERSION.x/ | \
grep patch-$VERSION\.$PATCHLEVEL.*xz | \
grep -o -E 'href="([^\"#]+)"' | \
sed -e 's/.*-//' -e 's/\.[^\.]*$//' | \
sort -V | sed '$!d'`
newsublevel=`echo $target | cut -d. -f3`
if [ -n "$rt" ]; then
newrtversion=`curl -s $mirror/projects/rt/$VERSION.$PATCHLEVEL | \
sed -e /tar/d -n -e 's/^.*patch-//' -e 's/\.patch\.xz.*$//p' \
| tail -1`
maxsublevel=`echo $newrtversion | sed -e "s/$VERSION\.$PATCHLEVEL\.//" \
-e "s/-rt.*//"`
if [ $newsublevel -gt $maxsublevel ]; then
# If not --cron, execute these echo commands
# otherwise, stay silent!
echo "The most recent -rt patch is for linux-$VERSION.$maxsublevel"
echo "Updating to $newrtversion instead of $target-rt*"
target=`echo $target | sed s/$newsublevel/$maxsublevel/`
newsublevel=$maxsublevel
fi
fi
if [ -z "$newsublevel" ]; then
echo "No patches have been released for $VERSION.$PATCHLEVEL.$SUBLEVEL"
echo "You are already up to date!"
exit 0
fi
echo "The latest available patch is linux-$target"
if [ $VERSION.$PATCHLEVEL.$SUBLEVEL = $target ]; then
echo "You are already up to date!"
exit 0
fi
levelsdiff=$[$newsublevel-$SUBLEVEL]
}
get_changelogs () {
#
# Regrettably, I have been unable to find changelogs for
# -ck or -rt
#
progress=$((SUBLEVEL+1))
echo -n "View all $levelsdiff changelogs (y/n)? "
read choice
case "$choice" in
yes | y | Yes | YES )
if [ $progress -ne $newsublevel ]; then
echo "curl -s $mirror/v$VERSION.x/ChangeLog-$VERSION.$PATCHLEVEL.[$progress-$newsublevel]"
curl -s "$mirror/v$VERSION.x/ChangeLog-$VERSION.$PATCHLEVEL.[$progress-$newsublevel]" 2> /dev/null | $pager
else
echo "curl -s $mirror/v$VERSION.x/ChangeLog-$VERSION.$PATCHLEVEL.$newsublevel"
curl -s "$mirror/v$VERSION.x/ChangeLog-$VERSION.$PATCHLEVEL.$newsublevel" 2> /dev/null | $pager
fi
;;
* )
false
;;
esac
}
clean_the_tree () {
if [ -e .config ]; then
lastconfig=`ls -l --time-style long-iso .config | cut -d\ -f6`
echo "Backing up .config to dot_config_$lastconfig"
sleep 2
cp -a .config dot_config_$lastconfig
fi
echo "Cleaning up the tree . . ."
sleep 1
if [ -x "$(command -v make-kpkg)" ]; then
make-kpkg clean
else
make distclean
fi
}
remove_patches() {
if [ -n "$CKVERSION" ]; then
curl -C http://ck.kolivas.org/patches/$VERSION.0/$VERSION.$PATCHLEVEL/$VERSION.$PATCHLEVEL-ck1/patch-$VERSION.$PATCHLEVEL-ck1.bz2 > /tmp/patch-$VERSION.$PATCHLEVEL-ck1.bz2
bzcat /tmp/patch-$VERSION.$PATCHLEVEL-ck1.bz2 | patch -p1 -R
fi
if [ -n "$rtversion" ]; then
curl $mirror/projects/rt/$VERSION.$PATCHLEVEL/older/patches-$VERSION.$PATCHLEVEL.$SUBLEVEL-rt$rtversion.tar.xz | xzcat | patch -p1 -R
fi
}
apply_patches() {
# needs to be able to accept mainline, -rt, -ck as an argument
# in the absence of an argument, it must default to mainline
echo -en "\nApply all available $levelsdiff patches now? "
while true; do
read choice
case "$choice" in
yes | y | Yes | YES )
break
;;
no | n | No | NO )
echo "If you say so . . . "
sleep 1
echo "Goodbye!"
exit 1
;;
* )
printf "Please answer yes or no\n\n"
;;
esac
done
clean_the_tree
# At this point, $progress is $((SUBLEVEL + 1))
tmplevel=$SUBLEVEL
while [ $progress -le $newsublevel ]; do
## Consider redoing this in a nicer way,
## since $progress of $levelsdiff gives me options
echo -en "Fetching sublevel $progress . . .\t"
if [ $progress -eq 1 ];then
echo "curl -s $mirror/v$VERSION.x/patch-$VERSION.$PATCHLEVEL.$progress.xz"
curl -s $mirror/v$VERSION.x/patch-$VERSION.$PATCHLEVEL.$progress.xz | xzcat | patch -p1
else
echo "curl -s $mirror/v$VERSION.x/incr/patch-$VERSION.$PATCHLEVEL.$tmplevel-$progress.xz"
curl -s $mirror/v$VERSION.x/incr/patch-$VERSION.$PATCHLEVEL.$tmplevel-$progress.xz | xzcat | patch -p1
fi
if [ $? -ne 0 ]; then
echo "Patch failed! Unsafe to continue."
echo "Aborting"
exit 1
fi
tmplevel=$((tmplevel+1))
progress=$((progress+1))
done
}
get_local_version
echo "Starting with linux-$VERSION.$PATCHLEVEL.$SUBLEVEL"
echo "Codename: $NAME"
get_latest_versions
get_changelogs
apply_patches
get_local_version
if [ "${PWD##*/}" != "linux-$VERSION.$PATCHLEVEL.$SUBLEVEL$ck$rt" ]; then
if [ -d "../linux-$VERSION.$PATCHLEVEL.$SUBLEVEL" ]; then
echo "Moving existing linux-$VERSION.$PATCHLEVEL.$SUBLEVEL$ck$rt out of the way"
mv ../linux-$VERSION.$PATCHLEVEL.$SUBLEVEL$ck$rt \
../../linux-$VERSION.$PATCHLEVEL.$SUBLEVEL$ck${rt}.old
fi
mv "$PWD" ../linux-$VERSION.$PATCHLEVEL.$SUBLEVEL$ck$rt
fi
echo -e "\nSuccess! You now have linux-$VERSION.$PATCHLEVEL.$SUBLEVEL$ck$rt"
echo "Do not forgot to: cd ../linux-$VERSION.$PATCHLEVEL.$newsublevel$ck$rt"