#!/bin/sh
# Update-f-prot - script to either reinstall the f-prot program files
# or just call /usr/lib/f-prot/check-updates to look for DEF updates
set -e
#set -x
DO_INSTALL=false
UPDATE_AVAILABLE=false
FORCE_INSTALL=false
INSTALL_FROM_FILE=false
UPDATE_DEFS=true
TARBALL=fp-linux-ws.tar.gz
MD5SUM=fp-linux-ws.tar.gz.md5
DOWNLOAD_LOC=ftp://ftp.f-prot.com/pub/linux/
DL_DIR=`mktemp -d -t dldir.XXXXXXXXXX` || exit 1
UNPACK_DIR=`mktemp -d -t  fp-unpack.XXXXXXXXX` || exit 1
WGET_OPTS="-nv"
FPROT_DIR=/usr/lib/f-prot
FPROTSTATE_DIR=/var/lib/f-prot
MD5SUM_STORED=$FPROTSTATE_DIR/$MD5SUM
MD5SUM_NEW=$DL_DIR/$MD5SUM
TARBALL_NEW=$DL_DIR/$TARBALL
CONFFILE=/etc/f-prot.conf
abort=no
# Some functions we need
do_abort()
{
    rm -rf $DL_DIR $UNPACK_DIR
    exit 1
}
do_cleanup() {
    rm -rf $DL_DIR $UNPACK_DIR
}
do_help() {
    cat <<EOF >&2
Usage: update-f-prot [options]

Without options, update-f-prot calls /usr/lib/f-prot/check-updates
to see if new virus definitions are available

options:
       -i         -- install F-Prot for small business again
       -f         -- force installation even if checksum indicates that
                     an identical version is already installed
       -d DIR     -- Directory where to look for locally available files
       -n         -- Skip the check for new virus definitions


EOF
}

do_download_md5sum() {
    cd $DL_DIR
    set +e
    echo "Downloading file $MD5SUM from $DOWNLOAD_LOC"
    wget --retr-symlinks --passive-ftp $WGET_OPTS ${DOWNLOAD_LOC}/${MD5SUM}
    case $? in
	127)
	    echo "Wget not found or not executable." >&2
	    echo "Please check the installation." >&2
	    abort=yes
	;;
	1)
	    cat <<EOF >&2
    Download failed. Please make sure that 
    your computer is connected to the Internet. 
    If you see this error although you are 
    connected, either the server is down or the 
    download location has changed. In the latter
    case you can still download the files manually. 
    Please file a bug report against 
    f-prot-installer!
EOF

	    abort=yes

	    ;;
	0)
	    # Do a minimal test if the file is really an md5sum and not
	    # a 404 error message or so. It should have exactly one line.
	    
	    if [ `wc -l $MD5SUM_NEW|awk '{print $1}'` -ne 1 ]; then
		echo "Downloaded file $DL_DIR/$MD5SUM is not an md5sum." >&2
		echo "Please re-run this script to repeat the download." >&2
		echo . >&2
		abort=yes
	    else
		echo md5sum looks O.K.
	    fi
	    
	    
	    ;;
	*)
	# Shit happens
	    echo "Unknown error occured. exiting.">&2
	    abort=yes
	    
	    
    esac
    set -e
    [ $abort = "no" ] || do_abort
}

# A function to compare the stored md5sum in /var/lib with
# the new one, which was either downloaded or provided by the user.

do_compare_md5sums() {
    if [ -f $MD5SUM_STORED ]; then
	sum1="`awk '{print $1}' $MD5SUM_STORED`"
	sum2="`awk '{print $1}' $MD5SUM_NEW`"
	if [ "$sum1" = "$sum2" ]; then
	    cat <<EOF

       Old and new checksum are identical. 
       You already have the latest version 
       installed. Congrats!
EOF
	    if [ $FORCE_INSTALL = "false" ]; then
		cat <<EOF

       If you want to force a re-installation, 
       please call update-f-prot with the -f option.

EOF
	    fi
	    UPDATE_AVAILABLE=false
	else
	    
	# If the two md5sum files are not identical, this does of
	# course _not_ guarantee, that the "new" one is really
	# newer. But, well, I still hope that this will yield the
	# desired result in most cases. If anyone has a better idea,
	# please tell me.
	    
cat <<EOF


    The two checksums are not identical 
    This usually means that there is a 
    new Version of F-prot for Small Business
    available.

    I'm going to download the new version now. 
    Download size is approximately 3.4 MByte.

EOF

	    UPDATE_AVAILABLE=true
	fi	
    else
	# No other way to verify if installation is current. So
	# we have no option but to install
	UPDATE_AVAILABLE=true
    fi
    

}

# O.K. Here we download the actual tarball.

