: ########################################################################## # Title : mailusers - send input as mail to users # Author : Heiner Steven # 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