#!/bin/sh
# $Header: /home/ftpadm/src/genindex/RCS/genindex,v 1.3 1993/01/12 01:54:12 cross Exp cross $

config="`dirname $0`/config.sh"
if [ ! -r "$config" ]; then
    echo "config file $config not found. aborting." 1>&2
fi
. "$config"


if [ $# -ge 1 ]; then ROOT="$1" ; fi
if [ $# -ge 2 ]; then PREFIX="$2" ; fi
if [ $# -ge 3 ]; then DEST="$3" ; fi
if [ $# -ge 4 ]; then echo "too many arguments. exiting." 1>&2 ; exit 1 ; fi 

if tty -s > /dev/null 2>&1 ; then
    INTERACTIVE=1
else
    INTERACTIVE=0
fi

# ---- subroutines

cleanup='
# args: none
    if [ -s "$allerr" ]; then
	(   echo "Subject: non-fatal errors during index-generation"
	    echo ""
	    cat "$allerr"
	) | eval "$report"
    fi
    rm -f "$tmperr" "$tmpindex" "${tmpindex}.Z" "$tmpnew" "$allerr"
'

report='
    case $INTERACTIVE in 
	0) $MAILPROG $FTPADM ;;
	*) cat 1>&2 2>/dev/tty ;;
    esac
'

collecterr='
# args: additional error text
# global variables: $result, $tmperr (read), "$allerr" (write)
    case "$result" in
    0)  if [ -s "$tmperr" ]; then
	    (   echo "$* reported non-fatal errors:"
		cat "$tmperr"
	        echo ""
	    ) >> "$allerr"
	fi
	rm -f "$tmperr" ;;
    *)  ( 
	    echo "Subject: index generation error"
	    echo ""
	    echo "execution of $0 ($*) at `date` resulted in fatal errors"
	    echo ""
	    if [ -s "$tmperr" ]; then
		cat "$tmperr"
	    else
		echo "(no further information available)"
	    fi
	    echo ""
	) | eval "$report"
	exit 1 ;;
    esac
'


securemv='
#args: $1 from, $2 to
    from="$1"
    if [ -d "$2" ]; then to="$2/`basename $from`" ; else to="$2" ; fi
    tmp="${to}.$$.tmp"

    cp "$from" "$tmp" 2>"$tmperr"
    result=$?
    if [ "$result" -ne 0 ]; then rm -f "$tmp" ; fi
    set "mv $from $to"; eval "$collecterr"

    if [ -f "$to" -o -d "$to" ]; then
	rm -f "$to" 2>"$tmperr"
	result=$?
	set "rm $to"; eval "$collecterr"
    fi

    mv "$tmp" "$to" 2>"$tmperr"
    result=$?
    set "mv $tmp $to"; eval "$collecterr"

    rm -f $from
'

