CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
Search Posts SEARCH
Who's Online WHO'S
Log in LOG

Home: Perl Programming Help: Intermediate:
email programme



Apr 12, 2001, 8:43 AM

Post #1 of 4 (290 views)
email programme Can't Post


I want to automate the process which will send the email to multiple addresses. Is there any email programme that i can use in my perl code on WINDOWS NT ?



Apr 12, 2001, 2:00 PM

Post #2 of 4 (284 views)
Re: email programme [In reply to] Can't Post

Hi sdaithankar,

You probably want to check Mail::Bulkmail module?

I hope this helps

; -----
Real Programmers dont need class,
They just have style...


Apr 13, 2001, 7:49 AM

Post #3 of 4 (276 views)
Re: email programme [In reply to] Can't Post

I successfully integrated this script in a Netware environment. Netware servers do not have a mail client that can be called from a perl script. This script will drop the mail to be sent to an SMTP server of your choice (preferably an SMTP server you are authorized to use :) )

Hope it helps.


#, jmerrill 03/06/97
# modified by Neil Jowsey to fix a problem with email addressing
# modified by Michael Lecuyer <> for International use.
# ISO-8859-1 compliant: May 18, 1988
# Also added variable field names. Forms with names
# FIELD1, FIELD2, will be prepended to MESSAGE. This allows
# HTML forms to pass data back that's more convenient to
# a form setting when specific information is requested.
# This is a short script used to send mail through an SMTP host based on CGI data
# passed in by a client or another process. This expects to communicate with an
# SMTP host that complies with RFC 821 "Simple Mail Transfer Protocol". It does not
# use the enhanced SMTP (eg. EHLO), rather the most basic SMTP (eg. HELO). In RFC
# 821 terminology, this script is the "sender-SMTP".
# The CGI variables accepted are:
# MAILHOST (Required) Set to the DNS name or IP address of a host that will accept
# and forward SMTP mail. This is the host through whom the
# mail will be sent. This is used to open the socket.
# FROM (Recommended) Set to the reverse-path SMTP address of the sender. If an
# error occurs in delivering mail from the MAILHOST on, that
# error will be sent to this address. Replies will also go to
# this address. This is used in the "MAIL FROM:<>" line (see
# RFC 821).
# TO (Required) Set to the forward-path SMTP address of the user to deliver
# the mail to. This is used in the "RCPT TO:<>" line(s). If
# multiple recipients are listed (separated by commas) then
# multiple "RCPT TO:<>" lines are sent to the MAILHOST (see
# RFC 821).
# CC (Optional) This is a list of recipients to be carbon-copied with the
# mail message. It behaves the same as TO, and is in fact sent
# as part of the same connection to the mailhost as the TO.
# BCC (Optional) This is a list of recipients to be blind carbon-copied with
# the mail message. It behaves the same as the TO and CC fields
# except that it is sent over a separate connection to the
# mailhost so that the TO and CC recipients don't see the 'bcc'
# line in the mail header.
# SUBJECT (Optional) Set to a string of text that to appear on the subject line
# when the user receives the message. It is concatenated into
# the message "DATA" sent to the MAILHOST. If this isn't
# defined, then MESSAGE is required.
# MESSAGE (Optional) Set to the string of text that makes up the body of the
# mail message. It is appended to the end of the message
# "DATA" sent to the MAILHOST. If this isn't defined, then
# SUBJECT is required.
# VERBOSE (Optional) If set to "on" then the SMTP chat sequence and connection
# information will be sent back to the client in HTML format.
# FIELDxx (Optional) Field values. They may be provided when forms requiring
# specific information may be incorporated into a message
# For example FIELD1 might contain someone's name, while FORM2
# might contain their occupation.
# Eg: use hidden fields to name fields, others for data:
# The mail addresses sent in FROM and TO must be in standard SMTP '@' style notation
# as described in RFC 821. Basically, anything your SMTP host specified in MAILHOST
# will accept can be used to fill the FROM and TO data.
# Examples
# - specifies user 'joey' at host ''.
# - specifies user 'joey' at host '' but through host
# gatehost.
# Since the PERL5 that currently ships with the Novell Web Server doesn't come with any
# of the standard libraries, the Sockets library is not used here. Things are "more or
# less" hard coded. This isn't the best practice, but done to make it easier to deploy
# on a Novell Web Server.
# When this CGI script finishes, if VERBOSE is set to on, it returns the send/receive
# chat with the MAILHOST in the same format used in RFC 821. Some basic errors are
# checked for.
# This is not an entirely fault-tolerant script. It just does the basics. It is also a
# very powerful script in that it can be used to send any message to any SMTP host from
# anyone. It never checks that the user specified in FROM is a valid user. When using
# this script take care to limit what the user can actually enter in vs. what you set
# for the user. Enjoy.

# The following line is commented out because the sockets library isn't currently available.
# use Socket;

# standard Perl cgi opening commands
print &PrintHeader;

$verbose = $in{VERBOSE};

# Get current GMT date/time information
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = gmtime;
$month = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$mon];

