======== Listing 4 (formletter--Perl source) =========

#!/usr/bin/perl
#
# formletter -- send "personalized" form letters.
#
# usage:
#    formletter [template file] [user...]
#

#
# stuff to change by necessity or whim
#
$tempdict = "$ENV{'HOME'}/lib/formletters";
$sigfile = "$ENV{'HOME'}/.mailsig";
$mailer = "/usr/ucb/mail";
$sleeptime = 30;
$altgreetfile = ".greetings";

#
# sanity checking
#
(-d $tempdict) || 
    die "template directory $tempdict not found\n";
if ($#ARGV <= 0 || ! -f "$tempdict/$ARGV[0]") {
    #
    # too-few args, or specified template not there
    #
    warn "Usage: $0 [template] [address...]\n";
    warn "Current templates on file:\n";
    opendir(FLD, $tempdict) || 
	die "Can't open $tempdict: $!\n";
    @files = sort(grep(!/^\./, readdir(FLD)));
    die "\t", join("\n\t", @files), "\n";
}

#
# get signature
#
if (open(SIG, $sigfile)) {
    @sig = <SIG>;
    close SIG;
}
else { # not there; just use name and login ID
    @user = getpwnam($ENV{'USER'});
    chop($host = `hostname`);
    $sig[0] = "-- $user[6] ($user[0]@$host)\n";
}

#
# load alternate greetings, if any
#
if (open(ALT, "$tempdict/$altgreetfile")) {
    while (<ALT>) {
	($user, $greeting) = split(/:/, $_);
	chop($greeting);
	$altgreet{$user} = $greeting;
    }
}

#
# read template file
#
$template = "$tempdict/$ARGV[0]";
open (TMPL, $template) || 
    die "can't open form template $ARGV[0]: $!\n";
while (<TMPL>) {
    if (/^Subject:/) {
	($junk, $subj) = split(/:/);
	chop($subj);
    }
    if (/^Eval:/) {
	$/ = "";	   # set paragraph mode
        $to_eval = <TMPL>; # read paragraph
	$/ = "\n";	   # unset paragraph mode
    }
    if (/^Text:/) {
	@text = <TMPL>;	   # slurp remaining lines
    }
}
close(TMPL);
@text || die "No text seen in template $ARGV[0]\n";

#
# send mail to remaining arguments 
# (assumed to be addresses)
#
shift;
while (@ARGV) {
    $whoto = shift;
    #
    # if address contains no "@", assume it's 
    # a local user: look 'em up
    #
    if (! ($whoto =~ /@/)) {
	($name,$passwd,$uid,$gid,$quota,$comment,
	   $gcos,$dir,$shell) = getpwnam($whoto);
	if (! $name) { # oops, probably a typo
	    warn "$whoto: no such user\n";
	    next;
	}
	#
	# get first name
	#
	($greeting) = split(/ /, $gcos); 
    }

    #
    # check for an overriding greeting 
    #
    $altgreet{$whoto} && 
	($greeting = $altgreet{$whoto});

    #
    # run the template's program, if any
    #
    eval $to_eval;
    die "$@\n" if $@;	# oops

    #
    # send the mail
    #
    open (MAILP, $subj ? 
	"| $mailer -s \"$subj\" $whoto":
        "| $mailer $whoto");

    print MAILP ($greeting) ? "$greeting --\n\n" : "";
    for (@text) {
	s/"/\\"/g;
	print MAILP eval qq/"$_"/;
    }
    print MAILP "\n--\n", join("",@sig);
    close MAILP;
    sleep($sleeptime) if (@ARGV);
}

