home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / Mailer.pm < prev    next >
Encoding:
Perl POD Document  |  2004-03-29  |  7.3 KB  |  329 lines

  1. #
  2.  
  3. package Mail::Mailer;
  4.  
  5. =head1 NAME
  6.  
  7. Mail::Mailer - Simple interface to electronic mailing mechanisms
  8.  
  9. =head1 SYNOPSIS
  10.  
  11.     use Mail::Mailer;
  12.     use Mail::Mailer qw(mail);
  13.  
  14.     $mailer = new Mail::Mailer;
  15.  
  16.     $mailer = new Mail::Mailer $type, @args;
  17.  
  18.     $mailer->open(\%headers);
  19.  
  20.     print $mailer $body;
  21.  
  22.     $mailer->close;
  23.  
  24.  
  25. =head1 DESCRIPTION
  26.  
  27. Sends mail using any of the built-in methods.  You can alter the
  28. behaviour of a method by passing C<$command> to the C<new> method.
  29.  
  30. =over 4
  31.  
  32. =item C<sendmail>
  33.  
  34. Use the C<sendmail> program to deliver the mail.  C<$command> is the
  35. path to C<sendmail>.
  36.  
  37. =item C<smtp>
  38.  
  39. Use the C<smtp> protocol via Net::SMTP to deliver the mail. The server
  40. to use can be specified in C<@args> with
  41.  
  42.     $mailer = new Mail::Mailer 'smtp', Server => $server;
  43.  
  44. The smtp mailer does not handle C<Cc> and C<Bcc> lines, neither their
  45. C<Resent-*> fellows. The C<Debug> options enables debugging output
  46. from C<Net::SMTP>.
  47.  
  48. =item C<qmail>
  49.  
  50. Use qmail's qmail-inject program to deliver the mail.
  51.  
  52. =item C<testfile>
  53.  
  54. Used for debugging, this displays the data on STDOUT.  No mail is ever
  55. sent.  C<$command> is ignored.
  56.  
  57. =back
  58.  
  59. C<Mail::Mailer> will search for executables in the above order. The
  60. default mailer will be the first one found.
  61.  
  62. =head2 ARGUMENTS
  63.  
  64. C<new> can optionally be given a C<$command> and C<$type>.  C<$type>
  65. is one C<sendmail>, C<mail>, ... given above.  The meaning of
  66. C<$command> depends on C<$type>.
  67.  
  68. C<open> is given a reference to a hash.  The hash consists of key and
  69. value pairs, the key being the name of the header field (eg, C<To>),
  70. and the value being the corresponding contents of the header field.
  71. The value can either be a scalar (eg, C<gnat@frii.com>) or a reference
  72. to an array of scalars (C<eg, ['gnat@frii.com', 'Tim.Bunce@ig.co.uk']>).
  73.  
  74. =head1 TO DO
  75.  
  76. Assist formatting of fields in ...::rfc822:send_headers to ensure
  77. valid in the face of newlines and longlines etc.
  78.  
  79. Secure all forms of send_headers() against hacker attack and invalid
  80. contents. Especially "\n~..." in ...::mail::send_headers.
  81.  
  82. =head1 ENVIRONMENT VARIABLES
  83.  
  84. =over 4
  85.  
  86. =item PERL_MAILERS
  87.  
  88. Augments/override the build in choice for binary used to send out
  89. our mail messages.
  90.  
  91. Format:
  92.  
  93.     "type1:mailbinary1;mailbinary2;...:type2:mailbinaryX;...:..."
  94.  
  95. Example: assume you want you use private sendmail binary instead
  96. of mailx, one could set C<PERL_MAILERS> to:
  97.  
  98.     "mail:/does/not/exists:sendmail:$HOME/test/bin/sendmail"
  99.  
  100. On systems which may include C<:> in file names, use C<|> as separator
  101. between type-groups.
  102.  
  103.     "mail:c:/does/not/exists|sendmail:$HOME/test/bin/sendmail"
  104.  
  105.  
  106. =back
  107.  
  108. =head1 SEE ALSO
  109.  
  110. Mail::Send
  111.  
  112. =head1 AUTHORS
  113.  
  114. Maintained by Mark Overmeer <mailtools@overmeer.net>
  115.  
  116. Original code written by Tim Bunce E<lt>F<Tim.Bunce@ig.co.uk>E<gt>,
  117. with a kick start from Graham Barr E<lt>F<gbarr@pobox.com>E<gt>. With
  118. contributions by Gerard Hickey E<lt>F<hickey@ctron.com>E<gt> Small fix
  119. and documentation by Nathan Torkington E<lt>F<gnat@frii.com>E<gt>.
  120.  
  121. =cut
  122.  
  123. use Carp;
  124. use IO::Handle;
  125. use vars qw(@ISA $VERSION $MailerBinary $MailerType %Mailers @Mailers);
  126. use Config;
  127. use strict;
  128.  
  129. $VERSION = "1.62";
  130.  
  131. sub Version { $VERSION }
  132.  
  133. @ISA = qw(IO::Handle);
  134.  
  135. # Suggested binaries for types?  Should this be handled in the object class?
  136. @Mailers = (
  137.  
  138.     # Headers-blank-Body all on stdin
  139.     'sendmail'  => '/usr/lib/sendmail;/usr/sbin/sendmail;/usr/ucblib/sendmail',
  140.  
  141.     'smtp'    => undef,
  142.     'qmail'     => '/usr/sbin/qmail-inject;/var/qmail/bin/qmail-inject',
  143.     'testfile'    => undef
  144. );
  145.  
  146. if($ENV{PERL_MAILERS})
  147. {   push @Mailers
  148.        , map { split /\:/, $_, 2}
  149.              split /$Config{path_sep}/, $ENV{PERL_MAILERS};
  150. }
  151.  
  152. %Mailers = @Mailers;
  153.  
  154. $MailerBinary = undef;
  155.  
  156. # does this really need to be done? or should a default mailer be specfied?
  157.  
  158. if($^O eq 'os2') {
  159.     $Mailers{sendmail} = 'sendmail' unless is_exe($Mailers{sendmail});
  160. }
  161.  
  162. if($^O eq 'MacOS' || $^O eq 'VMS' || $^O eq 'MSWin32' || $^O eq 'os2') {
  163.     $MailerType = 'smtp';
  164.     $MailerBinary = $Mailers{$MailerType};
  165. }
  166. else {
  167.     my $i;
  168.     for($i = 0 ; $i < @Mailers ; $i += 2) {
  169.     $MailerType = $Mailers[$i];
  170.     my $binary;
  171.     if($binary = is_exe($Mailers{$MailerType})) {
  172.         $MailerBinary = $binary;
  173.         last;
  174.     }
  175.     }
  176. }
  177.  
  178. sub import {
  179.     shift;
  180.  
  181.     if(@_) {
  182.     my $type = shift;
  183.     my $exe = shift || $Mailers{$type};
  184.  
  185.         carp "Cannot locate '$exe'"
  186.             unless is_exe($exe);
  187.  
  188.         $MailerType = $type;
  189.         $Mailers{$MailerType} = $exe;
  190.     }
  191. }
  192.  
  193. sub to_array {
  194.     my($self, $thing) = @_;
  195.     if (ref($thing)) {
  196.     return @$thing;
  197.     } else {
  198.     return ($thing);
  199.     }
  200. }
  201.  
  202. sub is_exe {
  203.     my $exe = shift || '';
  204.     my $cmd;
  205.  
  206.     foreach $cmd (split /\;/, $exe) {
  207.     $cmd =~ s/^\s+//;
  208.  
  209.     # remove any options
  210.     my $name = ($cmd =~ /^(\S+)/)[0];
  211.  
  212.     # check for absolute or relative path
  213.     return ($cmd)
  214.         if (-x $name and ! -d $name and $name =~ m:[\\/]:);
  215.  
  216.     if (defined $ENV{PATH}) {
  217.         my $dir;
  218.         foreach $dir (split(/$Config{path_sep}/, $ENV{PATH})) {
  219.         return "$dir/$cmd"
  220.             if (-x "$dir/$name" && ! -d "$dir/$name");
  221.         }
  222.     }
  223.     }
  224.     0;
  225. }
  226.  
  227. sub new {
  228.     my($class, $type, @args) = @_;
  229.  
  230.     $type = $MailerType unless $type;
  231.     croak "No MailerType specified" unless defined $type;
  232.  
  233.     my $exe = $Mailers{$type};
  234.  
  235.     if(defined($exe)) {
  236.     $exe = is_exe ($exe) if defined $type;
  237.  
  238.     $exe  = $MailerBinary  unless $exe;
  239.     croak "No mailer type specified (and no default available), thus can not find executable program."
  240.         unless $exe;
  241.     }
  242.  
  243.     $class = "Mail::Mailer::$type";
  244.     eval "require $class" or die $@;
  245.     my $glob = $class->SUPER::new; # local($glob) = gensym;    # Make glob for FileHandle and attributes
  246.  
  247.     %{*$glob} = (Exe     => $exe,
  248.          Args    => [ @args ]
  249.         );
  250.     
  251.     $glob; # bless $glob, $class;
  252. }
  253.  
  254.  
  255. sub open {
  256.     my($self, $hdrs) = @_;
  257.     my $exe = *$self->{Exe}; # || Carp::croak "$self->open: bad exe";
  258.     my $args = *$self->{Args};
  259.     _cleanup_hdrs($hdrs);
  260.     my @to = $self->who_to($hdrs);
  261.     
  262.     $self->close;    # just in case;
  263.  
  264.     # Fork and start a mailer
  265.     (defined($exe) && open($self,"|-"))
  266.     || $self->exec($exe, $args, \@to)
  267.     || die $!;
  268.  
  269.     # Set the headers
  270.     $self->set_headers($hdrs);
  271.  
  272.     # return self (a FileHandle) ready to accept the body
  273.     $self;
  274. }
  275.  
  276.  
  277. sub _cleanup_hdrs {
  278.   my $hdrs = shift;
  279.   my $h;
  280.   foreach $h (values %$hdrs) {
  281.     foreach (ref($h) ? @{$h} : $h) {
  282.       s/\n\s*/ /g;
  283.       s/\s+$//;
  284.     }
  285.   }
  286. }
  287.  
  288.  
  289. sub exec {
  290.     my($self, $exe, $args, $to) = @_;
  291.     # Fork and exec the mailer (no shell involved to avoid risks)
  292.     my @exe = split(/\s+/,$exe);
  293.  
  294.     exec(@exe, @$args, @$to);
  295. }
  296.  
  297. sub can_cc { 1 }    # overridden in subclass for mailer that can't
  298.  
  299. sub who_to {
  300.     my($self, $hdrs) = @_;
  301.     my @to = $self->to_array($hdrs->{To});
  302.     if (!$self->can_cc) {  # Can't cc/bcc so add them to @to
  303.     push(@to, $self->to_array($hdrs->{Cc})) if $hdrs->{Cc};
  304.     push(@to, $self->to_array($hdrs->{Bcc})) if $hdrs->{Bcc};
  305.     }
  306.     @to;
  307. }
  308.  
  309. sub epilogue {
  310.     # This could send a .signature, also see ::smtp subclass
  311. }
  312.  
  313. sub close {
  314.     my($self, @to) = @_;
  315.     if (fileno($self)) {
  316.     $self->epilogue;
  317.     close($self)
  318.     }
  319. }
  320.  
  321.  
  322. sub DESTROY {
  323.     my $self = shift;
  324.     $self->close;
  325. }
  326.  
  327. 1;
  328.  
  329.