# host to send mail 'through'
$host = $in{MAILHOST}; # create the host string
if (length($host) < 1) {
cgiSMTPError("\'MAILHOST\' not specified.", "You must specify a Mailhost to accept the SMTP mail.");
} else {
chomp($host); # remove all leading and trailing white space

# return address
$mailfrom = $in{FROM}; # create the from string
chomp($mailfrom); # remove all leading and trailing white space

# construct lists of recipients
$tostr = $in{TO}; # create the recipient string
if (length($tostr) < 1) {
cgiSMTPError("\'TO\' recipient not specified.", "You must specify a recipient in the TO field.");
$tostr .= ", $in{CC}" unless ! $in{CC}; # if CC, concatinate to recipient string
split(/,/, $tostr); # break the ',' delimited recipient string into a list
@rcptto = @_; # create the main recipient list
split(/,/, $in{BCC}); # break the BCC recipient string in to a list
@rcptbcc = @_; # create the BCC recipient list

# Message body
# First part is made of the fields.
for ($i = 0; $i < 100; $i++)
$fn = "FIELD" . $i;
if ($in{$fn})
chomp($in{$fn}); # remove all leading and trailing white space

$forminfo .= "$in{$fn}\n";
# The Next part is made of the actual message.
# Create body string, then preceed any lines that begin with '.' with another '.'
# so the line actually begins with '..'(as per RFC 821). The SMTP host will strip off the first
# '.' on any line that begins with '.' so we compensate for that here.
($body=$forminfo . $in{MESSAGE}) =~ s/\n\./\n\.\./g;

# Message header
# This is a very basic mail header in the order recommended by RFC 822.
# bcc: is not specified here but will be added in a separate connection to
# the SMTP host.
$head .= "Date: $mday $month $year $hour:$min:$sec GMT\r\n";
$head .= convert_header("From: $in{FROM}\r\n");
$head .= convert_header("Subject: $in{SUBJECT}\r\n");
$head .= convert_header("To: $in{TO}\r\n");
if ( $in{CC} ) {
$head .= convert_header("cc: $in{CC}\r\n"); # cc: is appended if specified by the client
$head .="Content-Type: text/plain; charset=iso-8859-1\r\n";
$head .="Content-Transfer-Encoding: quoted-printable\r\n";

# Send the message through the mail host.
print strToHTML("Sending mail to $in{TO}\n");
$smtpchat = cgiSMTP($host, $mailfrom, \@rcptto, $head, $body);

# If BCC was sent by the client, add bcc: to header and send mail to the mailboxes
# specified in BCC.
if ( $in{BCC} ) {
$head .= "bcc: $in{BCC}\r\n";
print strToHTML("\nSending mail to BCC recipients.\n");
$smtpchat = cgiSMTP($host, $mailfrom, \@rcptbcc, $head, $body);

print strToHTML("Mail has been sent. Replies or errors will be sent to $mailfrom.\n");

# -------------------------------------------------------------------
# ---- This is the end of the main script...subroutines follow ------
# -------------------------------------------------------------------

# Subroutine that takes a mail host name, a sender string, a recipients list, a header
# and a message body and sends it to the mail host. It returns a send/receive chat
# string similar to what RFC 822 shows as it's examples.
sub cgiSMTP {
my ($host, $from, $rcpts, $head, $data) = @_;
my $localhost = $ENV{SERVER_NAME};
my $rcpt;
# If an this host is an IP address is specified, pack it into a string and get the host name
# This string will be used in the HELO command.
if ($localhost=~/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {
$localhost = gethostbyaddr(pack("C4", split(/\./, $localhost)), $PF_INET);
cgiSMTPConnect($host); # Connect to the mail host
&cgiSMTPGetReply; # Get the initial connect response string
cgiSMTPSend("HELO $localhost"); # Send the HELO command
cgiSMTPSend("MAIL FROM:<$from>"); # Send the MAIL command
foreach $rcpt (@$rcpts) { # Send the RCPT command for each recipient
$rcpt=~s/\s*//g; # strip out any white space
cgiSMTPSend("RCPT TO:<$rcpt>");
cgiSMTPSend("DATA"); # Send the DATA command
cgiSMTPSend("$head\r\n$body\r\n."); # Send the message body followed by "<CRLF>."
cgiSMTPSend("QUIT"); # Send the QUIT command
&cgiSMTPDisconnect; # Close the connection to the mail host
return $chat; # Return the chat string
} # end of sub cgiSMTP

# Subroutine that makes a connection to the mail host. It is currently using hard-coded
# values and other kludges to get around not being able to use the Socket library. If it
# fails, the entire script is exited by calling cgiSMTPError.
sub cgiSMTPConnect {
my $host = shift;
my $PF_INET=2; # coded as a string because the Socket library is not available
my $SOCK_STREAM=1; # coded as a string because the Socket library is not available
my $port, $iaddr, $paddr;
if ($verbose eq "on") {
print strToHTML("Connecting to port $port on host $host\n");
$port = getservbyname("smtp", "tcp");

# Get $iaddr. Pack the mail host's IP address. Inline alternate for the following commented line:
# $iaddr=inet_aton($host)
if ($host=~/\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}/) {
$iaddr=pack("C4", split(/\./, $host))
} else {
($iaddr=gethostbyname($host)) || cgiSMTPError($!, "Can't find host $host");
# Get $paddr. Pack PF_INET, $port, $iaddr and 8 bytes of '0'. Alternate for the following commented line:
# $paddr=sockaddr_in($port, $iaddr);
$paddr=pack("CxxC", $PF_INET, $port).$iaddr.pack("x8") ;
if ($verbose eq "on") {
print strToHTML("Opening socket SMTPSOCK with PF_INET=$PF_INET, SOCK_STREAM=$SOCK_STREAM, and proto=$proto\n");
socket(SMTPSOCK, $PF_INET, $SOCK_STREAM, $proto) || cgiSMTPError($!, "Can't open socket to host.");
if ($verbose eq "on") {
print strToHTML("Connecting socket to server $host: ");
print unpack("C*", $paddr);
print strToHTML("\n");
connect(SMTPSOCK, $paddr) || cgiSMTPError($!, "Failed to connect.");
} # end of sub cgiSMTPConnect

# Subroutine to close the socket to the mailhost
sub cgiSMTPDisconnect {
if ($verbose eq "on") {
print strToHTML("Closing connection to $host\n");
} # end of sub cgiSMTPDisconnect

# Subroutine to send a command or message string to the mail host.
# This routine takes a string that does not end in <CRLF>, appends a <CRLF>, sends that string
# to the mail host, gets a reply from that mail host, checks for a non-error reply, and returns
# the chat string. When it checks for a non-error reply, it is only checking that the code
# returned was a success reply. It makes no attempt to verify that the reply was valid for the
# type of command sent (in this way it may not be RFC 822 standard).
sub cgiSMTPSend {
my $sendstr = shift()."\r\n"; # append <CRLF> to the end of the send string
my $replystr, $response, $code;
# If verbose, then print the send string with prepended "S: "
if ($verbose eq "on") {
foreach (split(/\n/, $sendstr)) {
print strToHTML("S: $_\n");
# Send the string to the mail host and get the response
send(SMTPSOCK, $sendstr, 0) ||
cgiSMTPError($!, "Failed to send the following text:\n
".strToHTML($text) );
$response = &cgiSMTPGetReply; # Get the mail host's reply to the sent command
# If verbose, the print the response with prepended "R: "
if ($verbose eq "on") {
foreach (split(/\n/, $response)) {
print strToHTML("R: $_\n");
$code = substr($response, 0, 3); # get the returned code from the response
# If the code isn't a non-error code, kill the script by calling cgiSMTPError
if (! ($code =~ /211|214|220|221|250|251|354/)) {
cgiSMTPError($response, "Mail command failed sending:\n$sendstr");
return $response;
} # end sub cgiSMTPSend

# Subroutine to get a response string to an SMTP command. The string will end in
# a line feed. Null is also checked for. If the string has a '-' following the
# response code, then it is a multi-line response and this routine calls itself to
# get the next line. The entire response (multiple lines in the case of a multi-
# line response) is returned to the original caller.
sub cgiSMTPGetReply {
my $text, $ch, $chat;
# Get one character at a time until recv fails, or the character is 0 or 10
until (recv(SMTPSOCK, $ch, 1, 0) && (ord($ch) == 0 or ord($ch) == 10) ) {
$text .= $ch; # append the received character to the text
$text .= $ch; # append the final received character to the text
# If this is a multi-line respones, get the next line
($text=~/^\d{3}-/) && ($text .= &cgiSMTPGetReply);
# return the response
return $text;
} # end sub cgiSMTPGetReply

sub strToHTML {
my $text = shift;
$text =~ s|\&|\&amp\;|g; # convert all '&' to "&" (must be first)
$text =~ s|<|\&lt\;|g; # convert all '<' to "<"
$text =~ s|>|\&gt\;|g; # convert all '>' to ">"
$text =~ s|\n|
\n|g; # convert all line feeds to "
" and line feed
return $text;
} # end sub strToHTML

sub cgiSMTPError {
my $err = shift;
my $text = shift;
&cgiSMTPDisconnect; # close any connection that may have been made
print "<b>\n
ERROR: "; # print the error
print strToHTML($text);
print "</b>\n
print strToHTML($err);
print "</em>";
exit; # terminate the script
} # end sub cgiSMTPError

# Turn all 8 bit characters into their "=XX" equivalents
sub convert_body
my ($msgbody, $radbruten) = ($_[0], "");

$msgbody =~ s/([^ \t\n!-<>-~])/sprintf("=X", ord($1))/eg;

$msgbody =~ s/([ \t]+)$/
join '', map {sprintf("=X", ord($_))}
(split '', $1)/meg;


# Turn all 8 bit characters into their "=XX" equivalents adding the escape
# information specific to headers.
sub convert_header
my ($header) = $_[0];

$header=~ s/([^ \t\n!-<>-~])/
sprintf("=?iso-8859-1?Q?=X?=", ord($1))/eg;


Apr 13, 2001, 8:00 AM

Post #4 of 4 (273 views)
Re: email programme [In reply to] Can't Post

Thanks !!


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives