homesubscribeadvertisecustomer serviceback issuesfeedbackcontacts

  Enter email address:
  How To
    Best Defense
  Developer's Den
    Compile Time
On Stands Now Click to view Table of Contents for Linux Magazine May 2000 Issue
Linux Magazine
Subscribe to Linux Magazine

Linux Magazine / December 1999 / PERL OF WISDOM
Saws Into Ploughshares
       page 01 02   next >>

Saws Into Ploughshares
by Cameron Laird

Many of us make the mistake of limiting our own vision. We put tools or people in boxes that are too confining. Even experienced Perl programmers sometimes believe, "Perl is great for text filters," or "Unix system administrators should use Perl to automate their work," without seeing that Perl can do much, much more. The fact is that Perl's virtues of expressiveness and concision apply to more than simple text manipulation or sysadmin automation.

Suppose you're the administrator of an e-mail server. People look to you to solve their "I can't get my messages!" complaints. You know the patterns: Users misremember their passwords, misconfigured firewalls block traffic, servers go haywire. Can Perl help?

Sure it can! Help desks are often trained to reproduce what the end user is doing. For the e-mail case, this might mean reconfiguring an e-mail client program like Netscape Communicator to duplicate what the end user is doing. Perl can help you do this much more quickly than by pointing-and-clicking, though. It's also a lot easier to "glue" a little Perl utility together that will check this information for you.

Listing One: Complete Contents of pop-check Utility

 1   #!/usr/bin/perl    
 2   use Net::POP3;    
 3   usage(0) if "-h" eq $ARGV[0] || "-help" eq $ARGV[0];    
 4   usage(1) if 2 != $#ARGV;    
 5   ($hostname, $account, $password) = @ARGV;    
 6   # Net::POP3->new () optionally takes a Timeout argument.     
 7   # This is handy for tracking down one class of problems.    
 8   $handle = Net::POP3->new($hostname) or die "Unable    
         to establish POP3 connection to $hostname.\n";    
 9   defined($handle->login($account, $password)) or die    
         "Unable to authenticate ($account, $password)    
         at $hostname.\n";    
 10  # I've never seen a POP3 server fail on the     
         $handle->list access.    
 11  # Still, it's prudent to allow for the possibility.    
 12  $message_list = $handle->list or die "Unable to 
     retrieve list of available messages.\n";    
 13  foreach $item (keys %$message_list) {    
 14  $header = $handle->top($item);    
 15  print @$header;    
 16  }    
 17  sub usage {    
 18  # This utility exposes PASSWORD in the process table    
       and on    
 19     #the wire.If you're operating from an insecure host,    
 20  # you'll want to compose an alternative user    
       interface to    
 21  # fortify defenses. Note that Net:POP3 includes an     
 22  # method.    
 23  print "Use this utility as 'pop_check HOSTNAME    
       ACCOUNT PASSWORD',\n";    
 24  print " or 'pop_check -help', to see this     
 25  exit($_[0]);    
 26  }    

pop_check to the Rescue

The pop_check utility (Listing One) can be run from the command line to retrieve useful information immediately:


You can run this Perl script instead of reconfiguring your own e-mail client with the settings of your distressed user. And you don't have to worry about resetting your original e-mail client configuration when you're done, either. You can run pop_check from any platform that supports Perl, including Linux, Windows, and Macintosh. Rather than issuing an e-mail client's muddy error messages ("Possible networking misconfiguration; consult your Network Administrator"), pop_ check will swiftly identify the most common e-mail problems. And this Perl utility does it in three dozen easily understood lines of source code.

You'll see that lines 3 and 4 of Listing One present pop_check's user with a usage message. $#ARGV counts (one fewer than) the number of command-line arguments.

By line 6, pop_check will have exactly three command-line arguments. This compound assignment interprets them as the name of the POP3 server and a valid account-password combination on that server.

Graham Barr, Perl5.005 Source Maintainer, defined the libnet collection of Perl modules with object-oriented (OO) interfaces. While most introductions to Perl now explain at least the rudiments of its OO style, I particularly recommend the book Object-Oriented Perl by Damian Conway. Conway has appeared in Perl of Wisdom before; September 1999's random-Randal generator depended crucially on Damian's Parse::RecDescent module. His book, just published late this summer, is lucid, literate, and useful enough to be valuable for both beginners and experienced Perl programmers.

I'm careful to catch error conditions in lines 8 through 12. One of the best things a program can do is report comprehensibly on exceptions, faults, and confusions. Being a user is easy when everything's working right; we particularly need the computer to do its part in generating feedback, though, when there's a problem. This is especially true for pop_check. Most of the time I use pop_check because something is going wrong, and I need to track that down. Proper error messages are crucial.

In principle, the special variable $! includes more detailed diagnostic information, so it would be natural to write

die "Unable to establish POP3 connection to $hostname ($!).\n";

or something similar. However, version 1.0606 does not yet set $! to anything interesting, so I ignore it.

Heed the defined() in line 9. As much as I like Christiansen and Torkington's ground-breaking Perl Cookbook, their Net::POP3 example mishandles login()'s return value. This is a common error. Often people write

somefunction() or die "message"

when they intend

defined(somefunction()) or die "message"

Finally, to confirm that the POP3 server is doing its job correctly, pop_check loops through the entire list of messages retained at the server and prints the header for each.

       page 01 02   next >>
Linux Magazine / December 1999 / PERL OF WISDOM
Saws Into Ploughshares

homesubscribeadvertisecustomer serviceback issuesfeedbackcontacts