do_download_tarball() {
    cd $DL_DIR
    set +e
    wget --passive-ftp --retr-symlinks --progress=bar ${DOWNLOAD_LOC}/${TARBALL}
    case $? in
	127)
	    echo >&2 wget not found or not executable.
	    echo >&2 Please check the installation.
	    abort=yes
	    ;;
	1)
	    cat <<EOF >&2

    Download failed. Please make sure that 
    your computer is connected to the Internet. 
    If you see this error although you are connected, 
    either the server is down or the download 
    location has changed. In the latter case you can 
    still download the files manually. Please file a bug 
    report against f-prot-installer!

EOF
	    abort=yes
	    
	    ;;
	0)
	    echo .
	    echo $TARBALL successfully downloaded from ${DOWNLOAD_LOC}.
	    echo .
	    ;;
	*)
	# Shit happens
	    echo . >&2
	    echo Unknown error occured. exiting. >&2
	    echo . >&2
	    abort=yes

	    
    esac
    [ $abort = "no" ] || do_abort
    set -e
}

do_check_tarball()
{
    sum1="`awk '/NR == 1/ {print $1}' $MD5SUM_NEW`"
    sum2="`md5sum $TARBALL_NEW | awk '/NR == 1/ {print $1}'`"
    if [ "$sum1" != "$sum2" ]; then
	echo >&2 "md5sum mismatch:"
	echo >&2 "   checksum file:  $sum1"
	echo >&2 "   calculated sum: $sum2"
	echo >&2 .
	echo >&2 .
	echo >&2 "The tarball is possibly corrupted"
	echo >&2 "You can try to re-run $0 to download"
	echo >&2 "an uncorrupted copy."
	echo >&2 .
	abort=yes
    fi

    if [ "`ls -l $TARBALL_NEW | awk '{print $3}'`" != root ]; then
	echo >&2 "file not owned by root: $TARBALL_NEW"
	abort=yes
    fi
    if [ "`ls -l $MD5SUM_NEW | awk '{print $3}'`" != root ]; then
	echo >&2 "file not owned by root: $MD5SUM_NEW"
	abort=yes
    fi

    [ $abort = "no" ] || do_abort
}

do_patch()
{
    for f in \
	$UNPACK_DIR/f-prot/tools/check-updates.pl \
	$UNPACK_DIR/f-prot/man_pages/check-updates.pl.8
    do
      echo Patching $f ...
	sed \
	    -e 's,/usr/local/f-prot,/usr/lib/f-prot,g' \
	    -e 's,check-updates\.pl,check-updates,g' \
	    $f > $f.new
	if cmp --silent $f $f.new; then
	    rm -f $f.new
	else
	    mv -f $f $f.orig
	    mv $f.new $f
	    rm -f $f.orig
	fi
    done
	mv $UNPACK_DIR/f-prot/tools/check-updates.pl $UNPACK_DIR/f-prot/tools/check-updates
	mv $UNPACK_DIR/f-prot/man_pages/check-updates.pl.8 $UNPACK_DIR/f-prot/man_pages/check-updates.8


}

