Update libnet to CPAN version 3.01
[perl.git] / cpan / libnet / lib / Net / POP3.pm
1 # Net::POP3.pm
2 #
3 # Versions up to 2.29 Copyright (c) 1995-2004 Graham Barr <gbarr@pobox.com>.
4 # All rights reserved.
5 # Changes in Version 2.29_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
6 # rights reserved.
7 # This program is free software; you can redistribute it and/or
8 # modify it under the same terms as Perl itself.
9
10 package Net::POP3;
11
12 use 5.008001;
13
14 use strict;
15 use warnings;
16
17 use Carp;
18 use IO::Socket;
19 use Net::Cmd;
20 use Net::Config;
21
22 our $VERSION = "3.01";
23
24 # Code for detecting if we can use SSL
25 my $ssl_class = eval {
26   require IO::Socket::SSL;
27   # first version with default CA on most platforms
28   IO::Socket::SSL->VERSION(1.999);
29 } && 'IO::Socket::SSL';
30
31 my $nossl_warn = !$ssl_class &&
32   'To use SSL please install IO::Socket::SSL with version>=1.999';
33
34 # Code for detecting if we can use IPv6
35 my $inet6_class = eval {
36   require IO::Socket::IP;
37   IO::Socket::IP->VERSION(0.20);
38 } && 'IO::Socket::IP' || eval {
39   require IO::Socket::INET6;
40   IO::Socket::INET6->VERSION(2.62);
41 } && 'IO::Socket::INET6';
42
43 sub can_ssl   { $ssl_class };
44 sub can_inet6 { $inet6_class };
45
46 our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
47
48 sub new {
49   my $self = shift;
50   my $type = ref($self) || $self;
51   my ($host, %arg);
52   if (@_ % 2) {
53     $host = shift;
54     %arg  = @_;
55   }
56   else {
57     %arg  = @_;
58     $host = delete $arg{Host};
59   }
60   my $hosts = defined $host ? [$host] : $NetConfig{pop3_hosts};
61   my $obj;
62   my @localport = exists $arg{ResvPort} ? (LocalPort => $arg{ResvPort}) : ();
63
64   if ($arg{SSL}) {
65     # SSL from start
66     die $nossl_warn if !$ssl_class;
67     $arg{Port} ||= 995;
68   }
69
70   $arg{Timeout} = 120 if ! defined $arg{Timeout};
71
72   foreach my $h (@{$hosts}) {
73     $obj = $type->SUPER::new(
74       PeerAddr => ($host = $h),
75       PeerPort => $arg{Port} || 'pop3(110)',
76       Proto => 'tcp',
77       @localport,
78       Timeout => $arg{Timeout},
79       )
80       and last;
81   }
82
83   return
84     unless defined $obj;
85
86   ${*$obj}{'net_pop3_arg'} = \%arg;
87   if ($arg{SSL}) {
88     Net::POP3::_SSL->start_SSL($obj,
89       SSL_verifycn_name => $host,%arg
90     ) or return;
91   }
92
93   ${*$obj}{'net_pop3_host'} = $host;
94
95   $obj->autoflush(1);
96   $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
97
98   unless ($obj->response() == CMD_OK) {
99     $obj->close();
100     return;
101   }
102
103   ${*$obj}{'net_pop3_banner'} = $obj->message;
104
105   $obj;
106 }
107
108
109 sub host {
110   my $me = shift;
111   ${*$me}{'net_pop3_host'};
112 }
113
114 ##
115 ## We don't want people sending me their passwords when they report problems
116 ## now do we :-)
117 ##
118
119
120 sub debug_text { $_[2] =~ /^(pass|rpop)/i ? "$1 ....\n" : $_[2]; }
121
122
123 sub login {
124   @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->login( USER, PASS )';
125   my ($me, $user, $pass) = @_;
126
127   if (@_ <= 2) {
128     ($user, $pass) = $me->_lookup_credentials($user);
129   }
130
131   $me->user($user)
132     and $me->pass($pass);
133 }
134
135 sub starttls {
136   my $self = shift;
137   $ssl_class or die $nossl_warn;
138   $self->_STLS or return;
139   Net::POP3::_SSL->start_SSL($self,
140     %{ ${*$self}{'net_pop3_arg'} }, # (ssl) args given in new
141     @_   # more (ssl) args
142   ) or return;
143   return 1;
144 }
145
146 sub apop {
147   @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->apop( USER, PASS )';
148   my ($me, $user, $pass) = @_;
149   my $banner;
150   my $md;
151
152   if (eval { local $SIG{__DIE__}; require Digest::MD5 }) {
153     $md = Digest::MD5->new();
154   }
155   elsif (eval { local $SIG{__DIE__}; require MD5 }) {
156     $md = MD5->new();
157   }
158   else {
159     carp "You need to install Digest::MD5 or MD5 to use the APOP command";
160     return;
161   }
162
163   return
164     unless ($banner = (${*$me}{'net_pop3_banner'} =~ /(<.*>)/)[0]);
165
166   if (@_ <= 2) {
167     ($user, $pass) = $me->_lookup_credentials($user);
168   }
169
170   $md->add($banner, $pass);
171
172   return
173     unless ($me->_APOP($user, $md->hexdigest));
174
175   $me->_get_mailbox_count();
176 }
177
178
179 sub user {
180   @_ == 2 or croak 'usage: $pop3->user( USER )';
181   $_[0]->_USER($_[1]) ? 1 : undef;
182 }
183
184
185 sub pass {
186   @_ == 2 or croak 'usage: $pop3->pass( PASS )';
187
188   my ($me, $pass) = @_;
189
190   return
191     unless ($me->_PASS($pass));
192
193   $me->_get_mailbox_count();
194 }
195
196
197 sub reset {
198   @_ == 1 or croak 'usage: $obj->reset()';
199
200   my $me = shift;
201
202   return 0
203     unless ($me->_RSET);
204
205   if (defined ${*$me}{'net_pop3_mail'}) {
206     local $_;
207     foreach (@{${*$me}{'net_pop3_mail'}}) {
208       delete $_->{'net_pop3_deleted'};
209     }
210   }
211 }
212
213
214 sub last {
215   @_ == 1 or croak 'usage: $obj->last()';
216
217   return
218     unless $_[0]->_LAST && $_[0]->message =~ /(\d+)/;
219
220   return $1;
221 }
222
223
224 sub top {
225   @_ == 2 || @_ == 3 or croak 'usage: $pop3->top( MSGNUM [, NUMLINES ])';
226   my $me = shift;
227
228   return
229     unless $me->_TOP($_[0], $_[1] || 0);
230
231   $me->read_until_dot;
232 }
233
234
235 sub popstat {
236   @_ == 1 or croak 'usage: $pop3->popstat()';
237   my $me = shift;
238
239   return ()
240     unless $me->_STAT && $me->message =~ /(\d+)\D+(\d+)/;
241
242   ($1 || 0, $2 || 0);
243 }
244
245
246 sub list {
247   @_ == 1 || @_ == 2 or croak 'usage: $pop3->list( [ MSGNUM ] )';
248   my $me = shift;
249
250   return
251     unless $me->_LIST(@_);
252
253   if (@_) {
254     $me->message =~ /\d+\D+(\d+)/;
255     return $1 || undef;
256   }
257
258   my $info = $me->read_until_dot
259     or return;
260
261   my %hash = map { (/(\d+)\D+(\d+)/) } @$info;
262
263   return \%hash;
264 }
265
266
267 sub get {
268   @_ == 2 or @_ == 3 or croak 'usage: $pop3->get( MSGNUM [, FH ])';
269   my $me = shift;
270
271   return
272     unless $me->_RETR(shift);
273
274   $me->read_until_dot(@_);
275 }
276
277
278 sub getfh {
279   @_ == 2 or croak 'usage: $pop3->getfh( MSGNUM )';
280   my $me = shift;
281
282   return unless $me->_RETR(shift);
283   return $me->tied_fh;
284 }
285
286
287 sub delete {
288   @_ == 2 or croak 'usage: $pop3->delete( MSGNUM )';
289   my $me = shift;
290   return 0 unless $me->_DELE(@_);
291   ${*$me}{'net_pop3_deleted'} = 1;
292 }
293
294
295 sub uidl {
296   @_ == 1 || @_ == 2 or croak 'usage: $pop3->uidl( [ MSGNUM ] )';
297   my $me = shift;
298   my $uidl;
299
300   $me->_UIDL(@_)
301     or return;
302   if (@_) {
303     $uidl = ($me->message =~ /\d+\s+([\041-\176]+)/)[0];
304   }
305   else {
306     my $ref = $me->read_until_dot
307       or return;
308     $uidl = {};
309     foreach my $ln (@$ref) {
310       my ($msg, $uid) = $ln =~ /^\s*(\d+)\s+([\041-\176]+)/;
311       $uidl->{$msg} = $uid;
312     }
313   }
314   return $uidl;
315 }
316
317
318 sub ping {
319   @_ == 2 or croak 'usage: $pop3->ping( USER )';
320   my $me = shift;
321
322   return () unless $me->_PING(@_) && $me->message =~ /(\d+)\D+(\d+)/;
323
324   ($1 || 0, $2 || 0);
325 }
326
327
328 sub _lookup_credentials {
329   my ($me, $user) = @_;
330
331   require Net::Netrc;
332
333        $user ||= eval { local $SIG{__DIE__}; (getpwuid($>))[0] }
334     || $ENV{NAME}
335     || $ENV{USER}
336     || $ENV{LOGNAME};
337
338   my $m = Net::Netrc->lookup(${*$me}{'net_pop3_host'}, $user);
339   $m ||= Net::Netrc->lookup(${*$me}{'net_pop3_host'});
340
341   my $pass = $m
342     ? $m->password || ""
343     : "";
344
345   ($user, $pass);
346 }
347
348
349 sub _get_mailbox_count {
350   my ($me) = @_;
351   my $ret = ${*$me}{'net_pop3_count'} =
352     ($me->message =~ /(\d+)\s+message/io) ? $1 : ($me->popstat)[0];
353
354   $ret ? $ret : "0E0";
355 }
356
357
358 sub _STAT { shift->command('STAT'       )->response() == CMD_OK }
359 sub _LIST { shift->command('LIST',    @_)->response() == CMD_OK }
360 sub _RETR { shift->command('RETR', $_[0])->response() == CMD_OK }
361 sub _DELE { shift->command('DELE', $_[0])->response() == CMD_OK }
362 sub _NOOP { shift->command('NOOP'       )->response() == CMD_OK }
363 sub _RSET { shift->command('RSET'       )->response() == CMD_OK }
364 sub _QUIT { shift->command('QUIT'       )->response() == CMD_OK }
365 sub _TOP  { shift->command( 'TOP',    @_)->response() == CMD_OK }
366 sub _UIDL { shift->command('UIDL',    @_)->response() == CMD_OK }
367 sub _USER { shift->command('USER', $_[0])->response() == CMD_OK }
368 sub _PASS { shift->command('PASS', $_[0])->response() == CMD_OK }
369 sub _APOP { shift->command('APOP',    @_)->response() == CMD_OK }
370 sub _PING { shift->command('PING', $_[0])->response() == CMD_OK }
371 sub _RPOP { shift->command('RPOP', $_[0])->response() == CMD_OK }
372 sub _LAST { shift->command('LAST'       )->response() == CMD_OK }
373 sub _CAPA { shift->command('CAPA'       )->response() == CMD_OK }
374 sub _STLS { shift->command("STLS",     )->response() == CMD_OK }
375
376
377 sub quit {
378   my $me = shift;
379
380   $me->_QUIT;
381   $me->close;
382 }
383
384
385 sub DESTROY {
386   my $me = shift;
387
388   if (defined fileno($me) and ${*$me}{'net_pop3_deleted'}) {
389     $me->reset;
390     $me->quit;
391   }
392 }
393
394 ##
395 ## POP3 has weird responses, so we emulate them to look the same :-)
396 ##
397
398
399 sub response {
400   my $cmd  = shift;
401   my $str  = $cmd->getline() or return;
402   my $code = "500";
403
404   $cmd->debug_print(0, $str)
405     if ($cmd->debug);
406
407   if ($str =~ s/^\+OK\s*//io) {
408     $code = "200";
409   }
410   elsif ($str =~ s/^\+\s*//io) {
411     $code = "300";
412   }
413   else {
414     $str =~ s/^-ERR\s*//io;
415   }
416
417   ${*$cmd}{'net_cmd_resp'} = [$str];
418   ${*$cmd}{'net_cmd_code'} = $code;
419
420   substr($code, 0, 1);
421 }
422
423
424 sub capa {
425   my $this = shift;
426   my ($capa, %capabilities);
427
428   # Fake a capability here
429   $capabilities{APOP} = '' if ($this->banner() =~ /<.*>/);
430
431   if ($this->_CAPA()) {
432     $capabilities{CAPA} = 1;
433     $capa = $this->read_until_dot();
434     %capabilities = (%capabilities, map {/^\s*(\S+)\s*(.*)/} @$capa);
435   }
436   else {
437
438     # Check AUTH for SASL capabilities
439     if ($this->command('AUTH')->response() == CMD_OK) {
440       my $mechanism = $this->read_until_dot();
441       $capabilities{SASL} = join " ", map {m/([A-Z0-9_-]+)/} @{$mechanism};
442     }
443   }
444
445   return ${*$this}{'net_pop3e_capabilities'} = \%capabilities;
446 }
447
448
449 sub capabilities {
450   my $this = shift;
451
452   ${*$this}{'net_pop3e_capabilities'} || $this->capa;
453 }
454
455
456 sub auth {
457   my ($self, $username, $password) = @_;
458
459   eval {
460     require MIME::Base64;
461     require Authen::SASL;
462   } or $self->set_status(500, ["Need MIME::Base64 and Authen::SASL todo auth"]), return 0;
463
464   my $capa       = $self->capa;
465   my $mechanisms = $capa->{SASL} || 'CRAM-MD5';
466
467   my $sasl;
468
469   if (ref($username) and UNIVERSAL::isa($username, 'Authen::SASL')) {
470     $sasl = $username;
471     my $user_mech = $sasl->mechanism || '';
472     my @user_mech = split(/\s+/, $user_mech);
473     my %user_mech;
474     @user_mech{@user_mech} = ();
475
476     my @server_mech = split(/\s+/, $mechanisms);
477     my @mech = @user_mech
478       ? grep { exists $user_mech{$_} } @server_mech
479       : @server_mech;
480     unless (@mech) {
481       $self->set_status(
482         500,
483         [ 'Client SASL mechanisms (',
484           join(', ', @user_mech),
485           ') do not match the SASL mechnism the server announces (',
486           join(', ', @server_mech), ')',
487         ]
488       );
489       return 0;
490     }
491
492     $sasl->mechanism(join(" ", @mech));
493   }
494   else {
495     die "auth(username, password)" if not length $username;
496     $sasl = Authen::SASL->new(
497       mechanism => $mechanisms,
498       callback  => {
499         user     => $username,
500         pass     => $password,
501         authname => $username,
502       }
503     );
504   }
505
506   # We should probably allow the user to pass the host, but I don't
507   # currently know and SASL mechanisms that are used by smtp that need it
508   my ($hostname) = split /:/, ${*$self}{'net_pop3_host'};
509   my $client = eval { $sasl->client_new('pop', $hostname, 0) };
510
511   unless ($client) {
512     my $mech = $sasl->mechanism;
513     $self->set_status(
514       500,
515       [ " Authen::SASL failure: $@",
516         '(please check if your local Authen::SASL installation',
517         "supports mechanism '$mech'"
518       ]
519     );
520     return 0;
521   }
522
523   my ($token) = $client->client_start
524     or do {
525     my $mech = $client->mechanism;
526     $self->set_status(
527       500,
528       [ ' Authen::SASL failure:  $client->client_start ',
529         "mechanism '$mech' hostname #$hostname#",
530         $client->error
531       ]
532     );
533     return 0;
534     };
535
536   # We don't support sasl mechanisms that encrypt the socket traffic.
537   # todo that we would really need to change the ISA hierarchy
538   # so we don't inherit from IO::Socket, but instead hold it in an attribute
539
540   my @cmd = ("AUTH", $client->mechanism);
541   my $code;
542
543   push @cmd, MIME::Base64::encode_base64($token, '')
544     if defined $token and length $token;
545
546   while (($code = $self->command(@cmd)->response()) == CMD_MORE) {
547
548     my ($token) = $client->client_step(MIME::Base64::decode_base64(($self->message)[0])) or do {
549       $self->set_status(
550         500,
551         [ ' Authen::SASL failure:  $client->client_step ',
552           "mechanism '", $client->mechanism, " hostname #$hostname#, ",
553           $client->error
554         ]
555       );
556       return 0;
557     };
558
559     @cmd = (MIME::Base64::encode_base64(defined $token ? $token : '', ''));
560   }
561
562   $code == CMD_OK;
563 }
564
565
566 sub banner {
567   my $this = shift;
568
569   return ${*$this}{'net_pop3_banner'};
570 }
571
572 {
573   package Net::POP3::_SSL;
574   our @ISA = ( $ssl_class ? ($ssl_class):(), 'Net::POP3' );
575   sub starttls { die "POP3 connection is already in SSL mode" }
576   sub start_SSL {
577     my ($class,$pop3,%arg) = @_;
578     delete @arg{ grep { !m{^SSL_} } keys %arg };
579     ( $arg{SSL_verifycn_name} ||= $pop3->host )
580         =~s{(?<!:):[\w()]+$}{}; # strip port
581     $arg{SSL_verifycn_scheme} ||= 'pop3';
582     my $ok = $class->SUPER::start_SSL($pop3,%arg);
583     $@ = $ssl_class->errstr if !$ok;
584     return $ok;
585   }
586 }
587
588
589
590 1;
591
592 __END__
593
594 =head1 NAME
595
596 Net::POP3 - Post Office Protocol 3 Client class (RFC1939)
597
598 =head1 SYNOPSIS
599
600     use Net::POP3;
601
602     # Constructors
603     $pop = Net::POP3->new('pop3host');
604     $pop = Net::POP3->new('pop3host', Timeout => 60);
605     $pop = Net::POP3->new('pop3host', SSL => 1, Timeout => 60);
606
607     if ($pop->login($username, $password) > 0) {
608       my $msgnums = $pop->list; # hashref of msgnum => size
609       foreach my $msgnum (keys %$msgnums) {
610         my $msg = $pop->get($msgnum);
611         print @$msg;
612         $pop->delete($msgnum);
613       }
614     }
615
616     $pop->quit;
617
618 =head1 DESCRIPTION
619
620 This module implements a client interface to the POP3 protocol, enabling
621 a perl5 application to talk to POP3 servers. This documentation assumes
622 that you are familiar with the POP3 protocol described in RFC1939.
623
624 A new Net::POP3 object must be created with the I<new> method. Once
625 this has been done, all POP3 commands are accessed via method calls
626 on the object.
627
628 The Net::POP3 class is a subclass of Net::Cmd and IO::Socket::INET.
629
630 =head1 CONSTRUCTOR
631
632 =over 4
633
634 =item new ( [ HOST ] [, OPTIONS ] )
635
636 This is the constructor for a new Net::POP3 object. C<HOST> is the
637 name of the remote host to which an POP3 connection is required.
638
639 C<HOST> is optional. If C<HOST> is not given then it may instead be
640 passed as the C<Host> option described below. If neither is given then
641 the C<POP3_Hosts> specified in C<Net::Config> will be used.
642
643 C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
644 Possible options are:
645
646 B<Host> - POP3 host to connect to. It may be a single scalar, as defined for
647 the C<PeerAddr> option in L<IO::Socket::INET>, or a reference to
648 an array with hosts to try in turn. The L</host> method will return the value
649 which was used to connect to the host.
650
651 B<Port> - port to connect to.
652 Default - 110 for plain POP3 and 995 for POP3s (direct SSL).
653
654 B<SSL> - If the connection should be done from start with SSL, contrary to later
655 upgrade with C<starttls>.
656 You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
657 usually use the right arguments already.
658
659 B<ResvPort> - If given then the socket for the C<Net::POP3> object
660 will be bound to the local port given using C<bind> when the socket is
661 created.
662
663 B<Timeout> - Maximum time, in seconds, to wait for a response from the
664 POP3 server (default: 120)
665
666 B<Debug> - Enable debugging information
667
668 =back
669
670 =head1 METHODS
671
672 Unless otherwise stated all methods return either a I<true> or I<false>
673 value, with I<true> meaning that the operation was a success. When a method
674 states that it returns a value, failure will be returned as I<undef> or an
675 empty list.
676
677 C<Net::POP3> inherits from C<Net::Cmd> so methods defined in C<Net::Cmd> may
678 be used to send commands to the remote POP3 server in addition to the methods
679 documented here.
680
681 =over 4
682
683 =item host ()
684
685 Returns the value used by the constructor, and passed to IO::Socket::INET,
686 to connect to the host.
687
688 =item auth ( USERNAME, PASSWORD )
689
690 Attempt SASL authentication.
691
692 =item user ( USER )
693
694 Send the USER command.
695
696 =item pass ( PASS )
697
698 Send the PASS command. Returns the number of messages in the mailbox.
699
700 =item login ( [ USER [, PASS ]] )
701
702 Send both the USER and PASS commands. If C<PASS> is not given the
703 C<Net::POP3> uses C<Net::Netrc> to lookup the password using the host
704 and username. If the username is not specified then the current user name
705 will be used.
706
707 Returns the number of messages in the mailbox. However if there are no
708 messages on the server the string C<"0E0"> will be returned. This is
709 will give a true value in a boolean context, but zero in a numeric context.
710
711 If there was an error authenticating the user then I<undef> will be returned.
712
713 =item starttls ( SSLARGS )
714
715 Upgrade existing plain connection to SSL.
716 You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
717 usually use the right arguments already.
718
719 =item apop ( [ USER [, PASS ]] )
720
721 Authenticate with the server identifying as C<USER> with password C<PASS>.
722 Similar to L</login>, but the password is not sent in clear text.
723
724 To use this method you must have the Digest::MD5 or the MD5 module installed,
725 otherwise this method will return I<undef>.
726
727 =item banner ()
728
729 Return the sever's connection banner
730
731 =item capa ()
732
733 Return a reference to a hash of the capabilities of the server.  APOP
734 is added as a pseudo capability.  Note that I've been unable to
735 find a list of the standard capability values, and some appear to
736 be multi-word and some are not.  We make an attempt at intelligently
737 parsing them, but it may not be correct.
738
739 =item  capabilities ()
740
741 Just like capa, but only uses a cache from the last time we asked
742 the server, so as to avoid asking more than once.
743
744 =item top ( MSGNUM [, NUMLINES ] )
745
746 Get the header and the first C<NUMLINES> of the body for the message
747 C<MSGNUM>. Returns a reference to an array which contains the lines of text
748 read from the server.
749
750 =item list ( [ MSGNUM ] )
751
752 If called with an argument the C<list> returns the size of the message
753 in octets.
754
755 If called without arguments a reference to a hash is returned. The
756 keys will be the C<MSGNUM>'s of all undeleted messages and the values will
757 be their size in octets.
758
759 =item get ( MSGNUM [, FH ] )
760
761 Get the message C<MSGNUM> from the remote mailbox. If C<FH> is not given
762 then get returns a reference to an array which contains the lines of
763 text read from the server. If C<FH> is given then the lines returned
764 from the server are printed to the filehandle C<FH>.
765
766 =item getfh ( MSGNUM )
767
768 As per get(), but returns a tied filehandle.  Reading from this
769 filehandle returns the requested message.  The filehandle will return
770 EOF at the end of the message and should not be reused.
771
772 =item last ()
773
774 Returns the highest C<MSGNUM> of all the messages accessed.
775
776 =item popstat ()
777
778 Returns a list of two elements. These are the number of undeleted
779 elements and the size of the mbox in octets.
780
781 =item ping ( USER )
782
783 Returns a list of two elements. These are the number of new messages
784 and the total number of messages for C<USER>.
785
786 =item uidl ( [ MSGNUM ] )
787
788 Returns a unique identifier for C<MSGNUM> if given. If C<MSGNUM> is not
789 given C<uidl> returns a reference to a hash where the keys are the
790 message numbers and the values are the unique identifiers.
791
792 =item delete ( MSGNUM )
793
794 Mark message C<MSGNUM> to be deleted from the remote mailbox. All messages
795 that are marked to be deleted will be removed from the remote mailbox
796 when the server connection closed.
797
798 =item reset ()
799
800 Reset the status of the remote POP3 server. This includes resetting the
801 status of all messages to not be deleted.
802
803 =item quit ()
804
805 Quit and close the connection to the remote POP3 server. Any messages marked
806 as deleted will be deleted from the remote mailbox.
807
808 =item can_inet6 ()
809
810 Returns whether we can use IPv6.
811
812 =item can_ssl ()
813
814 Returns whether we can use SSL.
815
816 =back
817
818 =head1 NOTES
819
820 If a C<Net::POP3> object goes out of scope before C<quit> method is called
821 then the C<reset> method will called before the connection is closed. This
822 means that any messages marked to be deleted will not be.
823
824 =head1 SEE ALSO
825
826 L<Net::Netrc>,
827 L<Net::Cmd>,
828 L<IO::Socket::SSL>
829
830 =head1 AUTHOR
831
832 Graham Barr E<lt>F<gbarr@pobox.com>E<gt>
833
834 Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
835 1.22_02
836
837 =head1 COPYRIGHT
838
839 Versions up to 2.29 Copyright (c) 1995-2004 Graham Barr. All rights reserved.
840 Changes in Version 2.29_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
841 rights reserved.
842
843 This program is free software; you can redistribute it and/or modify
844 it under the same terms as Perl itself.
845
846 =cut