.forward with Reply to mail automatically

Talk about any thing that related to networking, running servers with *nux.

Moderator: kalinga

.forward with Reply to mail automatically

Postby kalinga » Tue Jan 24, 2006 1:51 pm

Copy it to /usr/local/bin/vacation. The file must be executable for everybody. This can be done with the command:

chmod 755 /usr/local/bin/vacation

Code: Select all

#!/usr/bin/perl
#
# NAME
#     vacation - Reply to mail automatically.
#
# SYNOPSIS
#     vacation [username]
#
# DESCRIPTION
#     Vacation automatically replies to incoming mail.
#
#     It is enabled by calling vacation without arguments. The
#     program creates a .vacation.msg file in your home directory,
#     which contains the message that is automatically sent to all
#     senders when vacation is enabled, and starts an editor for
#     you to modify the message.
#
#     If no .forward file exists in your home directory, it is
#     created and will contain a line of the form:
#
#          \username, "|/usr/local/bin/vacation username"
#
#     This sends one copy of an incoming message to username while
#     another copy is piped into vacation.
#
#     If a .forward file is present in your home directory and
#     it does not contain a line refering to the vacation program,
#     a line is appended of the form:
#
#          "|/usr/local/bin/vacation username"
#
#     This pipes a copy of an incoming message into the
#     the vacation program, in addition to the copies
#     to users or programs which were already specified in the
#     .forward file.
#
#     If a .forward file is present in your home directory which
#     already contains a line refering to the vacation program,
#     you are asked whether you want to disable the vacation
#     program. If you answer yes, the line refering to the
#     vacation program is removed from the .forward file. If the
#     .forward file is empty after removing this line, it is
#     removed completely.
#
#     Vacation will not respond to automatically generated mails
#     (like mails generated by vacation). Vacation will also not
#     respond to mail from either postmaster or mailer-daemon.
#
# FILES
#     ~/.forward           Contains e-mail adresses or programs
#                          to which mail must be forwarded.
#
#     ~/.vacation.msg      The reply message.
#
# VERSION
#     1.5 (30 August 2004)

# AUTHOR
#     Frits Wiarda, e-mail fwiarda(at)fwiarda.com
#
# AUTHORS ORIGINAL VERSION
#     Tom Christiansen, e-mail tchrist(at)convex.com
#     Larry Wall, e-mail lwall(at)jpl-devvax.jpl.nasa.gov
#
# NOTES
#     This script has been tested with Red Hat Linux 8.0. Note that
#     for other systems it can be necessary to modify line 1, containing
#     a reference to the perl interpreter.
#
#     Be sure .forward files are processed on your system. Note that some
#     systems refuse to process .forward files that are group writable,
#     while the systems default umask makes files group writable.
#

######################################################################
#
# Set parameters.
#
######################################################################

$CMDNAME = "vacation";
$HELP = "Reply to mail automatically.\n\nUsage: vacation [username]\n\nWithout parameters vacation prompts the user for instructions.\n";
$USAGE = "Usage: vacation [username]\n";

######################################################################
#
# Print help message when the option "-?" or "--help" is specified.
#
######################################################################

die "$HELP" if $ARGV[0] eq "-?";
die "$HELP" if $ARGV[0] eq "--help";

######################################################################
#
# Locate various executables.
#
######################################################################

$ed = "/bin/ed";
unless (-x $ed) { $ed = "/usr/bin/ed"; }
unless (-x $ed) { die "$CMDNAME: Can't locate ed\n"; }

$editor = $ENV{"VISUAL"} || $ENV{"EDITOR"};
unless ($editor) {
   $editor = "/bin/vi";
   unless (-x $editor) { $editor = "/usr/bin/vi"; }
   unless (-x $editor) { die "$CMDNAME: Can't locate editor\n"; }
}