mkpattern='
    sed -e "s/[ 	]*#.*$//" -e "s/^\^//" -e "s/\$$//" $1 | \
    awk "/^$/ { next }
      /^\.\// || /^\*/ || /^\// {
	printf(\"( -path %s -prune -true ) -o \", \$0); next }
      { printf(\"( -path ./%s -prune -true ) -o \", \$0) }
'

mkgroups='
    groups $ANONUSER | \
    sed -e "s/^[^ ]* : //" -e "s/\([^ ]*\) /\1 -o -group /g" -e "s/^/-group /"
'


created='
    awk "BEGIN { m[\"Jan\"] =  1; m[\"Feb\"] =  2; m[\"Mar\"] =  3; 
		 m[\"Apr\"] =  4; m[\"May\"] =  5; m[\"Jun\"] =  6;
		 m[\"Jul\"] =  7; m[\"Aug\"] =  8; m[\"Sep\"] =  9; 
		 m[\"Oct\"] = 10; m[\"Nov\"] = 11; m[\"Dec\"] = 12; }
	 /^#CREATED/ && NF == 3 { printf(\"%4s%02d%2s%s%s\", \
		 substr(\$2,8,4), m[substr(\$2,4,3)], substr(\$2,1,2), \
		 substr(\$3,1,2), substr(\$3,4,2)); done = 1; exit }
	 END   { if (done == 0) print \"first\" }" $1
'

rawcreated='
    awk "/^#CREATED/ && NF == 3 { print \$2 ; exit }" $1
'


# ------ main

TZ=GMT
LANG=""
LANGUAGE=""
LC_CTYPE=""
export TZ LANG LANGUAGE LC_CTYPE

umask 022

allerr="$TMPDIR/index-err.$$"
tmperr="$TMPDIR/index-tmperr.$$"
tmpindex="$TMPDIR/INDEX.$$"
tmpnew="$TMPDIR/newdiff.$$"

case a"$ROOT" in
a) echo "usage: $0 archive-root" 1>&2
    exit 1
    ;;
a/*) break	# okay
    ;;
*)  echo "archive-root path must be absolute" 1>&2
    exit 1
    ;;
esac
case a"$PREFIX" in
a) break
    ;;
a/) PREFIX=""	# no leading /
    ;;
a/*) break	# okay
    ;;
*)  echo "prefix must be absolute" 1>&2
    exit 1
    ;;
esac
case a"$DEST" in
a)  if echo "$ROOT" | grep ' ' ; then
        echo "with multiple \$ROOT directories, \$DEST must be defined as real-root." >&2
	exit 1
    else
	DEST="$ROOT"
    fi
    ;;
a/*) break	# okay
    ;;
*)  echo "destination must be absolute" 1>&2
    exit 1
    ;;
esac

trap "eval $cleanup" 0 1 2 3 15

touch "$allerr"

# ---- generate "INDEX" and "INDEX.Z"

if [ -f "$IGNORENAME" ]; then
    PATTERN="`set $IGNORENAME; eval \"$mkpattern\"`"
else
    PATTERN=""
fi

GROUPS="`eval \"$mkgroups\"`"

DATEFORMAT="%Td-%Tb-%TY %TH:%TM"

touch "$tmpindex"
now=`$GFIND "$tmpindex" -printf "$DATEFORMAT"`

cat <<END > "$tmpindex"
#NAME		$SERVERNAME
#ADDRESS	$SERVERADDR
#ORGANIZATION	$SERVERORG
END

case "a$LOCATION" in a) ;; *)
    cat <<END >> "$tmpindex"
#LOCATION	$LOCATION
END
esac
case "a$ACCESS" in a) ;; *)
    cat <<END >> "$tmpindex"
#ACCESS		$ACCESS
END
esac

cat <<END >> "$tmpindex"
#MAIL		$FTPADM
#SERVER-TIMEZONE $SERVERZONE
#
#INDEX-TIMEZONE	+0000 (UTC)
#VERSION	1.0 (28-Aug-1992); de-mirror INDEX format
#CREATED	$now
#
END

rootsed="`echo $ROOT | sed -e 's/ /|/' -e 's/\//\\\\\//g'`"
prefixsed="`echo $PREFIX | sed -e 's/\//\\\\\//g'`"
(
  set -f

  permcheck='cat <<END
     (      -user $ANONUSER                -perm -${1}00 \
        -o ! -user $ANONUSER   ( $GROUPS ) -perm -0${1}0 \
	-o ! -user $ANONUSER ! ( $GROUPS ) -perm -00${1} )
END'
  PERMR=`set "4" ; eval "$permcheck"`
  PERMW=`set "2" ; eval "$permcheck"`
  PERMX=`set "1" ; eval "$permcheck"`

  $GFIND $ROOT $PATTERN 						      \
          \( -type d ! $PERMX -prune -true \)                                 \
    -o    \( -type d -printf "D" \(                                           \
		   $PERMR -printf "R" -o -printf "-" ,                        \
		   $PERMW -printf "W" -o -printf "-" ,                        \
		   -printf "X          0 $DATEFORMAT $PREFIX/%P\n"            \
	  \) \)                                                               \
    -o    \( -type l                                                          \
	     -printf "L---          0 $DATEFORMAT $PREFIX/%P -> %l\n" \)      \
    -o    \( -type f -size 0 \)                                               \
    -o    \( -type f ! $PERMR \)                                              \
    -o    \( -type f -printf "FR" \(                                          \
		   $PERMW -printf "W" -o -printf "-" ,                        \
		   $PERMX -printf "X" -o -printf "-" ,                        \
		   -printf " %10s $DATEFORMAT $PREFIX/%P\n"                   \
	  \) \)
) 2>"$tmperr" | (
    case "a$SORTOPTS" in
	a) cat - ;;
	*) sort $SORTOPTS - ;;
    esac
) >> "$tmpindex"

result=$?
set "gfind $ROOT"; eval "$collecterr"

# ---- move index to destination

dest="${DEST}/INDEX"
difftoday="${DEST}/NEW-TODAY"
diffweek="${DEST}/NEW-THIS-WEEK"
difflastw="${DEST}/NEW-LAST-WEEK"
diffmonth="${DEST}/NEW-THIS-MONTH"
difflastm="${DEST}/NEW-LAST-MONTH"
diffdir="${DEST}/INDEX-diffs"
olddiffs="${DEST}/INDEX-old"
yesterday="$olddiffs/yesterday"
monday="$olddiffs/monday"
month="$olddiffs/month"
diffexcept="INDEX-diffs|INDEX-old|INDEX$|INDEX.Z$|ls-lR$|ls-lR.Z$|/NEW-"

if [ -d "$olddiffs" ]; then : ; else
    umask 002
    mkdir "$olddiffs"
    umask 022
fi
if [ -f "$dest" ]; then
    mv "$dest" "$yesterday"
else
    touch "$yesterday"
fi
if [ ! -f "$monday" ]; then
    ln "$yesterday" "$monday"
fi
if [ ! -f "$month" ]; then
    ln "$yesterday" "$month"
fi
if date | grep "Tue" > /dev/null ; then
    rm -f "$monday"
    ln "$yesterday" "$monday"
    mv "$diffweek" "$difflastw" >/dev/null 2>&1
fi
if date | grep " 1 " > /dev/null ; then
    rm -f "$month"
    ln "$yesterday" "$month"
    mv "$diffmonth" "$difflastm" >/dev/null 2>&1
fi

compress < "$tmpindex" > "${tmpindex}.Z"
result=$?
set "compress $tmpindex"; eval "$collecterr"

set "${tmpindex}"   "${dest}";   eval "$securemv"
set "${tmpindex}.Z" "${dest}.Z"; eval "$securemv"

# ---- diffs

if [ -d "$diffdir" ]; then : ; else
    umask 002
    mkdir "$diffdir"
    umask 022
fi

# delete old diffs
$GFIND "$diffdir" -mtime +10 -exec /bin/rm -f '{}' \;

if [ -f "$yesterday" ]; then
    created1=`set "$yesterday"; eval "$created"`
    rawcreated1=`set "$yesterday"; eval "$rawcreated"`
    created2=`set "$dest"; eval "$created"`
    diffname="${TMPDIR}/${created1}-${created2}"

    cat <<END > $diffname
INDEX changes for $SERVERNAME [$SERVERADDR]
updates version $created1 to $created2
this is a context diff; feed it to "patch -N -s <indexname>"

Prereq $rawcreated1

END

    $DIFF $DIFFARGS "$yesterday" "$dest" >> "${diffname}" 2>"$tmperr"
    result=$?
    case $result in
    0)  # no differences
	rm "$diffname"
	touch "$diffname"
	;;
    1)  # some differences; ok
	cat "$diffname" | compress > "${diffname}.Z"
	result=$?
	set "compress $diffname"; eval "$collecterr"

	# no uncompressed version?
	# set "${diffname}"   "${diffdir}"; eval "$securemv"
	rm -f "${diffname}"
	set "${diffname}.Z" "${diffdir}"; eval "$securemv"
	;;
    *)  set "diff $DIFFARGS"; eval "$collecterr"
	;;
    esac



    HEADER="`sed 50q < "$dest" | egrep '^#'`"

    (   echo "$HEADER"
	echo "# diffs to last index ($rawcreated1)"
	echo "# "
	$DIFF "$yesterday" "$dest" | egrep '^> [^#]' |
		egrep -v $diffexcept |
		sed 's/^> //'
    ) > "$tmpnew"
    set "$tmpnew" "$difftoday"; eval "$securemv"

    (   echo "$HEADER"
	echo "# new files this week"
	echo "# "
	$DIFF "$monday" "$dest" | egrep '^> [^#]' | egrep -v $diffexcept |
	    sed 's/^> //'
    ) > "$tmpnew"
    set "$tmpnew" "$diffweek"; eval "$securemv"

    (   echo "$HEADER"
	echo "# new files this month"
	$DIFF "$month" "$dest" | egrep '^> [^#]' | egrep -v $diffexcept |
	    sed 's/^> //'
    ) > "$tmpnew"
    set "$tmpnew" "$diffmonth"; eval "$securemv"
fi

# ---- generate old ls-lR
rm -f "$tmpindex" "${tmpindex}.Z" "$tmperr"
$LS -lR $ROOT > "$tmpindex" 2>"$tmperr"
result=$?
set "ls -lR $ROOT"; eval "$collecterr"

compress < "$tmpindex" > "$tmpindex.Z"
result=$?
set "compress $tmpindex"; eval "$collecterr"

set "${tmpindex}"   "${DEST}/ls-lR" ;   eval "$securemv"
set "${tmpindex}.Z" "${DEST}/ls-lR.Z" ; eval "$securemv"

exit 0
