:
##########################################################################
# Shellscript:	checklinks - check symbolic links
# Version    :	0.2 (beta)
# Author     :	Heiner Steven (stv)
# Date       :	10.11.95
# SCCS-Id.   :	@(#) checklinks	1.1 04/02/18
##########################################################################
# Description
#
##########################################################################

PN=`basename "$0"`			# program name
VER='0.2 (beta)'

# Mail should be a mail program knowing how to set the mail subject
Mail=mail
[ -x /bin/mailx ] && Mail=/bin/mailx

Links="${TMPDIR:=/tmp}/cl.lnk.$$"		# File for symbolic links
InvLinks="$TMPDIR/cl.inv.$$"			# File for invalid links
Mails="$TMPDIR/cl.$$"				# Base name for mail text

Usage () {
    echo >&2 "$PN - check symbolic links, $VER (stv '98)
Usage: $PN [-hm] [-f linkfile] [-r user] [entry ...]
   -f:  file containing names of symbolik links
   -h:  print this help
   -m:  send mail to the creators of invalid symbolical links
   -r:	mail to pseudo-users is sent to this user (default is $LOGNAME)

All symbolic links starting with link or directory 'entry'
are followed. If the target does not exist, the link and the
(non-existant) target are printed.

The \"-r\" option may only be used with the \"-m\" option."
    exit 1
}

Msg () {
    for i
    do echo "$PN: $i" >&2
    done
}

Fatal () { Msg "$@"; exit 1; }

AbsPath () {
    D=`dirname $1`
    N=`basename $1`
    (cd $D; echo "`pwd`/$N")
}

Admin=
SendMail=no
LinkFile=
set -- `getopt hf:mr: "$@"` || Usage
while [ $# -gt 0 ]
do
    case "$1" in
	-f)	LinkFile="$2"; shift;;
	-m)	SendMail=yes;;
	-r)	Admin="$2"; shift;;
	--)	shift; break;;
	-h)	Usage;;
	-*)	Usage;;
	*)	break;;			# First entry
    esac
    shift
done

[ -n "$Admin" -a $SendMail = no ] &&
	Fatal "the \"-r\" option needs the \"-m\" option"

: ${Admin:=$LOGNAME}			# Set default
Hostname=`uname -n`

trap 'rm -f "$Links" "$InvLinks" "$Mails."* > /dev/null 2>&1' 0
trap "exit 2" 1 2 3 15

# Create file $Links with the names of symbolic links
if [ -n "$LinkFile" ]
then
    [ $# -gt 0 ] && Fatal "no arguments allowed with -f option"
    [ -f "$LinkFile" -a -r "$LinkFile" ] || Fatal "cannot read $LinkFile"
    cp "$LinkFile" "$Links" || exit
else					# Create file with links
    [ $# -lt 1 ] && set -- `pwd`	# No arguments: set default
    Msg "Creating list of symbolic links starting with $*..."
    find "$@" -type l -print > $Links || exit
fi

[ -s "$Links" ] || exit 0

set -u
if [ $SendMail = yes ]
then
    # We will need to postprocess the list of invalid links.
    # Save it to a file:
    exec 3>&1 > "$InvLinks"
fi

Msg "Checking links..."
while read Link
do
    [ -h "$Link" ] || { Msg "no symbolic link: $Link"; continue; }
    Ref=`ls -ld "$Link" 2>/dev/null | awk '{print $NF}'`
    [ -n "$Ref" ] ||			# Should never occur!
	{ Msg "cannot determine target for link $Link"; continue; }
    case "$Ref" in
	/*)	;;			# Absolute path name
	*)  Ref="`dirname "$Link"`/$Ref";;
    esac
    Target=`ls -ld "$Ref" 2>/dev/null`
    [ -z "$Target" ] && echo "$Link	$Ref"
done < $Links

if [ $SendMail = yes ]
then
    # Restore old stdout
    exec 1>&3 3>&-
    OldIFS="$IFS"
    IFS="	"
    export IFS

    users=" "				# need leading space
    exec 3<&0 0< "$InvLinks"
    while read link ref
    do
    	user=`ls -ld "$link" | awk '{print $3}'`
	[ -z "$user" ] && continue	# should not occur!

	# Don't send mail to pseudo-users
	case "$user" in
	    root|bin|nobody|daemon|uucp)	user=$Admin;;
	esac

	echo "$link	$ref" >> $Mails.$user
        case "$users" in
	    *" $user "*)	;;
	    *)		users="${users}$user ";;
	esac
    done
    exec 0<&3 3<&-

    IFS="$OldIFS"
    export IFS

    for user in $users
    do
	echo "
Hello $user,

The following symbolical links created by you
(or an installation program running with your login id)
do not point to a valid target.

Please check the links, and remove invalid ones.

The links were checked `date` on host
\"$Hostname\" starting with directory/directories

	"$@"

The following list consists of two columns: the location
of the symbolical link, and the (invalid) target the link
points to.
________________________________________ 
"	|
	cat - $Mails.$user |
	$Mail -s "Invalid symbolical links" $user $Admin

    done
fi
