#! /bin/sh

# A script to rebuild the newsfeed file after a gup run

gup=/var/mailserv/newsgup

# altered sites beautification
# may need customisation if you're not running BSD NetRel2
pr="pr -5 -a -t -o5"
#pr=cat

# your INN newsfeeds file.  this file is automatically updated by this script
# by combining the feeds lists for all the sites that gup controls, along
# with a general-purpose header and trailer for the file as a whole.
newsfeeds=/etc/news/feeds

# your INN control program, ctlinnd
# If you're running c news, set this to null as nothing special needs to
# be done.  Of course, if relaynews is running at the time some locking may
# be required at the point that the new $newsfeeds file is shifted into place.
# But maybe not...
ctlinnd=/usr/libexec/news/ctlinnd
#ctlinnd=

# a program that checks the integrity of $newsfeeds.  if it returns a non-zero
# result a backup $newsfeeds is quickly put in place and the news admin is
# notified
verify="$ctlinnd checkfile"
#verify=/bin/true

mailcmd=/usr/bin/mail

news_admin=news

PATH=/usr/bin:/bin

########################### end of user-config stuff ##########################

update_stamp=$gup/.last-update
tmpfeeds=/tmp/newsfeeds.$$
reload_thresh=5


cd $gup

# determine what's changed since last time - to save inn from reloading the
# entire newsfeeds file, and us from wasting our time.

if [ ! -f $update_stamp ]; then
	echo "$update_stamp doesn't exist - creating"
	touch $update_stamp
	first_update=1		# this must be our first time
else
	# decide what's changed, if anything
	touch ${update_stamp}.new	# prevent anything sneaking in
	cd sites
	altered=`find . -type f -name groups -newer $update_stamp -print |
		sed -e 's#\./##g' -e 's#/groups##'`
	cd ..
	if [ x"$altered" = x ]; then
		rm -f ${update_stamp}.new
		exit 0
	fi
	mv -f ${update_stamp}.new ${update_stamp}
	first_update=0
fi

(
# global header
cat headers/global

cd sites
for h in *; do
  if [ -s $h/groups ]; then
	echo
  # header
	sed -e "s/HOST/$h/g" $h/header
  # body
	sed -e 's/$/,\\/g' -e 's/^/  /g' $h/groups
  # trailer
	sed -e "s/HOST/$h/g" $h/trailer
  fi
done
cd ..

# global trailer
cat trailers/global

) >$tmpfeeds


# commit the new version

mv -f $newsfeeds.old $newsfeeds.old1
mv -f $newsfeeds $newsfeeds.old
mv $tmpfeeds $newsfeeds

# verify that it's ok

$verify >/dev/null 2>/dev/null

ok=$?

if [ $ok -eq 0 ]; then
  echo "${newsfeeds}: verification succeeded"
  echo
else
  echo "argh!  $newsfeeds verification failed - moving back previous version"
  mv $newsfeeds $newsfeeds.broken
  mv $newsfeeds.old $newsfeeds
  $mailcmd -s "gup newsfeeds failure!" $news_admin <<SIGH
gup has gone weird - the generated newsfeeds file has been rejected by
$verify.  Please check:
	$newsfeeds.broken

to determine the source of the problem.

yours in efficiency,
the gupdate daemon
SIGH
  # force a complete reload next time
  rm -f ${update_stamp}
  exit 1
fi

# tell INN about it

if [ "$ctlinnd" ]; then

  # inn newsfeed reloads are expensive, particularly for channels - only
  # reload what is necessary, except if there are more than ${reload_thresh}
  # sites that need dealing with.

  if [ $first_update -eq 1 ]; then
    echo "full update: ctlinnd reload newsfeeds"
    $ctlinnd reload newsfeeds gupup
  else
    echo "sites altered:"
    echo $altered | $pr
    echo

    if [ `echo $altered | wc -w | awk '{print $1}'` -le $reload_thresh ]; then
	for site in $altered; do
		news_name=`sed -e "s/HOST/$site/g" -e 's/:\\//g' sites/$site/header`
		if [ -s sites/$site/groups ]; then
		  echo "$site: ctlinnd begin $news_name"
		  $ctlinnd begin $news_name
		else
		  echo "$site: ctlinnd drop $news_name"
		  $ctlinnd drop $news_name
		fi
	done
    else
	echo "ctlinnd reload newsfeeds"
	$ctlinnd reload newsfeeds gupup
    fi
  fi
fi
