#/usr/local/bin/perl # # vacation program # Larry Wall # # updates by Tom Christiansen $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 = ; 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 <; 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 <; $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 <.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 () { 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 <.vacation.msg") || die "Can't create .vacation.msg: $!\n"; print MSG $default_msg; close MSG; }