$pager = $ENV{"PAGER"};
unless ($pager) {
   $pager = "/bin/more";
   unless (-x $pager) { $pager = "/usr/bin/more"; }
   unless (-x $pager) { $pager = "/bin/pg"; }
   unless (-x $pager) { $pager = "/usr/bin/pg"; }
   unless (-x $pager) { die "$CMDNAME: Can't locate pager\n"; }
}

$sendmail = "/bin/sendmail";
unless (-x $sendmail) { $sendmail = "/sbin/sendmail"; }
unless (-x $sendmail) { $sendmail = "/usr/sbin/sendmail"; }
unless (-x $sendmail) { $sendmail = "/usr/bin/sendmail"; }
unless (-x $sendmail) { die "$CMDNAME: Can't locate sendmail\n"; }

$vacation = $0;
unless (-x $vacation) { die "$CMDNAME: Can't locate own executable\n"; }

######################################################################
#
# Determine the user.
#
######################################################################

$user = $ENV{"USER"} || $ENV{"LOGNAME"} || getlogin || (getpwuid($>))[0];

######################################################################
#
# Without command line arguments we are interactive. With
# an option as command line argument or more then one command
# line argument we print an error message. With a user name as
# the only command line argument we answer mail.
#
######################################################################

if (!@ARGV) {
   &interactive();
}
else {
   $_ = shift;
   if ( /^-/ || @ARGV ) {
      die "$USAGE";
   }
   else {
      $user = $_;
      &answer;
    }
}

######################################################################
#
# Both the interactive and answer subroutines call exit directly. So
# this point is unreachable.
#
######################################################################

die "$CMDNAME: Panic\n";


######################################################################
#
# Answer mode. The vacation program reads mail from the standard
# inut, and uses sendmail to reply to it.
#
######################################################################

sub answer {

   # Get the users home directory from the password file.
   $home = (getpwnam($user))[7];
   die "$CMDNAME: No home directory for user $user\n" unless $home;

   # Change to the users home directory.
   chdir $home || die "$CMDNAME: Can't chdir to $home\n";

   # Set input record seperator to an empty line.
   $/ = '';                       

   # Read message into header.
   $header = <STDIN>;     

   # Concatenate headers spread over multiple lines.
   $header =~ s/\n\s+/ /gm;   

   # Do not reply to automatically generated mail.
   if ( $header =~ /^Auto-Submitted:/im ) {
      exit unless ($header =~ /^Auto-Submitted: no/im );
   }
   exit if $header =~ /^Precedence: junk/im;
   exit if $header =~ /^Precedence: bulk/im;

   # Do not reply to mail from mailer-daemon or postmaster.
   exit if $header =~ /^From.*mailer-daemon/im;
   exit if $header =~ /^From.*postmaster/im;

   # Get the sender of the mail.
   ($replyto) = ($header =~ /^Reply-To:(.*)/im);
   $replyto =~ s/^\s*//;
   $replyto =~ s/\s*$//;
   ($replyto) = ($header =~ /^From:(.*)/im) if $replyto eq "";
   $replyto =~ s/^\s*//;
   $replyto =~ s/\s*$//;
   die "$CMDNAME: No \"From:\" or \"Reply-To:\" header\n"
      if $replyto eq "";

   # Get the subject of the mail.
   ($subject) = ($header =~ /^Subject:(.*)/im);
   $subject =~ s/^\s*//;
   $subject =~ s/\s*$//;
   $subject = "(No subject)" unless $subject;

   # Get reply text. If no .vacation.msg file is present exit,
   # without sending anything and without generating an error
   # message. (So deleting the message file effectively means
   # disabling the vacation program.)
   if (open(MSG,".vacation.msg")) {
      undef $/;
      $msg = <MSG>;
      close MSG;
   }
   else {
      exit;
   }

   # Replace $SUBJECT with real subject text.
   $msg =~ s/\$SUBJECT/$subject/gm;
   
   # Send reply using sendmail.
   open(MAIL, "|$sendmail -oi -t -f $user") ||
      die "$CMDNAME: Can't run sendmail\n";
   print MAIL <<EOF;
To: $replyto
Auto-Submitted: auto-replied
Precedence: junk
EOF
   print MAIL $msg;
   close MAIL;

   # Ready.
   exit;

}


