#!/bin/sh
#--------------------------------------------------------------------
# Copyright (C) 2000, 2002 by MandrakeSoft,
# Chmouel Boudjnah <chmouel@mandrakesoft.com>, 
# Redistribution of this file is permitted under the terms of the GNU 
# Public License (GPL)
#--------------------------------------------------------------------
# $Id: installkernel,v 1.45 2003/09/03 08:24:30 flepied Exp $
#--------------------------------------------------------------------
## description: 
#	      Install a kernel to /boot and add an entry for grub,
#             lilo, or yaboot

sharfile=/usr/share/win4lin-loader/

NOLAUNCH=""
NOCOPY=""
AUTODETECT="yes"
REMOVE=
NOLINK=""
LOADER=""
NOCONFIG=""
NOENTRY=""

if [ -f /etc/sysconfig/installkernel ];then
    source /etc/sysconfig/installkernel
fi

function read_link () {
    #at this time we have perl since we do kernel copy
    [[ -x /usr/bin/perl ]] && perl -e '{print readlink shift, "\n"}' $1
}

function copy_image () {
    local config=""
    local link

    if [[ -f .config ]];then
	config=.config
    elif [[ -f ../../../.config ]];then
	config=../../../.config
    fi
    
    if [ -L $boot/win4lin ];then
	link=$(read_link $boot/win4lin)
	link=${link##*/} #make it relative
	rm -f /boot/win4lin
	[[ "${boot}/${link}" != "${boot}/win4lin-${version}" && -f ${boot}/${link} ]] && ln -sf ${link} /boot/win4lin.old
    elif [ -f $boot/win4lin ]; then
	mv -f $boot/win4lin $boot/win4lin.old
    fi
    
    if [[ -z $NOCONFIG ]];then
	if [[ -n $config ]];then
	    cat $config > $boot/config-$version
	fi
    fi
    cat $boot_image > $boot/win4lin-$version
    cp -f $map_file $boot/System.map.win4lin-$version
}

#TODO: commonize
function do_link () {
    local extra=

    case $version in
	2.2*linus) extra=-2.2.linus;;
	2.2*secure) extra=-2.2.secure;;
	2.2*smp) extra=-2.2.smp;;
	2.2*) extra=-2.2;;
	2.4*mosix) extra=-mosix;;
	2.4*BOOT) extra=-BOOT;;
	2.4*linus) extra=-linus;;
	2.4*smp) extra=-smp;;
	2.4*secure) extra=-secure;; #not existing at this time
	2.4*enterprise) extra=-enterprise;;
    esac
    
    ln -fs win4lin-$version $boot/win4lin${extra}
}

function do_remove_link () {
    local ext=
    for ext in 2.2.linus 2.2.secure 2.2.smp 2.2 mosix BOOT linus smp secure enterprise;do
	if [[ -L /boot/win4lin-${ext} && ! -e /boot/win4lin-${ext} ]];then
	    rm -f /boot/win4lin-${ext}
	fi
    done
    if [[ -L /boot/win4lin && ! -e /boot/win4lin ]];then
	rm -f /boot/win4lin
    fi
}

function do_load_loop_module () {
    /sbin/modprobe loop 2> /dev/null > /dev/null
}

function do_create_link_source () {

    local kversion=$1
    local version=$kversion

    version="`echo $version | sed 's/-i386//'`"
    version="`echo $version | sed 's/-i486//'`"
    version="`echo $version | sed 's/-i586//'`"
    version="`echo $version | sed 's/-i686//'`"
    version="`echo $version | sed 's/-1GB//'`"
    version="`echo $version | sed 's/-4GB//'`"
    version="`echo $version | sed 's/-64GB//'`"
    version="`echo $version | sed 's/-up//'`"
    version="`echo $version | sed 's/-smp//'`"
    version="`echo $version | sed 's/-secure//'`"
    version="`echo $version | sed 's/-BOOT//'`"

    local kernel_source=/usr/src/linux-$version
    if [ -d $kernel_source ]; then
	ln -sf $kernel_source /lib/modules/$kversion/build 
    fi
}

function do_remove_link_source () {
    local kversion=$1

    local link=/lib/modules/$kversion/build 
    if [ -$link ]; then
	rm -f $link
    fi
}


function usage () {
cat << EOF >&2
Usage: ${0##*/} -[algyNdnRsSCiLch] KERNEL_VERSION [BOOTIMAGE MAPFILE [BOOTDIR]]

  -a:  Autodetect boot loader.
  -l:  Add a lilo entry
  -g:  Add a Grub entry.
  -y:  Add a yaboot entry.
  -N:  Don't add entry to bootloader
  -d:  Don't autodetect boot loader.
  -n:  Don't launch lilo.

  -R:  Remove bootloader entry and prepare to remove kernel
  -s:  Create a link to the source tree
  -S:  Remove link to the source tree
  -C:  Don't copy config files
  -i:  Dont generate Initrd files	    
  -L:  Don't do link to default /boot/win4lin and /boot/System.map.win4lin
  -c:  Don't copy files.

  -h:  This help.
    
EOF
exit 2
}

while getopts algyNdnRsSCiLch opt
  do
  case "$opt" in
      a) AUTODETECT="yes";;
      l) LOADER="LILO";;
      g) LOADER="GRUB";;
      y) LOADER="YABOOT";;
      N) NOENTRY="yes";;
      d) AUTODETECT=;;
      n) NOLAUNCH="-n";;

      R) REMOVE="-r";;
      s) CREATE_LINK_SOURCE="yes" ;;
      S) REMOVE_LINK_SOURCE="yes" ;;

      C) NOCONFIG="yes";;
      i) NOINITRD="yes";;
      L) NOLINK="-n";;
      c) NOCOPY="yes";;

      h) usage;;
      *) usage;;
  esac
done
shift $((OPTIND - 1))

version=$1
boot_image=$2
map_file=$3

if [[ -z "$map_file" &&  -z "$NOCOPY" ]];then
    usage;
fi

[[ -n $4 ]] && boot=$4 || boot=/boot

[[ -n "$NOCOPY" ]] && cd $boot

[[ $AUTOREMOVE = "no" ]] && REMOVE=""
[[ $NOLINK = "yes" ]] && NOLINK=-n

if [[ $version == *BOOT ]];then
    cat <<EOF 1>&2
*********     WARNING	  **********
You install a BOOT kernel, and this is not intended for use on a normal system.
EOF
fi


[[ -n "$CREATE_LINK_SOURCE" ]] && do_create_link_source $version
[[ -n "$REMOVE_LINK_SOURCE" ]] && do_remove_link_source $version
[[ -z "$NOCOPY" ]] && copy_image
[[ -z "$NOLINK" ]] && [[ -z "$REMOVE" ]] && do_link
[[ -z "$NOLINK" ]] && [[ -n "$REMOVE" ]] && do_remove_link
[[ -z "$NOLINK" ]] && [[ -n "$REMOVE" ]] && do_load_loop_module
[[ -z "$NOINITRD" ]] && [[ -z "$REMOVE" ]] && $sharfile/make-initrd $NOLINK $version
if [[ $HOSTTYPE == *586 ]];then
    [[  ! -e /boot/grub/menu.lst && ! -e /etc/lilo.conf ]] && exit 0 #this is for install time.
elif [[ $HOSTTYPE == *powerpc ]];then
     [[  ! -e /etc/yaboot.conf ]] && exit 0
fi

[[ -n $AUTODETECT ]] && [[ -z $LOADER ]] && [[ -f /usr/sbin/detectloader ]] && LOADER=$(/usr/sbin/detectloader -q)

[[ $LOADER != "LILO" && $LOADER != "GRUB" && $LOADER != "YABOOT" ]] && {
    cat <<EOF 1>&2
Cannot find a boot loader, you may have to see why detectloader has
problems or specify via the command line.
EOF
exit 2;
}

if [[ -x /usr/bin/perl && -z $NOENTRY ]];then

    if [[ $LOADER = "GRUB" ]] && [[ -f $sharfile/grub ]];then
	perl $sharfile/grub $REMOVE $version
    fi

    if [[ $LOADER = "LILO" ]] && [[ -f $sharfile/lilo ]];then
	perl $sharfile/lilo $NOLAUNCH $REMOVE $version
    fi

    if [[ $LOADER = "YABOOT" ]] && [[ -f $sharfile/yaboot ]];then
	perl $sharfile/yaboot $NOLAUNCH $REMOVE $version
    fi
fi
