3 # Copyright (c) 1995-1997 Graham Barr <gbarr@pobox.com>. All rights reserved.
4 # This program is free software; you can redistribute it and/or
5 # modify it under the same terms as Perl itself.
11 use vars qw(@ISA $VERSION $debug);
16 $VERSION = "2.24"; # $Id: //depot/libnet/Net/POP3.pm#24 $
18 @ISA = qw(Net::Cmd IO::Socket::INET);
23 my $type = ref($self) || $self;
25 $host = shift if @_ % 2;
27 my $hosts = defined $host ? [ $host ] : $NetConfig{pop3_hosts};
29 my @localport = exists $arg{ResvPort} ? ( LocalPort => $arg{ResvPort} ): ();
32 foreach $h (@{$hosts})
34 $obj = $type->SUPER::new(PeerAddr => ($host = $h),
35 PeerPort => $arg{Port} || 'pop3(110)',
38 Timeout => defined $arg{Timeout}
47 ${*$obj}{'net_pop3_host'} = $host;
50 $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
52 unless ($obj->response() == CMD_OK)
58 ${*$obj}{'net_pop3_banner'} = $obj->message;
64 ## We don't want people sending me their passwords when they report problems
68 sub debug_text { $_[2] =~ /^(pass|rpop)/i ? "$1 ....\n" : $_[2]; }
72 @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->login( USER, PASS )';
73 my($me,$user,$pass) = @_;
76 ($user, $pass) = $me->_lookup_credentials($user);
85 @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->apop( USER, PASS )';
86 my($me,$user,$pass) = @_;
90 if (eval { local $SIG{__DIE__}; require Digest::MD5 }) {
91 $md = Digest::MD5->new();
92 } elsif (eval { local $SIG{__DIE__}; require MD5 }) {
95 carp "You need to install Digest::MD5 or MD5 to use the APOP command";
100 unless ( $banner = (${*$me}{'net_pop3_banner'} =~ /(<.*>)/)[0] );
103 ($user, $pass) = $me->_lookup_credentials($user);
106 $md->add($banner,$pass);
109 unless($me->_APOP($user,$md->hexdigest));
111 $me->_get_mailbox_count();
116 @_ == 2 or croak 'usage: $pop3->user( USER )';
117 $_[0]->_USER($_[1]) ? 1 : undef;
122 @_ == 2 or croak 'usage: $pop3->pass( PASS )';
127 unless($me->_PASS($pass));
129 $me->_get_mailbox_count();
134 @_ == 1 or croak 'usage: $obj->reset()';
141 if(defined ${*$me}{'net_pop3_mail'})
144 foreach (@{${*$me}{'net_pop3_mail'}})
146 delete $_->{'net_pop3_deleted'};
153 @_ == 1 or croak 'usage: $obj->last()';
156 unless $_[0]->_LAST && $_[0]->message =~ /(\d+)/;
163 @_ == 2 || @_ == 3 or croak 'usage: $pop3->top( MSGNUM [, NUMLINES ])';
167 unless $me->_TOP($_[0], $_[1] || 0);
174 @_ == 1 or croak 'usage: $pop3->popstat()';
178 unless $me->_STAT && $me->message =~ /(\d+)\D+(\d+)/;
185 @_ == 1 || @_ == 2 or croak 'usage: $pop3->list( [ MSGNUM ] )';
189 unless $me->_LIST(@_);
193 $me->message =~ /\d+\D+(\d+)/;
197 my $info = $me->read_until_dot
200 my %hash = map { (/(\d+)\D+(\d+)/) } @$info;
207 @_ == 2 or @_ == 3 or croak 'usage: $pop3->get( MSGNUM [, FH ])';
211 unless $me->_RETR(shift);
213 $me->read_until_dot(@_);
218 @_ == 2 or croak 'usage: $pop3->getfh( MSGNUM )';
221 return unless $me->_RETR(shift);
229 @_ == 2 or croak 'usage: $pop3->delete( MSGNUM )';
235 @_ == 1 || @_ == 2 or croak 'usage: $pop3->uidl( [ MSGNUM ] )';
243 $uidl = ($me->message =~ /\d+\s+([\041-\176]+)/)[0];
247 my $ref = $me->read_until_dot
251 foreach $ln (@$ref) {
252 my($msg,$uid) = $ln =~ /^\s*(\d+)\s+([\041-\176]+)/;
253 $uidl->{$msg} = $uid;
261 @_ == 2 or croak 'usage: $pop3->ping( USER )';
264 return () unless $me->_PING(@_) && $me->message =~ /(\d+)\D+(\d+)/;
269 sub _lookup_credentials
271 my ($me, $user) = @_;
275 $user ||= eval { local $SIG{__DIE__}; (getpwuid($>))[0] } ||
276 $ENV{NAME} || $ENV{USER} || $ENV{LOGNAME};
278 my $m = Net::Netrc->lookup(${*$me}{'net_pop3_host'},$user);
279 $m ||= Net::Netrc->lookup(${*$me}{'net_pop3_host'});
281 my $pass = $m ? $m->password || ""
287 sub _get_mailbox_count
290 my $ret = ${*$me}{'net_pop3_count'} = ($me->message =~ /(\d+)\s+message/io)
291 ? $1 : ($me->popstat)[0];
297 sub _STAT { shift->command('STAT')->response() == CMD_OK }
298 sub _LIST { shift->command('LIST',@_)->response() == CMD_OK }
299 sub _RETR { shift->command('RETR',$_[0])->response() == CMD_OK }
300 sub _DELE { shift->command('DELE',$_[0])->response() == CMD_OK }
301 sub _NOOP { shift->command('NOOP')->response() == CMD_OK }
302 sub _RSET { shift->command('RSET')->response() == CMD_OK }
303 sub _QUIT { shift->command('QUIT')->response() == CMD_OK }
304 sub _TOP { shift->command('TOP', @_)->response() == CMD_OK }
305 sub _UIDL { shift->command('UIDL',@_)->response() == CMD_OK }
306 sub _USER { shift->command('USER',$_[0])->response() == CMD_OK }
307 sub _PASS { shift->command('PASS',$_[0])->response() == CMD_OK }
308 sub _APOP { shift->command('APOP',@_)->response() == CMD_OK }
309 sub _PING { shift->command('PING',$_[0])->response() == CMD_OK }
311 sub _RPOP { shift->command('RPOP',$_[0])->response() == CMD_OK }
312 sub _LAST { shift->command('LAST')->response() == CMD_OK }
326 if(defined fileno($me))
334 ## POP3 has weird responses, so we emulate them to look the same :-)
340 my $str = $cmd->getline() || return undef;
343 $cmd->debug_print(0,$str)
346 if($str =~ s/^\+OK\s*//io)
352 $str =~ s/^-ERR\s*//io;
355 ${*$cmd}{'net_cmd_resp'} = [ $str ];
356 ${*$cmd}{'net_cmd_code'} = $code;
367 Net::POP3 - Post Office Protocol 3 Client class (RFC1939)
374 $pop = Net::POP3->new('pop3host');
375 $pop = Net::POP3->new('pop3host', Timeout => 60);
377 if ($pop->login($username, $password) > 0) {
378 my $msgnums = $pop->list; # hashref of msgnum => size
379 foreach my $msgnum (keys %$msgnums) {
380 my $msg = $pop->get($msgnum);
382 $pop->delete($msgnum);
390 This module implements a client interface to the POP3 protocol, enabling
391 a perl5 application to talk to POP3 servers. This documentation assumes
392 that you are familiar with the POP3 protocol described in RFC1939.
394 A new Net::POP3 object must be created with the I<new> method. Once
395 this has been done, all POP3 commands are accessed via method calls
402 =item new ( [ HOST, ] [ OPTIONS ] )
404 This is the constructor for a new Net::POP3 object. C<HOST> is the
405 name of the remote host to which a POP3 connection is required.
407 If C<HOST> is not given, then the C<POP3_Host> specified in C<Net::Config>
410 C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
411 Possible options are:
413 B<ResvPort> - If given then the socket for the C<Net::POP3> object
414 will be bound to the local port given using C<bind> when the socket is
417 B<Timeout> - Maximum time, in seconds, to wait for a response from the
418 POP3 server (default: 120)
420 B<Debug> - Enable debugging information
426 Unless otherwise stated all methods return either a I<true> or I<false>
427 value, with I<true> meaning that the operation was a success. When a method
428 states that it returns a value, failure will be returned as I<undef> or an
435 Send the USER command.
439 Send the PASS command. Returns the number of messages in the mailbox.
441 =item login ( [ USER [, PASS ]] )
443 Send both the USER and PASS commands. If C<PASS> is not given the
444 C<Net::POP3> uses C<Net::Netrc> to lookup the password using the host
445 and username. If the username is not specified then the current user name
448 Returns the number of messages in the mailbox. However if there are no
449 messages on the server the string C<"0E0"> will be returned. This is
450 will give a true value in a boolean context, but zero in a numeric context.
452 If there was an error authenticating the user then I<undef> will be returned.
454 =item apop ( [ USER [, PASS ]] )
456 Authenticate with the server identifying as C<USER> with password C<PASS>.
457 Similar to L</login>, but the password is not sent in clear text.
459 To use this method you must have the Digest::MD5 or the MD5 module installed,
460 otherwise this method will return I<undef>.
462 =item top ( MSGNUM [, NUMLINES ] )
464 Get the header and the first C<NUMLINES> of the body for the message
465 C<MSGNUM>. Returns a reference to an array which contains the lines of text
466 read from the server.
468 =item list ( [ MSGNUM ] )
470 If called with an argument the C<list> returns the size of the message
473 If called without arguments a reference to a hash is returned. The
474 keys will be the C<MSGNUM>'s of all undeleted messages and the values will
475 be their size in octets.
477 =item get ( MSGNUM [, FH ] )
479 Get the message C<MSGNUM> from the remote mailbox. If C<FH> is not given
480 then get returns a reference to an array which contains the lines of
481 text read from the server. If C<FH> is given then the lines returned
482 from the server are printed to the filehandle C<FH>.
484 =item getfh ( MSGNUM )
486 As per get(), but returns a tied filehandle. Reading from this
487 filehandle returns the requested message. The filehandle will return
488 EOF at the end of the message and should not be reused.
492 Returns the highest C<MSGNUM> of all the messages accessed.
496 Returns a list of two elements. These are the number of undeleted
497 elements and the size of the mbox in octets.
501 Returns a list of two elements. These are the number of new messages
502 and the total number of messages for C<USER>.
504 =item uidl ( [ MSGNUM ] )
506 Returns a unique identifier for C<MSGNUM> if given. If C<MSGNUM> is not
507 given C<uidl> returns a reference to a hash where the keys are the
508 message numbers and the values are the unique identifiers.
510 =item delete ( MSGNUM )
512 Mark message C<MSGNUM> to be deleted from the remote mailbox. All messages
513 that are marked to be deleted will be removed from the remote mailbox
514 when the server connection closed.
518 Reset the status of the remote POP3 server. This includes reseting the
519 status of all messages to not be deleted.
523 Quit and close the connection to the remote POP3 server. Any messages marked
524 as deleted will be deleted from the remote mailbox.
530 If a C<Net::POP3> object goes out of scope before C<quit> method is called
531 then the C<reset> method will called before the connection is closed. This
532 means that any messages marked to be deleted will not be.
541 Graham Barr <gbarr@pobox.com>
545 Copyright (c) 1995-1997 Graham Barr. All rights reserved.
546 This program is free software; you can redistribute it and/or modify
547 it under the same terms as Perl itself.
551 I<$Id: //depot/libnet/Net/POP3.pm#24 $>