######################################################################
#
# Internactive mode. The vacation program prompts the user
# for input (whether it should be enabled or disabled, etc.).
#
######################################################################

sub interactive {

   # Get the users home directory from the password file.
   $home = (getpwnam($user))[7];
   die "$CMDNAME: No home directory for user $user\n" unless $home;

   # Change to the users home directory.
   chdir $home || die "$CMDNAME: Can't chdir to $home\n";

   # Check whether vacation has been enabled.
   $enabled = 0;
   if (-f ".forward")
   {
      open(FOR, "<.forward") || die "$CMDNAME: Can't open .forward\n";
      while($line = <FOR>)
      {
         if ( $line =~ m|$vacation| )
         {
            $enabled = 1;
         }
      }
      close FOR;
   }

   # Ask whether the vacation feature must be disabled. After that
   # we are ready and exit.
   if ($enabled) {
      print "The vacation feature is enabled.\n";
      print "\n";
      if (&yorn("Would you like to disable the vacation feature? ")) {
         &disable;
      }
      else {
         print "Ok, vacation feature NOT disabled.\n";
      }
      exit;
   }

   # Vacation feature is disabled. Start dialog to enable it.
   # After that we are ready and exit.
   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 "You already have a message file in ~/.vacation.msg.\n";
         $see = &yorn("Would you like to see it? ");
         system $pager, ".vacation.msg" if $see;
         print "\n" 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.

You will now enter your favorite editor ($editor)
to edit the messasge to your own tastes. Remember that the first
line shall start with "Subject: ", and that the second line shall
be empty.

EOF
         $| = 1;
         print "Press return to continue. ";
         <STDIN>;
         $edit = 1;
      }
      last unless $edit;
      system $editor, ".vacation.msg";
      last;
   }
   if (&yorn("Would you like to enable the vacation feature now? ")) {
      &enable;
   }
   else {
      print "Ok, vacation feature NOT enabled.\n";
   }
   exit;
}

######################################################################
#
# Enable the vacation feature. If no .forward file exists one is
# created. If a .forward file exists, a line enabling the vacation
# program is appended to it.
#
######################################################################

sub enable {
   if (-f ".forward")
   {
      open(FOR, ">>.forward") ||
         die "$CMDNAME: Can't open .forward\n";
      print FOR "\"|$vacation $user\"\n";
      close FOR;
   }
   else
   {
      open(FOR, ">.forward") ||
         die "$CMDNAME: Can't create .forward\n";
      print FOR "\\$user, \"|$vacation $user\"\n";
      close FOR;
   }
   print <<EOF;
Ok, vacation feature ENABLED. Please remember to turn it off when
you get back from vacation. Bon voyage!
EOF
}

######################################################################
#
# Disable the vacation feature. The line enabling the vacation
# program is deleted from the .forward file.
#
######################################################################

sub disable {
   open(FOR, "|$ed -s .forward") ||
      die "$CMDNAME: Can't open pipe to ed .forward\n";
   print FOR "g|$vacation|d\nw\nq\n";
   close FOR;
   if (-z ".forward") {
      unlink(".forward");
   }
   print "Back to normal reception of mail.\n";
}

######################################################################
#
# A default .vacation.msg file is created.
#
######################################################################

sub make_default {
   return if $edit;
   open(MSG, ">.vacation.msg") ||
      die "$CMDNAME: Can't create .vacation.msg\n";
   print MSG <<EOF;
Subject: I am away from my mail

I will not be reading my mail for a while. Your mail regarding
$SUBJECT will be read when I return.
EOF
   close MSG;
}


######################################################################
#
# Ask a question and read an answer being y(es) or n(o).
#
######################################################################

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

kalinga
Site Admin
 
Posts: 209
Joined: Fri Oct 14, 2005 3:19 pm
Location: Sri Lanka

Postby kalinga » Wed Jul 26, 2006 11:34 am

