#!/bin/bash # # Copyright (C) 2010 Bart Trojanowski # # This script applies saref, natt, and klips patches to a # linux kernel git tree. set -e prog=$(basename $0) say() { echo >&2 "$@" } warn() { say "$prog: $@" } die() { warn "$@" exit 1 } do_help() { local err=$1 local out=1 [[ -n "$err" && "$err" -eq 0 ]] || out=2 cat >&$out < Options: -s --saref - apply the saref patch(es), create commit(s) -n --natt - apply the natt patch(es), create commit(s) -k --klips - apply the klips patch(es), create commit(s) Generic options: -h --help - this help --dry-run - don't apply anything -q --quiet - pass quiet flag to git-am -t --tmp-dir - use this temporary directory END exit $err } # set defaults do_saref=false do_natt=false do_klips=false dryrun_mode=false cleen_up=true arg_kernel= arg_quiet= arg_tmpdir=/tmp libreswan_rev= kernel_ver= # this will queue a patch if it looks like it would apply queue_patch() { local queue="$1" local pnum="$2" local patch="$3" # add it to the queue cat "$patch" >> "$queue" # check if the patch applies (including all the ones that came before it) ( cd "$arg_kernel" git apply --ignore-space-change --ignore-whitespace --check -p"$pnum" "$queue" || die "patch doesn't apply" ) } # apply the patch in the kernel tree apply_a_patch() { local pnum="$1" local patch="$2" local desc="$3" $dryrun_mode && return 0 # import the patch ( cd "$arg_kernel" git apply --ignore-space-change --ignore-whitespace --index < "$patch" diffstat -l -p"$pnum" < "$patch" | xargs git add git commit -m"$desc" ) } is_git_dir() { local dir="$1" [[ -d "$dir" \ && -f "$dir/HEAD" \ && -d "$dir/objects" \ && -d "$dir/refs" ]] } generate_saref_patch() { local workdir="$1" local series="$2" local count=0 for src in patches/kernel/$kernel_ver/0*.patch ; do count=$(($count + 1)) local patch="$workdir/saref$count.patch" local desc="Applied saref patch #$count from Libreswan $libreswan_rev" local pnum=1 say "Reading ${src##*/}..." say "Generating ${patch##*/}..." cat "$src" > "$patch" echo "$pnum" "$patch" "$desc" >> $series done } generate_natt_patch() { local workdir="$1" local series="$2" local patch="$workdir/natt.patch" local desc="Applied NATT patch from Libreswan $libreswan_rev" local pnum=1 say "Generating ${patch##*/}..." cat "patches/kernel/$kernel_ver/natt.patch" > "$patch" echo "$pnum" "$patch" "$desc" >> $series } generate_klips_patch() { local workdir="$1" local series="$2" local patch="$workdir/klips.patch" local desc="Applied klips patch from Libreswan $libreswan_rev" local pnum=1 say "Generating ${patch##*/}..." make kernelpatch2.6 > "$patch" echo "$pnum" "$patch" "$desc" >> $series } apply_patches() { local workdir="$arg_tmpdir/$prog-$$" local series="$workdir/series" local queue="$workdir/queue" [[ -d $workdir ]] && die "$workdir already exists, remove it" mkdir -p "$workdir" || die "failed to create: $workdir" if $cleen_up ; then trap "rm -rf $workdir" EXIT HUP INT QUIT ABRT else trap "echo 'not cleaning: $workdir'" EXIT HUP INT QUIT ABRT fi $do_saref && generate_saref_patch "$workdir" "$series" $do_natt && generate_natt_patch "$workdir" "$series" $do_klips && generate_klips_patch "$workdir" "$series" while read pnum patch desc ; do local name=$(basename "$patch") say "Testing $name..." queue_patch "$queue" "$pnum" "$patch" done < "$series" while read pnum patch desc ; do local name=$(basename "$patch") say "Applying $name..." apply_a_patch "$pnum" "$patch" "$desc" done < "$series" say "DONE" } # parse parameters while [[ -n "$1" ]] ; do [[ -n "$arg_kernel" ]] && die "garbage at end of line; see $prog --help" cmd="$1" shift case "$cmd" in -h|--help) do_help 0 ;; --dry-run) dryrun_mode=true ;; --debug) set -x ;; --keep) cleen_up=false ;; -q|--quiet) arg_quiet="--quiet" ;; -t|--tmp-dir) arg_tmpdir="$1" [[ -d "$arg_tmpdir" ]] || die "no such directory: $arg_tmpdir" shift ;; -s|--saref) do_saref=true ;; -n|--natt) do_natt=true ;; -k|--klips) do_klips=true ;; -*) warn "invalid option: $cmd" do_help 1 ;; *) arg_kernel="$cmd" ;; esac done ( $do_saref || $do_natt || $do_klips ) || die "need to specify at least one of --saref, --natt, or --klips" is_git_dir ".git" && libreswan_rev=$(git describe) [[ "${libreswan_rev:0:1}" = "v" ]] || die "run this script from the top of the libreswan git tree" echo "Libreswan revision $libreswan_rev" [[ -n "$arg_kernel" ]] || die "missing kernel directory; see $prog --help" is_git_dir "$arg_kernel/.git" && kernel_ver=$(git --git-dir="$arg_kernel/.git" describe | sed -ne's/v\(2\.6\.[0-9]\+\).*/\1/p') [[ "${kernel_ver:0:2}" = "2." ]] || die "$arg_kernel: this dones't look like a kernel git tree" apply_patches exit $ret