#! /bin/bash

#*********************************************************************
#
# ftar -- extract tar files using FAI classes
#
# This script is part of FAI (Fully Automatic Installation)
# Copyright (C) 2001-2015 Thomas Lange, lange@informatik.uni-koeln.de
# Universitaet zu Koeln
#
#*********************************************************************
# 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.
#
# A copy of the GNU General Public License is available as
# '/usr/share/common-licences/GPL' in the Debian GNU/Linux distribution
# or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html.  You
# can also obtain it by writing to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#*********************************************************************

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
die() {

    local e=$1   # first parameter is the exit code
    shift

    echo "ftar: $@" >&2 # print error message
    exit $e
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
extract() {

    local file=$1
    local catname=$2

    if [ $deletefiles -eq 1 ] ; then
      cd $target/$dir && rm -f  .* * 2>/dev/null
      deletefiles=0
    fi

    if [ $removedir -eq 1 ]; then
        cd $target/$dir || die 4 "ERROR: cd to $target/$dir failed. Aborting."
        [ $PWD = "/" ] && die 3 "WARNING: Will not do recursive removal of directory /"
        rm -rf .* * 2>/dev/null
        removedir=0
    fi

    echo "ftar: extracting $file to $target/$dir" | tr -s '/'
    $catname $file | tar $xattrs --numeric-owner -C $target/$dir $vflag -xf -
    tardone=1
    # if option -1 is set, only one class will be used
    [ $single -eq 1 ] && exit 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
usage() {

    cat <<EOF
ftar, extract tar files using classes.

   Copyright (C) 2001-2015 by Thomas Lange

Usage: ftar [OPTION] ... SOURCE

   -1                   Use only first tar file matching class name.
   -c class[class]      Define classes (space separated).
   -d                   Delete all files in target before extracting.
   -D                   Create debug output.
   -h                   Show summary of options.
   -r                   Recursively remove files in target before extracting.
   -s source_dir        Look for source files relative to source_dir.
   -t target_dir        Extract files relativ to target_dir.
   -v                   Be verbose. Not yet used.

EOF
    exit 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

source=$FAI/files
target=$FAI_ROOT
deletefiles=0
removedir=0
tardone=0
single=0
ignore=0

while getopts 1hDdrvs:t:c:i opt ; do
        case "$opt" in
        d) deletefiles=1 ;;
        D) debug=1 ;;
        i) ignore=1 ;;
        r) removedir=1 ;;
#        v) verbose=1 ;;
        1) single=1 ;;
        s) source=$OPTARG ;;
        t) target=$OPTARG ;;
        c) classes=$OPTARG ;;
        h) usage ;;
        esac
done
shift $(($OPTIND - 1))

[ "$1" ] || usage

# check if tar has xattrs support
tar --xattrs -cf /dev/null /dev/null 2>/dev/null 1>/dev/null
if [ $? -eq 0 ]; then
    xattrs="--xattrs --xattrs-include=*.* --selinux --acl"
else
    xattrs=
fi

[ -f $ENV{LOGDIR}/FAI_CLASSES ] && classes=$(< $ENV{LOGDIR}/FAI_CLASSES)
# last class has highest priority

# reverse order of classes
for class in $classes; do
    revclasses="$class $revclasses"
done

[ "$debug" ] && vflag="-v"
[ "$debug" ] && echo "ftar: classes : $revclasses"
[ -z "$source" ] && die 1 "Source directory undefined."
[ -z "$target" ] && die 1 "Target directory undefined."

# currently only one directory is used
dir=$1
fpath=$source/$dir
[ -d $fpath ] || die 1 "No directory $fpath"

for c in $revclasses ; do
    # what if a directory exists which is equal to the hostname or a classname?
    [ -f $fpath/$c.tgz ]      && extract $fpath/$c.tgz zcat
    [ -f $fpath/$c.tar ]      && extract $fpath/$c.tar cat
    [ -f $fpath/$c.tar.gz ]   && extract $fpath/$c.tar.gz zcat
    [ -f $fpath/$c.tar.bz2 ]  && extract $fpath/$c.tar.bz2 bzcat
    [ -f $fpath/$c.tar.xz ]   && extract $fpath/$c.tar.xz xzcat
    [ -f $fpath/$c.txz ]      && extract $fpath/$c.txz xzcat
done

if [ $tardone -eq 0 ]; then
    if [ $ignore -eq 1 ]; then
        echo "ftar: No matching class found in $fpath"
        exit 0
    else
        die 1 "No matching class found in $fpath"
    fi
fi

exit 0