there was some error in the above code.


Code: Select all
#!/usr/bin/perl
#
# NAME
#     vacation - Reply to mail automatically.
#
# SYNOPSIS
#     vacation [username]
#
# DESCRIPTION
#     Vacation automatically replies to incoming mail.
#
#     It is enabled by calling vacation without arguments. The
#     program creates a .vacation.msg file in your home directory,
#     which contains the message that is automatically sent to all
#     senders when vacation is enabled, and starts an editor for
#     you to modify the message.
#
#     If no .forward file exists in your home directory, it is
#     created and will contain a line of the form:
#
#          \username, "|/usr/local/bin/vacation username"
#
#     This sends one copy of an incoming message to username while
#     another copy is piped into vacation.
#
#     If a .forward file is present in your home directory and
#     it does not contain a line refering to the vacation program,
#     a line is appended of the form:
#
#          "|/usr/local/bin/vacation username"
#
#     This pipes a copy of an incoming message into the
#     the vacation program, in addition to the copies
#     to users or programs which were already specified in the
#     .forward file.
#
#     If a .forward file is present in your home directory which
#     already contains a line refering to the vacation program,
#     you are asked whether you want to disable the vacation
#     program. If you answer yes, the line refering to the
#     vacation program is removed from the .forward file. If the
#     .forward file is empty after removing this line, it is
#     removed completely.
#
#     Vacation will not respond to automatically generated mails
#     (like mails generated by vacation). Vacation will also not
#     respond to mail from either postmaster or mailer-daemon.
#
# FILES
#     ~/.forward           Contains e-mail adresses or programs
#                          to which mail must be forwarded.
#
#     ~/.vacation.msg      The reply message.
#
# VERSION
#     1.5 (30 August 2004)

# AUTHOR
#     Frits Wiarda, e-mail fwiarda(at)fwiarda.com
#
# AUTHORS ORIGINAL VERSION
#     Tom Christiansen, e-mail tchrist(at)convex.com
#     Larry Wall, e-mail lwall(at)jpl-devvax.jpl.nasa.gov
#
# NOTES
#     This script has been tested with Red Hat Linux 8.0. Note that
#     for other systems it can be necessary to modify line 1, containing
#     a reference to the perl interpreter.
#
#     Be sure .forward files are processed on your system. Note that some
#     systems refuse to process .forward files that are group writable,
#     while the systems default umask makes files group writable.
#

######################################################################
#
# Set parameters.
#
######################################################################

$CMDNAME = "vacation";
$HELP = "Reply to mail automatically.\n\nUsage: vacation [username]\n\nWithout parameters vacation prompts the user for instructions.\n";
$USAGE = "Usage: vacation [username]\n";

######################################################################
#
# Print help message when the option "-?" or "--help" is specified.
#
######################################################################

die "$HELP" if $ARGV[0] eq "-?";
die "$HELP" if $ARGV[0] eq "--help";

######################################################################
#
# Locate various executables.
#
######################################################################

$ed = "/bin/ed";
unless (-x $ed) { $ed = "/usr/bin/ed"; }
unless (-x $ed) { die "$CMDNAME: Can't locate ed\n"; }

$editor = $ENV{"VISUAL"} || $ENV{"EDITOR"};
unless ($editor) {
   $editor = "/bin/vi";
   unless (-x $editor) { $editor = "/usr/bin/vi"; }
   unless (-x $editor) { die "$CMDNAME: Can't locate editor\n"; }
}

$pager = $ENV{"PAGER"};
unless ($pager) {
   $pager = "/bin/more";
   unless (-x $pager) { $pager = "/usr/bin/more"; }
   unless (-x $pager) { $pager = "/bin/pg"; }
   unless (-x $pager) { $pager = "/usr/bin/pg"; }
   unless (-x $pager) { die "$CMDNAME: Can't locate pager\n"; }
}

