#! /bin/sh # fixscript will replace this line with code to load innshellvars # actsyncd - actsync daemon # # Usage: # actsyncd config_file [debug_level [debug_outfmt]] # # 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. # # Various bug fixes, code and documentation improvements since then # in 1999-2003, 2007-2009, 2021-2024. # # 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 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 config_file [debug_level [debug_outfmt]]" 1>&2 exit 1 ;; esac if [ ! -s "$cfg" ]; then echo "$0: config_file not found or empty: $cfg" 1>&2 exit 2 fi # parse config_file # host="$(sed -n -e 's/^host=[ ]*//p' $cfg | tail -n 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 -n 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 -n 1)" if [ -z "$ign" ]; then echo "$0: no ignore file specified in $cfg" 1>&2 exit 5 fi # Keep ftppath for backwards-compatibility. ftp="$(sed -n -e 's/^ftppath=[ ]*\/*//p' $cfg | tail -n 1)" path="$(sed -n -e 's/^path=[ ]*\/*//p' $cfg | tail -n 1)" protocol="$(sed -n -e 's/^protocol=[ ]*//p' $cfg \ | tr '[:upper:]' '[:lower:]' | tail -n 1)" if [ -z "$ftp" ] && [ -z "$path" ]; then if [ -z "$protocol" ]; then protocol="nntp" else if [ "$protocol" != "nntp" ]; then echo "$0: path expected with protocol $protocol" 1>&2 exit 6 fi fi fi # If not NNTP, assume FTP by default for backwards-compatibility. if [ -z "$protocol" ]; then protocol="ftp" fi if [ -n "$ftp" ] && [ -n "$path" ]; then echo "$0: ftppath and path cannot both be set" 1>&2 exit 6 fi if [ -n "$ftp" ] || [ -n "$path" ]; then if [ "$protocol" = "nntp" ]; then echo "$0: cannot set a path with protocol $protocol" 1>&2 exit 6 fi fi if [ -n "$ftp" ] && [ -z "$path" ]; then path=$ftp if [ "$protocol" != "ftp" ]; then echo "$0: cannot set ftppath with protocol $protocol" 1>&2 exit 6 fi fi # Try to find the ignore file in pathetc. 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 # DEBUG processing, if debug_level was given. # if [ -z "$DEBUG" ]; then # Force "-o c" mode (overrides any -o argument in the command line). # Standard actsyncd output mode (commands to ctlinnd). flags="$flags -o c" else if [ "$protocol" != "nntp" ]; then echo "$0: DEBUG mode (still) only available with nntp" >&2 exit 88 fi # force -v level as needed flags="$flags -v $DEBUG" # force -o level but reject -o x modes if [ -n "$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'" #shellcheck disable=SC2064 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 [ "$protocol" = "nntp" ]; 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 if [ "$protocol" = "ftp" ]; then program=$GETFTP else program=$GETHTTP fi echo "$program $protocol://$host/$path" >>$out if $program $protocol://$host/$path >>$out 2>&1; then case "$path" in *.bz2) echo "$BZIP2 -d active.bz2" >>$out if $BZIP2 -d active.bz2 >>$out 2>&1; then : else status=1 fi ;; *.gz) echo "$GZIP -d active.gz" >>$out if $GZIP -d active.gz >>$out 2>&1; then : else status=1 fi ;; *.Z) echo "$UNCOMPRESS active.Z" >>$out if $UNCOMPRESS active.Z >>$out 2>&1; then : else status=1 fi ;; esac else status=$NOSYNC fi fi if [ ! -s "active" ]; then echo "$0: active file not retrieved or empty" >>$out status=1 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" status=$? if [ "$status" -ne 0 ]; then echo "FATAL: $(date) for $host actsync balked" >>$out eval $cleanup exit "$status" 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 status=$? if [ "$status" -ne 0 ]; then echo "FATAL: $(date) for $host mod-active FAILED" >>$out eval $cleanup exit "$status" 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 $loop times" >>$out 2>&1 eval $cleanup exit 1