#!/bin/bash set -e length=50 die() { echo "E: $@" >&2 exit 1 } warn() { echo "W: $@" >&2 } uncompress_patch() { patch=$1 case "$patch" in *.bz2) bzcat $patch ;; *.gz) zcat $patch ;; *) cat $patch ;; esac } find_patch() { patch=$1 if [ -f "$patch" ]; then echo "$patch" elif [ -f "$patch.bz2" ]; then echo "$patch.bz2" elif [ -f "$patch.gz" ]; then echo "$patch.gz" else die "$patch is in the series, but doesn't exist!" fi } apply_patch() { patch=$(find_patch $home/$1) base=$1 if uncompress_patch "$patch" | patch -p1 --fuzz=1 -f -s -t --no-backup-if-mismatch; then printf "%-${length}s\tOK (+)\n" "$base" else printf "%-${length}s\tFAIL (+)\n" "$base" exit 1 fi } deapply_patch() { patch=$(find_patch $home/$1) base=$1 if uncompress_patch "$patch" | patch -p1 -f -s -t -R --no-backup-if-mismatch; then printf "%-${length}s\tOK (-)\n" "$base" else printf "%-${length}s\tFAIL (-)\n" "$base" exit 1 fi } unpatch_series() { series=$1 tac $series | while read action patch; do case "$action" in +) deapply_patch $patch ;; -) apply_patch $patch ;; X) bakfile="$(dirname $patch)/.$(basename $patch).bak" if [ -f "$bakfile" ]; then mv -f "$bakfile" "$patch" printf "%-${length}s\tRESTORED (X)\n" "$patch" else printf "%-${length}s\tNO BACKUP (X)\n" "$patch" fi ;; esac done echo "--> $(basename $series) fully unapplied." } patch_series() { series=$1 [ -f "$series" ] || return while read action patch; do case "$action" in +) apply_patch $patch ;; -) deapply_patch $patch ;; X) bakfile="$(dirname $patch)/.$(basename $patch).bak" if [ -f "$patch" ]; then mv -f "$patch" "$bakfile" printf "%-${length}s\tREMOVED (X)\n" "$patch" else printf "%-${length}s\tNO FILE (X)\n" "$patch" fi ;; esac done < $series echo "--> $(basename $series) fully applied." } if ! [ -d Documentation ] || ! [ -d kernel ]; then die 'Not in kernel top level directory. Exiting' exit 1 fi # for THIS particular version of the source package version=${override_version:-@version@} revision=$(echo $version | sed -ne 's,^\(.*\)-\([^-]*\)$,\2,p') upstream=$(echo $version | sed -ne 's,^\(.*\)-\([^-]*\)$,\1,p') revisions_count=0 for i in ${override_revisions:-@revisions@}; do revisions[$revisions_count]=$i revisions_count=$(($revisions_count + 1)) done home=${home:-/usr/src/kernel-patches/all/$upstream/debian} if [ -f version.Debian ]; then current=$(cat version.Debian) current_rev=$(echo $current | sed -ne 's,^\(.*\)-\([^-]*\)$,\2,p') current_up=$(echo $current | sed -ne 's,^\(.*\)-\([^-]*\)$,\1,p') if [ "$current" = "$upstream" ]; then current_rev=0 fi else warn "No version.Debian file, assuming pristine Linux $upstream" current=$upstream current_rev=0 fi target=${1:-$version} target_rev=$(echo $target | sed -ne 's,^\(.*\)-\([^-]*\)$,\2,p') target_up=$(echo $target | sed -ne 's,^\(.*\)-\([^-]*\)$,\1,p') # Sanity checks if dpkg --compare-versions "$target_up" ne "$upstream"; then die "Upstream $target_up doesn't match $upstream!" # We don't have that version out yet! elif [ ! -n "$target_rev" ] || ( dpkg --compare-versions "$target_rev" ne "$target" && dpkg --compare-versions "$target_rev" gt "$revision" ); then year=$(($(date +%Y) + 1)) die "Can't patch to nonexistent revision $target_rev (wait until $year)" fi # At this point, we must handle three cases. # 1. $target_rev is greater than $current_rev. We must patch forward for this. # 2. $target_rev is less than $current_rev. We must reverse the list of series, # reverse each used series (tac) and unapply applied patches and vice versa. # 3. $target_rev is undefined, and $target is $upstream. if dpkg --compare-versions "$target_rev" eq "$current_rev"; then echo "Nothing to do, exiting." exit 0 else cur_index=$revisions_count while [ $cur_index -gt 0 ]; do [ ${revisions[$(($cur_index - 1))]} == $current_rev ] && break cur_index=$(($cur_index - 1)) done target_index=$revisions_count while [ $target_index -gt 0 ]; do [ ${revisions[$(($target_index - 1))]} == $target_rev ] && break target_index=$(($target_index - 1)) done if [ $target_index -gt $cur_index ]; then while [ $target_index -gt $cur_index ]; do series="$home/series/${upstream}-${revisions[$cur_index]}" [ -f "$series" ] && patch_series $series cur_index=$(($cur_index + 1)) done elif [ $target_index -lt $cur_index ]; then while [ $target_index -lt $cur_index ]; do cur_index=$(($cur_index - 1)) series="$home/series/${upstream}-${revisions[$cur_index]}" [ -f "$series" ] && unpatch_series $series done fi fi echo $target > version.Debian # vim:noet:ai:ts=4