$sendmail = "/bin/sendmail";
unless (-x $sendmail) { $sendmail = "/sbin/sendmail"; }
unless (-x $sendmail) { $sendmail = "/usr/sbin/sendmail"; }
unless (-x $sendmail) { $sendmail = "/usr/bin/sendmail"; }
unless (-x $sendmail) { die "$CMDNAME: Can't locate sendmail\n"; }

$vacation = $0;
unless (-x $vacation) { die "$CMDNAME: Can't locate own executable\n"; }

######################################################################
#
# Determine the user.
#
######################################################################

$user = $ENV{"USER"} || $ENV{"LOGNAME"} || getlogin || (getpwuid($>))[0];

######################################################################
#
# Without command line arguments we are interactive. With
# an option as command line argument or more then one command
# line argument we print an error message. With a user name as
# the only command line argument we answer mail.
#
######################################################################

if (!@ARGV) {
   &interactive();
}
else {
   $_ = shift;
   if ( /^-/ || @ARGV ) {
      die "$USAGE";
   }
   else {
      $user = $_;
      &answer;
    }
}

######################################################################
#
# Both the interactive and answer subroutines call exit directly. So
# this point is unreachable.
#
######################################################################

die "$CMDNAME: Panic\n";


######################################################################
#
# Answer mode. The vacation program reads mail from the standard
# inut, and uses sendmail to reply to it.
#
######################################################################

sub answer {

   # Get the users home directory from the password file.
   $home = (getpwnam($user))[7];
   die "$CMDNAME: No home directory for user $user\n" unless $home;

   # Change to the users home directory.
   chdir $home || die "$CMDNAME: Can't chdir to $home\n";

   # Set input record seperator to an empty line.
   $/ = '';                       

   # Read message into header.
   $header = <STDIN>;     

   # Concatenate headers spread over multiple lines.
   $header =~ s/\n\s+/ /gm;   

   # Do not reply to automatically generated mail.
   if ( $header =~ /^Auto-Submitted:/im ) {
      exit unless ($header =~ /^Auto-Submitted: no/im );
   }
   exit if $header =~ /^Precedence: junk/im;
   exit if $header =~ /^Precedence: bulk/im;

   # Do not reply to mail from mailer-daemon or postmaster.
   exit if $header =~ /^From.*mailer-daemon/im;
   exit if $header =~ /^From.*postmaster/im;

   # Get the sender of the mail.
   ($replyto) = ($header =~ /^Reply-To:(.*)/im);
   $replyto =~ s/^\s*//;
   $replyto =~ s/\s*$//;
   ($replyto) = ($header =~ /^From:(.*)/im) if $replyto eq "";
   $replyto =~ s/^\s*//;
   $replyto =~ s/\s*$//;
   die "$CMDNAME: No \"From:\" or \"Reply-To:\" header\n"
      if $replyto eq "";

   # Get the subject of the mail.
   ($subject) = ($header =~ /^Subject:(.*)/im);
   $subject =~ s/^\s*//;
   $subject =~ s/\s*$//;
   $subject = "(No subject)" unless $subject;

   # Get reply text. If no .vacation.msg file is present exit,
   # without sending anything and without generating an error
   # message. (So deleting the message file effectively means
   # disabling the vacation program.)
   if (open(MSG,".vacation.msg")) {
      undef $/;
      $msg = <MSG>;
      close MSG;
   }
   else {
      exit;
   }

   # Replace $SUBJECT with real subject text.
   $msg =~ s/\$SUBJECT/$subject/gm;
   
   # Send reply using sendmail.
   open(MAIL, "|$sendmail -oi -t -f $user") ||
      die "$CMDNAME: Can't run sendmail\n";
   print MAIL <<EOF;
To: $replyto
Auto-Submitted: auto-replied
Precedence: junk
EOF
   print MAIL $msg;
   close MAIL;

   # Ready.
   exit;

}


######################################################################
#
# Internactive mode. The vacation program prompts the user
# for input (whether it should be enabled or disabled, etc.).
#
######################################################################

