############################################################################ # # # send_email() Version 1.0 # # Written by Craig Patchett craig@patchett.com # # and Matthew Wright mattw@worldwidemart.com # # Created 11/16/97 Last Modified 11/16/97 # # # # Copyright 1997 Craig Patchett & Matthew Wright. All Rights Reserved. # # This subroutine is part of The CGI/Perl Cookbook from John Wiley & Sons. # # License to use this program or install it on a server (in original or # # modified form) is granted only to those who have purchased a copy of The # # CGI/Perl Cookbook. (This notice must remain as part of the source code.) # # # # Function: Sends an email message and optional attached files via # # a pipe connection to sendmail or a compatible program. # # # # Usage: &send_email($subject, $from, $to[, $cc, $bcc, $body, # # $files, $encoding]); # # # # Variables: $subject -- String containing subject of message. # # Example 'Buy the CGI/Perl Cookbook!' # # $from -- String containing email address of person # # sending message. An associated name can # # follow the address if placed in parentheses. # # Example 'me@home.com (My Name)' # # $to -- String containing email addresses to send # # message to. Multiple addresses should be # # separated by commas. Associated names # # can follow each address if placed in # # parentheses. # # Example 'him@place.com (Name),her@place.com' # # $cc -- String containing email addresses to send # # copies of the message to. Same format as $to.# # $bcc -- String containing email addresses to send # # blind copies of the message to (i.e., nobody # # else receiving the message will know that # # copies were sent to these addresses). Same # # format as $to. # # $body -- Full path to file containing the body of the # # message or text containing body of message # # (if $body doesn't begin with a directory # # delimiter and contains at least one space # # then the subroutine assumes it contains # # message text). # # Example '/home/user/body.txt' # # Example 'This is message text.' # # $files -- String containing a list of full paths, # # separated by commas, to files to be attached # # to the message. # # Example '/home/user/file1, /home/user/file2' # # $encoding -- String containing a list of encoding types, # # separated by commas, to match the list of # # files in $file. Valid types are: text, # # uuencode, base64 # # Example 'text, base64' # # # # Returns: Nothing # # # # Uses Global: $SENDMAIL for the path to the sendmail program (assumes # # that sendmail is in search path if not set) # # # # Requires: base64.pl # # chkemail.pl # # error.pl # # uuencode.pl # # # # Files Created: None # # # ############################################################################ sub send_email { local($subject, $from, $to, $cc, $bcc, $body, $files, $encoding) = @_; local($i, $mime_id, $error, $name, $status, $message) = ''; local(@MIME_FILES, @MIME_TYPES, @ATTACH_FILES, @ENCODING) = (); # Attempt to set default values if globals aren't set if (!$SENDMAIL) { $SENDMAIL = "/usr/lib/sendmail" } # Split the input into arrays where needed, since values are passed # as strings separated by commas. local(@to) = split(/, */, $to); local(@cc) = split(/, */, $cc); local(@bcc) = split(/, */, $bcc); local(@attach_files) = split(/, */, $files); local(@encoding) = split(/, */, $encoding); # Check to see what file encoding is being used and if necessary, set the # mime flag and id. for ($i = 0; $i < @attach_files; ++$i) { if (!(-e $attach_files[$i])) { $Error_Message = "$attach_files[$i] does not exist."; return(9); } if ($encoding[$i] eq 'base64') { push(@MIME_FILES, $attach_files[$i]); push(@MIME_TYPES, $encoding[$i]); } else { push(@ATTACH_FILES, $attach_files[$i]); push(@ENCODING, $encoding[$i]); } } if (@MIME_FILES) { push(@ATTACH_FILES, @MIME_FILES); push(@ENCODING, @MIME_TYPES); $mime_id = 'CGI_Perl_Cookbook_-' . time; } # Set up other variables local(@bad_addresses) = (); $, = ', '; $" = ', '; # Open the connection to sendmail and line buffer output open(MAIL, "|$SENDMAIL -t -f $from"); select(MAIL); $| = 1; select(STDOUT); # Output the message header print MAIL "To: @to\n"; print MAIL "From: $from\n"; print MAIL "CC: @cc\n" if $cc; print MAIL "BCC: @bcc\n" if $bcc; print MAIL "Subject: $subject\n"; if($body =~/^/){#oma lisäys print MAIL "Content-type: text/html\n"; } # If there are mime files to attach, we need special headers. if ($mime_id) { print MAIL "x-sender: $from\n"; print MAIL "x-mailer: CGI/Perl Cookbook\n"; print MAIL "Mime-Version: 1.0\n"; print MAIL "Content-Type: multipart/mixed; boundary=\"$mime_id\"\n\n"; print MAIL "--$mime_id\n"; print MAIL "Content-Type: text/plain; charset=\"US-ASCII\"\n\n"; } else { print MAIL "\n" } # Output the message body. # if ($body) { # if (!($body =~ /^[\\\/:]/) && ($body =~ /\s/)) { print MAIL $body } # elsif (-e $body && -T $body) { &parse_template($body, *MAIL) } # } print MAIL $body; print MAIL "\n"; # Attach each file. for ($i = 0; $i < @ATTACH_FILES; ++$i) { $attach_file = $ATTACH_FILES[$i]; $encoding = $ENCODING[$i]; # Split the filename by directories. / for unix, \ for dos, : for mac $attach_file =~ /[\\\/:]([^\\\/:]+)$/g; $filename = $1; # Attach text file. if ($encoding eq 'text' && -e $attach_file) { if (!(open(TEXT, $attach_file))) { $Error_Message = "Can't open text file $attach_file ($!)."; return(9); } print MAIL "Attachment:\t$filename\n"; print MAIL "Encoding:\tNone\n\n"; # Attach the text file, converting any lines with a single period while () { s/^\.([\n\r\f]+)/..$1/; print MAIL } close(TEXT); print MAIL "\n\n"; } # Attach uuencoded file. elsif ($encoding eq 'uuencode' && -e $attach_file) { print MAIL "Attachment:\t$filename\n"; print MAIL "Encoding:\tUUEncoded\n"; print MAIL "begin 600 $filename\n"; $uuencoded_data = &uuencode($attach_file, 'open->attach_file'); if (!$uuencoded_data) { return(10) } print MAIL $uuencoded_data; print MAIL "`\nend\n\n"; } # Attach MIME files elsif ($encoding eq 'base64' && -e $attach_file) { print MAIL "--$mime_id\n"; # If it is a text file, print a text content type, otherwise print # an octet stream. if (-T $attach_file) { print MAIL "Content-type: text/plain; charset=US-ASCII; name=\"$filename\"\n"; } else { print MAIL "Content-type: application/octet-stream; name=\"$filename\"\n"; } print MAIL "Content-transfer-encoding: base64\n\n"; # Encode the data with base 64. $base64_encoded_data = &base64_encode_file($attach_file); if (!$base64_encoded_data) { return(11) } print MAIL "$base64_encoded_data\n"; } } # Print the final mime id if necessary and close the connection if ($mime_id) { print MAIL "--$mime_id--\n" } close(MAIL); return(0); } 1;