#/usr/local/bin/perl
#
# vacation program
# Larry Wall <lwall@jpl-devvax.jpl.nasa.gov>
#
# updates by Tom Christiansen <tchrist@convex.com>

$vacation = $0;
$vacation = '/usr/local/bin/nvacation' unless $vacation =~ m#^/#;

$user = $ENV{'USER'} || $ENV{'LOGNAME'} || getlogin || (getpwuid($>))[0];
$editor = $ENV{'VISUAL'} || $ENV{'EDITOR'} || 'vi';
$pager = $ENV{'PAGER'} || 'more';

$default_msg = <<'EOF';
I will not be reading my mail for a while.
Your mail regarding "$SUBJECT" will be read when I return.
EOF


if (!@ARGV) {		# interactive use, a la Sun
    &interactive();
    die "not reached";
}

@ignores = ( 
	'daemon', 
	 'postmaster', 
	 'mailer-daemon', 
	 'mailer',
	 'root',
     );

# set-up time scale suffix ratios
%scale = (
	's', 1,
	'm', 60,
	'h', 60 * 60,
	'd', 24 * 60 * 60,
	'w', 7 * 24 * 60 * 60,
    );


while ($ARGV[0] =~ /^-/) {
    $_ = shift;
    if (/^-I/i) {  # eric allman's source has both cases
	chdir;
	&initialize;
	exit;
    } elsif (/^-j/) {
	$opt_j++;
    } elsif (/^-f(.*)/) {
	&save_file($1 ? $1 : shift);
    } elsif (/^-a(.*)/) {
	&save_alias($1 ? $1 : shift);
    } elsif (/^-t([\d.]*)([smhdw])/) {
	$timeout = $1;
	$timeout *= $scale{$2} if $2;
    } else {
	die "Unrecognized switch: $_\n";
    }
}

if (!@ARGV) {
    &interactive();
    die "not reached";
}


$user = shift;
push(@ignores, $user);
push(@aliases, $user);
die "Usage: vacation username\n" if $user eq '' || @ARGV;

$home = (getpwnam($user))[7];
die "No home directory for user $user\n" unless $home;
chdir $home || die "Can't chdir to $home: $!\n";

$timeout = 7 * 24 * 60 * 60 unless $timeout;

dbmopen(VAC, ".vacation", 0666) || die "Can't open vacation dbm files: $!\n";


$/ = '';			# paragraph mode
$header = <>;
$header =~ s/\n\s+/ /g;		# fix continuation lines
$* = 1;

exit if $header =~ /^Precedence:\s*(bulk|junk)/i;
exit if $header =~ /^From.*-REQUEST@/i;

for (@ignores) {
    exit if $header =~ /^From.*\b$_\b/i;
} 

($from) = ($header =~ /^From\s+(\S+)/);	# that's the Unix-style From line
die "No \"From\" line!!!!\n" if $from eq "";

($subject) = ($header =~ /Subject:\s+(.*)/);
$subject = "(No subject)" unless $subject;
$subject =~ s/\s+$//;

($to) = ($header =~ /To:\s+(.*)/);
($cc) = ($header =~ /Cc:(\s+.*)/);
$to .= ', '.$cc if $cc;

if (open(MSG,'.vacation.msg')) {
    undef $/;
    $msg = <MSG>;
    close MSG;
} else {
    $msg = $default_msg;
} 
$msg =~ s/\$SUBJECT/$subject/g;		# Sun's vacation does this

unless ($opt_j) {
    foreach $name (@aliases) {
	$ok++ if $to =~ /\b$name\b/;
    }
    exit unless $ok;
}

$lastdate = $VAC{$from};
$now = time;
if ($lastdate ne '') {
    ($lastdate) = unpack("L",$lastdate);
    exit unless $lastdate;
    exit if $now < $lastdate + $timeout;
}

$VAC{$from} = pack("L", $now);
dbmclose(VAC);


