3 # Versions up to 2.24_1 Copyright (c) 1995-1997 Graham Barr <gbarr@pobox.com>.
5 # Changes in Version 2.25 onwards Copyright (C) 2013-2015 Steve Hay. All rights
7 # This module is free software; you can redistribute it and/or modify it under
8 # the same terms as Perl itself, i.e. under the terms of either the GNU General
9 # Public License or the Artistic License, as specified in the F<LICENCE> file.
24 our $VERSION = "3.08";
26 # Code for detecting if we can use SSL
27 my $ssl_class = eval {
28 require IO::Socket::SSL;
29 # first version with default CA on most platforms
30 no warnings 'numeric';
31 IO::Socket::SSL->VERSION(2.007);
32 } && 'IO::Socket::SSL';
34 my $nossl_warn = !$ssl_class &&
35 'To use SSL please install IO::Socket::SSL with version>=2.007';
37 # Code for detecting if we can use IPv6
38 my $family_key = 'Domain';
39 my $inet6_class = eval {
40 require IO::Socket::IP;
41 no warnings 'numeric';
42 IO::Socket::IP->VERSION(0.20) || die;
43 $family_key = 'Family';
44 } && 'IO::Socket::IP' || eval {
45 require IO::Socket::INET6;
46 no warnings 'numeric';
47 IO::Socket::INET6->VERSION(2.62);
48 } && 'IO::Socket::INET6';
51 sub can_ssl { $ssl_class };
52 sub can_inet6 { $inet6_class };
54 our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
59 my $type = ref($self) || $self;
67 $host = delete $arg{Host};
71 $host ||= $ENV{NNTPSERVER} || $ENV{NEWSHOST};
73 my $hosts = defined $host ? [$host] : $NetConfig{nntp_hosts};
78 my %connect = ( Proto => 'tcp');
82 die $nossl_warn if ! $ssl_class;
84 $connect{$_} = $arg{$_} for(grep { m{^SSL_} } keys %arg);
87 foreach my $o (qw(LocalAddr LocalPort Timeout)) {
88 $connect{$o} = $arg{$o} if exists $arg{$o};
90 $connect{$family_key} = $arg{Domain} || $arg{Family};
91 $connect{Timeout} = 120 unless defined $connect{Timeout};
92 $connect{PeerPort} = $arg{Port} || 'nntp(119)';
93 foreach my $h (@{$hosts}) {
94 $connect{PeerAddr} = $h;
95 $obj = $type->SUPER::new(%connect) or next;
96 ${*$obj}{'net_nntp_host'} = $h;
97 ${*$obj}{'net_nntp_arg'} = \%arg;
99 Net::NNTP::_SSL->start_SSL($obj,%arg) or next;
108 $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
110 unless ($obj->response() == CMD_OK) {
116 my @m = $obj->message;
118 unless (exists $arg{Reader} && $arg{Reader} == 0) {
120 # if server is INN and we have transfer rights the we are currently
121 # talking to innd not nnrpd
124 # If reader succeeds the we need to consider this code to determine postok
129 # I want to ignore this failure, so restore the previous status.
130 $obj->set_status($c, \@m);
134 ${*$obj}{'net_nntp_post'} = $c == 200 ? 1 : 0;
142 ${*$me}{'net_nntp_host'};
151 if ( (ref($nntp) and $nntp->code == 350 and $text =~ /^(\S+)/)
152 || ($text =~ /^(authinfo\s+pass)/io))
162 @_ == 1 or croak 'usage: $nntp->postok()';
164 ${*$nntp}{'net_nntp_post'} || 0;
170 $ssl_class or die $nossl_warn;
171 $self->_STARTTLS or return;
172 Net::NNTP::_SSL->start_SSL($self,
173 %{ ${*$self}{'net_nntp_arg'} }, # (ssl) args given in new
181 @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->article( [ MSGID ], [ FH ] )';
185 @fh = (pop) if @_ == 2 || (@_ && (ref($_[0]) || ref(\$_[0]) eq 'GLOB'));
188 ? $nntp->read_until_dot(@fh)
194 @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->articlefh( [ MSGID ] )';
197 return unless $nntp->_ARTICLE(@_);
198 return $nntp->tied_fh;
203 @_ == 3 or croak 'usage: $nntp->authinfo( USER, PASS )';
204 my ($nntp, $user, $pass) = @_;
206 $nntp->_AUTHINFO("USER", $user) == CMD_MORE
207 && $nntp->_AUTHINFO("PASS", $pass) == CMD_OK;
211 sub authinfo_simple {
212 @_ == 3 or croak 'usage: $nntp->authinfo( USER, PASS )';
213 my ($nntp, $user, $pass) = @_;
215 $nntp->_AUTHINFO('SIMPLE') == CMD_MORE
216 && $nntp->command($user, $pass)->response == CMD_OK;
221 @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->body( [ MSGID ], [ FH ] )';
225 @fh = (pop) if @_ == 2 || (@_ && ref($_[0]) || ref(\$_[0]) eq 'GLOB');
228 ? $nntp->read_until_dot(@fh)
234 @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->bodyfh( [ MSGID ] )';
236 return unless $nntp->_BODY(@_);
237 return $nntp->tied_fh;
242 @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->head( [ MSGID ], [ FH ] )';
246 @fh = (pop) if @_ == 2 || (@_ && ref($_[0]) || ref(\$_[0]) eq 'GLOB');
249 ? $nntp->read_until_dot(@fh)
255 @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->headfh( [ MSGID ] )';
257 return unless $nntp->_HEAD(@_);
258 return $nntp->tied_fh;
263 @_ == 1 || @_ == 2 or croak 'usage: $nntp->nntpstat( [ MSGID ] )';
266 $nntp->_STAT(@_) && $nntp->message =~ /(<[^>]+>)/o
273 @_ == 1 || @_ == 2 or croak 'usage: $nntp->group( [ GROUP ] )';
275 my $grp = ${*$nntp}{'net_nntp_group'};
278 unless (@_ || wantarray);
282 $newgrp = (defined($grp) and length($grp)) ? $grp : ""
283 unless defined($newgrp) and length($newgrp);
286 unless $nntp->_GROUP($newgrp) and $nntp->message =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\S+)/;
288 my ($count, $first, $last, $group) = ($1, $2, $3, $4);
290 # group may be replied as '(current group)'
291 $group = ${*$nntp}{'net_nntp_group'}
294 ${*$nntp}{'net_nntp_group'} = $group;
297 ? ($count, $first, $last, $group)
303 @_ == 1 or croak 'usage: $nntp->help()';
307 ? $nntp->read_until_dot
313 @_ >= 2 or croak 'usage: $nntp->ihave( MESSAGE-ID [, MESSAGE ])';
317 $nntp->_IHAVE($mid) && $nntp->datasend(@_)
318 ? @_ == 0 || $nntp->dataend
324 @_ == 1 or croak 'usage: $nntp->last()';
327 $nntp->_LAST && $nntp->message =~ /(<[^>]+>)/o
334 @_ == 1 or croak 'usage: $nntp->list()';
344 @_ >= 2 or croak 'usage: $nntp->newgroups( SINCE [, DISTRIBUTIONS ])';
346 my $time = _timestr(shift);
347 my $dist = shift || "";
349 $dist = join(",", @{$dist})
352 $nntp->_NEWGROUPS($time, $dist)
360 or croak 'usage: $nntp->newnews( SINCE [, GROUPS [, DISTRIBUTIONS ]])';
362 my $time = _timestr(shift);
363 my $grp = @_ ? shift: $nntp->group;
364 my $dist = shift || "";
367 $grp = join(",", @{$grp})
370 $dist = join(",", @{$dist})
373 $nntp->_NEWNEWS($grp, $time, $dist)
374 ? $nntp->_articlelist
380 @_ == 1 or croak 'usage: $nntp->next()';
383 $nntp->_NEXT && $nntp->message =~ /(<[^>]+>)/o
390 @_ >= 1 or croak 'usage: $nntp->post( [ MESSAGE ] )';
393 $nntp->_POST() && $nntp->datasend(@_)
394 ? @_ == 0 || $nntp->dataend
401 return unless $nntp->_POST();
402 return $nntp->tied_fh;
407 @_ == 1 or croak 'usage: $nntp->quit()';
416 @_ == 1 or croak 'usage: $nntp->slave()';
423 ## The following methods are not implemented by all servers
428 @_ == 1 || @_ == 2 or croak 'usage: $nntp->active( [ PATTERN ] )';
431 $nntp->_LIST('ACTIVE', @_)
438 @_ == 1 or croak 'usage: $nntp->active_times()';
441 $nntp->_LIST('ACTIVE.TIMES')
448 @_ == 1 or croak 'usage: $nntp->distributions()';
451 $nntp->_LIST('DISTRIBUTIONS')
452 ? $nntp->_description
457 sub distribution_patterns {
458 @_ == 1 or croak 'usage: $nntp->distributions()';
464 ## no critic (ControlStructures::ProhibitMutatingListFunctions)
465 $nntp->_LIST('DISTRIB.PATS')
466 && ($arr = $nntp->read_until_dot)
467 ? [grep { /^\d/ && (chomp, $_ = [split /:/]) } @$arr]
473 @_ == 1 || @_ == 2 or croak 'usage: $nntp->newsgroups( [ PATTERN ] )';
476 $nntp->_LIST('NEWSGROUPS', @_)
477 ? $nntp->_description
483 @_ == 1 or croak 'usage: $nntp->overview_fmt()';
486 $nntp->_LIST('OVERVIEW.FMT')
487 ? $nntp->_articlelist
493 @_ == 1 or croak 'usage: $nntp->subscriptions()';
496 $nntp->_LIST('SUBSCRIPTIONS')
497 ? $nntp->_articlelist
503 @_ == 1 || @_ == 2 or croak 'usage: $nntp->listgroup( [ GROUP ] )';
506 $nntp->_LISTGROUP(@_)
507 ? $nntp->_articlelist
513 @_ == 1 or croak 'usage: $nntp->reader()';
516 $nntp->_MODE('READER');
521 @_ == 1 || @_ == 2 or croak 'usage: $nntp->xgtitle( [ PATTERN ] )';
525 ? $nntp->_description
531 @_ >= 2 && @_ <= 4 or croak 'usage: $nntp->xhdr( HEADER, [ MESSAGE-SPEC ] )';
534 my $arg = _msg_arg(@_);
536 $nntp->_XHDR($hdr, $arg)
537 ? $nntp->_description
543 @_ == 2 || @_ == 3 or croak 'usage: $nntp->xover( MESSAGE-SPEC )';
545 my $arg = _msg_arg(@_);
554 @_ == 4 || @_ == 5 or croak '$nntp->xpat( HEADER, PATTERN, MESSAGE-SPEC )';
558 my $arg = _msg_arg(@_);
560 $pat = join(" ", @$pat)
563 $nntp->_XPAT($hdr, $arg, $pat)
564 ? $nntp->_description
570 @_ == 2 or croak 'usage: $nntp->xpath( MESSAGE-ID )';
571 my ($nntp, $mid) = @_;
574 unless $nntp->_XPATH($mid);
577 ($m = $nntp->message) =~ s/^\d+\s+//o;
578 my @p = split /\s+/, $m;
580 wantarray ? @p : $p[0];
585 @_ == 2 || @_ == 3 or croak 'usage: $nntp->xrover( MESSAGE-SPEC )';
587 my $arg = _msg_arg(@_);
590 ? $nntp->_description
596 @_ == 1 or croak 'usage: $nntp->date()';
600 && $nntp->message =~ /(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/
601 ? timegm($6, $5, $4, $3, $2 - 1, $1 - 1900)
607 ## Private subroutines
616 carp "Depriciated passing of two message numbers, " . "pass a reference"
618 $spec = [$spec, $_[0]];
624 if (defined $spec->[1]) {
626 if $spec->[1] != $spec->[0];
628 if $spec->[1] > $spec->[0];
642 my @g = reverse((gmtime($time))[0 .. 5]);
645 sprintf "%02d%02d%02d %02d%02d%02d GMT", @g;
651 my $arr = $nntp->read_until_dot
656 foreach my $ln (@$arr) {
657 my @a = split(/[\s\n]+/, $ln);
658 $hash->{$a[0]} = [@a[1, 2, 3]];
667 my $arr = $nntp->read_until_dot
672 foreach my $ln (@$arr) {
673 my @a = split(/[\t\n]/, $ln);
684 my $arr = $nntp->read_until_dot;
695 my $arr = $nntp->read_until_dot
700 foreach my $ln (@$arr) {
704 if $ln =~ s/^\s*(\S+)\s*//o;
716 sub _ARTICLE { shift->command('ARTICLE', @_)->response == CMD_OK }
717 sub _AUTHINFO { shift->command('AUTHINFO', @_)->response }
718 sub _BODY { shift->command('BODY', @_)->response == CMD_OK }
719 sub _DATE { shift->command('DATE')->response == CMD_INFO }
720 sub _GROUP { shift->command('GROUP', @_)->response == CMD_OK }
721 sub _HEAD { shift->command('HEAD', @_)->response == CMD_OK }
722 sub _HELP { shift->command('HELP', @_)->response == CMD_INFO }
723 sub _IHAVE { shift->command('IHAVE', @_)->response == CMD_MORE }
724 sub _LAST { shift->command('LAST')->response == CMD_OK }
725 sub _LIST { shift->command('LIST', @_)->response == CMD_OK }
726 sub _LISTGROUP { shift->command('LISTGROUP', @_)->response == CMD_OK }
727 sub _NEWGROUPS { shift->command('NEWGROUPS', @_)->response == CMD_OK }
728 sub _NEWNEWS { shift->command('NEWNEWS', @_)->response == CMD_OK }
729 sub _NEXT { shift->command('NEXT')->response == CMD_OK }
730 sub _POST { shift->command('POST', @_)->response == CMD_MORE }
731 sub _QUIT { shift->command('QUIT', @_)->response == CMD_OK }
732 sub _SLAVE { shift->command('SLAVE', @_)->response == CMD_OK }
733 sub _STARTTLS { shift->command("STARTTLS")->response() == CMD_MORE }
734 sub _STAT { shift->command('STAT', @_)->response == CMD_OK }
735 sub _MODE { shift->command('MODE', @_)->response == CMD_OK }
736 sub _XGTITLE { shift->command('XGTITLE', @_)->response == CMD_OK }
737 sub _XHDR { shift->command('XHDR', @_)->response == CMD_OK }
738 sub _XPAT { shift->command('XPAT', @_)->response == CMD_OK }
739 sub _XPATH { shift->command('XPATH', @_)->response == CMD_OK }
740 sub _XOVER { shift->command('XOVER', @_)->response == CMD_OK }
741 sub _XROVER { shift->command('XROVER', @_)->response == CMD_OK }
742 sub _XTHREAD { shift->unsupported }
743 sub _XSEARCH { shift->unsupported }
744 sub _XINDEX { shift->unsupported }
753 defined(fileno($nntp)) && $nntp->quit;
757 package Net::NNTP::_SSL;
758 our @ISA = ( $ssl_class ? ($ssl_class):(), 'Net::NNTP' );
759 sub starttls { die "NNTP connection is already in SSL mode" }
761 my ($class,$nntp,%arg) = @_;
762 delete @arg{ grep { !m{^SSL_} } keys %arg };
763 ( $arg{SSL_verifycn_name} ||= $nntp->host )
764 =~s{(?<!:):[\w()]+$}{}; # strip port
765 $arg{SSL_hostname} = $arg{SSL_verifycn_name}
766 if ! defined $arg{SSL_hostname} && $class->can_client_sni;
767 my $ok = $class->SUPER::start_SSL($nntp,
768 SSL_verifycn_scheme => 'nntp',
771 $@ = $ssl_class->errstr if !$ok;
785 Net::NNTP - NNTP Client class
791 $nntp = Net::NNTP->new("some.host.name");
794 # start with SSL, e.g. nntps
795 $nntp = Net::NNTP->new("some.host.name", SSL => 1);
797 # start with plain and upgrade to SSL
798 $nntp = Net::NNTP->new("some.host.name");
804 C<Net::NNTP> is a class implementing a simple NNTP client in Perl as described
805 in RFC977 and RFC4642.
806 With L<IO::Socket::SSL> installed it also provides support for implicit and
807 explicit TLS encryption, i.e. NNTPS or NNTP+STARTTLS.
809 The Net::NNTP class is a subclass of Net::Cmd and (depending on avaibility) of
810 IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
816 =item new ( [ HOST ] [, OPTIONS ])
818 This is the constructor for a new Net::NNTP object. C<HOST> is the
819 name of the remote host to which a NNTP connection is required. If not
820 given then it may be passed as the C<Host> option described below. If no host is passed
821 then two environment variables are checked, first C<NNTPSERVER> then
822 C<NEWSHOST>, then C<Net::Config> is checked, and if a host is not found
823 then C<news> is used.
825 C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
826 Possible options are:
828 B<Host> - NNTP host to connect to. It may be a single scalar, as defined for
829 the C<PeerAddr> option in L<IO::Socket::INET>, or a reference to
830 an array with hosts to try in turn. The L</host> method will return the value
831 which was used to connect to the host.
833 B<Port> - port to connect to.
834 Default - 119 for plain NNTP and 563 for immediate SSL (nntps).
836 B<SSL> - If the connection should be done from start with SSL, contrary to later
837 upgrade with C<starttls>.
838 You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
839 usually use the right arguments already.
841 B<Timeout> - Maximum time, in seconds, to wait for a response from the
842 NNTP server, a value of zero will cause all IO operations to block.
845 B<Debug> - Enable the printing of debugging information to STDERR
847 B<Reader> - If the remote server is INN then initially the connection
848 will be to nnrpd, by default C<Net::NNTP> will issue a C<MODE READER> command
849 so that the remote server becomes innd. If the C<Reader> option is given
850 with a value of zero, then this command will not be sent and the
851 connection will be left talking to nnrpd.
853 B<LocalAddr> and B<LocalPort> - These parameters are passed directly
854 to IO::Socket to allow binding the socket to a specific local address and port.
856 B<Domain> - This parameter is passed directly to IO::Socket and makes it
857 possible to enforce IPv4 connections even if L<IO::Socket::IP> is used as super
858 class. Alternatively B<Family> can be used.
864 Unless otherwise stated all methods return either a I<true> or I<false>
865 value, with I<true> meaning that the operation was a success. When a method
866 states that it returns a value, failure will be returned as I<undef> or an
869 C<Net::NNTP> inherits from C<Net::Cmd> so methods defined in C<Net::Cmd> may
870 be used to send commands to the remote NNTP server in addition to the methods
877 Returns the value used by the constructor, and passed to IO::Socket::INET,
878 to connect to the host.
882 Upgrade existing plain connection to SSL.
883 Any arguments necessary for SSL must be given in C<new> already.
885 =item article ( [ MSGID|MSGNUM ], [FH] )
887 Retrieve the header, a blank line, then the body (text) of the
890 If C<FH> is specified then it is expected to be a valid filehandle
891 and the result will be printed to it, on success a true value will be
892 returned. If C<FH> is not specified then the return value, on success,
893 will be a reference to an array containing the article requested, each
894 entry in the array will contain one line of the article.
896 If no arguments are passed then the current article in the currently
897 selected newsgroup is fetched.
899 C<MSGNUM> is a numeric id of an article in the current newsgroup, and
900 will change the current article pointer. C<MSGID> is the message id of
901 an article as shown in that article's header. It is anticipated that the
902 client will obtain the C<MSGID> from a list provided by the C<newnews>
903 command, from references contained within another article, or from the
904 message-id provided in the response to some other commands.
906 If there is an error then C<undef> will be returned.
908 =item body ( [ MSGID|MSGNUM ], [FH] )
910 Like C<article> but only fetches the body of the article.
912 =item head ( [ MSGID|MSGNUM ], [FH] )
914 Like C<article> but only fetches the headers for the article.
916 =item articlefh ( [ MSGID|MSGNUM ] )
918 =item bodyfh ( [ MSGID|MSGNUM ] )
920 =item headfh ( [ MSGID|MSGNUM ] )
922 These are similar to article(), body() and head(), but rather than
923 returning the requested data directly, they return a tied filehandle
924 from which to read the article.
926 =item nntpstat ( [ MSGID|MSGNUM ] )
928 The C<nntpstat> command is similar to the C<article> command except that no
929 text is returned. When selecting by message number within a group,
930 the C<nntpstat> command serves to set the "current article pointer" without
933 Using the C<nntpstat> command to
934 select by message-id is valid but of questionable value, since a
935 selection by message-id does B<not> alter the "current article pointer".
937 Returns the message-id of the "current article".
939 =item group ( [ GROUP ] )
941 Set and/or get the current group. If C<GROUP> is not given then information
942 is returned on the current group.
944 In a scalar context it returns the group name.
946 In an array context the return value is a list containing, the number
947 of articles in the group, the number of the first article, the number
948 of the last article and the group name.
952 Request help text (a short summary of commands that are understood by this
953 implementation) from the server. Returns the text or undef upon failure.
955 =item ihave ( MSGID [, MESSAGE ])
957 The C<ihave> command informs the server that the client has an article
958 whose id is C<MSGID>. If the server desires a copy of that
959 article and C<MESSAGE> has been given then it will be sent.
961 Returns I<true> if the server desires the article and C<MESSAGE> was
962 successfully sent, if specified.
964 If C<MESSAGE> is not specified then the message must be sent using the
965 C<datasend> and C<dataend> methods from L<Net::Cmd>
967 C<MESSAGE> can be either an array of lines or a reference to an array
968 and must be encoded by the caller to octets of whatever encoding is required,
969 e.g. by using the Encode module's C<encode()> function.
973 Set the "current article pointer" to the previous article in the current
976 Returns the message-id of the article.
980 Returns the date on the remote server. This date will be in a UNIX time
981 format (seconds since 1970)
985 C<postok> will return I<true> if the servers initial response indicated
986 that it will allow posting.
988 =item authinfo ( USER, PASS )
990 Authenticates to the server (using the original AUTHINFO USER / AUTHINFO PASS
991 form, defined in RFC2980) using the supplied username and password. Please
992 note that the password is sent in clear text to the server. This command
993 should not be used with valuable passwords unless the connection to the server
994 is somehow protected.
996 =item authinfo_simple ( USER, PASS )
998 Authenticates to the server (using the proposed NNTP V2 AUTHINFO SIMPLE form,
999 defined and deprecated in RFC2980) using the supplied username and password.
1000 As with L</authinfo> the password is sent in clear text.
1004 Obtain information about all the active newsgroups. The results is a reference
1005 to a hash where the key is a group name and each value is a reference to an
1006 array. The elements in this array are:- the last article number in the group,
1007 the first article number in the group and any information flags about the group.
1009 =item newgroups ( SINCE [, DISTRIBUTIONS ])
1011 C<SINCE> is a time value and C<DISTRIBUTIONS> is either a distribution
1012 pattern or a reference to a list of distribution patterns.
1013 The result is the same as C<list>, but the
1014 groups return will be limited to those created after C<SINCE> and, if
1015 specified, in one of the distribution areas in C<DISTRIBUTIONS>.
1017 =item newnews ( SINCE [, GROUPS [, DISTRIBUTIONS ]])
1019 C<SINCE> is a time value. C<GROUPS> is either a group pattern or a reference
1020 to a list of group patterns. C<DISTRIBUTIONS> is either a distribution
1021 pattern or a reference to a list of distribution patterns.
1023 Returns a reference to a list which contains the message-ids of all news posted
1024 after C<SINCE>, that are in a groups which matched C<GROUPS> and a
1025 distribution which matches C<DISTRIBUTIONS>.
1029 Set the "current article pointer" to the next article in the current
1032 Returns the message-id of the article.
1034 =item post ( [ MESSAGE ] )
1036 Post a new article to the news server. If C<MESSAGE> is specified and posting
1037 is allowed then the message will be sent.
1039 If C<MESSAGE> is not specified then the message must be sent using the
1040 C<datasend> and C<dataend> methods from L<Net::Cmd>
1042 C<MESSAGE> can be either an array of lines or a reference to an array
1043 and must be encoded by the caller to octets of whatever encoding is required,
1044 e.g. by using the Encode module's C<encode()> function.
1046 The message, either sent via C<datasend> or as the C<MESSAGE>
1047 parameter, must be in the format as described by RFC822 and must
1048 contain From:, Newsgroups: and Subject: headers.
1052 Post a new article to the news server using a tied filehandle. If
1053 posting is allowed, this method will return a tied filehandle that you
1054 can print() the contents of the article to be posted. You must
1055 explicitly close() the filehandle when you are finished posting the
1056 article, and the return value from the close() call will indicate
1057 whether the message was successfully posted.
1061 Tell the remote server that I am not a user client, but probably another
1066 Quit the remote server and close the socket connection.
1070 Returns whether we can use IPv6.
1074 Returns whether we can use SSL.
1078 =head2 Extension methods
1080 These methods use commands that are not part of the RFC977 documentation. Some
1081 servers may not support all of them.
1085 =item newsgroups ( [ PATTERN ] )
1087 Returns a reference to a hash where the keys are all the group names which
1088 match C<PATTERN>, or all of the groups if no pattern is specified, and
1089 each value contains the description text for the group.
1091 =item distributions ()
1093 Returns a reference to a hash where the keys are all the possible
1094 distribution names and the values are the distribution descriptions.
1096 =item distribution_patterns ()
1098 Returns a reference to an array where each element, itself an array
1099 reference, consists of the three fields of a line of the distrib.pats list
1100 maintained by some NNTP servers, namely: a weight, a wildmat and a value
1101 which the client may use to construct a Distribution header.
1103 =item subscriptions ()
1105 Returns a reference to a list which contains a list of groups which
1106 are recommended for a new user to subscribe to.
1108 =item overview_fmt ()
1110 Returns a reference to an array which contain the names of the fields returned
1113 =item active_times ()
1115 Returns a reference to a hash where the keys are the group names and each
1116 value is a reference to an array containing the time the groups was created
1117 and an identifier, possibly an Email address, of the creator.
1119 =item active ( [ PATTERN ] )
1121 Similar to C<list> but only active groups that match the pattern are returned.
1122 C<PATTERN> can be a group pattern.
1124 =item xgtitle ( PATTERN )
1126 Returns a reference to a hash where the keys are all the group names which
1127 match C<PATTERN> and each value is the description text for the group.
1129 =item xhdr ( HEADER, MESSAGE-SPEC )
1131 Obtain the header field C<HEADER> for all the messages specified.
1133 The return value will be a reference
1134 to a hash where the keys are the message numbers and each value contains
1135 the text of the requested header for that message.
1137 =item xover ( MESSAGE-SPEC )
1139 The return value will be a reference
1140 to a hash where the keys are the message numbers and each value contains
1141 a reference to an array which contains the overview fields for that
1144 The names of the fields can be obtained by calling C<overview_fmt>.
1146 =item xpath ( MESSAGE-ID )
1148 Returns the path name to the file on the server which contains the specified
1151 =item xpat ( HEADER, PATTERN, MESSAGE-SPEC)
1153 The result is the same as C<xhdr> except the is will be restricted to
1154 headers where the text of the header matches C<PATTERN>
1158 The XROVER command returns reference information for the article(s)
1161 Returns a reference to a HASH where the keys are the message numbers and the
1162 values are the References: lines from the articles
1164 =item listgroup ( [ GROUP ] )
1166 Returns a reference to a list of all the active messages in C<GROUP>, or
1167 the current group if C<GROUP> is not specified.
1171 Tell the server that you are a reader and not another server.
1173 This is required by some servers. For example if you are connecting to
1174 an INN server and you have transfer permission your connection will
1175 be connected to the transfer daemon, not the NNTP daemon. Issuing
1176 this command will cause the transfer daemon to hand over control
1179 Some servers do not understand this command, but issuing it and ignoring
1180 the response is harmless.
1186 The following NNTP command are unsupported by the package, and there are
1200 C<MESSAGE-SPEC> is either a single message-id, a single message number, or
1201 a reference to a list of two message numbers.
1203 If C<MESSAGE-SPEC> is a reference to a list of two message numbers and the
1204 second number in a range is less than or equal to the first then the range
1205 represents all messages in the group after the first message number.
1207 B<NOTE> For compatibility reasons only with earlier versions of Net::NNTP
1208 a message spec can be passed as a list of two numbers, this is deprecated
1209 and a reference to the list should now be passed
1213 The C<NNTP> protocol uses the C<WILDMAT> format for patterns.
1214 The WILDMAT format was first developed by Rich Salz based on
1215 the format used in the UNIX "find" command to articulate
1216 file names. It was developed to provide a uniform mechanism
1217 for matching patterns in the same manner that the UNIX shell
1220 Patterns are implicitly anchored at the
1221 beginning and end of each string when testing for a match.
1223 There are five pattern matching operations other than a strict
1224 one-to-one match between the pattern and the source to be
1225 checked for a match.
1227 The first is an asterisk C<*> to match any sequence of zero or more
1230 The second is a question mark C<?> to match any single character. The
1231 third specifies a specific set of characters.
1233 The set is specified as a list of characters, or as a range of characters
1234 where the beginning and end of the range are separated by a minus (or dash)
1235 character, or as any combination of lists and ranges. The dash can
1236 also be included in the set as a character it if is the beginning
1237 or end of the set. This set is enclosed in square brackets. The
1238 close square bracket C<]> may be used in a set if it is the first
1239 character in the set.
1241 The fourth operation is the same as the
1242 logical not of the third operation and is specified the same
1243 way as the third with the addition of a caret character C<^> at
1244 the beginning of the test string just inside the open square
1247 The final operation uses the backslash character to
1248 invalidate the special meaning of an open square bracket C<[>,
1249 the asterisk, backslash or the question mark. Two backslashes in
1250 sequence will result in the evaluation of the backslash as a
1251 character with no special meaning.
1259 matches any single character other than a close square
1260 bracket or a minus sign/dash.
1264 matches any string that ends with the string "bdc"
1265 including the string "bdc" (without quotes).
1267 =item C<[0-9a-zA-Z]>
1269 matches any single printable alphanumeric ASCII character.
1273 matches any four character string which begins
1274 with a and ends with d.
1287 Graham Barr E<lt>F<gbarr@pobox.com>E<gt>
1289 Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
1294 Versions up to 2.24_1 Copyright (c) 1995-1997 Graham Barr. All rights reserved.
1295 Changes in Version 2.25 onwards Copyright (C) 2013-2015 Steve Hay. All rights
1298 This module is free software; you can redistribute it and/or modify it under the
1299 same terms as Perl itself, i.e. under the terms of either the GNU General Public
1300 License or the Artistic License, as specified in the F<LICENCE> file.