| |||||||
|
|
Click here to download plain text source code.
# subroutine name: send_mail # Sends e-mail message via sendmail (standard Unix program) or # via SMTP server (requires sendmail.pm module). # Input: # $from - "from" (sender) e-mail address # $to - "to" (recipient) e-mail address # $subject - subject of message # $message - e-mail message body # $bcc - reference to array of BCC recipients # $bcc_max_addresses - max. number of BCC recipients in one envelope # # If mailing variables ($mailprog, $smtp_server) are set incorrectly, # makes CGI process exit with error. # # Returns: string containing errors during sending e-mails (empty is successful). # # Global variables used: # $mailprog - path to sendmail program (or compatible) # $smtp_server - SMTP server address # $log_emails - enable/disable logging of all e-mails sent # $x_mailer - content of X-Mailer header sub send_mail { my ($from,$to,$subject,$message,$bcc,$bcc_max_addresses) = @_; $bcc_max_addresses = int($bcc_max_addresses) || 99; my ($errors,$allerrors); START_MAIL: $errors=""; # split @$bcc array on blocks 99 emails each my @bcc_slice; if (@$bcc) { @bcc_slice=@$bcc[0..($bcc_max_addresses>scalar @$bcc?scalar @$bcc-1:($bcc_max_addresses-1))]; splice(@$bcc,0,$bcc_max_addresses); }; # Open The Mail Program if ($mailprog && -e $mailprog) { # Using UNIX Sendmail # Use 3-pipes module only when STDOUT is open (required to work-around problem with open3 [or sendmail?] when STDOUT is closed) my $ipc_ok=defined fileno(STDOUT); eval "use IPC::Open3" if $ipc_ok; my $child_pid; if (!$ipc_ok || $@) { $ipc_ok=0; # failed to open 3-pipes module. # Open sendmail as usual (widely suppurted) open(MAIL,"|$mailprog -t") || die("Error in subroutine send_mail: Can't open $mailprog. Reason: $!"); } else { # Module IPC exists, use 3-pipes open function # Specifying STDIN, STDOUT, STDERR for sendmail program # Reason for it: sendmail may print errors in STDOUT of our script $child_pid = open3(\*MAIL,\*MAILOUTPUT, \*MAILERR, "$mailprog -t") || die("Error in subroutine send_mail: Can't open $mailprog. Reason: $!"); select(MAILERR); $| = 1; # make unbuffered select(MAILOUTPUT); $| = 1; # make unbuffered } select(MAIL); $| = 1; # make unbuffered select(STDOUT); print MAIL "To: $to\n" or $errors.="Unable to send e-mail: can't print to pipe, ipc_ok=$ipc_ok. To: $to\n"; unless ($errors) { print MAIL "Bcc: ".join(",\n\t",@bcc_slice)."\n" if (@bcc_slice); print MAIL "X-Mailer: $x_mailer\n" if ($x_mailer); print MAIL "From: $from\n"; print MAIL "Subject: $subject\n\n"; print MAIL "$message\n" or print "Unable to send e-mail to $to\n"; } close (MAIL) or $errors.="Unable to send e-mail: can't close pipe, ipc_ok=$ipc_ok. To: $to \n"; if ($ipc_ok) { # Pick up error messages from sendmail's output my $sendmail_response; while (my $line = <MAILOUTPUT>) { $sendmail_response .= "$line" unless ($line =~ m/^\s*$/s); }; $errors.= "SENDMAIL RESPONSE:$sendmail_response" if ($sendmail_response ne ""); close (MAILOUTPUT); my $sendmail_errors; while (my $line = <MAILERR>) { $sendmail_errors .= "$line" unless ($line =~ m/^\s*$/s); }; $errors.= "SENDMAIL ERROR:$sendmail_errors" if ($sendmail_errors ne ""); close (MAILERR); waitpid($child_pid, 0) if ($child_pid); } } elsif ($smtp_server) { # Direct socket connection to SMTP server # prepare mail message to send eval ("use sendmail"); if ($@) { die("Can't load 'sendmail.pm' module"); }; @{$sendmail::mailcfg{'smtp'}} = ($smtp_server); my %mail = ( To => $to, Bcc => join(",", @bcc_slice), From => $from, Subject => $subject, Message => $message, ); $mail{"X-Mailer"} = $x_mailer if ($x_mailer); &sendmail(%mail) or ($errors.=$sendmail::error); } else { die("send_mail failed: SMTP server not defined, sendmail program '$mailprog' not found"); } if ($log_emails) { if ($errors) { &LOG("mail_err","Failed to send email FROM:$from; TO:$to; SUBJECT:$subject; ERRORS: $errors"); } else { &LOG("mail","Email FROM:$from; TO:$to; SUBJECT:$subject\nMESSAGE:\n$message"); } } $allerrors.="$errors\n" if ($errors); goto START_MAIL if (@$bcc); $allerrors; } |
|||||||||||||||||||||
| Copyright © 1999-2007 Atomicsoft Ltd. All Rights Reserved. | ||