3 # Copyright (C) 1995-1997 Graham Barr. All rights reserved.
4 # Copyright (C) 2013-2016 Steve Hay. All rights reserved.
5 # This module is free software; you can redistribute it and/or modify it under
6 # the same terms as Perl itself, i.e. under the terms of either the GNU General
7 # Public License or the Artistic License, as specified in the F<LICENCE> file.
22 our $VERSION = "3.11";
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 no warnings 'numeric';
29 IO::Socket::SSL->VERSION(2.007);
30 } && 'IO::Socket::SSL';
32 my $nossl_warn = !$ssl_class &&
33 'To use SSL please install IO::Socket::SSL with version>=2.007';
35 # Code for detecting if we can use IPv6
36 my $family_key = 'Domain';
37 my $inet6_class = eval {
38 require IO::Socket::IP;
39 no warnings 'numeric';
40 IO::Socket::IP->VERSION(0.25) || die;
41 $family_key = 'Family';
42 } && 'IO::Socket::IP' || eval {
43 require IO::Socket::INET6;
44 no warnings 'numeric';
45 IO::Socket::INET6->VERSION(2.62);
46 } && 'IO::Socket::INET6';
49 sub can_ssl { $ssl_class };
50 sub can_inet6 { $inet6_class };
52 our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
57 my $type = ref($self) || $self;
65 $host = delete $arg{Host};
69 $host ||= $ENV{NNTPSERVER} || $ENV{NEWSHOST};
71 my $hosts = defined $host ? [$host] : $NetConfig{nntp_hosts};
76 my %connect = ( Proto => 'tcp');
80 die $nossl_warn if ! $ssl_class;
82 $connect{$_} = $arg{$_} for(grep { m{^SSL_} } keys %arg);
85 foreach my $o (qw(LocalAddr LocalPort Timeout)) {
86 $connect{$o} = $arg{$o} if exists $arg{$o};
88 $connect{$family_key} = $arg{Domain} || $arg{Family};
89 $connect{Timeout} = 120 unless defined $connect{Timeout};
90 $connect{PeerPort} = $arg{Port} || 'nntp(119)';
91 foreach my $h (@{$hosts}) {
92 $connect{PeerAddr} = $h;
93 $obj = $type->SUPER::new(%connect) or next;
94 ${*$obj}{'net_nntp_host'} = $h;
95 ${*$obj}{'net_nntp_arg'} = \%arg;
97 Net::NNTP::_SSL->start_SSL($obj,%arg) or next;
106 $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
108 unless ($obj->response() == CMD_OK) {
114 my @m = $obj->message;
116 unless (exists $arg{Reader} && $arg{Reader} == 0) {
118 # if server is INN and we have transfer rights the we are currently
119 # talking to innd not nnrpd
122 # If reader succeeds the we need to consider this code to determine postok
127 # I want to ignore this failure, so restore the previous status.
128 $obj->set_status($c, \@m);
132 ${*$obj}{'net_nntp_post'} = $c == 200 ? 1 : 0;
140 ${*$me}{'net_nntp_host'};
149 if ( (ref($nntp) and $nntp->code == 350 and $text =~ /^(\S+)/)
150 || ($text =~ /^(authinfo\s+pass)/io))
160 @_ == 1 or croak 'usage: $nntp->postok()';
162 ${*$nntp}{'net_nntp_post'} || 0;
168 $ssl_class or die $nossl_warn;
169 $self->_STARTTLS or return;
170 Net::NNTP::_SSL->start_SSL($self,
171 %{ ${*$self}{'net_nntp_arg'} }, # (ssl) args given in new
179 @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->article( [ MSGID ], [ FH ] )';
183 @fh = (pop) if @_ == 2 || (@_ && (ref($_[0]) || ref(\$_[0]) eq 'GLOB'));
186 ? $nntp->read_until_dot(@fh)
192 @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->articlefh( [ MSGID ] )';
195 return unless $nntp->_ARTICLE(@_);
196 return $nntp->tied_fh;
201 @_ == 3 or croak 'usage: $nntp->authinfo( USER, PASS )';
202 my ($nntp, $user, $pass) = @_;
204 $nntp->_AUTHINFO("USER", $user) == CMD_MORE
205 && $nntp->_AUTHINFO("PASS", $pass) == CMD_OK;
209 sub authinfo_simple {
210 @_ == 3 or croak 'usage: $nntp->authinfo( USER, PASS )';
211 my ($nntp, $user, $pass) = @_;
213 $nntp->_AUTHINFO('SIMPLE') == CMD_MORE
214 && $nntp->command($user, $pass)->response == CMD_OK;
219 @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->body( [ MSGID ], [ FH ] )';
223 @fh = (pop) if @_ == 2 || (@_ && ref($_[0]) || ref(\$_[0]) eq 'GLOB');
226 ? $nntp->read_until_dot(@fh)
232 @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->bodyfh( [ MSGID ] )';
234 return unless $nntp->_BODY(@_);
235 return $nntp->tied_fh;
240 @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->head( [ MSGID ], [ FH ] )';
244 @fh = (pop) if @_ == 2 || (@_ && ref($_[0]) || ref(\$_[0]) eq 'GLOB');
247 ? $nntp->read_until_dot(@fh)
253 @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->headfh( [ MSGID ] )';
255 return unless $nntp->_HEAD(@_);
256 return $nntp->tied_fh;
261 @_ == 1 || @_ == 2 or croak 'usage: $nntp->nntpstat( [ MSGID ] )';
264 $nntp->_STAT(@_) && $nntp->message =~ /(<[^>]+>)/o
271 @_ == 1 || @_ == 2 or croak 'usage: $nntp->group( [ GROUP ] )';
273 my $grp = ${*$nntp}{'net_nntp_group'};
276 unless (@_ || wantarray);
280 $newgrp = (defined($grp) and length($grp)) ? $grp : ""
281 unless defined($newgrp) and length($newgrp);
284 unless $nntp->_GROUP($newgrp) and $nntp->message =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\S+)/;
286 my ($count, $first, $last, $group) = ($1, $2, $3, $4);
288 # group may be replied as '(current group)'
289 $group = ${*$nntp}{'net_nntp_group'}
292 ${*$nntp}{'net_nntp_group'} = $group;
295 ? ($count, $first, $last, $group)
301 @_ == 1 or croak 'usage: $nntp->help()';
305 ? $nntp->read_until_dot
311 @_ >= 2 or croak 'usage: $nntp->ihave( MESSAGE-ID [, MESSAGE ])';
315 $nntp->_IHAVE($mid) && $nntp->datasend(@_)
316 ? @_ == 0 || $nntp->dataend
322 @_ == 1 or croak 'usage: $nntp->last()';
325 $nntp->_LAST && $nntp->message =~ /(<[^>]+>)/o
332 @_ == 1 or croak 'usage: $nntp->list()';
342 @_ >= 2 or croak 'usage: $nntp->newgroups( SINCE [, DISTRIBUTIONS ])';
344 my $time = _timestr(shift);
345 my $dist = shift || "";
347 $dist = join(",", @{$dist})
350 $nntp->_NEWGROUPS($time, $dist)
358 or croak 'usage: $nntp->newnews( SINCE [, GROUPS [, DISTRIBUTIONS ]])';
360 my $time = _timestr(shift);
361 my $grp = @_ ? shift: $nntp->group;
362 my $dist = shift || "";
365 $grp = join(",", @{$grp})
368 $dist = join(",", @{$dist})
371 $nntp->_NEWNEWS($grp, $time, $dist)
372 ? $nntp->_articlelist
378 @_ == 1 or croak 'usage: $nntp->next()';
381 $nntp->_NEXT && $nntp->message =~ /(<[^>]+>)/o
388 @_ >= 1 or croak 'usage: $nntp->post( [ MESSAGE ] )';
391 $nntp->_POST() && $nntp->datasend(@_)
392 ? @_ == 0 || $nntp->dataend
399 return unless $nntp->_POST();
400 return $nntp->tied_fh;
405 @_ == 1 or croak 'usage: $nntp->quit()';
414 @_ == 1 or croak 'usage: $nntp->slave()';
421 ## The following methods are not implemented by all servers
426 @_ == 1 || @_ == 2 or croak 'usage: $nntp->active( [ PATTERN ] )';
429 $nntp->_LIST('ACTIVE', @_)
436 @_ == 1 or croak 'usage: $nntp->active_times()';
439 $nntp->_LIST('ACTIVE.TIMES')
446 @_ == 1 or croak 'usage: $nntp->distributions()';
449 $nntp->_LIST('DISTRIBUTIONS')
450 ? $nntp->_description
455 sub distribution_patterns {
456 @_ == 1 or croak 'usage: $nntp->distributions()';
462 ## no critic (ControlStructures::ProhibitMutatingListFunctions)
463 $nntp->_LIST('DISTRIB.PATS')
464 && ($arr = $nntp->read_until_dot)
465 ? [grep { /^\d/ && (chomp, $_ = [split /:/]) } @$arr]
471 @_ == 1 || @_ == 2 or croak 'usage: $nntp->newsgroups( [ PATTERN ] )';
474 $nntp->_LIST('NEWSGROUPS', @_)
475 ? $nntp->_description
481 @_ == 1 or croak 'usage: $nntp->overview_fmt()';
484 $nntp->_LIST('OVERVIEW.FMT')
485 ? $nntp->_articlelist
491 @_ == 1 or croak 'usage: $nntp->subscriptions()';
494 $nntp->_LIST('SUBSCRIPTIONS')
495 ? $nntp->_articlelist
501 @_ == 1 || @_ == 2 or croak 'usage: $nntp->listgroup( [ GROUP ] )';
504 $nntp->_LISTGROUP(@_)
505 ? $nntp->_articlelist
511 @_ == 1 or croak 'usage: $nntp->reader()';
514 $nntp->_MODE('READER');
519 @_ == 1 || @_ == 2 or croak 'usage: $nntp->xgtitle( [ PATTERN ] )';
523 ? $nntp->_description
529 @_ >= 2 && @_ <= 4 or croak 'usage: $nntp->xhdr( HEADER, [ MESSAGE-SPEC ] )';
532 my $arg = _msg_arg(@_);
534 $nntp->_XHDR($hdr, $arg)
535 ? $nntp->_description
541 @_ == 2 || @_ == 3 or croak 'usage: $nntp->xover( MESSAGE-SPEC )';
543 my $arg = _msg_arg(@_);
552 @_ == 4 || @_ == 5 or croak '$nntp->xpat( HEADER, PATTERN, MESSAGE-SPEC )';
556 my $arg = _msg_arg(@_);
558 $pat = join(" ", @$pat)
561 $nntp->_XPAT($hdr, $arg, $pat)
562 ? $nntp->_description
568 @_ == 2 or croak 'usage: $nntp->xpath( MESSAGE-ID )';
569 my ($nntp, $mid) = @_;
572 unless $nntp->_XPATH($mid);
575 ($m = $nntp->message) =~ s/^\d+\s+//o;
576 my @p = split /\s+/, $m;
578 wantarray ? @p : $p[0];
583 @_ == 2 || @_ == 3 or croak 'usage: $nntp->xrover( MESSAGE-SPEC )';
585 my $arg = _msg_arg(@_);
588 ? $nntp->_description
594 @_ == 1 or croak 'usage: $nntp->date()';
598 && $nntp->message =~ /(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/
599 ? timegm($6, $5, $4, $3, $2 - 1, $1 - 1900)
605 ## Private subroutines
614 carp "Depriciated passing of two message numbers, " . "pass a reference"
616 $spec = [$spec, $_[0]];
622 if (defined $spec->[1]) {
624 if $spec->[1] != $spec->[0];
626 if $spec->[1] > $spec->[0];
640 my @g = reverse((gmtime($time))[0 .. 5]);
643 sprintf "%02d%02d%02d %02d%02d%02d GMT", @g;
649 my $arr = $nntp->read_until_dot
654 foreach my $ln (@$arr) {
655 my @a = split(/[\s\n]+/, $ln);
656 $hash->{$a[0]} = [@a[1, 2, 3]];
665 my $arr = $nntp->read_until_dot
670 foreach my $ln (@$arr) {
671 my @a = split(/[\t\n]/, $ln);
682 my $arr = $nntp->read_until_dot;
693 my $arr = $nntp->read_until_dot
698 foreach my $ln (@$arr) {
702 if $ln =~ s/^\s*(\S+)\s*//o;
714 sub _ARTICLE { shift->command('ARTICLE', @_)->response == CMD_OK }
715 sub _AUTHINFO { shift->command('AUTHINFO', @_)->response }
716 sub _BODY { shift->command('BODY', @_)->response == CMD_OK }
717 sub _DATE { shift->command('DATE')->response == CMD_INFO }
718 sub _GROUP { shift->command('GROUP', @_)->response == CMD_OK }
719 sub _HEAD { shift->command('HEAD', @_)->response == CMD_OK }
720 sub _HELP { shift->command('HELP', @_)->response == CMD_INFO }
721 sub _IHAVE { shift->command('IHAVE', @_)->response == CMD_MORE }
722 sub _LAST { shift->command('LAST')->response == CMD_OK }
723 sub _LIST { shift->command('LIST', @_)->response == CMD_OK }
724 sub _LISTGROUP { shift->command('LISTGROUP', @_)->response == CMD_OK }
725 sub _NEWGROUPS { shift->command('NEWGROUPS', @_)->response == CMD_OK }
726 sub _NEWNEWS { shift->command('NEWNEWS', @_)->response == CMD_OK }
727 sub _NEXT { shift->command('NEXT')->response == CMD_OK }
728 sub _POST { shift->command('POST', @_)->response == CMD_MORE }
729 sub _QUIT { shift->command('QUIT', @_)->response == CMD_OK }
730 sub _SLAVE { shift->command('SLAVE', @_)->response == CMD_OK }
731 sub _STARTTLS { shift->command("STARTTLS")->response() == CMD_MORE }
732 sub _STAT { shift->command('STAT', @_)->response == CMD_OK }
733 sub _MODE { shift->command('MODE', @_)->response == CMD_OK }
734 sub _XGTITLE { shift->command('XGTITLE', @_)->response == CMD_OK }
735 sub _XHDR { shift->command('XHDR', @_)->response == CMD_OK }
736 sub _XPAT { shift->command('XPAT', @_)->response == CMD_OK }
737 sub _XPATH { shift->command('XPATH', @_)->response == CMD_OK }
738 sub _XOVER { shift->command('XOVER', @_)->response == CMD_OK }
739 sub _XROVER { shift->command('XROVER', @_)->response == CMD_OK }
740 sub _XTHREAD { shift->unsupported }
741 sub _XSEARCH { shift->unsupported }
742 sub _XINDEX { shift->unsupported }
751 defined(fileno($nntp)) && $nntp->quit;
755 package Net::NNTP::_SSL;
756 our @ISA = ( $ssl_class ? ($ssl_class):(), 'Net::NNTP' );
757 sub starttls { die "NNTP connection is already in SSL mode" }
759 my ($class,$nntp,%arg) = @_;
760 delete @arg{ grep { !m{^SSL_} } keys %arg };
761 ( $arg{SSL_verifycn_name} ||= $nntp->host )
762 =~s{(?<!:):[\w()]+$}{}; # strip port
763 $arg{SSL_hostname} = $arg{SSL_verifycn_name}
764 if ! defined $arg{SSL_hostname} && $class->can_client_sni;
765 my $ok = $class->SUPER::start_SSL($nntp,
766 SSL_verifycn_scheme => 'nntp',
769 $@ = $ssl_class->errstr if !$ok;
783 Net::NNTP - NNTP Client class
789 $nntp = Net::NNTP->new("some.host.name");
792 # start with SSL, e.g. nntps
793 $nntp = Net::NNTP->new("some.host.name", SSL => 1);
795 # start with plain and upgrade to SSL
796 $nntp = Net::NNTP->new("some.host.name");
802 C<Net::NNTP> is a class implementing a simple NNTP client in Perl as described
803 in RFC977 and RFC4642.
804 With L<IO::Socket::SSL> installed it also provides support for implicit and
805 explicit TLS encryption, i.e. NNTPS or NNTP+STARTTLS.
807 The Net::NNTP class is a subclass of Net::Cmd and (depending on avaibility) of
808 IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
814 =item new ( [ HOST ] [, OPTIONS ])
816 This is the constructor for a new Net::NNTP object. C<HOST> is the
817 name of the remote host to which a NNTP connection is required. If not
818 given then it may be passed as the C<Host> option described below. If no host is passed
819 then two environment variables are checked, first C<NNTPSERVER> then
820 C<NEWSHOST>, then C<Net::Config> is checked, and if a host is not found
821 then C<news> is used.
823 C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
824 Possible options are:
826 B<Host> - NNTP host to connect to. It may be a single scalar, as defined for
827 the C<PeerAddr> option in L<IO::Socket::INET>, or a reference to
828 an array with hosts to try in turn. The L</host> method will return the value
829 which was used to connect to the host.
831 B<Port> - port to connect to.
832 Default - 119 for plain NNTP and 563 for immediate SSL (nntps).
834 B<SSL> - If the connection should be done from start with SSL, contrary to later
835 upgrade with C<starttls>.
836 You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
837 usually use the right arguments already.
839 B<Timeout> - Maximum time, in seconds, to wait for a response from the
840 NNTP server, a value of zero will cause all IO operations to block.
843 B<Debug> - Enable the printing of debugging information to STDERR
845 B<Reader> - If the remote server is INN then initially the connection
846 will be to innd, by default C<Net::NNTP> will issue a C<MODE READER> command
847 so that the remote server becomes nnrpd. If the C<Reader> option is given
848 with a value of zero, then this command will not be sent and the
849 connection will be left talking to innd.
851 B<LocalAddr> and B<LocalPort> - These parameters are passed directly
852 to IO::Socket to allow binding the socket to a specific local address and port.
854 B<Domain> - This parameter is passed directly to IO::Socket and makes it
855 possible to enforce IPv4 connections even if L<IO::Socket::IP> is used as super
856 class. Alternatively B<Family> can be used.
862 Unless otherwise stated all methods return either a I<true> or I<false>
863 value, with I<true> meaning that the operation was a success. When a method
864 states that it returns a value, failure will be returned as I<undef> or an
867 C<Net::NNTP> inherits from C<Net::Cmd> so methods defined in C<Net::Cmd> may
868 be used to send commands to the remote NNTP server in addition to the methods
875 Returns the value used by the constructor, and passed to IO::Socket::INET,
876 to connect to the host.
880 Upgrade existing plain connection to SSL.
881 Any arguments necessary for SSL must be given in C<new> already.
883 =item article ( [ MSGID|MSGNUM ], [FH] )
885 Retrieve the header, a blank line, then the body (text) of the
888 If C<FH> is specified then it is expected to be a valid filehandle
889 and the result will be printed to it, on success a true value will be
890 returned. If C<FH> is not specified then the return value, on success,
891 will be a reference to an array containing the article requested, each
892 entry in the array will contain one line of the article.
894 If no arguments are passed then the current article in the currently
895 selected newsgroup is fetched.
897 C<MSGNUM> is a numeric id of an article in the current newsgroup, and
898 will change the current article pointer. C<MSGID> is the message id of
899 an article as shown in that article's header. It is anticipated that the
900 client will obtain the C<MSGID> from a list provided by the C<newnews>
901 command, from references contained within another article, or from the
902 message-id provided in the response to some other commands.
904 If there is an error then C<undef> will be returned.
906 =item body ( [ MSGID|MSGNUM ], [FH] )
908 Like C<article> but only fetches the body of the article.
910 =item head ( [ MSGID|MSGNUM ], [FH] )
912 Like C<article> but only fetches the headers for the article.
914 =item articlefh ( [ MSGID|MSGNUM ] )
916 =item bodyfh ( [ MSGID|MSGNUM ] )
918 =item headfh ( [ MSGID|MSGNUM ] )
920 These are similar to article(), body() and head(), but rather than
921 returning the requested data directly, they return a tied filehandle
922 from which to read the article.
924 =item nntpstat ( [ MSGID|MSGNUM ] )
926 The C<nntpstat> command is similar to the C<article> command except that no
927 text is returned. When selecting by message number within a group,
928 the C<nntpstat> command serves to set the "current article pointer" without
931 Using the C<nntpstat> command to
932 select by message-id is valid but of questionable value, since a
933 selection by message-id does B<not> alter the "current article pointer".
935 Returns the message-id of the "current article".
937 =item group ( [ GROUP ] )
939 Set and/or get the current group. If C<GROUP> is not given then information
940 is returned on the current group.
942 In a scalar context it returns the group name.
944 In an array context the return value is a list containing, the number
945 of articles in the group, the number of the first article, the number
946 of the last article and the group name.
950 Request help text (a short summary of commands that are understood by this
951 implementation) from the server. Returns the text or undef upon failure.
953 =item ihave ( MSGID [, MESSAGE ])
955 The C<ihave> command informs the server that the client has an article
956 whose id is C<MSGID>. If the server desires a copy of that
957 article and C<MESSAGE> has been given then it will be sent.
959 Returns I<true> if the server desires the article and C<MESSAGE> was
960 successfully sent, if specified.
962 If C<MESSAGE> is not specified then the message must be sent using the
963 C<datasend> and C<dataend> methods from L<Net::Cmd>
965 C<MESSAGE> can be either an array of lines or a reference to an array
966 and must be encoded by the caller to octets of whatever encoding is required,
967 e.g. by using the Encode module's C<encode()> function.
971 Set the "current article pointer" to the previous article in the current
974 Returns the message-id of the article.
978 Returns the date on the remote server. This date will be in a UNIX time
979 format (seconds since 1970)
983 C<postok> will return I<true> if the servers initial response indicated
984 that it will allow posting.
986 =item authinfo ( USER, PASS )
988 Authenticates to the server (using the original AUTHINFO USER / AUTHINFO PASS
989 form, defined in RFC2980) using the supplied username and password. Please
990 note that the password is sent in clear text to the server. This command
991 should not be used with valuable passwords unless the connection to the server
992 is somehow protected.
994 =item authinfo_simple ( USER, PASS )
996 Authenticates to the server (using the proposed NNTP V2 AUTHINFO SIMPLE form,
997 defined and deprecated in RFC2980) using the supplied username and password.
998 As with L</authinfo> the password is sent in clear text.
1002 Obtain information about all the active newsgroups. The results is a reference
1003 to a hash where the key is a group name and each value is a reference to an
1004 array. The elements in this array are:- the last article number in the group,
1005 the first article number in the group and any information flags about the group.
1007 =item newgroups ( SINCE [, DISTRIBUTIONS ])
1009 C<SINCE> is a time value and C<DISTRIBUTIONS> is either a distribution
1010 pattern or a reference to a list of distribution patterns.
1011 The result is the same as C<list>, but the
1012 groups return will be limited to those created after C<SINCE> and, if
1013 specified, in one of the distribution areas in C<DISTRIBUTIONS>.
1015 =item newnews ( SINCE [, GROUPS [, DISTRIBUTIONS ]])
1017 C<SINCE> is a time value. C<GROUPS> is either a group pattern or a reference
1018 to a list of group patterns. C<DISTRIBUTIONS> is either a distribution
1019 pattern or a reference to a list of distribution patterns.
1021 Returns a reference to a list which contains the message-ids of all news posted
1022 after C<SINCE>, that are in a groups which matched C<GROUPS> and a
1023 distribution which matches C<DISTRIBUTIONS>.
1027 Set the "current article pointer" to the next article in the current
1030 Returns the message-id of the article.
1032 =item post ( [ MESSAGE ] )
1034 Post a new article to the news server. If C<MESSAGE> is specified and posting
1035 is allowed then the message will be sent.
1037 If C<MESSAGE> is not specified then the message must be sent using the
1038 C<datasend> and C<dataend> methods from L<Net::Cmd>
1040 C<MESSAGE> can be either an array of lines or a reference to an array
1041 and must be encoded by the caller to octets of whatever encoding is required,
1042 e.g. by using the Encode module's C<encode()> function.
1044 The message, either sent via C<datasend> or as the C<MESSAGE>
1045 parameter, must be in the format as described by RFC822 and must
1046 contain From:, Newsgroups: and Subject: headers.
1050 Post a new article to the news server using a tied filehandle. If
1051 posting is allowed, this method will return a tied filehandle that you
1052 can print() the contents of the article to be posted. You must
1053 explicitly close() the filehandle when you are finished posting the
1054 article, and the return value from the close() call will indicate
1055 whether the message was successfully posted.
1059 Tell the remote server that I am not a user client, but probably another
1064 Quit the remote server and close the socket connection.
1068 Returns whether we can use IPv6.
1072 Returns whether we can use SSL.
1076 =head2 Extension methods
1078 These methods use commands that are not part of the RFC977 documentation. Some
1079 servers may not support all of them.
1083 =item newsgroups ( [ PATTERN ] )
1085 Returns a reference to a hash where the keys are all the group names which
1086 match C<PATTERN>, or all of the groups if no pattern is specified, and
1087 each value contains the description text for the group.
1089 =item distributions ()
1091 Returns a reference to a hash where the keys are all the possible
1092 distribution names and the values are the distribution descriptions.
1094 =item distribution_patterns ()
1096 Returns a reference to an array where each element, itself an array
1097 reference, consists of the three fields of a line of the distrib.pats list
1098 maintained by some NNTP servers, namely: a weight, a wildmat and a value
1099 which the client may use to construct a Distribution header.
1101 =item subscriptions ()
1103 Returns a reference to a list which contains a list of groups which
1104 are recommended for a new user to subscribe to.
1106 =item overview_fmt ()
1108 Returns a reference to an array which contain the names of the fields returned
1111 =item active_times ()
1113 Returns a reference to a hash where the keys are the group names and each
1114 value is a reference to an array containing the time the groups was created
1115 and an identifier, possibly an Email address, of the creator.
1117 =item active ( [ PATTERN ] )
1119 Similar to C<list> but only active groups that match the pattern are returned.
1120 C<PATTERN> can be a group pattern.
1122 =item xgtitle ( PATTERN )
1124 Returns a reference to a hash where the keys are all the group names which
1125 match C<PATTERN> and each value is the description text for the group.
1127 =item xhdr ( HEADER, MESSAGE-SPEC )
1129 Obtain the header field C<HEADER> for all the messages specified.
1131 The return value will be a reference
1132 to a hash where the keys are the message numbers and each value contains
1133 the text of the requested header for that message.
1135 =item xover ( MESSAGE-SPEC )
1137 The return value will be a reference
1138 to a hash where the keys are the message numbers and each value contains
1139 a reference to an array which contains the overview fields for that
1142 The names of the fields can be obtained by calling C<overview_fmt>.
1144 =item xpath ( MESSAGE-ID )
1146 Returns the path name to the file on the server which contains the specified
1149 =item xpat ( HEADER, PATTERN, MESSAGE-SPEC)
1151 The result is the same as C<xhdr> except the is will be restricted to
1152 headers where the text of the header matches C<PATTERN>
1156 The XROVER command returns reference information for the article(s)
1159 Returns a reference to a HASH where the keys are the message numbers and the
1160 values are the References: lines from the articles
1162 =item listgroup ( [ GROUP ] )
1164 Returns a reference to a list of all the active messages in C<GROUP>, or
1165 the current group if C<GROUP> is not specified.
1169 Tell the server that you are a reader and not another server.
1171 This is required by some servers. For example if you are connecting to
1172 an INN server and you have transfer permission your connection will
1173 be connected to the transfer daemon, not the NNTP daemon. Issuing
1174 this command will cause the transfer daemon to hand over control
1177 Some servers do not understand this command, but issuing it and ignoring
1178 the response is harmless.
1184 The following NNTP command are unsupported by the package, and there are
1198 C<MESSAGE-SPEC> is either a single message-id, a single message number, or
1199 a reference to a list of two message numbers.
1201 If C<MESSAGE-SPEC> is a reference to a list of two message numbers and the
1202 second number in a range is less than or equal to the first then the range
1203 represents all messages in the group after the first message number.
1205 B<NOTE> For compatibility reasons only with earlier versions of Net::NNTP
1206 a message spec can be passed as a list of two numbers, this is deprecated
1207 and a reference to the list should now be passed
1211 The C<NNTP> protocol uses the C<WILDMAT> format for patterns.
1212 The WILDMAT format was first developed by Rich Salz based on
1213 the format used in the UNIX "find" command to articulate
1214 file names. It was developed to provide a uniform mechanism
1215 for matching patterns in the same manner that the UNIX shell
1218 Patterns are implicitly anchored at the
1219 beginning and end of each string when testing for a match.
1221 There are five pattern matching operations other than a strict
1222 one-to-one match between the pattern and the source to be
1223 checked for a match.
1225 The first is an asterisk C<*> to match any sequence of zero or more
1228 The second is a question mark C<?> to match any single character. The
1229 third specifies a specific set of characters.
1231 The set is specified as a list of characters, or as a range of characters
1232 where the beginning and end of the range are separated by a minus (or dash)
1233 character, or as any combination of lists and ranges. The dash can
1234 also be included in the set as a character it if is the beginning
1235 or end of the set. This set is enclosed in square brackets. The
1236 close square bracket C<]> may be used in a set if it is the first
1237 character in the set.
1239 The fourth operation is the same as the
1240 logical not of the third operation and is specified the same
1241 way as the third with the addition of a caret character C<^> at
1242 the beginning of the test string just inside the open square
1245 The final operation uses the backslash character to
1246 invalidate the special meaning of an open square bracket C<[>,
1247 the asterisk, backslash or the question mark. Two backslashes in
1248 sequence will result in the evaluation of the backslash as a
1249 character with no special meaning.
1257 matches any single character other than a close square
1258 bracket or a minus sign/dash.
1262 matches any string that ends with the string "bdc"
1263 including the string "bdc" (without quotes).
1265 =item C<[0-9a-zA-Z]>
1267 matches any single printable alphanumeric ASCII character.
1271 matches any four character string which begins
1272 with a and ends with d.
1285 Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
1287 Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
1292 Copyright (C) 1995-1997 Graham Barr. All rights reserved.
1294 Copyright (C) 2013-2016 Steve Hay. All rights reserved.
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.