sub interactive {

   # Get the users home directory from the password file.
   $home = (getpwnam($user))[7];
   die "$CMDNAME: No home directory for user $user\n" unless $home;

   # Change to the users home directory.
   chdir $home || die "$CMDNAME: Can't chdir to $home\n";

   # Check whether vacation has been enabled.
   $enabled = 0;
   if (-f ".forward")
   {
      open(FOR, "<.forward") || die "$CMDNAME: Can't open .forward\n";
      while($line = <FOR>)
      {
         if ( $line =~ m|$vacation| )
         {
            $enabled = 1;
         }
      }
      close FOR;
   }

   # Ask whether the vacation feature must be disabled. After that
   # we are ready and exit.
   if ($enabled) {
      print "The vacation feature is enabled.\n";
      print "\n";
      if (&yorn("Would you like to disable the vacation feature? ")) {
         &disable;
      }
      else {
         print "Ok, vacation feature NOT disabled.\n";
      }
      exit;
   }

   # Vacation feature is disabled. Start dialog to enable it.
   # After that we are ready and exit.
   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 "You already have a message file in ~/.vacation.msg.\n";
         $see = &yorn("Would you like to see it? ");
         system $pager, ".vacation.msg" if $see;
         print "\n" 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.

You will now enter your favorite editor ($editor)
to edit the messasge to your own tastes. Remember that the first
line shall start with "Subject: ", and that the second line shall
be empty.

EOF
         $| = 1;
         print "Press return to continue. ";
         <STDIN>;
         $edit = 1;
      }
      last unless $edit;
      system $editor, ".vacation.msg";
      last;
   }
   if (&yorn("Would you like to enable the vacation feature now? ")) {
      &enable;
   }
   else {
      print "Ok, vacation feature NOT enabled.\n";
   }
   exit;
}

######################################################################
#
# Enable the vacation feature. If no .forward file exists one is
# created. If a .forward file exists, a line enabling the vacation
# program is appended to it.
#
######################################################################

sub enable {
   if (-f ".forward")
   {
      open(FOR, ">>.forward") ||
         die "$CMDNAME: Can't open .forward\n";
      print FOR "\"|$vacation $user\"\n";
      close FOR;
   }
   else
   {
      open(FOR, ">.forward") ||
         die "$CMDNAME: Can't create .forward\n";
      print FOR "\\$user, \"|$vacation $user\"\n";
      close FOR;
   }
   print <<EOF;
Ok, vacation feature ENABLED. Please remember to turn it off when
you get back from vacation. Bon voyage!
EOF
}

######################################################################
#
# Disable the vacation feature. The line enabling the vacation
# program is deleted from the .forward file.
#
######################################################################

sub disable {
   open(FOR, "|$ed -s .forward") ||
      die "$CMDNAME: Can't open pipe to ed .forward\n";
   print FOR "g|$vacation|d\nw\nq\n";
   close FOR;
   if (-z ".forward") {
      unlink(".forward");
   }
   print "Back to normal reception of mail.\n";
}

######################################################################
#
# A default .vacation.msg file is created.
#
######################################################################

sub make_default {
   return if $edit;
   open(MSG, ">.vacation.msg") ||
      die "$CMDNAME: Can't create .vacation.msg\n";
   print MSG <<EOF;
Subject: I am away from my mail

I will not be reading my mail for a while. Your mail regarding
$SUBJECT will be read when I return.
EOF
   close MSG;
}


######################################################################
#
# Ask a question and read an answer being y(es) or n(o).
#
######################################################################

sub yorn {
   local($answer);
   for (;;) {
      print $_[0];
      $answer = <STDIN>;
      last if $answer =~ /^[yn]/i;
      print "Please answer \"yes\" or \"no\" (\"y\" or \"n\")\n";
   }
   print "\n";
   $answer =~ /^y/i;
}
kalinga
Site Admin
 
Posts: 209
Joined: Fri Oct 14, 2005 3:19 pm
Location: Sri Lanka


Return to Linux - Networking

Who is online

Users browsing this forum: No registered users and 1 guest

cron