do_unpack()
{
    cd $UNPACK_DIR
    tar -x -C $UNPACK_DIR -z -f $TARBALL_NEW
    chmod og-w $UNPACK_DIR/*
    chown -R root:root $UNPACK_DIR

## FIXME: We should probably not wipe out /var/lib/f-prot
## unconditionally but check if the DEF-files there are more current
## that the files that came with the tarball.

    rm -rf $FPROT_DIR $FPROTSTATE_DIR
    mkdir -p $FPROT_DIR $FPROTSTATE_DIR

#     this is obsolete with f-prot 4.0.0
#     # old location of man pages ...
#     if [ -f f-prot.8 -o -f check-updates.sh ]; then
# 	mkdir -p $UNPACK_DIR/man8
# 	mv -f *.8 $UNPACK_DIR/man8/
#     fi
#

    do_patch

    cp -pr $UNPACK_DIR/f-prot/* $FPROT_DIR/
    # Necessary with f-prot 4.6.X
    ln -sf /usr/lib/f-prot/f-prot.sh /usr/bin/f-prot
    chmod 755 $FPROT_DIR/tools
    chmod 755 $FPROT_DIR/tools/check-updates
    cp -f $MD5SUM_NEW $MD5SUM_STORED
    rm -f /usr/share/man/man_pages/check-updates.pl.8
    gzip -9 $FPROT_DIR/man_pages/*.[1,8]
    ln -sf ../../../lib/f-prot/man_pages/f-prot.1.gz /usr/share/man/man1/f-prot.1.gz
    ln -sf ../../../lib/f-prot/man_pages/check-updates.8.gz \
	/usr/share/man/man8/check-updates.8.gz

    for f in $FPROT_DIR/*.DEF; do
	mv -f $f /var/lib/f-prot/
	ln -sf /var/lib/f-prot/`basename $f` $f
    done
    for f in CHANGES LICENSE README doc_ws; do
	ln -sf ../../../lib/f-prot/$f /usr/share/doc/f-prot-installer/$f.f-prot
    done
    # remove bogus symlink that works only if f-prot is installed into /usr/local
    rm -f $FPROT_DIR/check-updates.sh
}

# Check if we are root
if [ "$UID" -ne "0" ]; then
    echo "Must be root to run this script. exiting.">&2
    do_abort    
fi

while getopts :ifnd: OPT; do
    case $OPT in
	i|+i)
	    echo "installing f-prot"
	    DO_INSTALL=true
	;;
	f|+f)
	    echo Reinstallation forced
	    DO_INSTALL=true
	    FORCE_INSTALL=true
	;;
	d|+d)
	    echo looking for F-prot in $OPTARG
	    # Verify that the files are really there
	    if [ -f $OPTARG/$MD5SUM ]; then
		MD5SUM_NEW=$OPTARG/$MD5SUM
	    else
		echo . >&2
		echo "$MD5SUM was not found. Please identify the ">&2
		echo "correct directory and re-run $(basename $0)">&2
		echo . >&2
		abort=yes
	    fi
	    if [ -f $OPTARG/$TARBALL ]; then
		TARBALL_NEW=$OPTARG/$TARBALL

	    else
		echo . >&2
		echo "$TARBALL was not found in $OPTARG. Please" >&2
		echo "re-run `basename $0` with the correct directory">&2
                echo "as argument following the -d option">&2
		echo . >&2
		abort=yes
	    fi
	    INSTALL_FROM_FILE=true
	    ;;
	n|+n)
	    echo Not updating DEFs
            UPDATE_DEFS=false
	    ;;
	*)
#	    echo "usage: `basename $0` [+-ifd ARG} [--] ARGS..."
	    do_help
	    abort=yes
    esac
done
[ $abort = "no" ] || do_abort
shift `expr $OPTIND - 1`

## Oh, well, hope that this was all preparation necessary. Now, let's go to work..
## First, make sure that the configuration file exists
if [ ! -f $CONFFILE ]; then
    cat <<EOF
    Configuration file $CONFFILE was not found,
    check-updates will most likely fail.
    Please create it by running

    "echo /var/lib/f-prot > /etc/f-prot.conf"

    If this fails, please reinstall f-prot by running

    "update-f-prot -fi"
    
EOF
    exit 1
    
fi
if [ $DO_INSTALL = "true" ]; then
## this is an additional sanity test meant to fix bug #191688: If an
## earlier installation has failed, but still for some reason there is
## an md5sum file in /var/lib/f-prot lying around, f-prot will never
## get properly installed unless the user discovers the -f option.
## simple solution: If the installation in /usr/lib/f-prot is
## incomlete, we delete the md5sum file, thus forcing a new
## installation.
    
    for file in \
	$FPROT_DIR/tools/check-updates \
	$FPROT_DIR/f-prot \
	$FPROT_DIR/ENGLISH.TX0 \
	$FPROT_DIR/man_pages/f-prot.1.gz \
	$FPROT_DIR/man_pages/check-updates.8.gz; \
	do
      if [ ! -f $file ]; then
##	echo "Required file $file was not found."
##	echo "Old f-prot installation is incomplete."
##	echo "Forcing Reinstallation."
	  rm -f $MD5SUM_STORED
      fi
    done
    if [ $INSTALL_FROM_FILE = "false" ]; then
	do_download_md5sum
	do_compare_md5sums
	if [ $UPDATE_AVAILABLE = "true" -o $FORCE_INSTALL = "true" ]; then
	    do_download_tarball
	    do_check_tarball
	    do_unpack    
	fi
    else
	do_compare_md5sums
	if [ $UPDATE_AVAILABLE = "true" -o $FORCE_INSTALL = "true" ]; then
	    do_check_tarball
	    do_unpack    
       	else
	    echo No update available
	fi
    fi
    
fi
if [ $UPDATE_DEFS = "true" ]; then
    echo Checking if virus definitions need to be updated...
    if [ -f /usr/lib/f-prot/tools/check-updates ]; then
	/usr/lib/f-prot/tools/check-updates
    elif [ -f /usr/lib/f-prot/check-updates ]; then
	cat <<EOF >&2
You appear to be using an old version of F-Prot. 
Please consider running "update-f-prot -i".
EOF
	/usr/lib/f-prot/check-updates
    elif [ -f /usr/lib/f-prot/check-updates.sh ]; then
	cat <<EOF >&2
You are using an old version of F-Prot or 
your installation is inconsistent. 
Please consider running "update-f-prot -i"
EOF
	/usr/lib/f-prot/check-updates.sh
    else
    	echo >&2 Alert: Virus definition update script 
	echo >&2 /usr/lib/f-prot/tools/check-updates
	echo >&2 was not found.
	echo >&2 .
	echo >&2 Please run update-f-prot -i to correct this.
	do_abort
    fi
fi
do_cleanup
exit 0
