📄 ch18.htm
字号:
Close the socket.<BR>
Define the </I><TT><I>closeSocket()</I></TT><I>
fuNCtion which will act as a signal handler.<BR>
Close the socket.<BR>
Call </I><TT><I>die()</I></TT><I>
to display a message and end the script.<BR>
Define the send </I><TT><I>SMTP()</I></TT><I>
fuNCtion.<BR>
Get the debug parameter.<BR>
Get the </I><TT><I>smtp</I></TT><I>
command from the parameter array.<BR>
Send the </I><TT><I>smtp</I></TT><I>
command to </I><TT><I>STDERR</I></TT><I>
if the debug parameters were true.<BR>
Send the </I><TT><I>smtp</I></TT><I>
command to the mail server.<BR>
Get the mail server's response.<BR>
Send the response to </I><TT><I>STDERR</I></TT><I>
if the debug parameter were true.<BR>
Split the response into reply code and message, and return just
the reply code.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 18.2 18LST02.PL-Sending Mail with Perl<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
#!/usr/bin/perl -w
use Socket;
use strict;
my($mailTo) = 'medined@planet.net';
my($mailServer) = 'mailhost2.planet.net';
my($mailFrom) = 'medined@planet.net';
my($realName) = "Rolf D'Barno";
my($subject) = 'Test';
my($body) = "Test Line One.\nTest Line Two.\n";
$main::SIG{'INT'} = 'closeSocket';
my($proto) = getprotobyname("tcp") || 6;
my($port) = getservbyname("SMTP", "tcp") || 25;
my($serverAddr) = (gethostbyname($mailServer))[4];
if (! defined($length)) {
die('gethostbyname failed.');
}
socket(SMTP, AF_INET(), SOCK_STREAM(), $proto)
or die("socket: $!");
$packFormat = 'S n a4 x8'; # Windows 95, SunOs 4.1+
#$packFormat = 'S n c4 x8'; # SunOs 5.4+ (Solaris 2)
connect(SMTP, pack($packFormat, AF_INET(), $port, $serverAddr))
or die("connect: $!");
select(SMTP); $| = 1; select(STDOUT); # use unbuffered i/o.
{
my($inpBuf) = '';
recv(SMTP, $inpBuf, 200, 0);
recv(SMTP, $inpBuf, 200, 0);
}
sendSMTP(1, "HELO\n");
sendSMTP(1, "MAIL From: <$mailFrom>\n");
sendSMTP(1, "RCPT To: <$mailTo>\n");
sendSMTP(1, "DATA\n");
send(SMTP, "From: $realName\n", 0);
send(SMTP, "Subject: $subject\n", 0);
send(SMTP, $body, 0);
sendSMTP(1, "\r\n.\r\n");
sendSMTP(1, "QUIT\n");
close(SMTP);
sub closeSocket { # close smtp socket on error
close(SMTP);
die("SMTP socket closed due to SIGINT\n");
}
sub sendSMTP {
my($debug) = shift;
my($buffer) = @_;
print STDERR ("> $buffer") if $debug;
send(SMTP, $buffer, 0);
recv(SMTP, $buffer, 200, 0);
print STDERR ("< $buffer") if $debug;
return( (split(/ /, $buffer))[0] );
}
</PRE>
</BLOCKQUOTE>
<HR>
<P>
This program displays:
<BLOCKQUOTE>
<PRE>
<B>> HELO
</FONT></B><FONT SIZE=2 FACE="Courier New">< 250 saturn.planet.net Hello medined@stan54.planet.net
[207.3.100.120], pleased to meet you
</FONT><B><FONT SIZE=2 FACE="Courier">> MAIL From: <medined@planet.net>
</FONT></B><FONT SIZE=2 FACE="Courier New">< 250 <medined@planet.net>... Sender ok
</FONT><B><FONT SIZE=2 FACE="Courier">> RCPT To: <~r00tbeer@fundy.csd.unbsj.ca>
</FONT></B><FONT SIZE=2 FACE="Courier New">< 250 <~r00tbeer@fundy.csd.unbsj.ca>... Recipient ok
</FONT><B><FONT SIZE=2 FACE="Courier">> DATA
</FONT></B><FONT SIZE=2 FACE="Courier New">< 354 Enter mail, end with "." on a line by itself
</FONT><B><FONT SIZE=2 FACE="Courier">>
<B>.
</B></FONT></B><FONT SIZE=2 FACE="Courier New">< 250 TAA12656 Message accepted for delivery
</FONT><B><FONT SIZE=2 FACE="Courier">> QUIT
</FONT></B><FONT SIZE=2 FACE="Courier New">< 221 saturn.planet.net closing connection
</PRE>
</BLOCKQUOTE>
<P>
The lines in bold are the commands that were sent to the server.
The body of the letter is not shown in the output.
<H2><A NAME="ReceivingMailPOP"><FONT SIZE=5 COLOR=#FF0000>
Receiving Mail (POP)</FONT></A></H2>
<P>
The flip side to sending mail is, of course, receiving it. This
is done using the POP or Post Office Protocol. SiNCe you've already
read about the SMTP protocol in detail, I'll skip describing the
details of the POP. After all, the details can be read in the
RFC documents when they are needed. Instead, I'll use the POP3Client
module- available on the CD-ROM-to demonstrate receiving mail.
<P>
Listing 18.3 contains a program that will <I>filter</I> your mail.
It will display a report of the authors and subject line for any
mail that relates to EarthDawn™, a role-playing game from
FASA. This program will not delete any mail from the server, so
you can experiment with confideNCe.<BR>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Before trying to run this program, make sure that the POP3Client module (POP3Client.pm) is in the <TT><B><FONT FACE="Courier">Mail</FONT></B></TT> subdirectory of the library directory. You may need to create the <TT><B><FONT
FACE="Courier">Mail</FONT></B></TT> subdirectory as I did. On my system, this directory is called it is probably different on your system though. See your system administratior if you need help placing the file into the correct directory.
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Caution</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
This script was tested using Windows 95. You might need to modify it for other systems. On SunOS 5.4+ (Solaris 2), you'll need to change the <TT><B><FONT FACE="Courier">POP3Client</FONT></B></TT> module to use a packing format of <TT>'<B>S n c4
x8</B>'</TT> instead of <TT>'<B>S n a4 x8</B>'</TT>. Other changes might also be needed.
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>
<BLOCKQUOTE>
<I>Turn on the warning compiler option.<BR>
Load the </I><TT><I>POP3Client module</I></TT><I>.
The </I><TT><I>POP3Client</I></TT><I>
module will load the </I><TT><I>Socket</I></TT><I>
module automatically.<BR>
Turn on the </I><TT><I>strict</I></TT><I>
pragma.<BR>
Declare some variables used to temporary values.<BR>
Define the header format for the report.<BR>
Define the detail format for the report.<BR>
Initialize </I><TT><I>$username</I></TT><I>
to a valid username for the mail server.<BR>
Initialize </I><TT><I>$password</I></TT><I>
to a valid password for the user name.<BR>
Create a new </I><TT><I>POP3Client</I></TT><I>
object.<BR>
Iterate over the mail messages on the server. </I><TT><I>$pop->Count</I></TT><I>
holds the number of messages waiting on the server to be read.
<BR>
Initialize a flag variable. When set true, the script will have
a mail message relating to </I><TT><I>EarthDawn</I></TT><I>.
<BR>
Iterate over the headers in each mail messages. The </I><TT><I>Head()</I></TT><I>
method of the </I><TT><I>POP3Client</I></TT><I>
module returns the header lines one at a time in the </I><TT><I>$_
</I></TT><I>variable.<BR>
Store the author's name if looking at the From header line.<BR>
Store the subject if looking at the Subject line.<BR>
This is the filter test. It checks to see if the word "EarthDawn"
is in the subject line. If so, the </I><TT><I>$earthDawn</I></TT><I>
flag variable is set to true (or 1).<BR>
This line is commented out; normally it would copy the text of
the message into the </I><TT><I>@body</I></TT><I>
array.<BR>
This line is also commented out; it will delete the current mail
message from the server. <I><B>Use with caution!</B> ONCe deleleted,
you can't recover the messages.<BR>
Set the flag variable, </I></I><TT><I>$earthDawn</I></TT><I>,
to true.<BR>
Write a detail line to the report if the flag variable is true.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 18.3 18LST03.PL-Creating a Mail Filter<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
#!/usr/bin/perl -w
use Mail::POP3Client;
use strict;
my($i, $from, $subject);
format main::STDOUT_TOP =
@||||||||||||||||||||||||||||||||||||||||||||||||| Pg @<
"Waiting Mail Regarding EarthDawn", $%
Sender Subject
---------------------- --------------------------------
.
format main::STDOUT =
@<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$from, $subject
.
my($username) = 'medined';
my($password) = 'XXXXXXXX';
my($mailServer) = 'mailhost2.planet.net';
my($pop) = Mail::POP3Client->new($username, $password, $mailServer);
for ($i = 1; $i <= $pop->Count; $i++) {
my($earthDawn) = 0;
foreach ($pop->Head($i)) {
$from = $1 if /From:\s(.+)/;
$subject = $1 if /Subject:\s(.+)/;
if (/Subject: .*EarthDawn/) {
# @body = $pop->Body($i);
# $pop->Delete($i);
$earthDawn = 1;
}
}
if ($earthDawn) {
write();
}
}
</PRE>
</BLOCKQUOTE>
<HR>
<P>
This program displays:
<BLOCKQUOTE>
<PRE>
Waiting Mail Regarding EarthDawn Pg 1
Sender Subject
---------------------- ---------------------------------
Bob.Schmitt [EarthDawn] NethermaNCer
Doug.Stoechel [EarthDawn] Weaponsmith
Mindy.Bailey [EarthDawn] Troubador
</PRE>
</BLOCKQUOTE>
<P>
When you run this script, you should change <TT>$username</TT>,
<TT>$password</TT>, and <TT>$mailServer</TT>
and the filter test to whatever is appropriate for your system.
<P>
You could combine the filter program with the send mail program
(from Listing 18.2) to create an automatic mail-response program.
For example, if the subject of a message is "Info,"
you can automaticallly send a predefined message with information
about a given topic. You could also create a program to automatically
forward the messages to a covering person while you are on vacation.
I'm sure that with a little thought you can come up with a half-dozen
ways to make your life easier by automatically handling some of
your iNComing mail.
<H2><A NAME="CheckingforUpnessEcho"><FONT SIZE=5 COLOR=#FF0000>
Checking for Upness (Echo)</FONT></A></H2>
<P>
Occasionally it's good to know if a server is up and fuNCtioning.
The echo service is used to make that determination. Listing 18.4
shows a program that checks the upness of two servers.<BR>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Caution</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Windows 95 (and perhaps other operating systems) can't use the SIGALRM interrupt signal. This might cause problems if you use this script on those systems because the program will wait forever when a server does not respond.</BLOCKQUOTE>
</TD></TR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -