#! /bin/sh
. /usr/lib/news/lib/innshellvars

# @(#) $Id: actsyncd.in,v 1.6.2.1 2003/10/18 05:49:04 rra Exp $
# @(#) Under RCS control in /usr/local/news/src/inn/local/RCS/actsyncd.sh,v
#
# actsyncd - actsync daemon
#
# usage:
#	actsyncd [-x] config_file [debug_level [debug_outfmt]]
#
#	-x		xexec instead of reload
#	config_file	name of file used to determine how to run actsync
#	debug_level	force no action and use -v debug_level
#	debug_outfmt	change -o a1 output to -o debug_outfmt for debug

# By: Landon Curt Noll  	chongo@toad.com		(chongo was here /\../\)
#
# Copyright (c) Landon Curt Noll, 1993.
# All rights reserved.
#
# Permission to use and modify is hereby granted so long as this 
# notice remains.  Use at your own risk.  No warranty is implied.

# preset vars
#

# Our lock file
LOCK="${LOCKS}/LOCK.actsyncd"
# where actsync is located
ACTSYNC="${PATHBIN}/actsync"
# exit value of actsync if unable to get an active file
NOSYNC=127

# parse args
#
if [ $# -gt 1 ]; then
    case $1 in
    -x|-r) shift ;;     # no longer relevant
    esac
fi
case $# in
    1) cfg="$1"; DEBUG=; DEBUG_FMT=; ;;
    2) cfg="$1"; DEBUG="$2"; DEBUG_FMT=; ;;
    3) cfg="$1"; DEBUG="$2"; DEBUG_FMT="$3"; ;;
    *) echo "usage: $0 [-x] config_file [debug_level [debug_outfmt]]" 1>&2;
       exit 1 ;;
esac
if [ ! -s "$cfg" ]; then
    echo "$0: config_file not found or empty: $ign" 1>&2
    exit 2
fi

# parse config_file
#
host="`sed -n -e 's/^host=[ 	]*//p' $cfg | tail -1`"
if [ -z "$host" ]; then
    echo "$0: no host specified in $cfg" 1>&2
    exit 3
fi
flags="`sed -n -e 's/^flags=[ 	]*//p' $cfg | tail -1`"
if [ -z "$flags" ]; then
    echo "$0: no flags specified in $cfg" 1>&2
    exit 4
fi
ign="`sed -n -e 's/^ignore_file=[ 	]*//p' $cfg | tail -1`"
if [ -z "$ign" ]; then
    echo "$0: no ignore file specified in $cfg" 1>&2
    exit 5
fi
ftp="`sed   -n -e 's/^ftppath=[ 	]*//p' $cfg | tail -1`"
spool="`sed -n -e 's/^spool=[ 	]*//p' $cfg | tail -1`"
if [ -z "$spool" ]; then
    spool=$SPOOL
    #echo "$0: no spool directory specified in $cfg" 1>&2
    #exit 6
fi
if [ ! -f "$ign" ]; then
    ign="${PATHETC}/$ign"
fi
if [ ! -s "$ign" ]; then
    echo "$0: ignore_file not found or empty: $ign" 1>&2
    exit 7
fi

# force -o c mode (overrides any -o argument in the command line)
#
if [ -z "$DEBUG" ]; then

    # standard actsyncd output mode
    flags="$flags -o c"

# DEBUG processing, if debug_level was given
#
else

    if [ ! -z "$ftp" ]; then
        echo "$0: cannot use DEBUG mode with ftp (yet)" >&2
        exit 88;
    fi

    # force -v level as needed
    flags="$flags -v $DEBUG"

    # force -o level but reject -o x modes
    if [ ! -z "$DEBUG_FMT" ]; then
	case "$DEBUG_FMT" in
	x*) echo "$0: do not use any of the -o x debug_outfmt modes!" 1>&2;
	    exit 8 ;;
	*) flags="$flags -o $DEBUG_FMT" ;;
	esac
    fi

    # execute actsync directly
    echo "DEBUG: will execute $ACTSYNC -i $ign $flags $host" 1>&2
    eval "$ACTSYNC -i $ign $flags $host"
    status="$?"
    echo "DEBUG: exit status $status" 1>&2
    exit "$status"
