#!/bin/sh
#
#  Copyright (c) 2005 Canonical LTD
#
#  Author: Matt Zimmerman <mdz@canonical.com>
#
#  2006, Oliver Grawert <ogra@canonical.com>
#        Vagrant Cascadian <vagrant@freegeek.org>
#  2007, Scott Balneaves <sbalneav@ltsp.org>
#        Oliver Grawert <ogra@canonical.com>
#  2008, Vagrant Cascadian <vagrant@freegeek.org>
#        Warren Togami <wtogami@redhat.com>
#        Oliver Grawert <ogra@canonical.com>
#  2009, Warren Togami <wtogami@redhat.com>
#  2012, Alkis Georgopoulos <alkisg@gmail.com>
#
#  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; either version 2 of the
#  License, or (at your option) any later version.
#
#  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.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, you can find it on the World Wide
#  Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
#  Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#

set -e

usage() {
cat <<EOF
$0 [OPTION] [ARCH...]
  -b, --basedir     Base of ltsp chroot.  Default is /opt/ltsp if unspecified.
  -t, --tftpdirs    List of tftpd dirs to update in. Defaults to
                    "/var/lib/tftpboot /tftpboot /srv/tftp".
  -c, --copytftp    Copy files.  Defaults to "true".
  -d, --tftpbootdir Subdir within tftpdir where ltsp kernels are.  Defaults
                    to "ltsp".
  -h, --help        This message.
EOF
}

# distro specific functions

# Find $version from vmlinuz-* filename,
# if corresponding /opt/ltsp/$CHROOT_NAME/lib/modules/$version is
# missing, then delete kernel and images from tftpboot directory.
#
# Some distros won't match vmlinuz-*, but this is at least safe
# because it will simply cleanup nothing.
cleanup_kernels() {
    # Loop through every vmlinuz-* file
    for kernelpath in $(find $TFTPBOOT/$CHROOT_NAME -name 'vmlinuz-*'); do
        kernel=`basename $kernelpath`
        version=${kernel##vmlinuz-}
        if [ ! -d $BASE/$CHROOT_NAME/lib/modules/$version ]; then
            echo "Removing $kernelpath"
            # Common
            rm -f $TFTPBOOT/$CHROOT_NAME/vmlinuz-$version
            rm -f $TFTPBOOT/$CHROOT_NAME/config-$version
            rm -f $TFTPBOOT/$CHROOT_NAME/System.map-$version
            # Fedora
            rm -f $TFTPBOOT/$CHROOT_NAME/initrd-$version.img
            rm -f $TFTPBOOT/$CHROOT_NAME/initramfs-$version.img
            rm -f $TFTPBOOT/$CHROOT_NAME/elf-$version.img
            rm -f $TFTPBOOT/$CHROOT_NAME/wraplinux-nbi-$version.img
            rm -f $TFTPBOOT/$CHROOT_NAME/aout-$version.img
            rm -f $TFTPBOOT/$CHROOT_NAME/symvers-$version.gz
            # Debian
            rm -f $TFTPBOOT/$CHROOT_NAME/initrd.img-$version
            rm -f $TFTPBOOT/$CHROOT_NAME/nbi.img-$version
            # Ubuntu
            rm -f $TFTPBOOT/$CHROOT_NAME/abi-$version
            rm -f $TFTPBOOT/$CHROOT_NAME/vmcoreinfo-$version
        fi
    done
}

#
# Handle args
#

ARGS=$(getopt -o b:t:c:d:h --long base:,tftpdirs:,copytftp:,tftpbootdir:,help \
       -n $0 -- "$@")

[ $? != 0 ] && exit 1

eval set -- "${ARGS}"

while true ; do
    case "$1" in
        -b|--base)        BASE=$2 ; shift 2 ;;
        -t|--tftpdirs)    TFTPDIRS=$2 ; shift 2 ;;
        -c|--copytftp)    COPYTFTP=$2 ; shift 2 ;;
        -d|--tftpbootdir) TFTPBOOTDIR=$2 ; shift 2 ;;
        -h|--help)        usage ; exit 0 ;;
        --) shift ; break ;;
        *) echo "Internal error!" ; exit 1 ;;
    esac
done

# ltsp-server-functions also sources distro specific function overrides
. /usr/share/ltsp/ltsp-server-functions

if [ -f /etc/ltsp/ltsp-update-kernels.conf ]; then
    . /etc/ltsp/ltsp-update-kernels.conf
fi

BASE=${BASE:-"/opt/ltsp"}
TFTPDIRS=${TFTPDIRS:-"/var/lib/tftpboot /tftpboot /srv/tftp"}
COPYTFTP=${COPYTFTP:-"true"}
TFTPBOOTDIR=${TFTPBOOTDIR:-"ltsp"}

for TFTPDIR in $TFTPDIRS ; do
    if [ ! -d $TFTPDIR ] ; then
        # skip directory
        continue
    fi

    TFTPBOOT="$TFTPDIR/$TFTPBOOTDIR"

    if [ "$TFTPDIR" = "$BASE" ]; then
        COPYTFTP="false"
        TFTPBOOT="$TFTPDIR"
    fi

    ALL_CHROOTS="$@"
    ALL_CHROOTS=${ALL_CHROOTS:-"$(find $BASE/ -mindepth 1 -maxdepth 1 -type d | \
                                  grep -v images)"}

    for CHROOT in $ALL_CHROOTS ; do
        if [ ! -x $CHROOT/bin/true ]; then
            # not a valid chroot
            echo "Skipping invalid chroot: $CHROOT"
            continue
        fi

        echo "Updating $TFTPDIR directories for chroot: $CHROOT"
        CHROOT_NAME="$(basename $CHROOT)"

        if [ "$COPYTFTP" = "true" ]; then
            mkdir -p $TFTPBOOT/$CHROOT_NAME
            cp -a $CHROOT/boot/. $TFTPBOOT/$CHROOT_NAME/

            # Make sure permissions are always correct (LP: #759115)
            chmod -f 644 $TFTPBOOT/$CHROOT_NAME/vmlinuz-* $TFTPBOOT/$CHROOT_NAME/initrd.img-* $TFTPBOOT/$CHROOT_NAME/nbi.img-* || true
        fi

        # OFW on Mac is lame, they cannot tftp from directories
        if [ -e $TFTPBOOT/$CHROOT_NAME/yaboot ]; then
            if [ ! -e $TFTPDIR/yaboot ]; then
                ln -sf ltsp/$CHROOT_NAME/yaboot $TFTPDIR/yaboot
            fi
            if [ ! -e $TFTPDIR/yaboot.conf ]; then
                ln -sf ltsp/$CHROOT_NAME/yaboot.conf $TFTPDIR/yaboot.conf
            fi
        fi

        # Cleanup old kernels and images from tftpboot directory
        cleanup_kernels
    done
    # Update selinux file contexts if necessary
    [ -f /selinux/enforce ] && /sbin/restorecon -R $TFTPDIR > /dev/null
done
