#!/bin/bash

############################################################################
#
# Script for generating a kernel source tree with the SCST patches applied.
#
# Copyright (C) 2010 Bart Van Assche <bvanassche@acm.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, version 2
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
############################################################################


########################
# Function definitions #
########################

function usage {
  echo "Usage: $0 <kernel version>"
}

# First three components of the kernel version number.
function kernel_version {
  echo "$1" | sed -n 's/^\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/p'
}

# Last component of the kernel version, or the empty string if $1 has only
# three components.
function patchlevel {
  echo "$1" | sed -n 's/^\([0-9]*\.[0-9]*\.[0-9]*\)[.-]\(.*\)$/\2/p'
}

# Download the file from URL $1 and save it in the current directory.
function download_file {
  if [ ! -e "$(basename "$1")" ]; then
    if [ "${quiet_download}" = "false" ]; then
      echo "Downloading $1 ..."
    fi
    wget -q -nc "$1"
  fi
}

# Make sure the kernel tarball and patch file are present in directory
# ${kernel_sources}. Download any missing files from ${kernel_mirror}.
function download_kernel {
  local kver="$(kernel_version $1)"
  local plevel="$(patchlevel $1)"

  mkdir -p "${kernel_sources}" || return $?
  test -w "${kernel_sources}" || return $?
  (
    cd "${kernel_sources}" || return $?
    download_file "${kernel_mirror}/linux-$(kernel_version $1).tar.bz2" \
      || return $?
    if [ "${plevel}" != "" ]; then
      download_file "${kernel_mirror}/patch-$1.bz2" \
        || download_file "${kernel_longterm}/v$(kernel_version $1)/patch-$1.bz2" \
        || return $?
    fi
  )
}


#########################
# Argument verification #
#########################

set -e

if [ "$1" = "" ]; then
  echo "Error: missing kernel version argument."
  exit 1
fi


##########################
# Kernel tree generation #
##########################

kernel_mirror="ftp://ftp.eu.kernel.org/pub/linux/kernel/v2.6"
kernel_longterm="http://www.kernel.org/pub/linux/kernel/v2.6/longterm"
kernel_sources="$HOME/software/downloads"

scriptname="$0"
if [ "${scriptname#/}" = "${scriptname}" ]; then
  scriptname="$PWD/$scriptname"
fi
target="linux-$1"
kernel_version="$(kernel_version "$1")"
patchlevel="$(patchlevel "$1")"

download_kernel "$1"

mkdir "${target}" || exit $?
cd "${target}" || exit $?

tar --strip-components=1 -xjf "${kernel_sources}/linux-${kernel_version}.tar.bz2"

if [ ! -z "$patchlevel" ]; then
  echo "==== ${kernel_sources}/patch-$1.bz2"
  bzip2 -cd < "${kernel_sources}/patch-$1.bz2" | patch -s -p1
fi

svn status -v "$(dirname "$(dirname "$scriptname")")" \
| grep -v '^Performing' \
| cut -c41- \
| grep -- "-${kernel_version}.*.patch$" \
| grep -v /in-tree/ \
| while read p
  do
    if [ "${p/readahead-2.6.32.below11.patch//}" = "$p" \
         -o "${patchlevel:-0}" -lt 11 ]
    then
      echo "==== $p"
      patch -p1 <$p
    fi
  done