fi

# Lock out others
#
shlock -p $$ -f "${LOCK}" || {
    echo "$0: Locked by `cat '${LOCK}'`" 1>&2
    exit 9
}

# setup
#
origdir=`pwd`
workdir="${TMPDIR}/actsyncd"
ctlinndcmds="cc_commands"
out="sync.msg"
cleanup="$SED -e 's/^/    /' < $out; cd ${origdir}; rm -rf '$workdir' '$LOCK'"
trap "eval $cleanup; exit 123" 1 2 3 15

set -e
rm -rf "$workdir"
mkdir "$workdir"
cd "$workdir"
set +e

rm -f "$out"
touch "$out"
chmod 0644 "$out"

# try to sync 
# 
# Try to sync off of the host.  If unable to connect/sync then retry
# up to 9 more times waiting 6 minutes between each try.
#
echo "=-= `date` for $host" >>$out 2>&1
for loop in 1 2 3 4 5 6 7 8 9 10; do

    # get the active file to compare against
    status=0
    case $host in
    /*) cp $host          active; status=$? ;;
    .*) cp $origdir/$host active; status=$? ;;
     *)
        if [ -z "$ftp" ]; then
           port=`expr "$host" : '.*:\(.*\)'`
           if [ -n "$port" ]; then
             port="-p $port"
             host=`expr "$host" : '\(.*\):.*'`
           fi
           echo "getlist -h $host $port" >>$out
           if getlist -h $host $port > active 2>>$out; then
             :
           else
             status=$NOSYNC
           fi
        else
           echo "$GETFTP ftp://$host/$ftp" >>$out
           $GETFTP ftp://$host/$ftp >>$out 2>&1
           status=$?
           if [ "$status" -ne 0 ]; then
             status=$NOSYNC
           else
             case "$ftp" in
             *.gz)
                   echo "$GZIP -d active" >>$out
                   if $GZIP -d active >>$out 2>&1; then
                     :
                   else
                     status=1
                   fi
                   ;;
             *.Z)
                   echo "$UNCOMPRESS active" >>$out
                   if $UNCOMPRESS active >>$out 2>&1; then
                     :
                   else
                     status=1
                   fi
                   ;;
             esac
           fi
        fi
        ;;
    esac

    if [ "$status" -ne "$NOSYNC" ]; then

	# detect bad status
	#
	if [ "$status" -ne 0 ]; then
	    echo "FATAL: `date` for $host exit $status" >>$out
            eval $cleanup
	    exit "$status"
	fi

        echo "$ACTSYNC -i $ign $flags ./active" >>$out
        eval "$ACTSYNC -i $ign $flags ./active >$ctlinndcmds 2>>$out"

        if [ $? -ne 0 ]; then
            echo "FATAL: `date` for $host actsync balked" >>$out
            eval $cleanup
            exit $?
        fi

        if [ ! -s $ctlinndcmds ]; then
            echo "No changes need to be made" >>$out
        else
            echo "=-= `date` for $host, updating active" >>$out
            echo "mod-active $ctlinndcmds" >>$out
            mod-active $ctlinndcmds >>$out 2>&1

            if [ $? -ne 0 ]; then
                echo "FATAL: `date` for $host mod-active FAILED" >>$out
                eval $cleanup
        	exit 1
            fi
        fi

	# normal exit - all done
	#
	echo "=-= `date` for $host, end" >>$out
        eval $cleanup
	exit 0
    fi

    # failed to get the remote active file
    echo "=-= `date` for $host failed to connect/sync, retrying" >>$out

    # wait 6 minutes
    #
    sleep 360
done

# give up
#
echo "FATAL: `date` for $host failed to connect/sync 10 times" >>$out 2>&1
eval $cleanup
exit 1
