:
##########################################################################
# Title      :	mailusers - send input as mail to users
# Author     :	Heiner Steven <heiner.steven@odn.de>
# Date       :	1999-07-13
# Requires   :	getopts, MAILX
# Category   :	Mail, System Administration
# SCCS-Id.   :	@(#)mailusers	1.5
##########################################################################
# Description
#
##########################################################################

PN=`basename "$0"`			# Program name
VER='1.5'

: ${USER:=`expr "\`LANG=C id\`" : 'uid=[0-9]*(\([^\)]*\)).*`}
: ${USERTABLE:="root=$USER bin=$USER"}

for Mail in /bin/mailx /usr/ucb/mail /usr/ucb/Mail mail
do [ -x "$Mail" ] && break
done

Usage () {
    echo >&2 "$PN - send input as mail to users, $VER
usage: $PN [-s subj] [-f mailhead] [-m message] [-t usertab] [file ...]
    -s: set mail subject
    -f: file containing mail header (cannot be used with -m)
    -m: message to prepend to each mail (cannot be used with -f)
    -t: user translation table (default: \"$USERTABLE\")

Reads lines from the files specified (or standard input), and sends
them to users using mail. The first word of the line is assumed
to be the user name, i.e.

	$USER data data data data data"
    exit 1
}

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

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

# We place all temporary files within this subdirectory, to simplify
# the cleanup
TmpBase=$TMPDIR/mu.$$

Subject="$PN"
Message=
Header=
Dryrun=no
while getopts :f:hm:ns:t: Opt
do
    case "$Opt" in
	s)	Subject=$OPTARG;;
	f)	Header=$OPTARG;;
	m)	Message=$OPTARG;;
	n)	Dryrun=yes;;
	t)	USERTABLE=$OPTARG;;
	?|h)	Usage;;
    esac
done
shift `expr $OPTIND - 1`

[ -n "$Header" -a -n "$Message" ] &&
    Fatal "-f and -m options are mutually exclusive"

trap 'rm -rf "$TmpBase" >/dev/null 2>&1' 0
trap "exit 2" 1 2 3 15

set -e
mkdir "$TmpBase"
chmod 700 "$TmpBase" 
set +e

: ${Message:=$PN}
if [ -n "$Header" ]
then
    [ -r "$Header" ] || Fatal "cannot read mail header: $Header"
else
    Header=$TmpBase/header
    echo "$Message" > "$Header"
fi

# Initialize user translation table
# Example: "root=heiner" means, mail to "root" should be sent to "heiner"
for user in $USERTABLE
do
    if echo "$user" |
	    grep '^[a-z0-9_][a-z0-9_]*=[a-z0-9_][a-z0-9_]*$' >/dev/null
    then eval "$user"
    else Fatal "invalid user table entry: $user"
    fi
done

# If there was no input file specified, redirect stdin to a temporary
# file, and read this file
if [ $# -lt 1 ]
then
    Data=$TmpBase/data
    cat "$@" > "$Data"
    set -- "$Data"
fi

[ $Dryrun = yes ] && Msg "-n option given - will not send mail"

users=' '
for file
do
    [ -s "$file" ] || continue			# empty file; nothing to do

    exec 3<&0 0<"$file"
    while read user rest
    do
	[ -n "$user" ] || continue
	mailfile=$TmpBase/$user
	[ -f "$mailfile" ] || cat "$Header" > "$mailfile" || exit 1
	echo "$user	$rest" >> "$mailfile"

	case "$users" in
	    *' '$user' '*)	;; 		# User is already in list
	    *) users="$users$user ";;
	esac
    done
    exec 0<&3 3<&-
done

Msg "got lines for the following users: <$users>"

for user in $users
do
    mailfile=$TmpBase/$user

    eval name='$'$user
    if [ -n "$name" ]
    then Msg "sending mail for $user to $name"
    else name=$user
    fi

    if [ $Dryrun = no ]
    then
    	$Mail -s "$Subject" $name $USER < "$mailfile"
    fi
done