open(MAIL, "|/usr/lib/sendmail -oi -t $from") || die "Can't run sendmail: $!\n";

print MAIL <<EOF;
To: $from
#Subject: This is a recording... [Re: $subject]
Precedence: junk

EOF
print MAIL $msg;
close MAIL;
exit;

sub yorn {
    local($answer);
    for (;;) {
	print $_[0];
	$answer = <STDIN>;
	last if $answer =~ /^[yn]/i;
	print "Please answer \"yes\" or \"no\" ('y' or 'n')\n";
    }
    $answer =~ /^y/i;
}

sub interactive {
    chdir;
    chop($cwd = `pwd`);

    &disable if -f '.forward';

    print <<EOF;
This program can be used to answer your mail automatically
when you go away on vacation.
EOF

    for (;;) {
	if (-f '.vacation.msg') {
	    print "\nYou already have a message file in $cwd/.vacation.msg.\n";
	    $see = &yorn("Would you like to see it? ");
	    system $pager, '.vacation.msg' if $see;
	    $edit = &yorn("Would you like to edit it? ");
	}
	else {
	    &make_default;
	    print <<EOF;

I've created a default vacation message in ~/.vacation.msg.  This
message will be automatically returned to anyone sending you mail while
you're out.

Press return when ready to continue, and you will enter your favorite
editor ($editor) to edit the messasge to your own tastes.  

EOF
	    $| = 1;
	    print "Press return to continue: "; 
	    <STDIN>;
	    $edit = 1;
	}

	last unless $edit;
	system $editor, '.vacation.msg';
	last;
    }


    print "\nTo enable the vacation feature a \".forward\" file is created.\n";
    if (&yorn("Would you like to enable the vacation feature now? ")) {
	&initialize;
	print <<EOF;

Ok, vacation feature ENABLED.  Please remember to turn it off when
you get back from vacation.  Bon voyage!
EOF
    }
    else {
	    print "Ok, vacation feature NOT enabled.\n";
	}

    exit;
}

sub initialize {
    &zero('.vacation.pag');
    &zero('.vacation.dir');
    open(FOR, ">.forward") || die "Can't create .forward: $!\n";
    print FOR "\\$user, \"|$vacation $user\"\n";
    close FOR;
    &make_default;
} 

sub zero {
    local($FILE) = @_;
    open (FILE, ">$FILE") || die "can't creat $FILE: $!";
    close FILE;
} 


sub save_file {
    local($FILE) = @_;
    local($_);

    open FILE || die "can't open $FILE: $!";

    while (<FILE>) {
	push(@ignores, split);
    } 
    close FILE;
} 

sub disable {
    print "\nYou have a .forward file in your home directory containing: ",
	  "\n",
	  `cat .forward`,
	  "\n";
    if (&yorn(
"Would you like to remove it and disable the vacation feature? ")) {
	unlink('.forward') || die "Can't unlink .forward: $!\n";
	dbmopen(VAC, '.vacation', 0444) || die "no .vacation dbmfile\n";
	sub byvalue { $VAC{$a} <=> $VAC{$b}; }
	if (@keys = sort byvalue keys %VAC) {
	    require 'ctime.pl';
	    open (PAGER, "|$pager") || die "can't open $pager: $!";
	    print PAGER <<EOF;
While you were away, mail was sent to the following addresses:

EOF
	    for $key (@keys) {
		($when) = unpack("L", $VAC{$key});
		printf PAGER "%-20s %s", $key, &ctime($when);
	    } 
	    close PAGER;
	}
	print "Back to normal reception of mail.\n";
	exit;
    } else {
	print "Ok, vacation feature NOT disabled.\n";
    }
} 

sub make_default {
    return if $edit;
    open(MSG, ">.vacation.msg") || die "Can't create .vacation.msg: $!\n";
    print MSG $default_msg;
    close MSG;
} 







