source: for-distributions/trunk/bin/windows/perl/lib/Net/NNTP.pm@ 14489

Last change on this file since 14489 was 14489, checked in by oranfry, 17 years ago

upgrading to perl 5.8

File size: 26.5 KB
Line 
1# Net::NNTP.pm
2#
3# Copyright (c) 1995-1997 Graham Barr <[email protected]>. 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.
6
7package Net::NNTP;
8
9use strict;
10use vars qw(@ISA $VERSION $debug);
11use IO::Socket;
12use Net::Cmd;
13use Carp;
14use Time::Local;
15use Net::Config;
16
17$VERSION = "2.23";
18@ISA = qw(Net::Cmd IO::Socket::INET);
19
20sub new
21{
22 my $self = shift;
23 my $type = ref($self) || $self;
24 my ($host,%arg);
25 if (@_ % 2) {
26 $host = shift ;
27 %arg = @_;
28 } else {
29 %arg = @_;
30 $host=delete $arg{Host};
31 }
32 my $obj;
33
34 $host ||= $ENV{NNTPSERVER} || $ENV{NEWSHOST};
35
36 my $hosts = defined $host ? [ $host ] : $NetConfig{nntp_hosts};
37
38 @{$hosts} = qw(news)
39 unless @{$hosts};
40
41 my $h;
42 foreach $h (@{$hosts})
43 {
44 $obj = $type->SUPER::new(PeerAddr => ($host = $h),
45 PeerPort => $arg{Port} || 'nntp(119)',
46 Proto => 'tcp',
47 Timeout => defined $arg{Timeout}
48 ? $arg{Timeout}
49 : 120
50 ) and last;
51 }
52
53 return undef
54 unless defined $obj;
55
56 ${*$obj}{'net_nntp_host'} = $host;
57
58 $obj->autoflush(1);
59 $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
60
61 unless ($obj->response() == CMD_OK)
62 {
63 $obj->close;
64 return undef;
65 }
66
67 my $c = $obj->code;
68 my @m = $obj->message;
69
70 unless(exists $arg{Reader} && $arg{Reader} == 0) {
71 # if server is INN and we have transfer rights the we are currently
72 # talking to innd not nnrpd
73 if($obj->reader)
74 {
75 # If reader suceeds the we need to consider this code to determine postok
76 $c = $obj->code;
77 }
78 else
79 {
80 # I want to ignore this failure, so restore the previous status.
81 $obj->set_status($c,\@m);
82 }
83 }
84
85 ${*$obj}{'net_nntp_post'} = $c == 200 ? 1 : 0;
86
87 $obj;
88}
89
90sub host {
91 my $me = shift;
92 ${*$me}{'net_nntp_host'};
93}
94
95sub debug_text
96{
97 my $nntp = shift;
98 my $inout = shift;
99 my $text = shift;
100
101 if((ref($nntp) and $nntp->code == 350 and $text =~ /^(\S+)/)
102 || ($text =~ /^(authinfo\s+pass)/io))
103 {
104 $text = "$1 ....\n"
105 }
106
107 $text;
108}
109
110sub postok
111{
112 @_ == 1 or croak 'usage: $nntp->postok()';
113 my $nntp = shift;
114 ${*$nntp}{'net_nntp_post'} || 0;
115}
116
117sub article
118{
119 @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->article( [ MSGID ], [ FH ] )';
120 my $nntp = shift;
121 my @fh;
122
123 @fh = (pop) if @_ == 2 || (@_ && ref($_[0]) || ref(\$_[0]) eq 'GLOB');
124
125 $nntp->_ARTICLE(@_)
126 ? $nntp->read_until_dot(@fh)
127 : undef;
128}
129
130sub articlefh {
131 @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->articlefh( [ MSGID ] )';
132 my $nntp = shift;
133
134 return unless $nntp->_ARTICLE(@_);
135 return $nntp->tied_fh;
136}
137
138sub authinfo
139{
140 @_ == 3 or croak 'usage: $nntp->authinfo( USER, PASS )';
141 my($nntp,$user,$pass) = @_;
142
143 $nntp->_AUTHINFO("USER",$user) == CMD_MORE
144 && $nntp->_AUTHINFO("PASS",$pass) == CMD_OK;
145}
146
147sub authinfo_simple
148{
149 @_ == 3 or croak 'usage: $nntp->authinfo( USER, PASS )';
150 my($nntp,$user,$pass) = @_;
151
152 $nntp->_AUTHINFO('SIMPLE') == CMD_MORE
153 && $nntp->command($user,$pass)->response == CMD_OK;
154}
155
156sub body
157{
158 @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->body( [ MSGID ], [ FH ] )';
159 my $nntp = shift;
160 my @fh;
161
162 @fh = (pop) if @_ == 2 || (@_ && ref($_[0]) || ref(\$_[0]) eq 'GLOB');
163
164 $nntp->_BODY(@_)
165 ? $nntp->read_until_dot(@fh)
166 : undef;
167}
168
169sub bodyfh
170{
171 @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->bodyfh( [ MSGID ] )';
172 my $nntp = shift;
173 return unless $nntp->_BODY(@_);
174 return $nntp->tied_fh;
175}
176
177sub head
178{
179 @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->head( [ MSGID ], [ FH ] )';
180 my $nntp = shift;
181 my @fh;
182
183 @fh = (pop) if @_ == 2 || (@_ && ref($_[0]) || ref(\$_[0]) eq 'GLOB');
184
185 $nntp->_HEAD(@_)
186 ? $nntp->read_until_dot(@fh)
187 : undef;
188}
189
190sub headfh
191{
192 @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->headfh( [ MSGID ] )';
193 my $nntp = shift;
194 return unless $nntp->_HEAD(@_);
195 return $nntp->tied_fh;
196}
197
198sub nntpstat
199{
200 @_ == 1 || @_ == 2 or croak 'usage: $nntp->nntpstat( [ MSGID ] )';
201 my $nntp = shift;
202
203 $nntp->_STAT(@_) && $nntp->message =~ /(<[^>]+>)/o
204 ? $1
205 : undef;
206}
207
208
209sub group
210{
211 @_ == 1 || @_ == 2 or croak 'usage: $nntp->group( [ GROUP ] )';
212 my $nntp = shift;
213 my $grp = ${*$nntp}{'net_nntp_group'} || undef;
214
215 return $grp
216 unless(@_ || wantarray);
217
218 my $newgrp = shift;
219
220 return wantarray ? () : undef
221 unless $nntp->_GROUP($newgrp || $grp || "")
222 && $nntp->message =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\S+)/;
223
224 my($count,$first,$last,$group) = ($1,$2,$3,$4);
225
226 # group may be replied as '(current group)'
227 $group = ${*$nntp}{'net_nntp_group'}
228 if $group =~ /\(/;
229
230 ${*$nntp}{'net_nntp_group'} = $group;
231
232 wantarray
233 ? ($count,$first,$last,$group)
234 : $group;
235}
236
237sub help
238{
239 @_ == 1 or croak 'usage: $nntp->help()';
240 my $nntp = shift;
241
242 $nntp->_HELP
243 ? $nntp->read_until_dot
244 : undef;
245}
246
247sub ihave
248{
249 @_ >= 2 or croak 'usage: $nntp->ihave( MESSAGE-ID [, MESSAGE ])';
250 my $nntp = shift;
251 my $mid = shift;
252
253 $nntp->_IHAVE($mid) && $nntp->datasend(@_)
254 ? @_ == 0 || $nntp->dataend
255 : undef;
256}
257
258sub last
259{
260 @_ == 1 or croak 'usage: $nntp->last()';
261 my $nntp = shift;
262
263 $nntp->_LAST && $nntp->message =~ /(<[^>]+>)/o
264 ? $1
265 : undef;
266}
267
268sub list
269{
270 @_ == 1 or croak 'usage: $nntp->list()';
271 my $nntp = shift;
272
273 $nntp->_LIST
274 ? $nntp->_grouplist
275 : undef;
276}
277
278sub newgroups
279{
280 @_ >= 2 or croak 'usage: $nntp->newgroups( SINCE [, DISTRIBUTIONS ])';
281 my $nntp = shift;
282 my $time = _timestr(shift);
283 my $dist = shift || "";
284
285 $dist = join(",", @{$dist})
286 if ref($dist);
287
288 $nntp->_NEWGROUPS($time,$dist)
289 ? $nntp->_grouplist
290 : undef;
291}
292
293sub newnews
294{
295 @_ >= 2 && @_ <= 4 or
296 croak 'usage: $nntp->newnews( SINCE [, GROUPS [, DISTRIBUTIONS ]])';
297 my $nntp = shift;
298 my $time = _timestr(shift);
299 my $grp = @_ ? shift : $nntp->group;
300 my $dist = shift || "";
301
302 $grp ||= "*";
303 $grp = join(",", @{$grp})
304 if ref($grp);
305
306 $dist = join(",", @{$dist})
307 if ref($dist);
308
309 $nntp->_NEWNEWS($grp,$time,$dist)
310 ? $nntp->_articlelist
311 : undef;
312}
313
314sub next
315{
316 @_ == 1 or croak 'usage: $nntp->next()';
317 my $nntp = shift;
318
319 $nntp->_NEXT && $nntp->message =~ /(<[^>]+>)/o
320 ? $1
321 : undef;
322}
323
324sub post
325{
326 @_ >= 1 or croak 'usage: $nntp->post( [ MESSAGE ] )';
327 my $nntp = shift;
328
329 $nntp->_POST() && $nntp->datasend(@_)
330 ? @_ == 0 || $nntp->dataend
331 : undef;
332}
333
334sub postfh {
335 my $nntp = shift;
336 return unless $nntp->_POST();
337 return $nntp->tied_fh;
338}
339
340sub quit
341{
342 @_ == 1 or croak 'usage: $nntp->quit()';
343 my $nntp = shift;
344
345 $nntp->_QUIT;
346 $nntp->close;
347}
348
349sub slave
350{
351 @_ == 1 or croak 'usage: $nntp->slave()';
352 my $nntp = shift;
353
354 $nntp->_SLAVE;
355}
356
357##
358## The following methods are not implemented by all servers
359##
360
361sub active
362{
363 @_ == 1 || @_ == 2 or croak 'usage: $nntp->active( [ PATTERN ] )';
364 my $nntp = shift;
365
366 $nntp->_LIST('ACTIVE',@_)
367 ? $nntp->_grouplist
368 : undef;
369}
370
371sub active_times
372{
373 @_ == 1 or croak 'usage: $nntp->active_times()';
374 my $nntp = shift;
375
376 $nntp->_LIST('ACTIVE.TIMES')
377 ? $nntp->_grouplist
378 : undef;
379}
380
381sub distributions
382{
383 @_ == 1 or croak 'usage: $nntp->distributions()';
384 my $nntp = shift;
385
386 $nntp->_LIST('DISTRIBUTIONS')
387 ? $nntp->_description
388 : undef;
389}
390
391sub distribution_patterns
392{
393 @_ == 1 or croak 'usage: $nntp->distributions()';
394 my $nntp = shift;
395
396 my $arr;
397 local $_;
398
399 $nntp->_LIST('DISTRIB.PATS') && ($arr = $nntp->read_until_dot)
400 ? [grep { /^\d/ && (chomp, $_ = [ split /:/ ]) } @$arr]
401 : undef;
402}
403
404sub newsgroups
405{
406 @_ == 1 || @_ == 2 or croak 'usage: $nntp->newsgroups( [ PATTERN ] )';
407 my $nntp = shift;
408
409 $nntp->_LIST('NEWSGROUPS',@_)
410 ? $nntp->_description
411 : undef;
412}
413
414sub overview_fmt
415{
416 @_ == 1 or croak 'usage: $nntp->overview_fmt()';
417 my $nntp = shift;
418
419 $nntp->_LIST('OVERVIEW.FMT')
420 ? $nntp->_articlelist
421 : undef;
422}
423
424sub subscriptions
425{
426 @_ == 1 or croak 'usage: $nntp->subscriptions()';
427 my $nntp = shift;
428
429 $nntp->_LIST('SUBSCRIPTIONS')
430 ? $nntp->_articlelist
431 : undef;
432}
433
434sub listgroup
435{
436 @_ == 1 || @_ == 2 or croak 'usage: $nntp->listgroup( [ GROUP ] )';
437 my $nntp = shift;
438
439 $nntp->_LISTGROUP(@_)
440 ? $nntp->_articlelist
441 : undef;
442}
443
444sub reader
445{
446 @_ == 1 or croak 'usage: $nntp->reader()';
447 my $nntp = shift;
448
449 $nntp->_MODE('READER');
450}
451
452sub xgtitle
453{
454 @_ == 1 || @_ == 2 or croak 'usage: $nntp->xgtitle( [ PATTERN ] )';
455 my $nntp = shift;
456
457 $nntp->_XGTITLE(@_)
458 ? $nntp->_description
459 : undef;
460}
461
462sub xhdr
463{
464 @_ >= 2 && @_ <= 4 or croak 'usage: $nntp->xhdr( HEADER, [ MESSAGE-SPEC ] )';
465 my $nntp = shift;
466 my $hdr = shift;
467 my $arg = _msg_arg(@_);
468
469 $nntp->_XHDR($hdr, $arg)
470 ? $nntp->_description
471 : undef;
472}
473
474sub xover
475{
476 @_ == 2 || @_ == 3 or croak 'usage: $nntp->xover( MESSAGE-SPEC )';
477 my $nntp = shift;
478 my $arg = _msg_arg(@_);
479
480 $nntp->_XOVER($arg)
481 ? $nntp->_fieldlist
482 : undef;
483}
484
485sub xpat
486{
487 @_ == 4 || @_ == 5 or croak '$nntp->xpat( HEADER, PATTERN, MESSAGE-SPEC )';
488 my $nntp = shift;
489 my $hdr = shift;
490 my $pat = shift;
491 my $arg = _msg_arg(@_);
492
493 $pat = join(" ", @$pat)
494 if ref($pat);
495
496 $nntp->_XPAT($hdr,$arg,$pat)
497 ? $nntp->_description
498 : undef;
499}
500
501sub xpath
502{
503 @_ == 2 or croak 'usage: $nntp->xpath( MESSAGE-ID )';
504 my($nntp,$mid) = @_;
505
506 return undef
507 unless $nntp->_XPATH($mid);
508
509 my $m; ($m = $nntp->message) =~ s/^\d+\s+//o;
510 my @p = split /\s+/, $m;
511
512 wantarray ? @p : $p[0];
513}
514
515sub xrover
516{
517 @_ == 2 || @_ == 3 or croak 'usage: $nntp->xrover( MESSAGE-SPEC )';
518 my $nntp = shift;
519 my $arg = _msg_arg(@_);
520
521 $nntp->_XROVER($arg)
522 ? $nntp->_description
523 : undef;
524}
525
526sub date
527{
528 @_ == 1 or croak 'usage: $nntp->date()';
529 my $nntp = shift;
530
531 $nntp->_DATE && $nntp->message =~ /(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/
532 ? timegm($6,$5,$4,$3,$2-1,$1 - 1900)
533 : undef;
534}
535
536
537##
538## Private subroutines
539##
540
541sub _msg_arg
542{
543 my $spec = shift;
544 my $arg = "";
545
546 if(@_)
547 {
548 carp "Depriciated passing of two message numbers, "
549 . "pass a reference"
550 if $^W;
551 $spec = [ $spec, $_[0] ];
552 }
553
554 if(defined $spec)
555 {
556 if(ref($spec))
557 {
558 $arg = $spec->[0];
559 if(defined $spec->[1])
560 {
561 $arg .= "-"
562 if $spec->[1] != $spec->[0];
563 $arg .= $spec->[1]
564 if $spec->[1] > $spec->[0];
565 }
566 }
567 else
568 {
569 $arg = $spec;
570 }
571 }
572
573 $arg;
574}
575
576sub _timestr
577{
578 my $time = shift;
579 my @g = reverse((gmtime($time))[0..5]);
580 $g[1] += 1;
581 $g[0] %= 100;
582 sprintf "%02d%02d%02d %02d%02d%02d GMT", @g;
583}
584
585sub _grouplist
586{
587 my $nntp = shift;
588 my $arr = $nntp->read_until_dot or
589 return undef;
590
591 my $hash = {};
592 my $ln;
593
594 foreach $ln (@$arr)
595 {
596 my @a = split(/[\s\n]+/,$ln);
597 $hash->{$a[0]} = [ @a[1,2,3] ];
598 }
599
600 $hash;
601}
602
603sub _fieldlist
604{
605 my $nntp = shift;
606 my $arr = $nntp->read_until_dot or
607 return undef;
608
609 my $hash = {};
610 my $ln;
611
612 foreach $ln (@$arr)
613 {
614 my @a = split(/[\t\n]/,$ln);
615 my $m = shift @a;
616 $hash->{$m} = [ @a ];
617 }
618
619 $hash;
620}
621
622sub _articlelist
623{
624 my $nntp = shift;
625 my $arr = $nntp->read_until_dot;
626
627 chomp(@$arr)
628 if $arr;
629
630 $arr;
631}
632
633sub _description
634{
635 my $nntp = shift;
636 my $arr = $nntp->read_until_dot or
637 return undef;
638
639 my $hash = {};
640 my $ln;
641
642 foreach $ln (@$arr)
643 {
644 chomp($ln);
645
646 $hash->{$1} = $ln
647 if $ln =~ s/^\s*(\S+)\s*//o;
648 }
649
650 $hash;
651
652}
653
654##
655## The commands
656##
657
658sub _ARTICLE { shift->command('ARTICLE',@_)->response == CMD_OK }
659sub _AUTHINFO { shift->command('AUTHINFO',@_)->response }
660sub _BODY { shift->command('BODY',@_)->response == CMD_OK }
661sub _DATE { shift->command('DATE')->response == CMD_INFO }
662sub _GROUP { shift->command('GROUP',@_)->response == CMD_OK }
663sub _HEAD { shift->command('HEAD',@_)->response == CMD_OK }
664sub _HELP { shift->command('HELP',@_)->response == CMD_INFO }
665sub _IHAVE { shift->command('IHAVE',@_)->response == CMD_MORE }
666sub _LAST { shift->command('LAST')->response == CMD_OK }
667sub _LIST { shift->command('LIST',@_)->response == CMD_OK }
668sub _LISTGROUP { shift->command('LISTGROUP',@_)->response == CMD_OK }
669sub _NEWGROUPS { shift->command('NEWGROUPS',@_)->response == CMD_OK }
670sub _NEWNEWS { shift->command('NEWNEWS',@_)->response == CMD_OK }
671sub _NEXT { shift->command('NEXT')->response == CMD_OK }
672sub _POST { shift->command('POST',@_)->response == CMD_MORE }
673sub _QUIT { shift->command('QUIT',@_)->response == CMD_OK }
674sub _SLAVE { shift->command('SLAVE',@_)->response == CMD_OK }
675sub _STAT { shift->command('STAT',@_)->response == CMD_OK }
676sub _MODE { shift->command('MODE',@_)->response == CMD_OK }
677sub _XGTITLE { shift->command('XGTITLE',@_)->response == CMD_OK }
678sub _XHDR { shift->command('XHDR',@_)->response == CMD_OK }
679sub _XPAT { shift->command('XPAT',@_)->response == CMD_OK }
680sub _XPATH { shift->command('XPATH',@_)->response == CMD_OK }
681sub _XOVER { shift->command('XOVER',@_)->response == CMD_OK }
682sub _XROVER { shift->command('XROVER',@_)->response == CMD_OK }
683sub _XTHREAD { shift->unsupported }
684sub _XSEARCH { shift->unsupported }
685sub _XINDEX { shift->unsupported }
686
687##
688## IO/perl methods
689##
690
691sub DESTROY
692{
693 my $nntp = shift;
694 defined(fileno($nntp)) && $nntp->quit
695}
696
697
6981;
699
700__END__
701
702=head1 NAME
703
704Net::NNTP - NNTP Client class
705
706=head1 SYNOPSIS
707
708 use Net::NNTP;
709
710 $nntp = Net::NNTP->new("some.host.name");
711 $nntp->quit;
712
713=head1 DESCRIPTION
714
715C<Net::NNTP> is a class implementing a simple NNTP client in Perl as described
716in RFC977. C<Net::NNTP> inherits its communication methods from C<Net::Cmd>
717
718=head1 CONSTRUCTOR
719
720=over 4
721
722=item new ( [ HOST ] [, OPTIONS ])
723
724This is the constructor for a new Net::NNTP object. C<HOST> is the
725name of the remote host to which a NNTP connection is required. If not
726given then it may be passed as the C<Host> option described below. If no host is passed
727then two environment variables are checked, first C<NNTPSERVER> then
728C<NEWSHOST>, then C<Net::Config> is checked, and if a host is not found
729then C<news> is used.
730
731C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
732Possible options are:
733
734B<Host> - NNTP host to connect to. It may be a single scalar, as defined for
735the C<PeerAddr> option in L<IO::Socket::INET>, or a reference to
736an array with hosts to try in turn. The L</host> method will return the value
737which was used to connect to the host.
738
739B<Timeout> - Maximum time, in seconds, to wait for a response from the
740NNTP server, a value of zero will cause all IO operations to block.
741(default: 120)
742
743B<Debug> - Enable the printing of debugging information to STDERR
744
745B<Reader> - If the remote server is INN then initially the connection
746will be to nnrpd, by default C<Net::NNTP> will issue a C<MODE READER> command
747so that the remote server becomes innd. If the C<Reader> option is given
748with a value of zero, then this command will not be sent and the
749connection will be left talking to nnrpd.
750
751=back
752
753=head1 METHODS
754
755Unless otherwise stated all methods return either a I<true> or I<false>
756value, with I<true> meaning that the operation was a success. When a method
757states that it returns a value, failure will be returned as I<undef> or an
758empty list.
759
760=over 4
761
762=item article ( [ MSGID|MSGNUM ], [FH] )
763
764Retrieve the header, a blank line, then the body (text) of the
765specified article.
766
767If C<FH> is specified then it is expected to be a valid filehandle
768and the result will be printed to it, on success a true value will be
769returned. If C<FH> is not specified then the return value, on success,
770will be a reference to an array containg the article requested, each
771entry in the array will contain one line of the article.
772
773If no arguments are passed then the current article in the currently
774selected newsgroup is fetched.
775
776C<MSGNUM> is a numeric id of an article in the current newsgroup, and
777will change the current article pointer. C<MSGID> is the message id of
778an article as shown in that article's header. It is anticipated that the
779client will obtain the C<MSGID> from a list provided by the C<newnews>
780command, from references contained within another article, or from the
781message-id provided in the response to some other commands.
782
783If there is an error then C<undef> will be returned.
784
785=item body ( [ MSGID|MSGNUM ], [FH] )
786
787Like C<article> but only fetches the body of the article.
788
789=item head ( [ MSGID|MSGNUM ], [FH] )
790
791Like C<article> but only fetches the headers for the article.
792
793=item articlefh ( [ MSGID|MSGNUM ] )
794
795=item bodyfh ( [ MSGID|MSGNUM ] )
796
797=item headfh ( [ MSGID|MSGNUM ] )
798
799These are similar to article(), body() and head(), but rather than
800returning the requested data directly, they return a tied filehandle
801from which to read the article.
802
803=item nntpstat ( [ MSGID|MSGNUM ] )
804
805The C<nntpstat> command is similar to the C<article> command except that no
806text is returned. When selecting by message number within a group,
807the C<nntpstat> command serves to set the "current article pointer" without
808sending text.
809
810Using the C<nntpstat> command to
811select by message-id is valid but of questionable value, since a
812selection by message-id does B<not> alter the "current article pointer".
813
814Returns the message-id of the "current article".
815
816=item group ( [ GROUP ] )
817
818Set and/or get the current group. If C<GROUP> is not given then information
819is returned on the current group.
820
821In a scalar context it returns the group name.
822
823In an array context the return value is a list containing, the number
824of articles in the group, the number of the first article, the number
825of the last article and the group name.
826
827=item ihave ( MSGID [, MESSAGE ])
828
829The C<ihave> command informs the server that the client has an article
830whose id is C<MSGID>. If the server desires a copy of that
831article, and C<MESSAGE> has been given the it will be sent.
832
833Returns I<true> if the server desires the article and C<MESSAGE> was
834successfully sent,if specified.
835
836If C<MESSAGE> is not specified then the message must be sent using the
837C<datasend> and C<dataend> methods from L<Net::Cmd>
838
839C<MESSAGE> can be either an array of lines or a reference to an array.
840
841=item last ()
842
843Set the "current article pointer" to the previous article in the current
844newsgroup.
845
846Returns the message-id of the article.
847
848=item date ()
849
850Returns the date on the remote server. This date will be in a UNIX time
851format (seconds since 1970)
852
853=item postok ()
854
855C<postok> will return I<true> if the servers initial response indicated
856that it will allow posting.
857
858=item authinfo ( USER, PASS )
859
860Authenticates to the server (using AUTHINFO USER / AUTHINFO PASS)
861using the supplied username and password. Please note that the
862password is sent in clear text to the server. This command should not
863be used with valuable passwords unless the connection to the server is
864somehow protected.
865
866=item list ()
867
868Obtain information about all the active newsgroups. The results is a reference
869to a hash where the key is a group name and each value is a reference to an
870array. The elements in this array are:- the last article number in the group,
871the first article number in the group and any information flags about the group.
872
873=item newgroups ( SINCE [, DISTRIBUTIONS ])
874
875C<SINCE> is a time value and C<DISTRIBUTIONS> is either a distribution
876pattern or a reference to a list of distribution patterns.
877The result is the same as C<list>, but the
878groups return will be limited to those created after C<SINCE> and, if
879specified, in one of the distribution areas in C<DISTRIBUTIONS>.
880
881=item newnews ( SINCE [, GROUPS [, DISTRIBUTIONS ]])
882
883C<SINCE> is a time value. C<GROUPS> is either a group pattern or a reference
884to a list of group patterns. C<DISTRIBUTIONS> is either a distribution
885pattern or a reference to a list of distribution patterns.
886
887Returns a reference to a list which contains the message-ids of all news posted
888after C<SINCE>, that are in a groups which matched C<GROUPS> and a
889distribution which matches C<DISTRIBUTIONS>.
890
891=item next ()
892
893Set the "current article pointer" to the next article in the current
894newsgroup.
895
896Returns the message-id of the article.
897
898=item post ( [ MESSAGE ] )
899
900Post a new article to the news server. If C<MESSAGE> is specified and posting
901is allowed then the message will be sent.
902
903If C<MESSAGE> is not specified then the message must be sent using the
904C<datasend> and C<dataend> methods from L<Net::Cmd>
905
906C<MESSAGE> can be either an array of lines or a reference to an array.
907
908The message, either sent via C<datasend> or as the C<MESSAGE>
909parameter, must be in the format as described by RFC822 and must
910contain From:, Newsgroups: and Subject: headers.
911
912=item postfh ()
913
914Post a new article to the news server using a tied filehandle. If
915posting is allowed, this method will return a tied filehandle that you
916can print() the contents of the article to be posted. You must
917explicitly close() the filehandle when you are finished posting the
918article, and the return value from the close() call will indicate
919whether the message was successfully posted.
920
921=item slave ()
922
923Tell the remote server that I am not a user client, but probably another
924news server.
925
926=item quit ()
927
928Quit the remote server and close the socket connection.
929
930=back
931
932=head2 Extension methods
933
934These methods use commands that are not part of the RFC977 documentation. Some
935servers may not support all of them.
936
937=over 4
938
939=item newsgroups ( [ PATTERN ] )
940
941Returns a reference to a hash where the keys are all the group names which
942match C<PATTERN>, or all of the groups if no pattern is specified, and
943each value contains the description text for the group.
944
945=item distributions ()
946
947Returns a reference to a hash where the keys are all the possible
948distribution names and the values are the distribution descriptions.
949
950=item subscriptions ()
951
952Returns a reference to a list which contains a list of groups which
953are recommended for a new user to subscribe to.
954
955=item overview_fmt ()
956
957Returns a reference to an array which contain the names of the fields returned
958by C<xover>.
959
960=item active_times ()
961
962Returns a reference to a hash where the keys are the group names and each
963value is a reference to an array containing the time the groups was created
964and an identifier, possibly an Email address, of the creator.
965
966=item active ( [ PATTERN ] )
967
968Similar to C<list> but only active groups that match the pattern are returned.
969C<PATTERN> can be a group pattern.
970
971=item xgtitle ( PATTERN )
972
973Returns a reference to a hash where the keys are all the group names which
974match C<PATTERN> and each value is the description text for the group.
975
976=item xhdr ( HEADER, MESSAGE-SPEC )
977
978Obtain the header field C<HEADER> for all the messages specified.
979
980The return value will be a reference
981to a hash where the keys are the message numbers and each value contains
982the text of the requested header for that message.
983
984=item xover ( MESSAGE-SPEC )
985
986The return value will be a reference
987to a hash where the keys are the message numbers and each value contains
988a reference to an array which contains the overview fields for that
989message.
990
991The names of the fields can be obtained by calling C<overview_fmt>.
992
993=item xpath ( MESSAGE-ID )
994
995Returns the path name to the file on the server which contains the specified
996message.
997
998=item xpat ( HEADER, PATTERN, MESSAGE-SPEC)
999
1000The result is the same as C<xhdr> except the is will be restricted to
1001headers where the text of the header matches C<PATTERN>
1002
1003=item xrover
1004
1005The XROVER command returns reference information for the article(s)
1006specified.
1007
1008Returns a reference to a HASH where the keys are the message numbers and the
1009values are the References: lines from the articles
1010
1011=item listgroup ( [ GROUP ] )
1012
1013Returns a reference to a list of all the active messages in C<GROUP>, or
1014the current group if C<GROUP> is not specified.
1015
1016=item reader
1017
1018Tell the server that you are a reader and not another server.
1019
1020This is required by some servers. For example if you are connecting to
1021an INN server and you have transfer permission your connection will
1022be connected to the transfer daemon, not the NNTP daemon. Issuing
1023this command will cause the transfer daemon to hand over control
1024to the NNTP daemon.
1025
1026Some servers do not understand this command, but issuing it and ignoring
1027the response is harmless.
1028
1029=back
1030
1031=head1 UNSUPPORTED
1032
1033The following NNTP command are unsupported by the package, and there are
1034no plans to do so.
1035
1036 AUTHINFO GENERIC
1037 XTHREAD
1038 XSEARCH
1039 XINDEX
1040
1041=head1 DEFINITIONS
1042
1043=over 4
1044
1045=item MESSAGE-SPEC
1046
1047C<MESSAGE-SPEC> is either a single message-id, a single message number, or
1048a reference to a list of two message numbers.
1049
1050If C<MESSAGE-SPEC> is a reference to a list of two message numbers and the
1051second number in a range is less than or equal to the first then the range
1052represents all messages in the group after the first message number.
1053
1054B<NOTE> For compatibility reasons only with earlier versions of Net::NNTP
1055a message spec can be passed as a list of two numbers, this is deprecated
1056and a reference to the list should now be passed
1057
1058=item PATTERN
1059
1060The C<NNTP> protocol uses the C<WILDMAT> format for patterns.
1061The WILDMAT format was first developed by Rich Salz based on
1062the format used in the UNIX "find" command to articulate
1063file names. It was developed to provide a uniform mechanism
1064for matching patterns in the same manner that the UNIX shell
1065matches filenames.
1066
1067Patterns are implicitly anchored at the
1068beginning and end of each string when testing for a match.
1069
1070There are five pattern matching operations other than a strict
1071one-to-one match between the pattern and the source to be
1072checked for a match.
1073
1074The first is an asterisk C<*> to match any sequence of zero or more
1075characters.
1076
1077The second is a question mark C<?> to match any single character. The
1078third specifies a specific set of characters.
1079
1080The set is specified as a list of characters, or as a range of characters
1081where the beginning and end of the range are separated by a minus (or dash)
1082character, or as any combination of lists and ranges. The dash can
1083also be included in the set as a character it if is the beginning
1084or end of the set. This set is enclosed in square brackets. The
1085close square bracket C<]> may be used in a set if it is the first
1086character in the set.
1087
1088The fourth operation is the same as the
1089logical not of the third operation and is specified the same
1090way as the third with the addition of a caret character C<^> at
1091the beginning of the test string just inside the open square
1092bracket.
1093
1094The final operation uses the backslash character to
1095invalidate the special meaning of an open square bracket C<[>,
1096the asterisk, backslash or the question mark. Two backslashes in
1097sequence will result in the evaluation of the backslash as a
1098character with no special meaning.
1099
1100=over 4
1101
1102=item Examples
1103
1104=item C<[^]-]>
1105
1106matches any single character other than a close square
1107bracket or a minus sign/dash.
1108
1109=item C<*bdc>
1110
1111matches any string that ends with the string "bdc"
1112including the string "bdc" (without quotes).
1113
1114=item C<[0-9a-zA-Z]>
1115
1116matches any single printable alphanumeric ASCII character.
1117
1118=item C<a??d>
1119
1120matches any four character string which begins
1121with a and ends with d.
1122
1123=back
1124
1125=back
1126
1127=head1 SEE ALSO
1128
1129L<Net::Cmd>
1130
1131=head1 AUTHOR
1132
1133Graham Barr <[email protected]>
1134
1135=head1 COPYRIGHT
1136
1137Copyright (c) 1995-1997 Graham Barr. All rights reserved.
1138This program is free software; you can redistribute it and/or modify
1139it under the same terms as Perl itself.
1140
1141=for html <hr>
1142
1143I<$Id: //depot/libnet/Net/NNTP.pm#18 $>
1144
1145=cut
Note: See TracBrowser for help on using the repository browser.