├── CREDITS ├── log └── run ├── run ├── TODO ├── config-to-checkgroups ├── monitor ├── INSTALL ├── colobus_feeder ├── mbox2ezmlm ├── LICENSE ├── colobus.sql ├── colobus_requeue ├── config.example ├── README ├── Colobus.pm ├── colobus-archive ├── colobus ├── rfc1036.txt ├── rfc977.txt └── rfc2980.txt /CREDITS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abh/colobus/HEAD/CREDITS -------------------------------------------------------------------------------- /log/run: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | exec multilog t s1000000 n20 /var/log/colobus 3 | -------------------------------------------------------------------------------- /run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec softlimit -m 20000000 \ 3 | tcpserver -X -x rules.cdb -c 60 -vhR -u 515 -g 514 0 119 /pkg/bin/perl ./colobus 2>&1 4 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | * implement option to skip sending banner and let tcpserver do it 2 | 3 | * take advantage of database for requests that return info about 4 | multiple articles 5 | 6 | * clean up encoded subjects correctly (need to decode first) 7 | -- can use Encode::MIME::Header, but it requires perl 5.7.3 8 | 9 | * tie STDOUT so we can track bytes output accurately 10 | -------------------------------------------------------------------------------- /config-to-checkgroups: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | use strict; 3 | 4 | =pod 5 | 6 | Helper script for converting colobus config format to a checkgroups 7 | list. 8 | 9 | =cut 10 | 11 | use Colobus qw(%config read_config); 12 | read_config($ARGV[0] or 'config'); 13 | 14 | for my $g (sort keys %groups) { 15 | print $g,"\t\t",$groups{$g}->{mail}; # we want to use desc here, but it's probably too long 16 | print " (Moderated)" if $groups{$g}->{moderated}; 17 | print "\n"; 18 | } 19 | -------------------------------------------------------------------------------- /monitor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | # Copyright (c) 2001 Jim Winstead Jr. See the LICENSE file for details. 3 | use strict; 4 | 5 | use Net::NNTP (); 6 | 7 | $SIG{ALRM} = sub { 8 | die "timed out\n"; 9 | }; 10 | 11 | alarm 10; 12 | 13 | my $nntp = new Net::NNTP "localhost" 14 | or die("couldn't connect"); 15 | 16 | my $groups = $nntp->list() 17 | or die("couldn't get list of groups"); 18 | 19 | foreach my $group (keys %$groups) { 20 | my ($total,$first,$last,$name) = $nntp->group($group) 21 | or die("couldn't enter group $group"); 22 | my $head = $nntp->head($last) 23 | or die("couldn't get head of $group/$last"); 24 | } 25 | 26 | $nntp->quit; 27 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | * create a database and load the table definition in colobus.sql 2 | * copy ./config.example to ./config and edit as appropriate for your 3 | site 4 | * edit ./run and change the user and group ids used to something 5 | appropriate 6 | * edit ./log/run and make sure the logs go where you want 7 | * chmod +t `pwd` 8 | * run ./colobus-archive -a to create the initial databases (may take a while) 9 | * ln -s `pwd` /service/colobus 10 | * wait a minute for svscan to pick up the new service 11 | * test with a newsreader 12 | * run ./colobus-archive -a regularly (like from cron) to keep the 13 | overview database up to date. it can also be run from within the 14 | editor file for your list (and you can restrict it to just updating 15 | the overview for that group). 16 | 17 | (not using http://cr.yp.to/daemontools.html and 18 | http://cr.yp.to/ucspi-tcp.html? you're on your own.) 19 | -------------------------------------------------------------------------------- /colobus_feeder: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | use strict; 3 | use Colobus qw(%config %feeds %groups read_config); 4 | use Carp; 5 | 6 | read_config(); 7 | 8 | for my $feed (keys %feeds) { 9 | #next unless $feed eq "nntpfeed"; 10 | print "processing $feed\n" if -t STDIN; 11 | my $host = $feeds{$feed}->{host}; 12 | my %args; 13 | %args = (silent => 1) unless -t STDIN; 14 | run("tcpclient -RHl0 $host nntp $^X ./colobus -s $feed", { %args, failok => 1 }); 15 | } 16 | 17 | sub run { 18 | my @ar = @_; 19 | my $parms = ref $ar[-1] eq "HASH" ? pop @ar : {}; 20 | 21 | print "Running: ", join(" ",@ar), "\n" unless $parms->{silent}; 22 | 23 | return 1 if system (@ar) == 0; 24 | 25 | my $exit_value = $? >> 8; 26 | return 0 if $parms->{fail_silent_if} 27 | && $exit_value == $parms->{fail_silent_if}; 28 | 29 | my $msg = "system @ar failed: $exit_value ($?)"; 30 | croak $msg unless $parms->{failok}; 31 | print "$msg\n" ; 32 | return 0; 33 | } 34 | 35 | 1; 36 | -------------------------------------------------------------------------------- /mbox2ezmlm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | # Copyright (c) 2002 Jim Winstead Jr. See the LICENSE file for details. 3 | use strict; 4 | use File::Path qw(mkpath); 5 | use Date::Parse qw(str2time); 6 | 7 | my $dir = shift 8 | or die "usage: $0 directory < mbox\n"; 9 | 10 | die "usage: $0 directory < mbox\n" if -t; 11 | 12 | die "$0: $dir is not a directory\n" unless -d $dir; 13 | 14 | my $count = 0; 15 | my $size = 0; 16 | my $date = 0; 17 | my $file; 18 | 19 | while (<>) { 20 | if (/^From .+?@.+? (.+)/) { 21 | close OUT if $file; 22 | utime time, $date, $file if $file; 23 | $count++; 24 | my $path = sprintf("%s/archive/%d", $dir, int($count/100)); 25 | mkpath($path); 26 | $file = "$path/".sprintf("%02d",$count%100); 27 | $date = str2time($1) || time; 28 | open OUT, ">$file" 29 | or die "couldn't open $file for writing: $!\n"; 30 | chmod 0744, $file; 31 | next; 32 | } 33 | print OUT $_ if $file; 34 | $size += length $_; 35 | } 36 | close OUT; 37 | 38 | $size = int($size / 256); 39 | 40 | open NUM, ">$dir/num"; 41 | print NUM "$count:$size\n"; 42 | close NUM; 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2001 Jim Winstead Jr. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /colobus.sql: -------------------------------------------------------------------------------- 1 | 2 | DROP TABLE IF EXISTS groups; 3 | CREATE TABLE groups ( 4 | id smallint unsigned not null primary key, 5 | name varchar(255) not null, 6 | description varchar(255) not null, 7 | unique key (name) 8 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 9 | 10 | DROP TABLE IF EXISTS articles; 11 | CREATE TABLE articles ( 12 | group_id smallint(5) unsigned NOT NULL default '0', 13 | id int(10) unsigned NOT NULL default '0', 14 | msgid varchar(32) NOT NULL default '', 15 | subjhash varchar(32) NOT NULL default '', 16 | fromhash varchar(32) NOT NULL default '', 17 | thread_id int(10) unsigned NOT NULL default '0', 18 | parent int(10) unsigned NOT NULL default '0', 19 | received datetime NOT NULL default '0000-00-00 00:00:00', 20 | h_date varchar(255) NOT NULL default '', 21 | h_messageid varchar(255) NOT NULL default '', 22 | h_from varchar(255) NOT NULL default '', 23 | h_subject varchar(255) NOT NULL default '', 24 | h_references varchar(8192) NOT NULL default '', 25 | h_lines mediumint(8) unsigned NOT NULL default '0', 26 | h_bytes int(10) unsigned NOT NULL default '0', 27 | PRIMARY KEY (group_id,id), 28 | KEY msgid (msgid), 29 | KEY fromhash (fromhash), 30 | KEY grp (group_id,received), 31 | KEY grp_2 (group_id,thread_id,parent), 32 | KEY grp_3 (group_id,subjhash), 33 | KEY subjhash ( subjhash, received ), 34 | CONSTRAINT `articles_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`) 35 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 36 | 37 | -------------------------------------------------------------------------------- /colobus_requeue: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | use strict; 3 | use Colobus qw(%config %feeds %groups get_group_max open_article); 4 | use Carp; 5 | use File::Path qw(mkpath); 6 | use Symbol; 7 | 8 | Colobus::read_config(); 9 | 10 | my %feeds_fh; 11 | my $timestamp; 12 | my $serial = 0; 13 | 14 | my $qfeed = shift; 15 | 16 | reopen(); 17 | 18 | for my $group (keys %groups) { 19 | print "doing $group\n"; 20 | for my $i (1..get_group_max($group)) { 21 | my $f; 22 | next unless $f = open_article($group, $i) and close $f; 23 | for my $feed (keys %feeds) { 24 | next unless !$qfeed or $feed eq $qfeed; 25 | my $fh = $feeds_fh{$feed}; 26 | print $fh "$group/$i\n"; 27 | } 28 | reopen() unless $i % 250; 29 | } 30 | reopen(); 31 | } 32 | 33 | reopen(); 34 | 35 | sub reopen { 36 | for my $feed (keys %feeds) { 37 | next unless !$qfeed or $feed eq $qfeed; 38 | if ($feeds_fh{$feed}) { 39 | close $feeds_fh{$feed}; 40 | $feeds_fh{$feed} = undef; 41 | rename "feeds/$feed/$timestamp.$serial.$$.tmp", "feeds/$feed/$timestamp.$serial.$$" 42 | or die "could not rename feeds/$feed/$timestamp.$serial.$$.tmp feeds/$feed/$timestamp.$serial.$$: $!"; 43 | } 44 | $serial++; 45 | $timestamp = time; 46 | mkpath "feeds/$feed" unless -e "feeds/$feed"; 47 | my $fh = Symbol::gensym(); 48 | open ($fh, ">feeds/$feed/$timestamp.$serial.$$.tmp") 49 | or die "Could not open spool file for feed $feed: $!"; 50 | $feeds_fh{$feed} = $fh; 51 | } 52 | } 53 | 54 | 55 | 1; 56 | -------------------------------------------------------------------------------- /config.example: -------------------------------------------------------------------------------- 1 | # servername is used in some of the server's output 2 | servername => example.com 3 | 4 | # timeout is in seconds 5 | timeout => 300 6 | 7 | # disallow specific nntp commands 8 | disallow => ihave,xindex 9 | 10 | # dsn for connecting to database 11 | dsn => DBI:mysql:database=colobus;host=localhost 12 | dbuser => colobus 13 | dbpass => colobus 14 | 15 | # newsgroups 16 | # 17 | # the fields used are: 18 | # - num = the number of the newsgroup (must be unique) 19 | # - path = path to ezmlm directory for the mailing list corresponding 20 | # to this newsgroup (only num and archive/ need to be readable) 21 | # - mail = mail address to send posts to (leave out to disallow posting) 22 | # - desc = description to show for this newsgroup 23 | # - first = first post in group (in case your archive doesn't start at 1) 24 | # - moderated = moderated group (some newsreaders display this specially) 25 | # - recommend = recommend this group to new subscribers (not many 26 | # clients pay attention to this information) 27 | # - hidden = don't show in listings 28 | 29 | group example.announce { 30 | num => 1 31 | path => /path/to/ezmlm/announce 32 | mail => announce@example.com 33 | desc => Announcements 34 | moderated 35 | recommend 36 | } 37 | 38 | group example.general { 39 | num => 2 40 | path => /path/to/ezmlm/general 41 | mail => general@example.com 42 | desc => General discussion 43 | } 44 | 45 | group example.cvs { 46 | num => 3 47 | path => /path/to/ezmlm/cvs 48 | desc => Automated mailings from commits to the CVS repository 49 | followup => example.general 50 | } 51 | 52 | group example.test { 53 | num => 4 54 | path => /path/to/ezmlm/test 55 | mail => test@example.com 56 | desc => Used for testing the mailing lists and news server 57 | hidden 58 | } 59 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | colobus is an nntp server, written in perl, that provides access to 2 | mail archives in the ezmlm archive format. 3 | 4 | basic installation instructions can be found in the INSTALL file. 5 | 6 | the license (mit-style) can be found in the LICENSE file. 7 | 8 | it uses the DBI perl module to maintain the overview database, so you'll need 9 | to install that and the relevant DBD driver (only MySQL has been tested) if 10 | they aren't already installed. 11 | 12 | it uses the Mail::Address perl module (from MailTools) to parse mail 13 | addresses and make them presentable to news clients (which have a 14 | stricter requirement for the format of the From: header). 15 | 16 | it implements all of rfc 977 (although it will always returns an empty 17 | result for 'newnews' commands). it also ignores the 'distributions' 18 | parameters on the 'newnews' and 'newgroups' commands. 19 | 20 | it implements the extended 'list', 'mode reader', 'mode stream', 21 | 'xgtitle', 'xhdr', 'xpat', 'xpath', 'xover', and 'xrover' commands 22 | from rfc 2980. 23 | 24 | it implements a completely non-standard 'xversion' command to get the 25 | version of the news server. 26 | 27 | (the relevant rfc documents have been included in the distribution, 28 | by the way.) 29 | 30 | it supports posting by forwarding the post as an email to the list 31 | addresses, with the envelope sender sent to the from address of the 32 | news posting. it handles cross-posting by posting to each list 33 | seperately. it adds an 'Received:' header that includes the ip address 34 | of the poster, to help track evil-doers. 35 | 36 | information about the black-and-white colobus can be found at 37 | http://www.selu.com/bio/PrimateGallery/PrimateWeek/Colobus/. 38 | 39 | additionally, information about the red colobus can be found at 40 | http://www.bioko.org/primates/pennanti.asp. 41 | 42 | jim winstead , may 2004 43 | http://trainedmonkey.com/colobus/ 44 | -------------------------------------------------------------------------------- /Colobus.pm: -------------------------------------------------------------------------------- 1 | package Colobus; 2 | use strict; 3 | use vars qw(@EXPORT_OK @ISA %config %groups %feeds); 4 | use Exporter; 5 | @EXPORT_OK = qw(%config %groups %feeds get_group_max open_article read_config); 6 | @ISA = qw(Exporter); 7 | 8 | %config = ( 9 | timeout => 300, 10 | servername => 'news', 11 | ); 12 | 13 | sub read_config { 14 | my $file = shift || "config"; 15 | my $fh; 16 | open $fh, "<$file" 17 | or die "unable to open file '$file': $!"; 18 | 19 | my ($group, $feed); 20 | 21 | while (<$fh>) { 22 | chomp; 23 | next if m/^\s*#/; 24 | next unless /\S/; 25 | 26 | $group = $feed = undef, next if m/}/; 27 | 28 | my ($k,$v) = map { s/^\s*(.+?)\s*$/$1/; $_; } split /\s+=>\s+/; 29 | if ($k) { 30 | read_config($v), next if lc $k eq "include"; 31 | $feeds{$feed}{$k} = $v, next 32 | if $feed; 33 | $groups{$group}{$k} = $v, next 34 | if $group; 35 | $config{$k} = $v; 36 | } 37 | 38 | unless ($group or $feed) { 39 | if (my ($k) = $_ =~ m/\s*(.*?)\s*{/) { 40 | ($k =~ s/^(feed|group)\s+// and defined $1 and $1 eq "feed") 41 | ? $feed = $k 42 | : $group = $k; 43 | } 44 | } 45 | 46 | } 47 | close $fh; 48 | 49 | } 50 | 51 | sub get_group_max { 52 | my ($group) = lc shift 53 | or return; 54 | return unless exists $groups{$group}; 55 | my $num_file = $groups{$group}->{path}."/num"; 56 | if (open FILE, "<$num_file") { 57 | my ($max) = ( =~ m/^(\d+)/); 58 | close FILE; 59 | return $max; 60 | } 61 | else { 62 | warn "Could not open $num_file: $!\n"; 63 | } 64 | } 65 | 66 | sub open_article { 67 | my ($group,$artno) = @_; 68 | return unless exists $groups{$group}; 69 | my $fh = Symbol::gensym(); 70 | my $file = sprintf("%s/archive/%d/%02d", $groups{$group}->{path}, 71 | int $artno / 100, $artno % 100); 72 | open $fh, "<$file" 73 | or return; 74 | return $fh; 75 | } 76 | 77 | 78 | 1; 79 | -------------------------------------------------------------------------------- /colobus-archive: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | use strict; 3 | 4 | use DBI (); 5 | use Mail::Address (); 6 | use Digest::MD5 qw(md5_hex); 7 | use Symbol qw(gensym); 8 | use Getopt::Long; 9 | use File::Path qw(mkpath); 10 | 11 | use Data::Dumper; 12 | 13 | use Colobus qw(%config %feeds %groups get_group_max open_article read_config); 14 | 15 | my $TRACE = -t || $ENV{TRACE}; 16 | 17 | my $group; 18 | 19 | $| = 1; 20 | 21 | my $config = "config"; 22 | my $all; 23 | GetOptions( 24 | "a|all!" => \$all, 25 | "c|config=s" => \$config, 26 | "d|debug!" => \$TRACE, 27 | ); 28 | 29 | read_config($config); 30 | 31 | @ARGV = sort keys %groups if $all; 32 | 33 | die "usage: $0 [-a] [-c config] group ...\n" unless @ARGV; 34 | 35 | # TODO -- add support for 'Bytes' here 36 | 37 | # these are the headers we track for the overview database 38 | my (@overview) = qw(Subject From Date Message-ID References In-Reply-To Lines); 39 | my (%overview); @overview{@overview} = ('') x @overview; 40 | 41 | my $dsn = $config{'dsn'} || "DBI:mysql:database=colobus;host=localhost"; 42 | my $dbh = DBI->connect($dsn, $config{'dbuser'}, $config{'dbpass'}, { PrintError => 1 }) 43 | or die($DBI::errstr); 44 | 45 | if (grep { !$groups{$_}->{num} } keys %groups) { 46 | my $db_groups = $dbh->selectall_hashref(q[select name,id from groups], 'name' ); 47 | my $maxid = 0; 48 | while (my ($name, $data) = each %$db_groups) { 49 | my $id = $data->{id}; 50 | $groups{$name}->{num} = $id unless $groups{$name}->{num}; 51 | $maxid = $id if $id > $maxid; 52 | warn "group num in groups table and config file differs for $name\n" 53 | unless $groups{$name}->{num} == $id; 54 | } 55 | 56 | $_ > $maxid and $maxid = $_ for map { $_->{num} } values %groups; 57 | 58 | while (my ($name, $id) = each %groups) { 59 | next if ($db_groups->{$name}); 60 | my $id = ($groups{$name}->{num}) || ++$maxid; 61 | $dbh->do(q[insert into groups (name, id) values (?,?)], undef, $name, $id); 62 | } 63 | } 64 | 65 | my $ins_header = $dbh->prepare(<feeds/$feed/$timestamp.$$.tmp") 88 | or die "Could not open spool file for feed $feed: $!"; 89 | $feed_fh{$feed} = $fh; 90 | } 91 | 92 | for $group (@ARGV) { 93 | next unless $groups{$group}->{'num'}; 94 | my $grp = $groups{$group}->{'num'}; 95 | 96 | print "$group: " if $TRACE; 97 | 98 | my ($indexed) = $dbh->selectrow_array("SELECT MAX(id) FROM articles WHERE group_id = ?", undef, $grp) || 0; 99 | 100 | open NUM, '<', $groups{$group}->{'path'}."/num" 101 | or die "unable to open num file: $!"; 102 | my ($latest) = (split ':', scalar )[0]; 103 | close NUM; 104 | 105 | for my $num ($indexed + 1 .. $latest) { 106 | print "." if $TRACE and not $num % 100; 107 | my $xover = get_article_xover_from_file($group, $num) or next; 108 | my $ref = $xover->{'References'} || ''; 109 | my (@parents) = $ref =~ m/<(.+?)>/m; 110 | $xover->{'In-Reply-To'} && $xover->{'In-Reply-To'} =~ m/<(.+?)>/ && push @parents, $1; 111 | 112 | my $parent; 113 | while (my $parent_msg = pop(@parents)) { 114 | $parent = $dbh->selectrow_hashref("SELECT id,thread_id FROM articles WHERE msgid = ?", undef, md5_hex($parent_msg)); 115 | last if $parent; 116 | } 117 | 118 | my $subj_hash = md5_hex(clean_subject($xover->{'Subject'} || '')); 119 | 120 | # if no parent, but subject starts with 'Re:', try to find the parent/thread 121 | if (!$parent && $xover->{'Subject'} && $xover->{'Subject'} =~ m/^(Re|An|Antwort|Aw)(\^\d+|\[\d+\]|\(\d+\))?:\s*/i) { 122 | $parent = $dbh->selectrow_hashref("SELECT thread_id FROM articles WHERE subjhash = ? AND received BETWEEN FROM_UNIXTIME(?) - INTERVAL 14 DAY AND FROM_UNIXTIME(?) ORDER BY received DESC LIMIT 1", undef, $subj_hash, $xover->{'mtime'}, $xover->{'mtime'}); 123 | } 124 | 125 | # if no parent, try grouping the message with other very recent messages with the same subject 126 | if (!$parent && $xover->{'Subject'}) { 127 | $parent = $dbh->selectrow_hashref("SELECT thread_id FROM articles WHERE subjhash = ? AND received BETWEEN FROM_UNIXTIME(?) - INTERVAL 3 DAY AND FROM_UNIXTIME(?) ORDER BY received DESC LIMIT 1", undef, $subj_hash, $xover->{'mtime'}, $xover->{'mtime'}); 128 | } 129 | 130 | my ($message_id) = md5_hex($xover->{'Message-ID'} =~ m/<(.+?)>/); 131 | my ($from_hash) = md5_hex($xover->{'From'}); 132 | 133 | $ins_header->execute( 134 | $grp, 135 | $num, 136 | $message_id, 137 | $subj_hash, 138 | $from_hash, 139 | $parent->{'thread_id'} || $num, 140 | $parent->{'id'} || 0, 141 | $xover->{'mtime'}, 142 | $xover->{'Date'} || "", 143 | $xover->{'Message-ID'} || "", 144 | $xover->{'From'} || "", 145 | $xover->{'Subject'} || "", 146 | $xover->{'References'} || "", 147 | $xover->{'Lines'} || 0, 148 | ) or die "failed to insert into overview: $DBI::errstr"; 149 | 150 | for my $feed (keys %feeds) { 151 | my $fh = $feed_fh{$feed}; 152 | local $| = 1; 153 | print $fh "$group/$num\n" or die "could not print to fh for $feed: $!"; 154 | } 155 | 156 | } 157 | 158 | print " done.\n" if $TRACE; 159 | } 160 | 161 | for my $feed (keys %feeds) { 162 | close $feed_fh{$feed} or die "could not close spool file for feed $feed: $!"; 163 | rename "feeds/$feed/$timestamp.$$.tmp", "feeds/$feed/$timestamp.$$" 164 | or die "could not rename spool file for feed $feed: $!"; 165 | } 166 | 167 | sub clean_subject { 168 | my $subj = shift; 169 | my $i; 170 | while ($subj =~ s/^(Re|An|Antwort|Aw)(\^\d+|\[\d+\]|\(\d+\))?:\s*//i) { last if $i++ > 5 }; 171 | $subj =~ s/\s//g; 172 | return lc $subj; 173 | } 174 | 175 | 176 | sub get_article_xover_from_file { 177 | my ($group,$artno) = @_; 178 | return unless exists $groups{$group}; 179 | my $article = open_article($group,$artno) 180 | or return; 181 | my (%xover); 182 | $xover{'mtime'} = (stat $article)[9]; 183 | my $body = 0; 184 | my $lines = 0; 185 | my $lastheader; 186 | LINE: 187 | while (my $line = <$article>) { 188 | $body = 1 unless $body or $line =~ /\S/; 189 | last if $body and $xover{Lines}; 190 | $lines++ if $body; 191 | unless ($body) { 192 | if ($lastheader && ($line =~ m/^\s+(.+?)\r?\n/is)) { 193 | ($xover{$lastheader} .= $1) =~ s/\s/ /g; 194 | next; 195 | } 196 | foreach my $header (keys %overview) { 197 | if ($line =~ m/^$header: *(.*)\r?\n/is) { 198 | ($xover{$lastheader = $header} = $1) =~ s/\s/ /g; 199 | next LINE; 200 | } 201 | } 202 | undef $lastheader; 203 | } 204 | } 205 | 206 | if (!$xover{'References'} && $xover{'In-Reply-To'}) { 207 | ($xover{'References'}) = ($xover{'In-Reply-To'} =~ m/(<.+?>)/); 208 | } 209 | 210 | $xover{'Lines'} ||= $lines; 211 | 212 | # make sure we have a message-id 213 | $xover{'Message-ID'} ||= "<$group-$artno\@$config{servername}>"; 214 | 215 | # fix the From header 216 | my ($from) = Mail::Address->parse($xover{'From'}); 217 | if ($from) { 218 | $xover{From} = $from->address; 219 | my $phrase = $from->phrase || $from->comment; 220 | $xover{From} .= " (".$phrase.")" if $phrase; 221 | } 222 | else { 223 | $xover{From} = "bogus\@$config{servername} (Unknown Sender)"; 224 | } 225 | return \%xover; 226 | } 227 | -------------------------------------------------------------------------------- /colobus: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | # Copyright (c) 2001,2003,2004 Jim Winstead Jr. 3 | # Copyright (c) 2001,2003,2004,2005,2006,2009 Ask Bjørn Hansen 4 | # See the LICENSE file for details. 5 | use strict; 6 | 7 | $| = 1; 8 | 9 | # this is designed to be run under tcpserver 10 | # (http://cr.yp.to/ucspi-tcp.html) 11 | # or inetd if you're into that sort of thing 12 | 13 | package Colobus; 14 | $Colobus::VERSION = "3.0"; 15 | 16 | if (-e ".git") { 17 | local $ENV{PATH} = "/usr/bin:/usr/local/bin:/opt/local/bin/"; 18 | if (my $git = `git describe`) { 19 | chomp $git; 20 | $Colobus::VERSION .= " ($git)"; 21 | } 22 | } 23 | 24 | my $TRACE = $ENV{TRACE}; 25 | $TRACE++ if -t STDIN and not defined $TRACE; 26 | 27 | # spool_feeds will set this to 0 so it can send commands manually 28 | my $RESPOND = 1; 29 | 30 | my $REMOTE = $ENV{TCPREMOTEIP} || 'console'; 31 | 32 | $0 = "colobus: $REMOTE"; 33 | 34 | use POSIX (); 35 | use DBI (); 36 | use Digest::MD5 qw(md5_hex); 37 | use Mail::Address (); 38 | use Time::Local (); 39 | use Symbol (); 40 | 41 | use Colobus qw(%config %feeds %groups get_group_max open_article read_config); 42 | 43 | # setting this to qw(/usr/sbin/sendmail) should work, but DO NOT ADD -t! 44 | my (@mailinject) = qw(/var/qmail/bin/qmail-inject -a); 45 | 46 | my ($group,$current); # the current group and article number (state!) 47 | 48 | my $config = 'config'; 49 | 50 | read_config($config); 51 | 52 | # these are the commands we understand, so far 53 | my (@commands) = qw(article body date group head help ihave last list 54 | listgroup mode next newgroups newnews post quit slave 55 | stat xgtitle xhdr xover xpat xpath xrover xversion); 56 | my (%commands); @commands{@commands} = ('') x @commands; 57 | if ($config{disallow}) { 58 | foreach (map { s/^\s*(.+?)\s*$/$1/; $_; } split /,/, $config{disallow}) { 59 | delete $commands{$_}; 60 | } 61 | } 62 | 63 | # these are the headers we track for the overview database 64 | my (@overview) = qw(Subject From Date Message-ID References Bytes Lines); 65 | my (%overview); @overview{@overview} = ('') x @overview; 66 | 67 | my $dsn = $config{'dsn'} || "DBI:mysql:database=colobus;host=localhost"; 68 | my $dbh = DBI->connect($dsn, $config{'dbuser'}, $config{'dbpass'}, { PrintError => 1 }) 69 | or die($DBI::errstr); 70 | 71 | 72 | if (grep { !$groups{$_}->{num} } keys %groups) { 73 | my $db_groups = $dbh->selectall_hashref(q[select name,id from groups], 'name' ); 74 | my $maxid = 0; 75 | while (my ($name, $data) = each %$db_groups) { 76 | my $id = $data->{id}; 77 | $groups{$name}->{num} = $id unless $groups{$name}->{num}; 78 | $maxid = $id if $id > $maxid; 79 | warn "group num in groups table and config file differs for $name\n" 80 | unless $groups{$name}->{num} == $id; 81 | } 82 | 83 | $_ > $maxid and $maxid = $_ for map { $_->{num} || 0 } values %groups; 84 | 85 | while (my ($name, $id) = each %groups) { 86 | next if ($db_groups->{$name}); 87 | my $id = ($groups{$name}->{num}) || ++$maxid; 88 | $dbh->do(q[insert into groups (name, id) values (?,?)], undef, $name, $id); 89 | } 90 | } 91 | 92 | my %groupsbyid; 93 | foreach (keys %groups) { 94 | next unless $groups{$_}->{num}; 95 | $groupsbyid{$groups{$_}->{num}} = $_; 96 | } 97 | 98 | my $query = <= ? AND id <= ? 108 | END 109 | 110 | my $xover_sth = $dbh->prepare($query) 111 | or die($DBI::errstr); 112 | 113 | if (@ARGV && $ARGV[0] eq '-s') { 114 | spool_feed($ARGV[1]); exit; 115 | } 116 | 117 | $SIG{ALRM} = sub { respond(500, "Timeout!"),exit; }; 118 | 119 | # output the greeting 120 | # XXX provide an option so one could have tcpserver send the banner 121 | respond(200, "$config{servername} - colobus $Colobus::VERSION ready - (posting ok)."); 122 | 123 | alarm $config{timeout}; 124 | while () { 125 | $_ =~ s/\r?\n$//s; # advanced chomp 126 | warn "dispatching $_\n" if $TRACE; 127 | defined dispatch(split / +/, $_) 128 | or respond(500, "command '$_' not recognized"); 129 | alarm $config{timeout}; 130 | } 131 | 132 | sub dispatch { 133 | my ($cmd) = lc shift; 134 | 135 | if (exists $commands{$cmd}) { 136 | my ($result) = eval "&$cmd"; 137 | warn $@ if $@; 138 | return $result if defined $result; 139 | return fault("command '$cmd' failed unexpectedly"); 140 | } 141 | 142 | return; 143 | } 144 | 145 | my $curpos = 0; 146 | 147 | sub respond { 148 | my ($code, $message) = @_; 149 | return "$code $message" unless $RESPOND; 150 | warn "$code $message\n" if $TRACE and !-t STDIN; 151 | my $s = print "$code $message\r\n"; 152 | $curpos = tell STDOUT; 153 | return $s; 154 | } 155 | 156 | sub dot () { 157 | warn ".\n" if $TRACE and !-t STDIN; 158 | print ".\r\n"; 159 | } 160 | 161 | sub fault { 162 | my ($msg) = shift || "program fault - command not performed"; 163 | return respond(503, $msg); 164 | } 165 | 166 | sub note { 167 | my ($path,$method,$code,$bytes) = @_; 168 | return unless $path; 169 | $method ||= 'GET'; 170 | $code ||= 200; 171 | $bytes ||= 0; 172 | if ((my $pos = tell STDOUT) > 0) { 173 | $bytes ||= $pos - $curpos; 174 | } 175 | print STDERR "$REMOTE - - ", 176 | POSIX::strftime("[%d/%b/%Y:%H:%M:%S %z]", localtime), 177 | " \"$method $path HTTP/1.0\" $code $bytes\n"; 178 | } 179 | 180 | sub get_group_active { 181 | my ($group) = lc shift 182 | or return; 183 | return 'n' unless exists $groups{$group} && $groups{$group}->{mail}; 184 | return 'm' if exists $groups{$group}->{moderated}; 185 | return 'y'; 186 | } 187 | 188 | sub get_group_description { 189 | my ($group) = lc shift 190 | or return; 191 | return unless exists $groups{$group} && $groups{$group}->{desc}; 192 | return $groups{$group}->{desc}; 193 | } 194 | 195 | sub get_group_minmax { 196 | my ($group) = lc shift; 197 | my $grp = $groups{$group}->{'num'} 198 | or return; 199 | return $dbh->selectrow_array("SELECT MIN(id),MAX(id) FROM articles WHERE group_id = ?", undef, $grp); 200 | } 201 | 202 | # we guess the group creation time from the modified time of the 203 | # first message in the archive. should be close enough. 204 | sub get_group_creation { 205 | my ($group) = lc shift 206 | or return; 207 | return unless exists $groups{$group}; 208 | my ($artno) = get_group_minmax($group); 209 | my $file = sprintf("%s/archive/%d/%02d", $groups{$group}->{path}, 210 | int $artno / 100, $artno % 100); 211 | return (stat($file))[9]; 212 | } 213 | 214 | sub get_group_recommend { 215 | my ($group) = lc shift 216 | or return; 217 | return exists $groups{$group} && exists $groups{$group}->{recommend}; 218 | } 219 | 220 | sub get_article_xover { 221 | my ($group,$begin,$end) = @_; 222 | my $grp = $groups{$group}->{'num'} 223 | or return; 224 | 225 | $xover_sth->execute($grp, $begin, $end || $begin) 226 | or return; 227 | 228 | my @xover; 229 | while (my $xover = $xover_sth->fetchrow_hashref) { 230 | my $msgid = get_article_message_id_from_xover($group,$xover); 231 | # generate xref and newsgroups info 232 | my $query = qq{SELECT group_id,id FROM articles WHERE msgid = ?}; 233 | my $res = $dbh->selectall_arrayref($query, undef, md5_hex($msgid)); 234 | 235 | $xover->{'xref'} 236 | = join ' ', map { $groupsbyid{$_->[0]}.":".$_->[1] } @$res if $res; 237 | 238 | $xover->{'xref'} ||= $group . ":" . $xover->{'id'}; 239 | 240 | ($xover->{'newsgroups'} = $xover->{'xref'}) =~ s/(:\d+)//g; 241 | $xover->{'newsgroups'} =~ s/\s+/,/g; 242 | 243 | push @xover, $xover; 244 | } 245 | return @xover; 246 | } 247 | 248 | sub get_article_message_id { 249 | my ($group,$artno) = @_; 250 | return unless exists $groups{$group}; 251 | return get_article_message_id_from_xover($group, 252 | get_article_xover($group,$artno)); 253 | } 254 | 255 | sub get_article_message_id_from_xover { 256 | my ($group,$xover) = @_; 257 | 258 | if ($xover->{'Message-ID'} && $xover->{'Message-ID'} =~ m/<(.+?)>/) { 259 | return $1; 260 | } 261 | return "$group-" . $xover->{'id'} . "\@$config{servername}"; 262 | } 263 | 264 | sub get_group_and_article { 265 | my ($msgid) = @_; 266 | 267 | $msgid =~ s/\[at\]/@/; # perl.org web obfuscation 268 | 269 | my $query = qq{SELECT group_id,id FROM articles WHERE msgid = ? LIMIT 1}; 270 | 271 | my $res = $dbh->selectrow_hashref($query, undef, md5_hex($msgid)); 272 | 273 | return $res ? ($groupsbyid{$res->{group_id}}, $res->{id}) 274 | : ($msgid =~ m/^(.+?)-(\d+)\@$config{servername}$/); 275 | 276 | return ($msgid =~ m/^(.+?)-(\d+)\@$config{servername}$/); 277 | } 278 | 279 | # this is a rather approximate conversion of 'wildmat' to perl. 280 | sub wildmat ($$) { 281 | my ($expr, $string) = @_; 282 | $expr =~ s/(?) { 300 | last if /^(\.)?\r?\n$/s; 301 | s/\r\n$/\n/s; 302 | next if /^Path:/; 303 | ($newsgroups) = /^Newsgroups: (.+)/ unless $newsgroups; 304 | !$from 305 | and /^From: (.*)/ 306 | and ($from) = (Mail::Address->parse($1))[0]->address; 307 | next if (!$to && (($to) = /^To: (.+?)\s*$/s)); 308 | next if /^Newsgroups:/; 309 | ++$cancel_message and next if /^Cancel:/; 310 | $bytes += length; 311 | $headers .= $_; 312 | alarm $config{timeout}; 313 | } 314 | 315 | return respond($ihave ? 437 : 441,"posting failed - no newsgroups specified") 316 | unless $newsgroups; 317 | return respond($ihave ? 437 : 441,"posting failed - no from specified") 318 | unless $from; 319 | return respond($ihave ? 437 : 441,"posting failed - invalid from") 320 | unless $from =~ m/^.+?@[-.\w]+$/; 321 | 322 | my (@mailto); 323 | 324 | $newsgroups =~ s/\s//g; 325 | my (@newsgroups) = split /,/, lc $newsgroups; 326 | foreach (@newsgroups) { 327 | push @mailto, $groups{$_}->{mail}; 328 | } 329 | return respond($ihave ? 437 : 441, "posting failed - no newsgroups known") 330 | unless @mailto; 331 | 332 | return respond($ihave ? 437 : 441, "cancels not accepted here") 333 | if $from =~ m/remove\.spam\@mindspring\.com/ or $cancel_message; 334 | 335 | open(FILE, "|-") 336 | || exec @mailinject, "-f$from", @mailto; 337 | #Received: from unknown (HELO intranet.sbs.srv.br) (200.207.122.67) 338 | # by toye.p.sourceforge.net with SMTP; 8 Dec 2000 16:10:58 -0000 339 | # this header can be used to track evildoers 340 | print FILE "To: ", join(',', grep defined, (@mailto, $to)), "\n"; 341 | print FILE $headers; 342 | print FILE "X-Posted-By: $ENV{TCPREMOTEIP}\n"; 343 | print FILE "\n"; 344 | 345 | alarm $config{timeout}; 346 | while () { 347 | s/\r\n$/\n/s; 348 | last if /^\.\n$/s; 349 | s/^\.//g; 350 | $bytes += length; 351 | print FILE; 352 | alarm $config{timeout}; 353 | } 354 | alarm 0; 355 | 356 | close FILE 357 | or return respond($ihave ? 436 : 441, "posting failed -- qmail barfed!"); 358 | 359 | foreach (@newsgroups) { 360 | note("/$_/new", "PUT", 200, $bytes); 361 | } 362 | 363 | respond($ihave ? 235 : 240,"article posted ok"); 364 | } 365 | 366 | sub outgoing { 367 | my ($which,$restrict) = @_; # restrict: 0=stat, 1=header, 2=body, 3=all 368 | my ($id, $ggg); # message-id, group derived from message-id 369 | 370 | $which ||= $current; # use the current article if none was specified 371 | 372 | # handle specification by message-id 373 | if ($which && $which =~ m/^<(.+?)>$/) { 374 | $id = $1; 375 | ($ggg,$which) = get_group_and_article($id); 376 | unless ($ggg) { 377 | note("/msgid/$id", $restrict == 1 ? "HEAD" : "GET", 404); 378 | return respond(430, "no such article found"); 379 | } 380 | } 381 | 382 | return respond(412,"no newsgroup has been selected") 383 | unless $ggg || $group; 384 | return respond(420,"no current article has been selected") 385 | unless $which; 386 | 387 | my $article = open_article($ggg || $group,$which); 388 | unless ($article) { 389 | note("/".($ggg||$group)."/$which", $restrict == 1 ? "HEAD" : "GET", 404); 390 | return respond($ggg ? 430 : 423, "no such article found"); 391 | } 392 | 393 | my ($xover) = get_article_xover($ggg||$group, $which) 394 | or return fault("failed to get xover data for $which <$id>"); 395 | 396 | # figure out the message-id and newsgroups 397 | $id ||= get_article_message_id_from_xover($group,$xover); 398 | 399 | if (!$restrict) { 400 | $current = $which unless $ggg; 401 | return respond(223, "$which <$id> article retrieved - request text separately"); 402 | } 403 | elsif ($restrict == 1) { 404 | respond(221, "$which <$id> article retrieved - head follows"); 405 | } 406 | elsif ($restrict == 2) { 407 | respond(222, "$which <$id> article retrieved - body follows"); 408 | } 409 | elsif ($restrict == 3) { 410 | respond(220, "$which <$id> article retrieved - head and body follows"); 411 | } 412 | 413 | # add some synthetic headers 414 | unless ($restrict == 2) { 415 | print "Newsgroups: ", $xover->{newsgroups} || $group, "\r\n"; 416 | print "Path: $config{servername}\r\n"; 417 | print "Xref: $config{servername} ", $xover->{xref}, "\r\n" 418 | if $xover->{xref}; 419 | print "Followup-To: ", $groups{$ggg||$group}{followup}, "\r\n" 420 | if $groups{$ggg||$group}{followup}; 421 | } 422 | 423 | my ($pasthead,$havedate,$havemsgid,$havesubj,$haveref); 424 | while (<$article>) { 425 | alarm $config{timeout}; 426 | s/^\./../s; # fix lines with a leading dot 427 | s/(?) +//; #trim trailing whitespace 443 | $havedate ||= m/^Date:/i; 444 | $havemsgid ||= s/^Message-ID:/Message-ID:/i; 445 | $havesubj ||= m/^Subject:/; 446 | $haveref ||= m/^References:/; 447 | if ($pasthead = m/^\r?\n$/s) { 448 | next if $restrict == 2; 449 | 450 | print "Approved: news\@$config{servername}\r\n" if $groups{$group||$ggg}->{moderated}; 451 | print "From: ", $xover->{From}, "\r\n"; 452 | print "Date: ", 453 | POSIX::strftime("%a, %d %B %Y %H:%M:%S %z", 454 | localtime((stat($article))[9])), 455 | "\r\n" 456 | unless $havedate; 457 | print "Message-ID: <$id>\r\n" unless $havemsgid; 458 | print "Subject: \r\n" unless $havesubj; 459 | print "References: ", $xover->{References}, "\r\n" 460 | unless $haveref || !$xover->{References}; 461 | 462 | if ($restrict == 1) { 463 | note("/".($group||$ggg)."/$which", "HEAD"); 464 | return dot(); 465 | } 466 | } 467 | next if $restrict == 2; 468 | } 469 | 470 | print; 471 | } 472 | if ($restrict == 3 and not $pasthead) { 473 | print "From: ", $xover->{From}, "\r\n"; 474 | print "Date: ", 475 | POSIX::strftime("%a, %d %B %Y %H:%M:%S %z", 476 | localtime((stat($article))[9])), 477 | "\r\n" 478 | unless $havedate; 479 | print "Message-ID: <$id>\r\n" unless $havemsgid; 480 | print "Subject: \r\n" unless $havesubj; 481 | print "References: ", $xover->{References}, "\r\n" 482 | unless $haveref || !$xover->{References}; 483 | print "\r\n"; 484 | } 485 | note("/$group/$which", "GET"); 486 | dot(); 487 | } 488 | 489 | =head1 COMMAND HANDLERS 490 | 491 | =cut 492 | 493 | sub article { 494 | outgoing(shift, 3); 495 | } 496 | 497 | sub body { 498 | outgoing(shift,2); 499 | } 500 | 501 | sub date { 502 | respond(111, POSIX::strftime("%Y%m%d%H%M%S", gmtime)); 503 | } 504 | 505 | sub head { 506 | outgoing(shift,1); 507 | } 508 | 509 | sub help { 510 | respond(100, "help text follows"); 511 | print " ", join "\r\n ", sort keys %commands; 512 | print "\r\n"; 513 | note("/help"); 514 | dot(); 515 | } 516 | 517 | sub have_messageid { 518 | return scalar $dbh->selectrow_array("SELECT group_id,id FROM articles WHERE msgid = ?", undef, md5_hex(shift)); 519 | } 520 | 521 | sub ihave { 522 | my ($messageid) = ($_[0] =~ m/^<(.+?)>$/); 523 | return respond(437, "article rejected - do not try again") 524 | if !$messageid || have_messageid($messageid); 525 | respond(335,"send article to be transferred. end with ."); 526 | incoming(1); 527 | } 528 | 529 | sub group { 530 | my ($ggg) = lc shift 531 | or return respond(501, "no group specified"); 532 | return respond(411, "no such news group") 533 | if !exists($groups{$ggg}); 534 | 535 | my ($min, $max) = get_group_minmax($ggg) 536 | or return fault("unable to get max for $ggg"); 537 | 538 | my $count = $max - $min + 1; 539 | 540 | # select the new group, reset the current article number 541 | $group = $ggg; $current = $min; 542 | 543 | respond(211, "$count $min $max $group"); 544 | } 545 | 546 | sub last { 547 | return respond(412, "no newsgroup selected") unless $group; 548 | return respond(420, "no current article has been selected") unless $current; 549 | my ($min, $max) = get_group_minmax($group); 550 | return respond(422, "no previous article in this group") 551 | if $current == $min; 552 | 553 | # look up the message-id for the previous article 554 | my $id = get_article_message_id($group,--$current); 555 | 556 | respond(223, "$current <$id> article retrieved - request text separately"); 557 | } 558 | 559 | sub list { 560 | my ($list) = lc shift || "active"; 561 | my ($match) = shift; 562 | 563 | if ($list eq 'active') { 564 | respond(215, "list of newsgroups follows"); 565 | for (sort keys %groups) { 566 | next if $match && !wildmat($match, $_); 567 | next if !$match && $groups{$_}->{'hidden'}; 568 | my ($min,$max) = get_group_minmax($_); 569 | my $act = get_group_active($_); 570 | printf "%s %010d %010d %s\r\n", $_, $max, $min, $act if $max && $act; 571 | } 572 | note("/list/active"); 573 | return dot(); 574 | } 575 | elsif ($list eq 'active.times') { 576 | respond(215, 'group creations in form "name time who".'); 577 | for (sort keys %groups) { 578 | next if $match && !wildmat($match, $_); 579 | next if $groups{$_}->{'hidden'}; 580 | my $time = get_group_creation($_) 581 | or next; 582 | print "$_ $time news\r\n"; 583 | } 584 | note("/active.times"); 585 | return dot(); 586 | } 587 | elsif ($list eq 'newsgroups') { 588 | respond(215, "list of newsgroups follows"); 589 | for (sort keys %groups) { 590 | next if $match && !wildmat($match, $_); 591 | next if !$match && $groups{$_}->{'hidden'}; 592 | my $desc = get_group_description($_) 593 | or next; 594 | print "$_ $desc\r\n"; 595 | } 596 | note("/list/newsgroups"); 597 | return dot(); 598 | } 599 | 600 | elsif ($list eq 'overview.fmt') { 601 | respond(215, "order of fields in overview database"); 602 | foreach (@overview) { 603 | print "$_:\r\n"; 604 | } 605 | print "Xref:full\r\n"; 606 | note("/list/overview.fmt"); 607 | return dot(); 608 | } 609 | 610 | elsif ($list eq 'distributions') { 611 | respond(215, "list of distributions follows"); 612 | note("/list/distributions"); 613 | return dot(); 614 | } 615 | elsif ($list eq 'distrib.pats') { 616 | respond(215, "list of distrib.pats follows"); 617 | note("/list/distrib.pats"); 618 | return dot(); 619 | } 620 | elsif ($list eq 'subscriptions') { 621 | respond(215, "list of suggested subscriptions follows"); 622 | for (sort keys %groups) { 623 | print "$_\r\n" if get_group_recommend($_); 624 | } 625 | note("/list/subscriptions"); 626 | return dot(); 627 | } 628 | respond(501, "list type not understood"); 629 | note("/list/$list","GET",404); 630 | } 631 | 632 | sub listgroup { 633 | my $ggg = shift || $group; 634 | respond(412, "not currently in newsgroup") 635 | if !$ggg; 636 | my ($min, $max) = get_group_minmax($ggg) 637 | or return fault("couldn't get information about group"); 638 | $group = $ggg; $current = $min; 639 | respond(211, "list of article numbers to follow"); 640 | alarm $config{timeout}; 641 | for (my $i = $min; $i <= $max; $i++) { 642 | print "$i\r\n"; 643 | alarm $config{timeout}; 644 | } 645 | note("/$ggg"); 646 | dot(); 647 | } 648 | 649 | sub mode { 650 | my $mode = lc shift; 651 | if ($mode eq 'reader') { 652 | return respond(200,"hello, you can post"); 653 | } 654 | if ($mode eq 'stream') { # shouldn't be necessary, so we don't support it 655 | return respond(200,"sure, why not?"); 656 | } 657 | respond(501, "mode not understood"); 658 | } 659 | 660 | sub next { 661 | return respond(412, "no newsgroup selected") unless $group; 662 | return respond(420, "no current article has been selected") unless $current; 663 | my ($min, $max) = get_group_minmax($group); 664 | return respond(421, "no next article in this group") 665 | if $current == $max; 666 | 667 | # look up the message-id for the next article 668 | my $id = get_article_message_id($group,++$current); 669 | 670 | respond(223, "$current <$id> article retrieved - request text separately"); 671 | } 672 | 673 | sub newgroups { 674 | my ($date,$time,$gmt) = @_; 675 | return fault("invalid date or time format") 676 | unless $date && $time && (!$gmt || $gmt eq 'GMT' || $gmt eq 'UTC'); 677 | 678 | my ($since); 679 | my ($y,$m,$d,$h,$i,$s) = (unpack("a2a2a2", $date), unpack("a2a2a2",$time)); 680 | $y += 100 if $y < 70; # violation of US patent #5,806,063. bite me. 681 | if ($gmt) { 682 | $since = Time::Local::timegm($s,$i,$h,$d,$m-1,$y); 683 | } 684 | else { 685 | $since = Time::Local::timelocal($s,$i,$h,$d,$m-1,$y); 686 | } 687 | 688 | respond(231, "list of new newsgroups follows"); 689 | for (sort keys %groups) { 690 | my $created = get_group_creation($_); 691 | next unless $created && $created > $since; 692 | my ($min, $max) = get_group_minmax($_); 693 | my $act = get_group_active($_); 694 | printf "%s %010d %010d %s\r\n", $_, $max, $min, $act if $max && $act; 695 | } 696 | note("/newgroups"); 697 | dot(); 698 | } 699 | 700 | sub newnews { 701 | respond(230, "list of new articles by message-id follows"); 702 | note("/newnews"); 703 | dot(); 704 | } 705 | 706 | sub post { 707 | respond(340,"send article to be posted. end with ."); 708 | incoming(0); 709 | } 710 | 711 | sub quit { 712 | respond(205, "closing connection - goodbye!"); 713 | exit; 714 | } 715 | 716 | sub slave { 717 | respond(202, "slave status noted"); 718 | # yeah, not really. nobody cares. 719 | } 720 | 721 | sub stat { 722 | outgoing(shift, 0); 723 | } 724 | 725 | sub xgtitle { 726 | my $match = shift; 727 | 728 | respond(282, "list of newsgroups follows"); 729 | for (sort keys %groups) { 730 | next if $match && !wildmat($match, $_); 731 | my $desc = get_group_description($_) 732 | or next; 733 | print "$_ $desc\r\n"; 734 | } 735 | note("/newsgroups".($match && "?q=$match")); 736 | dot(); 737 | } 738 | 739 | # this serves triple-duty as xrover and xpat, too. 740 | sub xhdr { 741 | my ($header,$range,$code,@pats) = @_; 742 | $code ||= 221; 743 | my ($ggg,$begin,$end); 744 | 745 | if ($range && $range =~ /^<(.+)>$/) { 746 | ($ggg,$begin) = get_group_and_article($1); 747 | if (!$ggg || !$begin) { 748 | note("/msgid/$1","HEAD",404); 749 | return respond(530,"no such article") 750 | } 751 | } 752 | else { 753 | return respond(412,"no news group currently selected") 754 | if !$group; 755 | return respond(520,"no current article selected") 756 | if !$range && !$current; 757 | $range && (($begin,$end) = split /-/, $range); 758 | $begin ||= $current; 759 | } 760 | 761 | # force the header into the case we use in the overview database 762 | foreach (keys %overview) { 763 | $header =~ s/^$_$/$_/i; 764 | } 765 | 766 | # short-circuit for headers not in overview database 767 | unless (exists $overview{$header}) { 768 | note("/$group?h=$header","GET",404); 769 | respond($code, "$header not in overview database, returning empty list"); 770 | return dot(); 771 | } 772 | 773 | my ($min,$max) = get_group_minmax($group); 774 | 775 | $begin = $min if ($begin && $begin < $min); 776 | $begin ||= $current; 777 | $end ||= defined $end ? $max : $begin; 778 | 779 | if (($begin > $max) || ($end && ($begin > $end)) || !($begin || $current)) { 780 | note("/$group?h=$header&b=$begin&e=$end","GET",204); 781 | return respond(420,"no article(s) selected"); 782 | } 783 | 784 | respond($code, "$header follows for $begin to $end"); 785 | alarm $config{timeout}; 786 | my (@xover) = get_article_xover($group, $begin, $end); 787 | foreach my $xover (@xover) { 788 | foreach my $p (@pats) { 789 | next ARTICLE unless wildmat($p,$xover->{$header}); 790 | } 791 | next unless $xover->{$header}; 792 | print $xover->{'id'}," ",$xover->{$header}, "\r\n"; 793 | #XXX fix support for multiple requested headers 794 | } 795 | #XXX include @pats in log 796 | note("/$group?h=$header&b=$begin&e=$end"); 797 | dot(); 798 | } 799 | 800 | sub xover { 801 | my ($begin,$end) = split /-/, (shift||""); 802 | return respond(412,"no news group currently selected") 803 | if !$group; 804 | return respond(501,"most specify beginning of range") 805 | if defined $end && !$begin; 806 | my ($min,$max) = get_group_minmax($group); 807 | 808 | $begin = $min if ($begin && $begin < $min); 809 | $begin ||= $current; 810 | $end ||= defined $end ? $max : $begin; 811 | 812 | if (($begin > $max) || ($end && ($begin > $end)) || !($begin || $current)) { 813 | note("/$group?b=$begin&e=$end","GET",204); 814 | return respond(420,"no article(s) selected"); 815 | } 816 | 817 | respond(224, "overview information follows for $begin to $end"); 818 | alarm $config{timeout}; 819 | my $last = $begin - 1; 820 | while ($last < $end) { 821 | $last = $last + 5000; 822 | $last = $end if $last > $end; 823 | my (@xover) = get_article_xover($group, $begin, $last); 824 | foreach my $xover (@xover) { 825 | print $xover->{'id'}; 826 | foreach my $header (@overview) { 827 | print "\t", ($xover->{$header} || ""); 828 | } 829 | print "\tXref: ", ($xover->{xref} || ""); 830 | print "\r\n"; 831 | } 832 | } 833 | note("/$group?b=$begin&e=$end"); 834 | dot(); 835 | } 836 | 837 | sub xpat { 838 | xhdr(shift,shift,221,@_); 839 | } 840 | 841 | sub xrover { 842 | xhdr("References",shift,224,@_); 843 | } 844 | 845 | sub xpath { 846 | my $id = shift; 847 | if ($id && $id =~ m/^<(.+?)>$/) { 848 | my ($ggg,$begin) = get_group_and_article($1); 849 | respond(223, "$ggg/$begin"); 850 | } 851 | else { 852 | respond(501, "invalid msgid"); 853 | } 854 | 855 | } 856 | 857 | sub spool_feed { 858 | my $feed = shift or die "No feed specified..."; 859 | 860 | $RESPOND = 0; 861 | 862 | open (STDIN, "<&6") or die "could not reopen stdin: $!"; 863 | open (STDOUT, ">&7") or die "could not reopen stdout: $!"; 864 | 865 | 866 | $SIG{ALRM} = sub { respond(500, "Timeout!"),exit; }; 867 | 868 | alarm 15; 869 | my $resp = ; 870 | die "Did not get 200 from $feed [$resp]\n" unless $resp =~ m/^200/; 871 | 872 | warn "spooling $feed\n" if $TRACE; 873 | 874 | opendir DIR, "feeds/$feed" or die "could not opendir for $feed: $!"; 875 | my @files = readdir DIR; 876 | closedir DIR; 877 | for my $file (sort @files) { 878 | next if $file =~ m/\.(tmp|spooling)$/; 879 | next if $file =~ m/^\./; 880 | next if $file =~ m/~$/; 881 | rename "feeds/$feed/$file", "feeds/$feed/$file.spooling" or next; 882 | -z "feeds/$feed/$file.spooling" and unlink "feeds/$feed/$file.spooling", next; 883 | 884 | open F, "feeds/$feed/$file.spooling" or die "could not open feeds/$feed/$file: $!"; 885 | my $timestamp = time; 886 | open RESEND, ">feeds/$feed/$timestamp.$$.tmp" 887 | or die "could not open feeds/$feed/$timestamp.$$.tmp: $!"; 888 | 889 | while () { 890 | chomp; 891 | my ($ggg, $artno) = split /\//; 892 | warn "sending $artno from $ggg\n" if $TRACE; 893 | 894 | my ($xover) = get_article_xover($ggg, $artno) 895 | or die fault("failed to get xover data for $artno"); 896 | 897 | # figure out the message-id and newsgroups 898 | my $id = get_article_message_id_from_xover($group,$xover); 899 | 900 | alarm 10; 901 | 902 | print "IHAVE <$id>\r\n"; 903 | 904 | # open ERR, ">>feeds/$feed.errors" or die "could not append to errors: $ !"; 905 | # print ERR "$ggg/$artno offering <$id>\n"; 906 | # close ERR or die "could not close error spool file"; 907 | 908 | 909 | # 235 article transferred ok 910 | # 335 send article to be transferred. End with . 911 | # 435 article not wanted - do not send it 912 | # 436 transfer failed - try again later 913 | # 437 article rejected - do not try again 914 | 915 | my $resp = ; 916 | 917 | if ($resp =~ m/^335/) { 918 | warn "they want $artno, sending it!\n" if $TRACE; 919 | $group = $ggg; 920 | outgoing($artno, 3); 921 | my $resp = ; 922 | $resp =~ s/\r\n//; 923 | #warn "$resp; next please!\n" and 924 | next if ($resp =~ m/235/); 925 | if ($resp =~ m/^437/) { 926 | open ERR, ">>feeds/$feed.errors" or die "could not append to errors: $!"; 927 | print ERR "$ggg/$artno $resp\n"; 928 | close ERR or die "could not close error spool file"; 929 | next; 930 | } 931 | warn "$resp; Didn't like it!\n" and next 932 | print(RESEND "$ggg/$artno\n"), next if ($resp =~ m/^436/); 933 | die "Unknown response: [$resp]\n"; 934 | } 935 | elsif ($resp =~ m/^435/) { 936 | warn "they don't want $artno ($resp), skipping it...\n" if $TRACE; 937 | next; 938 | } 939 | elsif ($resp =~ m/^436/) { 940 | print(RESEND "$ggg/$artno\n"); 941 | } 942 | else { 943 | die "Unknown response: $resp"; 944 | } 945 | 946 | alarm 0; 947 | 948 | } 949 | 950 | close RESEND; 951 | if (-z "feeds/$feed/$timestamp.$$.tmp") { 952 | unlink "feeds/$feed/$timestamp.$$.tmp"; 953 | } 954 | else { 955 | rename "feeds/$feed/$timestamp.$$.tmp", "feeds/$feed/$timestamp.$$"; 956 | } 957 | 958 | close F; 959 | 960 | unlink "feeds/$feed/$file.spooling" or die "could not unlink feeds/$feed/$file.spooling: $!"; 961 | 962 | } 963 | 964 | return; 965 | } 966 | 967 | 968 | sub xversion { 969 | respond(200, "Colobus $Colobus::VERSION"); 970 | } 971 | 972 | 973 | 1; 974 | -------------------------------------------------------------------------------- /rfc1036.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Network Working Group M. Horton 8 | Request for Comments: 1036 AT&T Bell Laboratories 9 | Obsoletes: RFC-850 R. Adams 10 | Center for Seismic Studies 11 | December 1987 12 | 13 | 14 | Standard for Interchange of USENET Messages 15 | 16 | 17 | 18 | STATUS OF THIS MEMO 19 | 20 | This document defines the standard format for the interchange of 21 | network News messages among USENET hosts. It updates and replaces 22 | RFC-850, reflecting version B2.11 of the News program. This memo is 23 | disributed as an RFC to make this information easily accessible to 24 | the Internet community. It does not specify an Internet standard. 25 | Distribution of this memo is unlimited. 26 | 27 | 1. Introduction 28 | 29 | This document defines the standard format for the interchange of 30 | network News messages among USENET hosts. It describes the format 31 | for messages themselves and gives partial standards for transmission 32 | of news. The news transmission is not entirely in order to give a 33 | good deal of flexibility to the hosts to choose transmission 34 | hardware and software, to batch news, and so on. 35 | 36 | There are five sections to this document. Section two defines the 37 | format. Section three defines the valid control messages. Section 38 | four specifies some valid transmission methods. Section five 39 | describes the overall news propagation algorithm. 40 | 41 | 2. Message Format 42 | 43 | The primary consideration in choosing a message format is that it 44 | fit in with existing tools as well as possible. Existing tools 45 | include implementations of both mail and news. (The notesfiles 46 | system from the University of Illinois is considered a news 47 | implementation.) A standard format for mail messages has existed 48 | for many years on the Internet, and this format meets most of the 49 | needs of USENET. Since the Internet format is extensible, 50 | extensions to meet the additional needs of USENET are easily made 51 | within the Internet standard. Therefore, the rule is adopted that 52 | all USENET news messages must be formatted as valid Internet mail 53 | messages, according to the Internet standard RFC-822. The USENET 54 | News standard is more restrictive than the Internet standard, 55 | 56 | 57 | 58 | Horton & Adams [Page 1] 59 | 60 | RFC 1036 Standard for USENET Messages December 1987 61 | 62 | 63 | placing additional requirements on each message and forbidding use 64 | of certain Internet features. However, it should always be possible 65 | to use a tool expecting an Internet message to process a news 66 | message. In any situation where this standard conflicts with the 67 | Internet standard, RFC-822 should be considered correct and this 68 | standard in error. 69 | 70 | Here is an example USENET message to illustrate the fields. 71 | 72 | From: jerry@eagle.ATT.COM (Jerry Schwarz) 73 | Path: cbosgd!mhuxj!mhuxt!eagle!jerry 74 | Newsgroups: news.announce 75 | Subject: Usenet Etiquette -- Please Read 76 | Message-ID: <642@eagle.ATT.COM> 77 | Date: Fri, 19 Nov 82 16:14:55 GMT 78 | Followup-To: news.misc 79 | Expires: Sat, 1 Jan 83 00:00:00 -0500 80 | Organization: AT&T Bell Laboratories, Murray Hill 81 | 82 | The body of the message comes here, after a blank line. 83 | 84 | Here is an example of a message in the old format (before the 85 | existence of this standard). It is recommended that 86 | implementations also accept messages in this format to ease upward 87 | conversion. 88 | 89 | From: cbosgd!mhuxj!mhuxt!eagle!jerry (Jerry Schwarz) 90 | Newsgroups: news.misc 91 | Title: Usenet Etiquette -- Please Read 92 | Article-I.D.: eagle.642 93 | Posted: Fri Nov 19 16:14:55 1982 94 | Received: Fri Nov 19 16:59:30 1982 95 | Expires: Mon Jan 1 00:00:00 1990 96 | 97 | The body of the message comes here, after a blank line. 98 | 99 | Some news systems transmit news in the A format, which looks like 100 | this: 101 | 102 | Aeagle.642 103 | news.misc 104 | cbosgd!mhuxj!mhuxt!eagle!jerry 105 | Fri Nov 19 16:14:55 1982 106 | Usenet Etiquette - Please Read 107 | The body of the message comes here, with no blank line. 108 | 109 | A standard USENET message consists of several header lines, followed 110 | by a blank line, followed by the body of the message. Each header 111 | 112 | 113 | 114 | Horton & Adams [Page 2] 115 | 116 | RFC 1036 Standard for USENET Messages December 1987 117 | 118 | 119 | line consist of a keyword, a colon, a blank, and some additional 120 | information. This is a subset of the Internet standard, simplified 121 | to allow simpler software to handle it. The "From" line may 122 | optionally include a full name, in the format above, or use the 123 | Internet angle bracket syntax. To keep the implementations simple, 124 | other formats (for example, with part of the machine address after 125 | the close parenthesis) are not allowed. The Internet convention of 126 | continuation header lines (beginning with a blank or tab) is 127 | allowed. 128 | 129 | Certain headers are required, and certain other headers are 130 | optional. Any unrecognized headers are allowed, and will be passed 131 | through unchanged. The required header lines are "From", "Date", 132 | "Newsgroups", "Subject", "Message-ID", and "Path". The optional 133 | header lines are "Followup-To", "Expires", "Reply-To", "Sender", 134 | "References", "Control", "Distribution", "Keywords", "Summary", 135 | "Approved", "Lines", "Xref", and "Organization". Each of these 136 | header lines will be described below. 137 | 138 | 2.1. Required Header lines 139 | 140 | 2.1.1. From 141 | 142 | The "From" line contains the electronic mailing address of the 143 | person who sent the message, in the Internet syntax. It may 144 | optionally also contain the full name of the person, in parentheses, 145 | after the electronic address. The electronic address is the same as 146 | the entity responsible for originating the message, unless the 147 | "Sender" header is present, in which case the "From" header might 148 | not be verified. Note that in all host and domain names, upper and 149 | lower case are considered the same, thus "mark@cbosgd.ATT.COM", 150 | "mark@cbosgd.att.com", and "mark@CBosgD.ATt.COm" are all equivalent. 151 | User names may or may not be case sensitive, for example, 152 | "Billy@cbosgd.ATT.COM" might be different from 153 | "BillY@cbosgd.ATT.COM". Programs should avoid changing the case of 154 | electronic addresses when forwarding news or mail. 155 | 156 | RFC-822 specifies that all text in parentheses is to be interpreted 157 | as a comment. It is common in Internet mail to place the full name 158 | of the user in a comment at the end of the "From" line. This 159 | standard specifies a more rigid syntax. The full name is not 160 | considered a comment, but an optional part of the header line. 161 | Either the full name is omitted, or it appears in parentheses after 162 | the electronic address of the person posting the message, or it 163 | appears before an electronic address which is enclosed in angle 164 | brackets. Thus, the three permissible forms are: 165 | 166 | 167 | 168 | 169 | 170 | Horton & Adams [Page 3] 171 | 172 | RFC 1036 Standard for USENET Messages December 1987 173 | 174 | 175 | From: mark@cbosgd.ATT.COM 176 | From: mark@cbosgd.ATT.COM (Mark Horton) 177 | From: Mark Horton 178 | 179 | Full names may contain any printing ASCII characters from space 180 | through tilde, except that they may not contain "(" (left 181 | parenthesis), ")" (right parenthesis), "<" (left angle bracket), or 182 | ">" (right angle bracket). Additional restrictions may be placed on 183 | full names by the mail standard, in particular, the characters "," 184 | (comma), ":" (colon), "@" (at), "!" (bang), "/" (slash), "=" 185 | (equal), and ";" (semicolon) are inadvisable in full names. 186 | 187 | 2.1.2. Date 188 | 189 | The "Date" line (formerly "Posted") is the date that the message was 190 | originally posted to the network. Its format must be acceptable 191 | both in RFC-822 and to the getdate(3) routine that is provided with 192 | the Usenet software. This date remains unchanged as the message is 193 | propagated throughout the network. One format that is acceptable to 194 | both is: 195 | 196 | Wdy, DD Mon YY HH:MM:SS TIMEZONE 197 | 198 | Several examples of valid dates appear in the sample message above. 199 | Note in particular that ctime(3) format: 200 | 201 | Wdy Mon DD HH:MM:SS YYYY 202 | 203 | is not acceptable because it is not a valid RFC-822 date. However, 204 | since older software still generates this format, news 205 | implementations are encouraged to accept this format and translate 206 | it into an acceptable format. 207 | 208 | There is no hope of having a complete list of timezones. Universal 209 | Time (GMT), the North American timezones (PST, PDT, MST, MDT, CST, 210 | CDT, EST, EDT) and the +/-hhmm offset specifed in RFC-822 should be 211 | supported. It is recommended that times in message headers be 212 | transmitted in GMT and displayed in the local time zone. 213 | 214 | 2.1.3. Newsgroups 215 | 216 | The "Newsgroups" line specifies the newsgroup or newsgroups in which 217 | the message belongs. Multiple newsgroups may be specified, 218 | separated by a comma. Newsgroups specified must all be the names of 219 | existing newsgroups, as no new newsgroups will be created by simply 220 | posting to them. 221 | 222 | 223 | 224 | 225 | 226 | Horton & Adams [Page 4] 227 | 228 | RFC 1036 Standard for USENET Messages December 1987 229 | 230 | 231 | Wildcards (e.g., the word "all") are never allowed in a "News- 232 | groups" line. For example, a newsgroup comp.all is illegal, 233 | although a newsgroup rec.sport.football is permitted. 234 | 235 | If a message is received with a "Newsgroups" line listing some valid 236 | newsgroups and some invalid newsgroups, a host should not remove 237 | invalid newsgroups from the list. Instead, the invalid newsgroups 238 | should be ignored. For example, suppose host A subscribes to the 239 | classes btl.all and comp.all, and exchanges news messages with host 240 | B, which subscribes to comp.all but not btl.all. Suppose A receives 241 | a message with Newsgroups: comp.unix,btl.general. 242 | 243 | This message is passed on to B because B receives comp.unix, but B 244 | does not receive btl.general. A must leave the "Newsgroups" line 245 | unchanged. If it were to remove btl.general, the edited header 246 | could eventually re-enter the btl.all class, resulting in a message 247 | that is not shown to users subscribing to btl.general. Also, 248 | follow-ups from outside btl.all would not be shown to such users. 249 | 250 | 2.1.4. Subject 251 | 252 | The "Subject" line (formerly "Title") tells what the message is 253 | about. It should be suggestive enough of the contents of the 254 | message to enable a reader to make a decision whether to read the 255 | message based on the subject alone. If the message is submitted in 256 | response to another message (e.g., is a follow-up) the default 257 | subject should begin with the four characters "Re:", and the 258 | "References" line is required. For follow-ups, the use of the 259 | "Summary" line is encouraged. 260 | 261 | 2.1.5. Message-ID 262 | 263 | The "Message-ID" line gives the message a unique identifier. The 264 | Message-ID may not be reused during the lifetime of any previous 265 | message with the same Message-ID. (It is recommended that no 266 | Message-ID be reused for at least two years.) Message-ID's have the 267 | syntax: 268 | 269 | "> 270 | 271 | In order to conform to RFC-822, the Message-ID must have the format: 272 | 273 | 274 | 275 | where full_domain_name is the full name of the host at which the 276 | message entered the network, including a domain that host is in, and 277 | unique is any string of printing ASCII characters, not including "<" 278 | (left angle bracket), ">" (right angle bracket), or "@" (at sign). 279 | 280 | 281 | 282 | Horton & Adams [Page 5] 283 | 284 | RFC 1036 Standard for USENET Messages December 1987 285 | 286 | 287 | For example, the unique part could be an integer representing a 288 | sequence number for messages submitted to the network, or a short 289 | string derived from the date and time the message was created. For 290 | example, a valid Message-ID for a message submitted from host ucbvax 291 | in domain "Berkeley.EDU" would be "<4123@ucbvax.Berkeley.EDU>". 292 | Programmers are urged not to make assumptions about the content of 293 | Message-ID fields from other hosts, but to treat them as unknown 294 | character strings. It is not safe, for example, to assume that a 295 | Message-ID will be under 14 characters, that it is unique in the 296 | first 14 characters, nor that is does not contain a "/". 297 | 298 | The angle brackets are considered part of the Message-ID. Thus, in 299 | references to the Message-ID, such as the ihave/sendme and cancel 300 | control messages, the angle brackets are included. White space 301 | characters (e.g., blank and tab) are not allowed in a Message-ID. 302 | Slashes ("/") are strongly discouraged. All characters between the 303 | angle brackets must be printing ASCII characters. 304 | 305 | 2.1.6. Path 306 | 307 | This line shows the path the message took to reach the current 308 | system. When a system forwards the message, it should add its own 309 | name to the list of systems in the "Path" line. The names may be 310 | separated by any punctuation character or characters (except "." 311 | which is considered part of the hostname). Thus, the following are 312 | valid entries: 313 | 314 | cbosgd!mhuxj!mhuxt 315 | cbosgd, mhuxj, mhuxt 316 | @cbosgd.ATT.COM,@mhuxj.ATT.COM,@mhuxt.ATT.COM 317 | teklabs, zehntel, sri-unix@cca!decvax 318 | 319 | (The latter path indicates a message that passed through decvax, 320 | cca, sri-unix, zehntel, and teklabs, in that order.) Additional 321 | names should be added from the left. For example, the most recently 322 | added name in the fourth example was teklabs. Letters, digits, 323 | periods and hyphens are considered part of host names; other 324 | punctuation, including blanks, are considered separators. 325 | 326 | Normally, the rightmost name will be the name of the originating 327 | system. However, it is also permissible to include an extra entry 328 | on the right, which is the name of the sender. This is for upward 329 | compatibility with older systems. 330 | 331 | The "Path" line is not used for replies, and should not be taken as 332 | a mailing address. It is intended to show the route the message 333 | traveled to reach the local host. There are several uses for this 334 | information. One is to monitor USENET routing for performance 335 | 336 | 337 | 338 | Horton & Adams [Page 6] 339 | 340 | RFC 1036 Standard for USENET Messages December 1987 341 | 342 | 343 | reasons. Another is to establish a path to reach new hosts. 344 | Perhaps the most important use is to cut down on redundant USENET 345 | traffic by failing to forward a message to a host that is known to 346 | have already received it. In particular, when host A sends a 347 | message to host B, the "Path" line includes A, so that host B will 348 | not immediately send the message back to host A. The name each host 349 | uses to identify itself should be the same as the name by which its 350 | neighbors know it, in order to make this optimization possible. 351 | 352 | A host adds its own name to the front of a path when it receives a 353 | message from another host. Thus, if a message with path "A!X!Y!Z" 354 | is passed from host A to host B, B will add its own name to the path 355 | when it receives the message from A, e.g., "B!A!X!Y!Z". If B then 356 | passes the message on to C, the message sent to C will contain the 357 | path "B!A!X!Y!Z", and when C receives it, C will change it to 358 | "C!B!A!X!Y!Z". 359 | 360 | Special upward compatibility note: Since the "From", "Sender", and 361 | "Reply-To" lines are in Internet format, and since many USENET hosts 362 | do not yet have mailers capable of understanding Internet format, it 363 | would break the reply capability to completely sever the connection 364 | between the "Path" header and the reply function. It is recognized 365 | that the path is not always a valid reply string in older 366 | implementations, and no requirement to fix this problem is placed on 367 | implementations. However, the existing convention of placing the 368 | host name and an "!" at the front of the path, and of starting the 369 | path with the host name, an "!", and the user name, should be 370 | maintained when possible. 371 | 372 | 2.2. Optional Headers 373 | 374 | 2.2.1. Reply-To 375 | 376 | This line has the same format as "From". If present, mailed replies 377 | to the author should be sent to the name given here. Otherwise, 378 | replies are mailed to the name on the "From" line. (This does not 379 | prevent additional copies from being sent to recipients named by the 380 | replier, or on "To" or "Cc" lines.) The full name may be optionally 381 | given, in parentheses, as in the "From" line. 382 | 383 | 2.2.2. Sender 384 | 385 | This field is present only if the submitter manually enters a "From" 386 | line. It is intended to record the entity responsible for 387 | submitting the message to the network. It should be verified by the 388 | software at the submitting host. 389 | 390 | 391 | 392 | 393 | 394 | Horton & Adams [Page 7] 395 | 396 | RFC 1036 Standard for USENET Messages December 1987 397 | 398 | 399 | For example, if John Smith is visiting CCA and wishes to post a 400 | message to the network, using friend Sarah Jones' account, the 401 | message might read: 402 | 403 | From: smith@ucbvax.Berkeley.EDU (John Smith) 404 | Sender: jones@cca.COM (Sarah Jones) 405 | 406 | If a gateway program enters a mail message into the network at host 407 | unix.SRI.COM, the lines might read: 408 | 409 | From: John.Doe@A.CS.CMU.EDU 410 | Sender: network@unix.SRI.COM 411 | 412 | The primary purpose of this field is to be able to track down 413 | messages to determine how they were entered into the network. The 414 | full name may be optionally given, in parentheses, as in the "From" 415 | line. 416 | 417 | 2.2.3. Followup-To 418 | 419 | This line has the same format as "Newsgroups". If present, follow- 420 | up messages are to be posted to the newsgroup or newsgroups listed 421 | here. If this line is not present, follow-ups are posted to the 422 | newsgroup or newsgroups listed in the "Newsgroups" line. 423 | 424 | If the keyword poster is present, follow-up messages are not 425 | permitted. The message should be mailed to the submitter of the 426 | message via mail. 427 | 428 | 2.2.4. Expires 429 | 430 | This line, if present, is in a legal USENET date format. It 431 | specifies a suggested expiration date for the message. If not 432 | present, the local default expiration date is used. This field is 433 | intended to be used to clean up messages with a limited usefulness, 434 | or to keep important messages around for longer than usual. For 435 | example, a message announcing an upcoming seminar could have an 436 | expiration date the day after the seminar, since the message is not 437 | useful after the seminar is over. Since local hosts have local 438 | policies for expiration of news (depending on available disk space, 439 | for instance), users are discouraged from providing expiration dates 440 | for messages unless there is a natural expiration date associated 441 | with the topic. System software should almost never provide a 442 | default "Expires" line. Leave it out and allow local policies to be 443 | used unless there is a good reason not to. 444 | 445 | 446 | 447 | 448 | 449 | 450 | Horton & Adams [Page 8] 451 | 452 | RFC 1036 Standard for USENET Messages December 1987 453 | 454 | 455 | 2.2.5. References 456 | 457 | This field lists the Message-ID's of any messages prompting the 458 | submission of this message. It is required for all follow-up 459 | messages, and forbidden when a new subject is raised. 460 | Implementations should provide a follow-up command, which allows a 461 | user to post a follow-up message. This command should generate a 462 | "Subject" line which is the same as the original message, except 463 | that if the original subject does not begin with "Re:" or "re:", the 464 | four characters "Re:" are inserted before the subject. If there is 465 | no "References" line on the original header, the "References" line 466 | should contain the Message-ID of the original message (including the 467 | angle brackets). If the original message does have a "References" 468 | line, the follow-up message should have a "References" line 469 | containing the text of the original "References" line, a blank, and 470 | the Message-ID of the original message. 471 | 472 | The purpose of the "References" header is to allow messages to be 473 | grouped into conversations by the user interface program. This 474 | allows conversations within a newsgroup to be kept together, and 475 | potentially users might shut off entire conversations without 476 | unsubscribing to a newsgroup. User interfaces need not make use of 477 | this header, but all automatically generated follow-ups should 478 | generate the "References" line for the benefit of systems that do 479 | use it, and manually generated follow-ups (e.g., typed in well after 480 | the original message has been printed by the machine) should be 481 | encouraged to include them as well. 482 | 483 | It is permissible to not include the entire previous "References" 484 | line if it is too long. An attempt should be made to include a 485 | reasonable number of backwards references. 486 | 487 | 2.2.6. Control 488 | 489 | If a message contains a "Control" line, the message is a control 490 | message. Control messages are used for communication among USENET 491 | host machines, not to be read by users. Control messages are 492 | distributed by the same newsgroup mechanism as ordinary messages. 493 | The body of the "Control" header line is the message to the host. 494 | 495 | For upward compatibility, messages that match the newsgroup pattern 496 | "all.all.ctl" should also be interpreted as control messages. If no 497 | "Control" header is present on such messages, the subject is used as 498 | the control message. However, messages on newsgroups matching this 499 | pattern do not conform to this standard. 500 | 501 | 502 | 503 | 504 | 505 | 506 | Horton & Adams [Page 9] 507 | 508 | RFC 1036 Standard for USENET Messages December 1987 509 | 510 | 511 | Also for upward compatibility, if the first 4 characters of the 512 | "Subject:" line are "cmsg", the rest of the "Subject:" line should 513 | be interpreted as a control message. 514 | 515 | 2.2.7. Distribution 516 | 517 | This line is used to alter the distribution scope of the message. 518 | It is a comma separated list similar to the "Newsgroups" line. User 519 | subscriptions are still controlled by "Newsgroups", but the message 520 | is sent to all systems subscribing to the newsgroups on the 521 | "Distribution" line in addition to the "Newsgroups" line. For the 522 | message to be transmitted, the receiving site must normally receive 523 | one of the specified newsgroups AND must receive one of the 524 | specified distributions. Thus, a message concerning a car for sale 525 | in New Jersey might have headers including: 526 | 527 | Newsgroups: rec.auto,misc.forsale 528 | Distribution: nj,ny 529 | 530 | so that it would only go to persons subscribing to rec.auto or misc. 531 | for sale within New Jersey or New York. The intent of this header 532 | is to restrict the distribution of a newsgroup further, not to 533 | increase it. A local newsgroup, such as nj.crazy-eddie, will 534 | probably not be propagated by hosts outside New Jersey that do not 535 | show such a newsgroup as valid. A follow-up message should default 536 | to the same "Distribution" line as the original message, but the 537 | user can change it to a more limited one, or escalate the 538 | distribution if it was originally restricted and a more widely 539 | distributed reply is appropriate. 540 | 541 | 2.2.8. Organization 542 | 543 | The text of this line is a short phrase describing the organization 544 | to which the sender belongs, or to which the machine belongs. The 545 | intent of this line is to help identify the person posting the 546 | message, since host names are often cryptic enough to make it hard 547 | to recognize the organization by the electronic address. 548 | 549 | 2.2.9. Keywords 550 | 551 | A few well-selected keywords identifying the message should be on 552 | this line. This is used as an aid in determining if this message is 553 | interesting to the reader. 554 | 555 | 2.2.10. Summary 556 | 557 | This line should contain a brief summary of the message. It is 558 | usually used as part of a follow-up to another message. Again, it 559 | 560 | 561 | 562 | Horton & Adams [Page 10] 563 | 564 | RFC 1036 Standard for USENET Messages December 1987 565 | 566 | 567 | is very useful to the reader in determining whether to read the 568 | message. 569 | 570 | 2.2.11. Approved 571 | 572 | This line is required for any message posted to a moderated 573 | newsgroup. It should be added by the moderator and consist of his 574 | mail address. It is also required with certain control messages. 575 | 576 | 2.2.12. Lines 577 | 578 | This contains a count of the number of lines in the body of the 579 | message. 580 | 581 | 2.2.13. Xref 582 | 583 | This line contains the name of the host (with domains omitted) and a 584 | white space separated list of colon-separated pairs of newsgroup 585 | names and message numbers. These are the newsgroups listed in the 586 | "Newsgroups" line and the corresponding message numbers from the 587 | spool directory. 588 | 589 | This is only of value to the local system, so it should not be 590 | transmitted. For example, in: 591 | 592 | Path: seismo!lll-crg!lll-lcc!pyramid!decwrl!reid 593 | From: reid@decwrl.DEC.COM (Brian Reid) 594 | Newsgroups: news.lists,news.groups 595 | Subject: USENET READERSHIP SUMMARY REPORT FOR SEP 86 596 | Message-ID: <5658@decwrl.DEC.COM> 597 | Date: 1 Oct 86 11:26:15 GMT 598 | Organization: DEC Western Research Laboratory 599 | Lines: 441 600 | Approved: reid@decwrl.UUCP 601 | Xref: seismo news.lists:461 news.groups:6378 602 | 603 | the "Xref" line shows that the message is message number 461 in the 604 | newsgroup news.lists, and message number 6378 in the newsgroup 605 | news.groups, on host seismo. This information may be used by 606 | certain user interfaces. 607 | 608 | 3. Control Messages 609 | 610 | This section lists the control messages currently defined. The body 611 | of the "Control" header line is the control message. Messages are a 612 | sequence of zero or more words, separated by white space (blanks or 613 | tabs). The first word is the name of the control message, remaining 614 | words are parameters to the message. The remainder of the header 615 | 616 | 617 | 618 | Horton & Adams [Page 11] 619 | 620 | RFC 1036 Standard for USENET Messages December 1987 621 | 622 | 623 | and the body of the message are also potential parameters; for 624 | example, the "From" line might suggest an address to which a 625 | response is to be mailed. 626 | 627 | Implementors and administrators may choose to allow control messages 628 | to be carried out automatically, or to queue them for annual 629 | processing. However, manually processed messages should be dealt 630 | with promptly. 631 | 632 | Failed control messages should NOT be mailed to the originator of 633 | the message, but to the local "usenet" account. 634 | 635 | 3.1. Cancel 636 | 637 | cancel 638 | 639 | 640 | If a message with the given Message-ID is present on the local 641 | system, the message is cancelled. This mechanism allows a user to 642 | cancel a message after the message has been distributed over the 643 | network. 644 | 645 | If the system is unable to cancel the message as requested, it 646 | should not forward the cancellation request to its neighbor systems. 647 | 648 | Only the author of the message or the local news administrator is 649 | allowed to send this message. The verified sender of a message is 650 | the "Sender" line, or if no "Sender" line is present, the "From" 651 | line. The verified sender of the cancel message must be the same as 652 | either the "Sender" or "From" field of the original message. A 653 | verified sender in the cancel message is allowed to match an 654 | unverified "From" in the original message. 655 | 656 | 3.2. Ihave/Sendme 657 | 658 | ihave [] 659 | sendme [] 660 | 661 | This message is part of the ihave/sendme protocol, which allows one 662 | host (say A) to tell another host (B) that a particular message has 663 | been received on A. Suppose that host A receives message 664 | "<1234@ucbvax.Berkeley.edu>", and wishes to transmit the message to 665 | host B. 666 | 667 | A sends the control message "ihave <1234@ucbvax.Berkeley.edu> A" to 668 | host B (by posting it to newsgroup to.B). B responds with the 669 | control message "sendme <1234@ucbvax.Berkeley.edu> B" (on newsgroup 670 | to.A), if it has not already received the message. Upon receiving 671 | 672 | 673 | 674 | Horton & Adams [Page 12] 675 | 676 | RFC 1036 Standard for USENET Messages December 1987 677 | 678 | 679 | the sendme message, A sends the message to B. 680 | 681 | This protocol can be used to cut down on redundant traffic between 682 | hosts. It is optional and should be used only if the particular 683 | situation makes it worthwhile. Frequently, the outcome is that, 684 | since most original messages are short, and since there is a high 685 | overhead to start sending a new message with UUCP, it costs as much 686 | to send the ihave as it would cost to send the message itself. 687 | 688 | One possible solution to this overhead problem is to batch requests. 689 | Several Message-ID's may be announced or requested in one message. 690 | If no Message-ID's are listed in the control message, the body of 691 | the message should be scanned for Message-ID's, one per line. 692 | 693 | 3.3. Newgroup 694 | 695 | newgroup [moderated] 696 | 697 | This control message creates a new newsgroup with the given name. 698 | Since no messages may be posted or forwarded until a newsgroup is 699 | created, this message is required before a newsgroup can be used. 700 | The body of the message is expected to be a short paragraph 701 | describing the intended use of the newsgroup. 702 | 703 | If the second argument is present and it is the keyword moderated, 704 | the group should be created moderated instead of the default of 705 | unmoderated. The newgroup message should be ignored unless there is 706 | an "Approved" line in the same message header. 707 | 708 | 3.4. Rmgroup 709 | 710 | rmgroup 711 | 712 | This message removes a newsgroup with the given name. Since the 713 | newsgroup is removed from every host on the network, this command 714 | should be used carefully by a responsible administrator. The 715 | rmgroup message should be ignored unless there is an "Approved:" 716 | line in the same message header. 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | Horton & Adams [Page 13] 731 | 732 | RFC 1036 Standard for USENET Messages December 1987 733 | 734 | 735 | 3.5. Sendsys 736 | sendsys (no arguments) 737 | 738 | The sys file, listing all neighbors and the newsgroups to be sent to 739 | each neighbor, will be mailed to the author of the control message 740 | ("Reply-To", if present, otherwise "From"). This information is 741 | considered public information, and it is a requirement of membership 742 | in USENET that this information be provided on request, either 743 | automatically in response to this control message, or manually, by 744 | mailing the requested information to the author of the message. 745 | This information is used to keep the map of USENET up to date, and 746 | to determine where netnews is sent. 747 | 748 | The format of the file mailed back to the author should be the same 749 | as that of the sys file. This format has one line per neighboring 750 | host (plus one line for the local host), containing four colon 751 | separated fields. The first field has the host name of the 752 | neighbor, the second field has a newsgroup pattern describing the 753 | newsgroups sent to the neighbor. The third and fourth fields are 754 | not defined by this standard. The sys file is not the same as the 755 | UUCP L.sys file. A sample response is: 756 | 757 | From: cbosgd!mark (Mark Horton) 758 | Date: Sun, 27 Mar 83 20:39:37 -0500 759 | Subject: response to your sendsys request 760 | To: mark@cbosgd.ATT.COM 761 | 762 | Responding-System: cbosgd.ATT.COM 763 | cbosgd:osg,cb,btl,bell,world,comp,sci,rec,talk,misc,news,soc,to, 764 | test 765 | ucbvax:world,comp,to.ucbvax:L: 766 | cbosg:world,comp,bell,btl,cb,osg,to.cbosg:F:/usr/spool/outnews 767 | /cbosg 768 | cbosgb:osg,to.cbosgb:F:/usr/spool/outnews/cbosgb 769 | sescent:world,comp,bell,btl,cb,to.sescent:F:/usr/spool/outnews 770 | /sescent 771 | npois:world,comp,bell,btl,ug,to.npois:F:/usr/spool/outnews/npois 772 | mhuxi:world,comp,bell,btl,ug,to.mhuxi:F:/usr/spool/outnews/mhuxi 773 | 774 | 3.6. Version 775 | 776 | version (no arguments) 777 | 778 | The name and version of the software running on the local system is 779 | to be mailed back to the author of the message ("Reply-to" if 780 | present, otherwise "From"). 781 | 782 | 3.7. Checkgroups 783 | 784 | 785 | 786 | Horton & Adams [Page 14] 787 | 788 | RFC 1036 Standard for USENET Messages December 1987 789 | 790 | 791 | The message body is a list of "official" newsgroups and their 792 | description, one group per line. They are compared against the list 793 | of active newsgroups on the current host. The names of any obsolete 794 | or new newsgroups are mailed to the user "usenet" and descriptions 795 | of the new newsgroups are added to the help file used when posting 796 | news. 797 | 798 | 4. Transmission Methods 799 | 800 | USENET is not a physical network, but rather a logical network 801 | resting on top of several existing physical networks. These 802 | networks include, but are not limited to, UUCP, the Internet, an 803 | Ethernet, the BLICN network, an NSC Hyperchannel, and a BERKNET. 804 | What is important is that two neighboring systems on USENET have 805 | some method to get a new message, in the format listed here, from 806 | one system to the other, and once on the receiving system, processed 807 | by the netnews software on that system. (On UNIX systems, this 808 | usually means the rnews program being run with the message on the 809 | standard input. <1>) 810 | 811 | It is not a requirement that USENET hosts have mail systems capable 812 | of understanding the Internet mail syntax, but it is strongly 813 | recommended. Since "From", "Reply-To", and "Sender" lines use the 814 | Internet syntax, replies will be difficult or impossible without an 815 | Internet mailer. A host without an Internet mailer can attempt to 816 | use the "Path" header line for replies, but this field is not 817 | guaranteed to be a working path for replies. In any event, any host 818 | generating or forwarding news messages must have an Internet address 819 | that allows them to receive mail from hosts with Internet mailers, 820 | and they must include their Internet address on their From line. 821 | 822 | 4.1. Remote Execution 823 | 824 | Some networks permit direct remote command execution. On these 825 | networks, news may be forwarded by spooling the rnews command with 826 | the message on the standard input. For example, if the remote 827 | system is called remote, news would be sent over a UUCP link 828 | with the command: 829 | 830 | uux - remote!rnews 831 | 832 | and on a Berknet: 833 | 834 | net -mremote rnews 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | Horton & Adams [Page 15] 843 | 844 | RFC 1036 Standard for USENET Messages December 1987 845 | 846 | 847 | It is important that the message be sent via a reliable mechanism, 848 | normally involving the possibility of spooling, rather than direct 849 | real-time remote execution. This is because, if the remote system 850 | is down, a direct execution command will fail, and the message will 851 | never be delivered. If the message is spooled, it will eventually 852 | be delivered when both systems are up. 853 | 854 | 4.2. Transfer by Mail 855 | 856 | On some systems, direct remote spooled execution is not possible. 857 | However, most systems support electronic mail, and a news message 858 | can be sent as mail. One approach is to send a mail message which 859 | is identical to the news message: the mail headers are the news 860 | headers, and the mail body is the news body. By convention, this 861 | mail is sent to the user newsmail on the remote machine. 862 | 863 | One problem with this method is that it may not be possible to 864 | convince the mail system that the "From" line of the message is 865 | valid, since the mail message was generated by a program on a 866 | system different from the source of the news message. Another 867 | problem is that error messages caused by the mail transmission 868 | would be sent to the originator of the news message, who has no 869 | control over news transmission between two cooperating hosts 870 | and does not know whom to contact. Transmission error messages 871 | should be directed to a responsible contact person on the 872 | sending machine. 873 | 874 | A solution to this problem is to encapsulate the news message into a 875 | mail message, such that the entire message (headers and body) are 876 | part of the body of the mail message. The convention here is that 877 | such mail is sent to user rnews on the remote system. A mail 878 | message body is generated by prepending the letter N to each line of 879 | the news message, and then attaching whatever mail headers are 880 | convenient to generate. The N's are attached to prevent any special 881 | lines in the news message from interfering with mail transmission, 882 | and to prevent any extra lines inserted by the mailer (headers, 883 | blank lines, etc.) from becoming part of the news message. A 884 | program on the receiving machine receives mail to rnews, extracting 885 | the message itself and invoking the rnews program. An example in 886 | this format might look like this: 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | Horton & Adams [Page 16] 899 | 900 | RFC 1036 Standard for USENET Messages December 1987 901 | 902 | 903 | Date: Mon, 3 Jan 83 08:33:47 MST 904 | From: news@cbosgd.ATT.COM 905 | Subject: network news message 906 | To: rnews@npois.ATT.COM 907 | 908 | NPath: cbosgd!mhuxj!harpo!utah-cs!sask!derek 909 | NFrom: derek@sask.UUCP (Derek Andrew) 910 | NNewsgroups: misc.test 911 | NSubject: necessary test 912 | NMessage-ID: <176@sask.UUCP> 913 | NDate: Mon, 3 Jan 83 00:59:15 MST 914 | N 915 | NThis really is a test. If anyone out there more than 6 916 | Nhops away would kindly confirm this note I would 917 | Nappreciate it. We suspect that our news postings 918 | Nare not getting out into the world. 919 | N 920 | 921 | Using mail solves the spooling problem, since mail must always be 922 | spooled if the destination host is down. However, it adds more 923 | overhead to the transmission process (to encapsulate and extract the 924 | message) and makes it harder for software to give different 925 | priorities to news and mail. 926 | 927 | 4.3. Batching 928 | 929 | Since news messages are usually short, and since a large number of 930 | messages are often sent between two hosts in a day, it may make 931 | sense to batch news messages. Several messages can be combined into 932 | one large message, using conventions agreed upon in advance by the 933 | two hosts. One such batching scheme is described here; its use is 934 | highly recommended. 935 | 936 | News messages are combined into a script, separated by a header of 937 | the form: 938 | 939 | 940 | #! rnews 1234 941 | 942 | where 1234 is the length of the message in bytes. Each such line is 943 | followed by a message containing the given number of bytes. (The 944 | newline at the end of each line of the message is counted as one 945 | byte, for purposes of this count, even if it is stored as .) For example, a batch of message might look 947 | like this: 948 | 949 | 950 | 951 | 952 | 953 | 954 | Horton & Adams [Page 17] 955 | 956 | RFC 1036 Standard for USENET Messages December 1987 957 | 958 | 959 | #! rnews 239 960 | From: jerry@eagle.ATT.COM (Jerry Schwarz) 961 | Path: cbosgd!mhuxj!mhuxt!eagle!jerry 962 | Newsgroups: news.announce 963 | Subject: Usenet Etiquette -- Please Read 964 | Message-ID: <642@eagle.ATT.COM> 965 | Date: Fri, 19 Nov 82 16:14:55 EST 966 | Approved: mark@cbosgd.ATT.COM 967 | 968 | Here is an important message about USENET Etiquette. 969 | #! rnews 234 970 | From: jerry@eagle.ATT.COM (Jerry Schwarz) 971 | Path: cbosgd!mhuxj!mhuxt!eagle!jerry 972 | Newsgroups: news.announce 973 | Subject: Notes on Etiquette message 974 | Message-ID: <643@eagle.ATT.COM> 975 | Date: Fri, 19 Nov 82 17:24:12 EST 976 | Approved: mark@cbosgd.ATT.COM 977 | 978 | There was something I forgot to mention in the last 979 | message. 980 | 981 | Batched news is recognized because the first character in the 982 | message is #. The message is then passed to the unbatcher for 983 | interpretation. 984 | 985 | The second argument (in this example rnews) determines which 986 | batching scheme is being used. Cooperating hosts may use whatever 987 | scheme is appropriate for them. 988 | 989 | 5. The News Propagation Algorithm 990 | 991 | This section describes the overall scheme of USENET and the 992 | algorithm followed by hosts in propagating news to the entire 993 | logical network. Since all hosts are affected by incorrectly 994 | formatted messages and by propagation errors, it is important 995 | for the method to be standardized. 996 | 997 | USENET is a directed graph. Each node in the graph is a host 998 | computer, and each arc in the graph is a transmission path from 999 | one host to another host. Each arc is labeled with a newsgroup 1000 | pattern, specifying which newsgroup classes are forwarded along 1001 | that link. Most arcs are bidirectional, that is, if host A 1002 | sends a class of newsgroups to host B, then host B usually sends 1003 | the same class of newsgroups to host A. This bidirectionality 1004 | is not, however, required. 1005 | 1006 | USENET is made up of many subnetworks. Each subnet has a name, such 1007 | 1008 | 1009 | 1010 | Horton & Adams [Page 18] 1011 | 1012 | RFC 1036 Standard for USENET Messages December 1987 1013 | 1014 | 1015 | as comp or btl. Each subnet is a connected graph, that is, a path 1016 | exists from every node to every other node in the subnet. In 1017 | addition, the entire graph is (theoretically) connected. (In 1018 | practice, some political considerations have caused some hosts to be 1019 | unable to post messages reaching the rest of the network.) 1020 | 1021 | A message is posted on one machine to a list of newsgroups. That 1022 | machine accepts it locally, then forwards it to all its neighbors 1023 | that are interested in at least one of the newsgroups of the 1024 | message. (Site A deems host B to be "interested" in a newsgroup if 1025 | the newsgroup matches the pattern on the arc from A to B. This 1026 | pattern is stored in a file on the A machine.) The hosts receiving 1027 | the incoming message examine it to make sure they really want the 1028 | message, accept it locally, and then in turn forward the message to 1029 | all their interested neighbors. This process continues until the 1030 | entire network has seen the message. 1031 | 1032 | An important part of the algorithm is the prevention of loops. The 1033 | above process would cause a message to loop along a cycle forever. 1034 | In particular, when host A sends a message to host B, host B will 1035 | send it back to host A, which will send it to host B, and so on. 1036 | One solution to this is the history mechanism. Each host keeps 1037 | track of all messages it has seen (by their Message-ID) and 1038 | whenever a message comes in that it has already seen, the incoming 1039 | message is discarded immediately. This solution is sufficient to 1040 | prevent loops, but additional optimizations can be made to avoid 1041 | sending messages to hosts that will simply throw them away. 1042 | 1043 | One optimization is that a message should never be sent to a machine 1044 | listed in the "Path" line of the header. When a machine name is 1045 | in the "Path" line, the message is known to have passed through the 1046 | machine. Another optimization is that, if the message originated 1047 | on host A, then host A has already seen the message. Thus, if a 1048 | message is posted to newsgroup misc.misc, it will match the pattern 1049 | misc.all (where all is a metasymbol that matches any string), and 1050 | will be forwarded to all hosts that subscribe to misc.all (as 1051 | determined by what their neighbors send them). These hosts make up 1052 | the misc subnetwork. A message posted to btl.general will reach all 1053 | hosts receiving btl.all, but will not reach hosts that do not get 1054 | btl.all. In effect, the messages reaches the btl subnetwork. A 1055 | messages posted to newsgroups misc.misc,btl.general will reach all 1056 | hosts subscribing to either of the two classes. 1057 | 1058 | Notes 1059 | 1060 | <1> UNIX is a registered trademark of AT&T. 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | Horton & Adams [Page 19] 1067 | -------------------------------------------------------------------------------- /rfc977.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | Network Working Group Brian Kantor (U.C. San Diego) 4 | Request for Comments: 977 Phil Lapsley (U.C. Berkeley) 5 | February 1986 6 | 7 | Network News Transfer Protocol 8 | 9 | A Proposed Standard for the Stream-Based 10 | Transmission of News 11 | 12 | Status of This Memo 13 | 14 | NNTP specifies a protocol for the distribution, inquiry, retrieval, 15 | and posting of news articles using a reliable stream-based 16 | transmission of news among the ARPA-Internet community. NNTP is 17 | designed so that news articles are stored in a central database 18 | allowing a subscriber to select only those items he wishes to read. 19 | Indexing, cross-referencing, and expiration of aged messages are also 20 | provided. This RFC suggests a proposed protocol for the ARPA-Internet 21 | community, and requests discussion and suggestions for improvements. 22 | Distribution of this memo is unlimited. 23 | 24 | 1. Introduction 25 | 26 | For many years, the ARPA-Internet community has supported the 27 | distribution of bulletins, information, and data in a timely fashion 28 | to thousands of participants. We collectively refer to such items of 29 | information as "news". Such news provides for the rapid 30 | dissemination of items of interest such as software bug fixes, new 31 | product reviews, technical tips, and programming pointers, as well as 32 | rapid-fire discussions of matters of concern to the working computer 33 | professional. News is very popular among its readers. 34 | 35 | There are popularly two methods of distributing such news: the 36 | Internet method of direct mailing, and the USENET news system. 37 | 38 | 1.1. Internet Mailing Lists 39 | 40 | The Internet community distributes news by the use of mailing lists. 41 | These are lists of subscriber's mailbox addresses and remailing 42 | sublists of all intended recipients. These mailing lists operate by 43 | remailing a copy of the information to be distributed to each 44 | subscriber on the mailing list. Such remailing is inefficient when a 45 | mailing list grows beyond a dozen or so people, since sending a 46 | separate copy to each of the subscribers occupies large quantities of 47 | network bandwidth, CPU resources, and significant amounts of disk 48 | storage at the destination host. There is also a significant problem 49 | in maintenance of the list itself: as subscribers move from one job 50 | to another; as new subscribers join and old ones leave; and as hosts 51 | come in and out of service. 52 | 53 | 54 | 55 | 56 | Kantor & Lapsley [Page 1] 57 | 58 | 59 | 60 | RFC 977 February 1986 61 | Network News Transfer Protocol 62 | 63 | 64 | 1.2. The USENET News System 65 | 66 | Clearly, a worthwhile reduction of the amount of these resources used 67 | can be achieved if articles are stored in a central database on the 68 | receiving host instead of in each subscriber's mailbox. The USENET 69 | news system provides a method of doing just this. There is a central 70 | repository of the news articles in one place (customarily a spool 71 | directory of some sort), and a set of programs that allow a 72 | subscriber to select those items he wishes to read. Indexing, 73 | cross-referencing, and expiration of aged messages are also provided. 74 | 75 | 1.3. Central Storage of News 76 | 77 | For clusters of hosts connected together by fast local area networks 78 | (such as Ethernet), it makes even more sense to consolidate news 79 | distribution onto one (or a very few) hosts, and to allow access to 80 | these news articles using a server and client model. Subscribers may 81 | then request only the articles they wish to see, without having to 82 | wastefully duplicate the storage of a copy of each item on each host. 83 | 84 | 1.4. A Central News Server 85 | 86 | A way to achieve these economies is to have a central computer system 87 | that can provide news service to the other systems on the local area 88 | network. Such a server would manage the collection of news articles 89 | and index files, with each person who desires to read news bulletins 90 | doing so over the LAN. For a large cluster of computer systems, the 91 | savings in total disk space is clearly worthwhile. Also, this allows 92 | workstations with limited disk storage space to participate in the 93 | news without incoming items consuming oppressive amounts of the 94 | workstation's disk storage. 95 | 96 | We have heard rumors of somewhat successful attempts to provide 97 | centralized news service using IBIS and other shared or distributed 98 | file systems. While it is possible that such a distributed file 99 | system implementation might work well with a group of similar 100 | computers running nearly identical operating systems, such a scheme 101 | is not general enough to offer service to a wide range of client 102 | systems, especially when many diverse operating systems may be in use 103 | among a group of clients. There are few (if any) shared or networked 104 | file systems that can offer the generality of service that stream 105 | connections using Internet TCP provide, particularly when a wide 106 | range of host hardware and operating systems are considered. 107 | 108 | NNTP specifies a protocol for the distribution, inquiry, retrieval, 109 | and posting of news articles using a reliable stream (such as TCP) 110 | server-client model. NNTP is designed so that news articles need only 111 | 112 | 113 | Kantor & Lapsley [Page 2] 114 | 115 | 116 | 117 | RFC 977 February 1986 118 | Network News Transfer Protocol 119 | 120 | 121 | be stored on one (presumably central) host, and subscribers on other 122 | hosts attached to the LAN may read news articles using stream 123 | connections to the news host. 124 | 125 | NNTP is modelled upon the news article specifications in RFC 850, 126 | which describes the USENET news system. However, NNTP makes few 127 | demands upon the structure, content, or storage of news articles, and 128 | thus we believe it easily can be adapted to other non-USENET news 129 | systems. 130 | 131 | Typically, the NNTP server runs as a background process on one host, 132 | and would accept connections from other hosts on the LAN. This works 133 | well when there are a number of small computer systems (such as 134 | workstations, with only one or at most a few users each), and a large 135 | central server. 136 | 137 | 1.5. Intermediate News Servers 138 | 139 | For clusters of machines with many users (as might be the case in a 140 | university or large industrial environment), an intermediate server 141 | might be used. This intermediate or "slave" server runs on each 142 | computer system, and is responsible for mediating news reading 143 | requests and performing local caching of recently-retrieved news 144 | articles. 145 | 146 | Typically, a client attempting to obtain news service would first 147 | attempt to connect to the news service port on the local machine. If 148 | this attempt were unsuccessful, indicating a failed server, an 149 | installation might choose to either deny news access, or to permit 150 | connection to the central "master" news server. 151 | 152 | For workstations or other small systems, direct connection to the 153 | master server would probably be the normal manner of operation. 154 | 155 | This specification does not cover the operation of slave NNTP 156 | servers. We merely suggest that slave servers are a logical addition 157 | to NNTP server usage which would enhance operation on large local 158 | area networks. 159 | 160 | 1.6. News Distribution 161 | 162 | NNTP has commands which provide a straightforward method of 163 | exchanging articles between cooperating hosts. Hosts which are well 164 | connected on a local area or other fast network and who wish to 165 | actually obtain copies of news articles for local storage might well 166 | find NNTP to be a more efficient way to distribute news than more 167 | traditional transfer methods (such as UUCP). 168 | 169 | 170 | Kantor & Lapsley [Page 3] 171 | 172 | 173 | 174 | RFC 977 February 1986 175 | Network News Transfer Protocol 176 | 177 | 178 | In the traditional method of distributing news articles, news is 179 | propagated from host to host by flooding - that is, each host will 180 | send all its new news articles on to each host that it feeds. These 181 | hosts will then in turn send these new articles on to other hosts 182 | that they feed. Clearly, sending articles that a host already has 183 | obtained a copy of from another feed (many hosts that receive news 184 | are redundantly fed) again is a waste of time and communications 185 | resources, but for transport mechanisms that are single-transaction 186 | based rather than interactive (such as UUCP in the UNIX-world <1>), 187 | distribution time is diminished by sending all articles and having 188 | the receiving host simply discard the duplicates. This is an 189 | especially true when communications sessions are limited to once a 190 | day. 191 | 192 | Using NNTP, hosts exchanging news articles have an interactive 193 | mechanism for deciding which articles are to be transmitted. A host 194 | desiring new news, or which has new news to send, will typically 195 | contact one or more of its neighbors using NNTP. First it will 196 | inquire if any new news groups have been created on the serving host 197 | by means of the NEWGROUPS command. If so, and those are appropriate 198 | or desired (as established by local site-dependent rules), those new 199 | newsgroups can be created. 200 | 201 | The client host will then inquire as to which new articles have 202 | arrived in all or some of the newsgroups that it desires to receive, 203 | using the NEWNEWS command. It will receive a list of new articles 204 | from the server, and can request transmission of those articles that 205 | it desires and does not already have. 206 | 207 | Finally, the client can advise the server of those new articles which 208 | the client has recently received. The server will indicate those 209 | articles that it has already obtained copies of, and which articles 210 | should be sent to add to its collection. 211 | 212 | In this manner, only those articles which are not duplicates and 213 | which are desired are transferred. 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | Kantor & Lapsley [Page 4] 228 | 229 | 230 | 231 | RFC 977 February 1986 232 | Network News Transfer Protocol 233 | 234 | 235 | 2. The NNTP Specification 236 | 237 | 2.1. Overview 238 | 239 | The news server specified by this document uses a stream connection 240 | (such as TCP) and SMTP-like commands and responses. It is designed 241 | to accept connections from hosts, and to provide a simple interface 242 | to the news database. 243 | 244 | This server is only an interface between programs and the news 245 | databases. It does not perform any user interaction or presentation- 246 | level functions. These "user-friendly" functions are better left to 247 | the client programs, which have a better understanding of the 248 | environment in which they are operating. 249 | 250 | When used via Internet TCP, the contact port assigned for this 251 | service is 119. 252 | 253 | 2.2. Character Codes 254 | 255 | Commands and replies are composed of characters from the ASCII 256 | character set. When the transport service provides an 8-bit byte 257 | (octet) transmission channel, each 7-bit character is transmitted 258 | right justified in an octet with the high order bit cleared to zero. 259 | 260 | 2.3. Commands 261 | 262 | Commands consist of a command word, which in some cases may be 263 | followed by a parameter. Commands with parameters must separate the 264 | parameters from each other and from the command by one or more space 265 | or tab characters. Command lines must be complete with all required 266 | parameters, and may not contain more than one command. 267 | 268 | Commands and command parameters are not case sensitive. That is, a 269 | command or parameter word may be upper case, lower case, or any 270 | mixture of upper and lower case. 271 | 272 | Each command line must be terminated by a CR-LF (Carriage Return - 273 | Line Feed) pair. 274 | 275 | Command lines shall not exceed 512 characters in length, counting all 276 | characters including spaces, separators, punctuation, and the 277 | trailing CR-LF (thus there are 510 characters maximum allowed for the 278 | command and its parameters). There is no provision for continuation 279 | command lines. 280 | 281 | 282 | 283 | 284 | Kantor & Lapsley [Page 5] 285 | 286 | 287 | 288 | RFC 977 February 1986 289 | Network News Transfer Protocol 290 | 291 | 292 | 2.4. Responses 293 | 294 | Responses are of two kinds, textual and status. 295 | 296 | 2.4.1. Text Responses 297 | 298 | Text is sent only after a numeric status response line has been sent 299 | that indicates that text will follow. Text is sent as a series of 300 | successive lines of textual matter, each terminated with CR-LF pair. 301 | A single line containing only a period (.) is sent to indicate the 302 | end of the text (i.e., the server will send a CR-LF pair at the end 303 | of the last line of text, a period, and another CR-LF pair). 304 | 305 | If the text contained a period as the first character of the text 306 | line in the original, that first period is doubled. Therefore, the 307 | client must examine the first character of each line received, and 308 | for those beginning with a period, determine either that this is the 309 | end of the text or whether to collapse the doubled period to a single 310 | one. 311 | 312 | The intention is that text messages will usually be displayed on the 313 | user's terminal whereas command/status responses will be interpreted 314 | by the client program before any possible display is done. 315 | 316 | 2.4.2. Status Responses 317 | 318 | These are status reports from the server and indicate the response to 319 | the last command received from the client. 320 | 321 | Status response lines begin with a 3 digit numeric code which is 322 | sufficient to distinguish all responses. Some of these may herald 323 | the subsequent transmission of text. 324 | 325 | The first digit of the response broadly indicates the success, 326 | failure, or progress of the previous command. 327 | 328 | 1xx - Informative message 329 | 2xx - Command ok 330 | 3xx - Command ok so far, send the rest of it. 331 | 4xx - Command was correct, but couldn't be performed for 332 | some reason. 333 | 5xx - Command unimplemented, or incorrect, or a serious 334 | program error occurred. 335 | 336 | 337 | 338 | 339 | 340 | 341 | Kantor & Lapsley [Page 6] 342 | 343 | 344 | 345 | RFC 977 February 1986 346 | Network News Transfer Protocol 347 | 348 | 349 | The next digit in the code indicates the function response category. 350 | 351 | x0x - Connection, setup, and miscellaneous messages 352 | x1x - Newsgroup selection 353 | x2x - Article selection 354 | x3x - Distribution functions 355 | x4x - Posting 356 | x8x - Nonstandard (private implementation) extensions 357 | x9x - Debugging output 358 | 359 | The exact response codes that should be expected from each command 360 | are detailed in the description of that command. In addition, below 361 | is listed a general set of response codes that may be received at any 362 | time. 363 | 364 | Certain status responses contain parameters such as numbers and 365 | names. The number and type of such parameters is fixed for each 366 | response code to simplify interpretation of the response. 367 | 368 | Parameters are separated from the numeric response code and from each 369 | other by a single space. All numeric parameters are decimal, and may 370 | have leading zeros. All string parameters begin after the separating 371 | space, and end before the following separating space or the CR-LF 372 | pair at the end of the line. (String parameters may not, therefore, 373 | contain spaces.) All text, if any, in the response which is not a 374 | parameter of the response must follow and be separated from the last 375 | parameter by a space. Also, note that the text following a response 376 | number may vary in different implementations of the server. The 377 | 3-digit numeric code should be used to determine what response was 378 | sent. 379 | 380 | Response codes not specified in this standard may be used for any 381 | installation-specific additional commands also not specified. These 382 | should be chosen to fit the pattern of x8x specified above. (Note 383 | that debugging is provided for explicitly in the x9x response codes.) 384 | The use of unspecified response codes for standard commands is 385 | prohibited. 386 | 387 | We have provided a response pattern x9x for debugging. Since much 388 | debugging output may be classed as "informative messages", we would 389 | expect, therefore, that responses 190 through 199 would be used for 390 | various debugging outputs. There is no requirement in this 391 | specification for debugging output, but if such is provided over the 392 | connected stream, it must use these response codes. If appropriate 393 | to a specific implementation, other x9x codes may be used for 394 | debugging. (An example might be to use e.g., 290 to acknowledge a 395 | remote debugging request.) 396 | 397 | 398 | Kantor & Lapsley [Page 7] 399 | 400 | 401 | 402 | RFC 977 February 1986 403 | Network News Transfer Protocol 404 | 405 | 406 | 2.4.3. General Responses 407 | 408 | The following is a list of general response codes that may be sent by 409 | the NNTP server. These are not specific to any one command, but may 410 | be returned as the result of a connection, a failure, or some unusual 411 | condition. 412 | 413 | In general, 1xx codes may be ignored or displayed as desired; code 414 | 200 or 201 is sent upon initial connection to the NNTP server 415 | depending upon posting permission; code 400 will be sent when the 416 | NNTP server discontinues service (by operator request, for example); 417 | and 5xx codes indicate that the command could not be performed for 418 | some unusual reason. 419 | 420 | 100 help text 421 | 190 422 | through 423 | 199 debug output 424 | 425 | 200 server ready - posting allowed 426 | 201 server ready - no posting allowed 427 | 428 | 400 service discontinued 429 | 430 | 500 command not recognized 431 | 501 command syntax error 432 | 502 access restriction or permission denied 433 | 503 program fault - command not performed 434 | 435 | 3. Command and Response Details 436 | 437 | On the following pages are descriptions of each command recognized by 438 | the NNTP server and the responses which will be returned by those 439 | commands. 440 | 441 | Each command is shown in upper case for clarity, although case is 442 | ignored in the interpretation of commands by the NNTP server. Any 443 | parameters are shown in lower case. A parameter shown in [square 444 | brackets] is optional. For example, [GMT] indicates that the 445 | triglyph GMT may present or omitted. 446 | 447 | Every command described in this section must be implemented by all 448 | NNTP servers. 449 | 450 | 451 | 452 | 453 | 454 | 455 | Kantor & Lapsley [Page 8] 456 | 457 | 458 | 459 | RFC 977 February 1986 460 | Network News Transfer Protocol 461 | 462 | 463 | There is no prohibition against additional commands being added; 464 | however, it is recommended that any such unspecified command begin 465 | with the letter "X" to avoid conflict with later revisions of this 466 | specification. 467 | 468 | Implementors are reminded that such additional commands may not 469 | redefine specified status response codes. Using additional 470 | unspecified responses for standard commands is also prohibited. 471 | 472 | 3.1. The ARTICLE, BODY, HEAD, and STAT commands 473 | 474 | There are two forms to the ARTICLE command (and the related BODY, 475 | HEAD, and STAT commands), each using a different method of specifying 476 | which article is to be retrieved. When the ARTICLE command is 477 | followed by a message-id in angle brackets ("<" and ">"), the first 478 | form of the command is used; when a numeric parameter or no parameter 479 | is supplied, the second form is invoked. 480 | 481 | The text of the article is returned as a textual response, as 482 | described earlier in this document. 483 | 484 | The HEAD and BODY commands are identical to the ARTICLE command 485 | except that they respectively return only the header lines or text 486 | body of the article. 487 | 488 | The STAT command is similar to the ARTICLE command except that no 489 | text is returned. When selecting by message number within a group, 490 | the STAT command serves to set the current article pointer without 491 | sending text. The returned acknowledgement response will contain the 492 | message-id, which may be of some value. Using the STAT command to 493 | select by message-id is valid but of questionable value, since a 494 | selection by message-id does NOT alter the "current article pointer". 495 | 496 | 3.1.1. ARTICLE (selection by message-id) 497 | 498 | ARTICLE 499 | 500 | Display the header, a blank line, then the body (text) of the 501 | specified article. Message-id is the message id of an article as 502 | shown in that article's header. It is anticipated that the client 503 | will obtain the message-id from a list provided by the NEWNEWS 504 | command, from references contained within another article, or from 505 | the message-id provided in the response to some other commands. 506 | 507 | Please note that the internally-maintained "current article pointer" 508 | is NOT ALTERED by this command. This is both to facilitate the 509 | presentation of articles that may be referenced within an article 510 | 511 | 512 | Kantor & Lapsley [Page 9] 513 | 514 | 515 | 516 | RFC 977 February 1986 517 | Network News Transfer Protocol 518 | 519 | 520 | being read, and because of the semantic difficulties of determining 521 | the proper sequence and membership of an article which may have been 522 | posted to more than one newsgroup. 523 | 524 | 3.1.2. ARTICLE (selection by number) 525 | 526 | ARTICLE [nnn] 527 | 528 | Displays the header, a blank line, then the body (text) of the 529 | current or specified article. The optional parameter nnn is the 530 | 531 | numeric id of an article in the current newsgroup and must be chosen 532 | from the range of articles provided when the newsgroup was selected. 533 | If it is omitted, the current article is assumed. 534 | 535 | The internally-maintained "current article pointer" is set by this 536 | command if a valid article number is specified. 537 | 538 | [the following applies to both forms of the article command.] A 539 | response indicating the current article number, a message-id string, 540 | and that text is to follow will be returned. 541 | 542 | The message-id string returned is an identification string contained 543 | within angle brackets ("<" and ">"), which is derived from the header 544 | of the article itself. The Message-ID header line (required by 545 | RFC850) from the article must be used to supply this information. If 546 | the message-id header line is missing from the article, a single 547 | digit "0" (zero) should be supplied within the angle brackets. 548 | 549 | Since the message-id field is unique with each article, it may be 550 | used by a news reading program to skip duplicate displays of articles 551 | that have been posted more than once, or to more than one newsgroup. 552 | 553 | 3.1.3. Responses 554 | 555 | 220 n article retrieved - head and body follow 556 | (n = article number, = message-id) 557 | 221 n article retrieved - head follows 558 | 222 n article retrieved - body follows 559 | 223 n article retrieved - request text separately 560 | 412 no newsgroup has been selected 561 | 420 no current article has been selected 562 | 423 no such article number in this group 563 | 430 no such article found 564 | 565 | 566 | 567 | 568 | 569 | Kantor & Lapsley [Page 10] 570 | 571 | 572 | 573 | RFC 977 February 1986 574 | Network News Transfer Protocol 575 | 576 | 577 | 3.2. The GROUP command 578 | 579 | 3.2.1. GROUP 580 | 581 | GROUP ggg 582 | 583 | The required parameter ggg is the name of the newsgroup to be 584 | selected (e.g. "net.news"). A list of valid newsgroups may be 585 | obtained from the LIST command. 586 | 587 | The successful selection response will return the article numbers of 588 | the first and last articles in the group, and an estimate of the 589 | number of articles on file in the group. It is not necessary that 590 | the estimate be correct, although that is helpful; it must only be 591 | equal to or larger than the actual number of articles on file. (Some 592 | implementations will actually count the number of articles on file. 593 | Others will just subtract first article number from last to get an 594 | estimate.) 595 | 596 | When a valid group is selected by means of this command, the 597 | internally maintained "current article pointer" is set to the first 598 | article in the group. If an invalid group is specified, the 599 | previously selected group and article remain selected. If an empty 600 | newsgroup is selected, the "current article pointer" is in an 601 | indeterminate state and should not be used. 602 | 603 | Note that the name of the newsgroup is not case-dependent. It must 604 | otherwise match a newsgroup obtained from the LIST command or an 605 | error will result. 606 | 607 | 3.2.2. Responses 608 | 609 | 211 n f l s group selected 610 | (n = estimated number of articles in group, 611 | f = first article number in the group, 612 | l = last article number in the group, 613 | s = name of the group.) 614 | 411 no such news group 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | Kantor & Lapsley [Page 11] 627 | 628 | 629 | 630 | RFC 977 February 1986 631 | Network News Transfer Protocol 632 | 633 | 634 | 3.3. The HELP command 635 | 636 | 3.3.1. HELP 637 | 638 | HELP 639 | 640 | Provides a short summary of commands that are understood by this 641 | implementation of the server. The help text will be presented as a 642 | textual response, terminated by a single period on a line by itself. 643 | 644 | 3.3.2. Responses 645 | 646 | 100 help text follows 647 | 648 | 3.4. The IHAVE command 649 | 650 | 3.4.1. IHAVE 651 | 652 | IHAVE 653 | 654 | The IHAVE command informs the server that the client has an article 655 | whose id is . If the server desires a copy of that 656 | article, it will return a response instructing the client to send the 657 | entire article. If the server does not want the article (if, for 658 | example, the server already has a copy of it), a response indicating 659 | that the article is not wanted will be returned. 660 | 661 | If transmission of the article is requested, the client should send 662 | the entire article, including header and body, in the manner 663 | specified for text transmission from the server. A response code 664 | indicating success or failure of the transferral of the article will 665 | be returned. 666 | 667 | This function differs from the POST command in that it is intended 668 | for use in transferring already-posted articles between hosts. 669 | Normally it will not be used when the client is a personal 670 | newsreading program. In particular, this function will invoke the 671 | server's news posting program with the appropriate settings (flags, 672 | options, etc) to indicate that the forthcoming article is being 673 | forwarded from another host. 674 | 675 | The server may, however, elect not to post or forward the article if 676 | after further examination of the article it deems it inappropriate to 677 | do so. The 436 or 437 error codes may be returned as appropriate to 678 | the situation. 679 | 680 | Reasons for such subsequent rejection of an article may include such 681 | 682 | 683 | Kantor & Lapsley [Page 12] 684 | 685 | 686 | 687 | RFC 977 February 1986 688 | Network News Transfer Protocol 689 | 690 | 691 | problems as inappropriate newsgroups or distributions, disk space 692 | limitations, article lengths, garbled headers, and the like. These 693 | are typically restrictions enforced by the server host's news 694 | software and not necessarily the NNTP server itself. 695 | 696 | 3.4.2. Responses 697 | 698 | 235 article transferred ok 699 | 335 send article to be transferred. End with . 700 | 435 article not wanted - do not send it 701 | 436 transfer failed - try again later 702 | 437 article rejected - do not try again 703 | 704 | An implementation note: 705 | 706 | Because some host news posting software may not be able to decide 707 | immediately that an article is inappropriate for posting or 708 | forwarding, it is acceptable to acknowledge the successful transfer 709 | of the article and to later silently discard it. Thus it is 710 | permitted to return the 235 acknowledgement code and later discard 711 | the received article. This is not a fully satisfactory solution to 712 | the problem. Perhaps some implementations will wish to send mail to 713 | the author of the article in certain of these cases. 714 | 715 | 3.5. The LAST command 716 | 717 | 3.5.1. LAST 718 | 719 | LAST 720 | 721 | The internally maintained "current article pointer" is set to the 722 | previous article in the current newsgroup. If already positioned at 723 | the first article of the newsgroup, an error message is returned and 724 | the current article remains selected. 725 | 726 | The internally-maintained "current article pointer" is set by this 727 | command. 728 | 729 | A response indicating the current article number, and a message-id 730 | string will be returned. No text is sent in response to this 731 | command. 732 | 733 | 3.5.2. Responses 734 | 735 | 223 n a article retrieved - request text separately 736 | (n = article number, a = unique article id) 737 | 738 | 739 | 740 | Kantor & Lapsley [Page 13] 741 | 742 | 743 | 744 | RFC 977 February 1986 745 | Network News Transfer Protocol 746 | 747 | 748 | 412 no newsgroup selected 749 | 420 no current article has been selected 750 | 422 no previous article in this group 751 | 752 | 3.6. The LIST command 753 | 754 | 3.6.1. LIST 755 | 756 | LIST 757 | 758 | Returns a list of valid newsgroups and associated information. Each 759 | newsgroup is sent as a line of text in the following format: 760 | 761 | group last first p 762 | 763 | where is the name of the newsgroup, is the number of 764 | the last known article currently in that newsgroup, is the 765 | number of the first article currently in the newsgroup, and

is 766 | either 'y' or 'n' indicating whether posting to this newsgroup is 767 | allowed ('y') or prohibited ('n'). 768 | 769 | The and fields will always be numeric. They may have 770 | leading zeros. If the field evaluates to less than the 771 | field, there are no articles currently on file in the 772 | newsgroup. 773 | 774 | Note that posting may still be prohibited to a client even though the 775 | LIST command indicates that posting is permitted to a particular 776 | newsgroup. See the POST command for an explanation of client 777 | prohibitions. The posting flag exists for each newsgroup because 778 | some newsgroups are moderated or are digests, and therefore cannot be 779 | posted to; that is, articles posted to them must be mailed to a 780 | moderator who will post them for the submitter. This is independent 781 | of the posting permission granted to a client by the NNTP server. 782 | 783 | Please note that an empty list (i.e., the text body returned by this 784 | command consists only of the terminating period) is a possible valid 785 | response, and indicates that there are currently no valid newsgroups. 786 | 787 | 3.6.2. Responses 788 | 789 | 215 list of newsgroups follows 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | Kantor & Lapsley [Page 14] 798 | 799 | 800 | 801 | RFC 977 February 1986 802 | Network News Transfer Protocol 803 | 804 | 805 | 3.7. The NEWGROUPS command 806 | 807 | 3.7.1. NEWGROUPS 808 | 809 | NEWGROUPS date time [GMT] [] 810 | 811 | A list of newsgroups created since will be listed in 812 | the same format as the LIST command. 813 | 814 | The date is sent as 6 digits in the format YYMMDD, where YY is the 815 | last two digits of the year, MM is the two digits of the month (with 816 | leading zero, if appropriate), and DD is the day of the month (with 817 | leading zero, if appropriate). The closest century is assumed as 818 | part of the year (i.e., 86 specifies 1986, 30 specifies 2030, 99 is 819 | 1999, 00 is 2000). 820 | 821 | Time must also be specified. It must be as 6 digits HHMMSS with HH 822 | being hours on the 24-hour clock, MM minutes 00-59, and SS seconds 823 | 00-59. The time is assumed to be in the server's timezone unless the 824 | token "GMT" appears, in which case both time and date are evaluated 825 | at the 0 meridian. 826 | 827 | The optional parameter "distributions" is a list of distribution 828 | groups, enclosed in angle brackets. If specified, the distribution 829 | portion of a new newsgroup (e.g, 'net' in 'net.wombat') will be 830 | examined for a match with the distribution categories listed, and 831 | only those new newsgroups which match will be listed. If more than 832 | one distribution group is to be listed, they must be separated by 833 | commas within the angle brackets. 834 | 835 | Please note that an empty list (i.e., the text body returned by this 836 | command consists only of the terminating period) is a possible valid 837 | response, and indicates that there are currently no new newsgroups. 838 | 839 | 3.7.2. Responses 840 | 841 | 231 list of new newsgroups follows 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | Kantor & Lapsley [Page 15] 855 | 856 | 857 | 858 | RFC 977 February 1986 859 | Network News Transfer Protocol 860 | 861 | 862 | 3.8. The NEWNEWS command 863 | 864 | 3.8.1. NEWNEWS 865 | 866 | NEWNEWS newsgroups date time [GMT] [] 867 | 868 | A list of message-ids of articles posted or received to the specified 869 | newsgroup since "date" will be listed. The format of the listing will 870 | be one message-id per line, as though text were being sent. A single 871 | line consisting solely of one period followed by CR-LF will terminate 872 | the list. 873 | 874 | Date and time are in the same format as the NEWGROUPS command. 875 | 876 | A newsgroup name containing a "*" (an asterisk) may be specified to 877 | broaden the article search to some or all newsgroups. The asterisk 878 | will be extended to match any part of a newsgroup name (e.g., 879 | net.micro* will match net.micro.wombat, net.micro.apple, etc). Thus 880 | if only an asterisk is given as the newsgroup name, all newsgroups 881 | will be searched for new news. 882 | 883 | (Please note that the asterisk "*" expansion is a general 884 | replacement; in particular, the specification of e.g., net.*.unix 885 | should be correctly expanded to embrace names such as net.wombat.unix 886 | and net.whocares.unix.) 887 | 888 | Conversely, if no asterisk appears in a given newsgroup name, only 889 | the specified newsgroup will be searched for new articles. Newsgroup 890 | names must be chosen from those returned in the listing of available 891 | groups. Multiple newsgroup names (including a "*") may be specified 892 | in this command, separated by a comma. No comma shall appear after 893 | the last newsgroup in the list. [Implementors are cautioned to keep 894 | the 512 character command length limit in mind.] 895 | 896 | The exclamation point ("!") may be used to negate a match. This can 897 | be used to selectively omit certain newsgroups from an otherwise 898 | larger list. For example, a newsgroups specification of 899 | "net.*,mod.*,!mod.map.*" would specify that all net. and 900 | all mod. EXCEPT mod.map. newsgroup names would be 901 | matched. If used, the exclamation point must appear as the first 902 | character of the given newsgroup name or pattern. 903 | 904 | The optional parameter "distributions" is a list of distribution 905 | groups, enclosed in angle brackets. If specified, the distribution 906 | portion of an article's newsgroup (e.g, 'net' in 'net.wombat') will 907 | be examined for a match with the distribution categories listed, and 908 | only those articles which have at least one newsgroup belonging to 909 | 910 | 911 | Kantor & Lapsley [Page 16] 912 | 913 | 914 | 915 | RFC 977 February 1986 916 | Network News Transfer Protocol 917 | 918 | 919 | the list of distributions will be listed. If more than one 920 | distribution group is to be supplied, they must be separated by 921 | commas within the angle brackets. 922 | 923 | The use of the IHAVE, NEWNEWS, and NEWGROUPS commands to distribute 924 | news is discussed in an earlier part of this document. 925 | 926 | Please note that an empty list (i.e., the text body returned by this 927 | command consists only of the terminating period) is a possible valid 928 | response, and indicates that there is currently no new news. 929 | 930 | 3.8.2. Responses 931 | 932 | 230 list of new articles by message-id follows 933 | 934 | 3.9. The NEXT command 935 | 936 | 3.9.1. NEXT 937 | 938 | NEXT 939 | 940 | The internally maintained "current article pointer" is advanced to 941 | the next article in the current newsgroup. If no more articles 942 | remain in the current group, an error message is returned and the 943 | current article remains selected. 944 | 945 | The internally-maintained "current article pointer" is set by this 946 | command. 947 | 948 | A response indicating the current article number, and the message-id 949 | string will be returned. No text is sent in response to this 950 | command. 951 | 952 | 3.9.2. Responses 953 | 954 | 223 n a article retrieved - request text separately 955 | (n = article number, a = unique article id) 956 | 412 no newsgroup selected 957 | 420 no current article has been selected 958 | 421 no next article in this group 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | Kantor & Lapsley [Page 17] 969 | 970 | 971 | 972 | RFC 977 February 1986 973 | Network News Transfer Protocol 974 | 975 | 976 | 3.10. The POST command 977 | 978 | 3.10.1. POST 979 | 980 | POST 981 | 982 | If posting is allowed, response code 340 is returned to indicate that 983 | the article to be posted should be sent. Response code 440 indicates 984 | that posting is prohibited for some installation-dependent reason. 985 | 986 | If posting is permitted, the article should be presented in the 987 | format specified by RFC850, and should include all required header 988 | lines. After the article's header and body have been completely sent 989 | by the client to the server, a further response code will be returned 990 | to indicate success or failure of the posting attempt. 991 | 992 | The text forming the header and body of the message to be posted 993 | should be sent by the client using the conventions for text received 994 | from the news server: A single period (".") on a line indicates the 995 | end of the text, with lines starting with a period in the original 996 | text having that period doubled during transmission. 997 | 998 | No attempt shall be made by the server to filter characters, fold or 999 | limit lines, or otherwise process incoming text. It is our intent 1000 | that the server just pass the incoming message to be posted to the 1001 | server installation's news posting software, which is separate from 1002 | this specification. See RFC850 for more details. 1003 | 1004 | Since most installations will want the client news program to allow 1005 | the user to prepare his message using some sort of text editor, and 1006 | transmit it to the server for posting only after it is composed, the 1007 | client program should take note of the herald message that greeted it 1008 | when the connection was first established. This message indicates 1009 | whether postings from that client are permitted or not, and can be 1010 | used to caution the user that his access is read-only if that is the 1011 | case. This will prevent the user from wasting a good deal of time 1012 | composing a message only to find posting of the message was denied. 1013 | The method and determination of which clients and hosts may post is 1014 | installation dependent and is not covered by this specification. 1015 | 1016 | 3.10.2. Responses 1017 | 1018 | 240 article posted ok 1019 | 340 send article to be posted. End with . 1020 | 440 posting not allowed 1021 | 441 posting failed 1022 | 1023 | 1024 | 1025 | Kantor & Lapsley [Page 18] 1026 | 1027 | 1028 | 1029 | RFC 977 February 1986 1030 | Network News Transfer Protocol 1031 | 1032 | 1033 | (for reference, one of the following codes will be sent upon initial 1034 | connection; the client program should determine whether posting is 1035 | generally permitted from these:) 200 server ready - posting allowed 1036 | 201 server ready - no posting allowed 1037 | 1038 | 3.11. The QUIT command 1039 | 1040 | 3.11.1. QUIT 1041 | 1042 | QUIT 1043 | 1044 | The server process acknowledges the QUIT command and then closes the 1045 | connection to the client. This is the preferred method for a client 1046 | to indicate that it has finished all its transactions with the NNTP 1047 | server. 1048 | 1049 | If a client simply disconnects (or the connection times out, or some 1050 | other fault occurs), the server should gracefully cease its attempts 1051 | to service the client. 1052 | 1053 | 3.11.2. Responses 1054 | 1055 | 205 closing connection - goodbye! 1056 | 1057 | 3.12. The SLAVE command 1058 | 1059 | 3.12.1. SLAVE 1060 | 1061 | SLAVE 1062 | 1063 | Indicates to the server that this client connection is to a slave 1064 | server, rather than a user. 1065 | 1066 | This command is intended for use in separating connections to single 1067 | users from those to subsidiary ("slave") servers. It may be used to 1068 | indicate that priority should therefore be given to requests from 1069 | this client, as it is presumably serving more than one person. It 1070 | might also be used to determine which connections to close when 1071 | system load levels are exceeded, perhaps giving preference to slave 1072 | servers. The actual use this command is put to is entirely 1073 | implementation dependent, and may vary from one host to another. In 1074 | NNTP servers which do not give priority to slave servers, this 1075 | command must nonetheless be recognized and acknowledged. 1076 | 1077 | 3.12.2. Responses 1078 | 1079 | 202 slave status noted 1080 | 1081 | 1082 | Kantor & Lapsley [Page 19] 1083 | 1084 | 1085 | 1086 | RFC 977 February 1986 1087 | Network News Transfer Protocol 1088 | 1089 | 1090 | 4. Sample Conversations 1091 | 1092 | These are samples of the conversations that might be expected with 1093 | the news server in hypothetical sessions. The notation C: indicates 1094 | commands sent to the news server from the client program; S: indicate 1095 | responses received from the server by the client. 1096 | 1097 | 4.1. Example 1 - relative access with NEXT 1098 | 1099 | S: (listens at TCP port 119) 1100 | 1101 | C: (requests connection on TCP port 119) 1102 | S: 200 wombatvax news server ready - posting ok 1103 | 1104 | (client asks for a current newsgroup list) 1105 | C: LIST 1106 | S: 215 list of newsgroups follows 1107 | S: net.wombats 00543 00501 y 1108 | S: net.unix-wizards 10125 10011 y 1109 | (more information here) 1110 | S: net.idiots 00100 00001 n 1111 | S: . 1112 | 1113 | (client selects a newsgroup) 1114 | C: GROUP net.unix-wizards 1115 | S: 211 104 10011 10125 net.unix-wizards group selected 1116 | (there are 104 articles on file, from 10011 to 10125) 1117 | 1118 | (client selects an article to read) 1119 | C: STAT 10110 1120 | S: 223 10110 <23445@sdcsvax.ARPA> article retrieved - statistics 1121 | only (article 10110 selected, its message-id is 1122 | <23445@sdcsvax.ARPA>) 1123 | 1124 | (client examines the header) 1125 | C: HEAD 1126 | S: 221 10110 <23445@sdcsvax.ARPA> article retrieved - head 1127 | follows (text of the header appears here) 1128 | S: . 1129 | 1130 | (client wants to see the text body of the article) 1131 | C: BODY 1132 | S: 222 10110 <23445@sdcsvax.ARPA> article retrieved - body 1133 | follows (body text here) 1134 | S: . 1135 | 1136 | (client selects next article in group) 1137 | 1138 | 1139 | Kantor & Lapsley [Page 20] 1140 | 1141 | 1142 | 1143 | RFC 977 February 1986 1144 | Network News Transfer Protocol 1145 | 1146 | 1147 | C: NEXT 1148 | S: 223 10113 <21495@nudebch.uucp> article retrieved - statistics 1149 | only (article 10113 was next in group) 1150 | 1151 | (client finishes session) 1152 | C: QUIT 1153 | S: 205 goodbye. 1154 | 1155 | 4.2. Example 2 - absolute article access with ARTICLE 1156 | 1157 | S: (listens at TCP port 119) 1158 | 1159 | C: (requests connection on TCP port 119) 1160 | S: 201 UCB-VAX netnews server ready -- no posting allowed 1161 | 1162 | C: GROUP msgs 1163 | S: 211 103 402 504 msgs Your new group is msgs 1164 | (there are 103 articles, from 402 to 504) 1165 | 1166 | C: ARTICLE 401 1167 | S: 423 No such article in this newsgroup 1168 | 1169 | C: ARTICLE 402 1170 | S: 220 402 <4105@ucbvax.ARPA> Article retrieved, text follows 1171 | S: (article header and body follow) 1172 | S: . 1173 | 1174 | C: HEAD 403 1175 | S: 221 403 <3108@mcvax.UUCP> Article retrieved, header follows 1176 | S: (article header follows) 1177 | S: . 1178 | 1179 | C: QUIT 1180 | S: 205 UCB-VAX news server closing connection. Goodbye. 1181 | 1182 | 4.3. Example 3 - NEWGROUPS command 1183 | 1184 | S: (listens at TCP port 119) 1185 | 1186 | C: (requests connection on TCP port 119) 1187 | S: 200 Imaginary Institute News Server ready (posting ok) 1188 | 1189 | (client asks for new newsgroups since April 3, 1985) 1190 | C: NEWGROUPS 850403 020000 1191 | 1192 | S: 231 New newsgroups since 03/04/85 02:00:00 follow 1193 | 1194 | 1195 | 1196 | Kantor & Lapsley [Page 21] 1197 | 1198 | 1199 | 1200 | RFC 977 February 1986 1201 | Network News Transfer Protocol 1202 | 1203 | 1204 | S: net.music.gdead 1205 | S: net.games.sources 1206 | S: . 1207 | 1208 | C: GROUP net.music.gdead 1209 | S: 211 0 1 1 net.music.gdead Newsgroup selected 1210 | (there are no articles in that newsgroup, and 1211 | the first and last article numbers should be ignored) 1212 | 1213 | C: QUIT 1214 | S: 205 Imaginary Institute news server ceasing service. Bye! 1215 | 1216 | 4.4. Example 4 - posting a news article 1217 | 1218 | S: (listens at TCP port 119) 1219 | 1220 | C: (requests connection on TCP port 119) 1221 | S: 200 BANZAIVAX news server ready, posting allowed. 1222 | 1223 | C: POST 1224 | S: 340 Continue posting; Period on a line by itself to end 1225 | C: (transmits news article in RFC850 format) 1226 | C: . 1227 | S: 240 Article posted successfully. 1228 | 1229 | C: QUIT 1230 | S: 205 BANZAIVAX closing connection. Goodbye. 1231 | 1232 | 4.5. Example 5 - interruption due to operator request 1233 | 1234 | S: (listens at TCP port 119) 1235 | 1236 | C: (requests connection on TCP port 119) 1237 | S: 201 genericvax news server ready, no posting allowed. 1238 | 1239 | (assume normal conversation for some time, and 1240 | that a newsgroup has been selected) 1241 | 1242 | C: NEXT 1243 | S: 223 1013 <5734@mcvax.UUCP> Article retrieved; text separate. 1244 | 1245 | C: HEAD 1246 | C: 221 1013 <5734@mcvax.UUCP> Article retrieved; head follows. 1247 | 1248 | S: (sends head of article, but halfway through is 1249 | interrupted by an operator request. The following 1250 | then occurs, without client intervention.) 1251 | 1252 | 1253 | Kantor & Lapsley [Page 22] 1254 | 1255 | 1256 | 1257 | RFC 977 February 1986 1258 | Network News Transfer Protocol 1259 | 1260 | 1261 | S: (ends current line with a CR-LF pair) 1262 | S: . 1263 | S: 400 Connection closed by operator. Goodbye. 1264 | S: (closes connection) 1265 | 1266 | 4.6. Example 6 - Using the news server to distribute news between 1267 | systems. 1268 | 1269 | S: (listens at TCP port 119) 1270 | 1271 | C: (requests connection on TCP port 119) 1272 | S: 201 Foobar NNTP server ready (no posting) 1273 | 1274 | (client asks for new newsgroups since 2 am, May 15, 1985) 1275 | C: NEWGROUPS 850515 020000 1276 | S: 235 New newsgroups since 850515 follow 1277 | S: net.fluff 1278 | S: net.lint 1279 | S: . 1280 | 1281 | (client asks for new news articles since 2 am, May 15, 1985) 1282 | C: NEWNEWS * 850515 020000 1283 | S: 230 New news since 850515 020000 follows 1284 | S: <1772@foo.UUCP> 1285 | S: <87623@baz.UUCP> 1286 | S: <17872@GOLD.CSNET> 1287 | S: . 1288 | 1289 | (client asks for article <1772@foo.UUCP>) 1290 | C: ARTICLE <1772@foo.UUCP> 1291 | S: 220 <1772@foo.UUCP> All of article follows 1292 | S: (sends entire message) 1293 | S: . 1294 | 1295 | (client asks for article <87623@baz.UUCP> 1296 | C: ARTICLE <87623@baz.UUCP> 1297 | S: 220 <87623@baz.UUCP> All of article follows 1298 | S: (sends entire message) 1299 | S: . 1300 | 1301 | (client asks for article <17872@GOLD.CSNET> 1302 | C: ARTICLE <17872@GOLD.CSNET> 1303 | S: 220 <17872@GOLD.CSNET> All of article follows 1304 | S: (sends entire message) 1305 | S: . 1306 | 1307 | 1308 | 1309 | 1310 | Kantor & Lapsley [Page 23] 1311 | 1312 | 1313 | 1314 | RFC 977 February 1986 1315 | Network News Transfer Protocol 1316 | 1317 | 1318 | (client offers an article it has received recently) 1319 | C: IHAVE <4105@ucbvax.ARPA> 1320 | S: 435 Already seen that one, where you been? 1321 | 1322 | (client offers another article) 1323 | C: IHAVE <4106@ucbvax.ARPA> 1324 | S: 335 News to me! to end. 1325 | C: (sends article) 1326 | C: . 1327 | S: 235 Article transferred successfully. Thanks. 1328 | 1329 | (or) 1330 | 1331 | S: 436 Transfer failed. 1332 | 1333 | (client is all through with the session) 1334 | C: QUIT 1335 | S: 205 Foobar NNTP server bids you farewell. 1336 | 1337 | 4.7. Summary of commands and responses. 1338 | 1339 | The following are the commands recognized and responses returned by 1340 | the NNTP server. 1341 | 1342 | 4.7.1. Commands 1343 | 1344 | ARTICLE 1345 | BODY 1346 | GROUP 1347 | HEAD 1348 | HELP 1349 | IHAVE 1350 | LAST 1351 | LIST 1352 | NEWGROUPS 1353 | NEWNEWS 1354 | NEXT 1355 | POST 1356 | QUIT 1357 | SLAVE 1358 | STAT 1359 | 1360 | 4.7.2. Responses 1361 | 1362 | 100 help text follows 1363 | 199 debug output 1364 | 1365 | 1366 | 1367 | Kantor & Lapsley [Page 24] 1368 | 1369 | 1370 | 1371 | RFC 977 February 1986 1372 | Network News Transfer Protocol 1373 | 1374 | 1375 | 200 server ready - posting allowed 1376 | 201 server ready - no posting allowed 1377 | 202 slave status noted 1378 | 205 closing connection - goodbye! 1379 | 211 n f l s group selected 1380 | 215 list of newsgroups follows 1381 | 220 n article retrieved - head and body follow 221 n article 1382 | retrieved - head follows 1383 | 222 n article retrieved - body follows 1384 | 223 n article retrieved - request text separately 230 list of new 1385 | articles by message-id follows 1386 | 231 list of new newsgroups follows 1387 | 235 article transferred ok 1388 | 240 article posted ok 1389 | 1390 | 335 send article to be transferred. End with . 1391 | 340 send article to be posted. End with . 1392 | 1393 | 400 service discontinued 1394 | 411 no such news group 1395 | 412 no newsgroup has been selected 1396 | 420 no current article has been selected 1397 | 421 no next article in this group 1398 | 422 no previous article in this group 1399 | 423 no such article number in this group 1400 | 430 no such article found 1401 | 435 article not wanted - do not send it 1402 | 436 transfer failed - try again later 1403 | 437 article rejected - do not try again. 1404 | 440 posting not allowed 1405 | 441 posting failed 1406 | 1407 | 500 command not recognized 1408 | 501 command syntax error 1409 | 502 access restriction or permission denied 1410 | 503 program fault - command not performed 1411 | 1412 | 4.8. A Brief Word about the USENET News System 1413 | 1414 | In the UNIX world, which traditionally has been linked by 1200 baud 1415 | dial-up telephone lines, the USENET News system has evolved to handle 1416 | central storage, indexing, retrieval, and distribution of news. With 1417 | the exception of its underlying transport mechanism (UUCP), USENET 1418 | News is an efficient means of providing news and bulletin service to 1419 | subscribers on UNIX and other hosts worldwide. The USENET News 1420 | 1421 | 1422 | 1423 | 1424 | Kantor & Lapsley [Page 25] 1425 | 1426 | 1427 | 1428 | RFC 977 February 1986 1429 | Network News Transfer Protocol 1430 | 1431 | 1432 | system is discussed in detail in RFC 850. It runs on most versions 1433 | of UNIX and on many other operating systems, and is customarily 1434 | distributed without charge. 1435 | 1436 | USENET uses a spooling area on the UNIX host to store news articles, 1437 | one per file. Each article consists of a series of heading text, 1438 | which contain the sender's identification and organizational 1439 | affiliation, timestamps, electronic mail reply paths, subject, 1440 | newsgroup (subject category), and the like. A complete news article 1441 | is reproduced in its entirety below. Please consult RFC 850 for more 1442 | details. 1443 | 1444 | Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site 1445 | sdcsvax.UUCP 1446 | Posting-Version: version B 2.10.1 6/24/83 SMI; site unitek.uucp 1447 | Path:sdcsvax!sdcrdcf!hplabs!qantel!ihnp4!alberta!ubc-vision!unitek 1448 | !honman 1449 | From: honman@unitek.uucp (Man Wong) 1450 | Newsgroups: net.unix-wizards 1451 | Subject: foreground -> background ? 1452 | Message-ID: <167@unitek.uucp> 1453 | Date: 25 Sep 85 23:51:52 GMT 1454 | Date-Received: 29 Sep 85 09:54:48 GMT 1455 | Reply-To: honman@unitek.UUCP (Hon-Man Wong) 1456 | Distribution: net.all 1457 | Organization: Unitek Technologies Corporation 1458 | Lines: 12 1459 | 1460 | I have a process (C program) which generates a child and waits for 1461 | it to return. What I would like to do is to be able to run the 1462 | child process interactively for a while before kicking itself into 1463 | the background so I can return to the parent process (while the 1464 | child process is RUNNING in the background). Can it be done? And 1465 | if it can, how? 1466 | 1467 | Please reply by E-mail. Thanks in advance. 1468 | 1469 | Hon-Man Wong 1470 | 1471 | 1472 | 1473 | 1474 | 1475 | 1476 | 1477 | 1478 | 1479 | 1480 | 1481 | Kantor & Lapsley [Page 26] 1482 | 1483 | 1484 | 1485 | RFC 977 February 1986 1486 | Network News Transfer Protocol 1487 | 1488 | 1489 | 5. References 1490 | 1491 | [1] Crocker, D., "Standard for the Format of ARPA Internet Text 1492 | Messages", RFC-822, Department of Electrical Engineering, 1493 | University of Delaware, August, 1982. 1494 | 1495 | [2] Horton, M., "Standard for Interchange of USENET Messages", 1496 | RFC-850, USENET Project, June, 1983. 1497 | 1498 | [3] Postel, J., "Transmission Control Protocol- DARPA Internet 1499 | Program Protocol Specification", RFC-793, USC/Information 1500 | Sciences Institute, September, 1981. 1501 | 1502 | [4] Postel, J., "Simple Mail Transfer Protocol", RFC-821, 1503 | USC/Information Sciences Institute, August, 1982. 1504 | 1505 | 6. Acknowledgements 1506 | 1507 | The authors wish to express their heartfelt thanks to those many 1508 | people who contributed to this specification, and especially to Erik 1509 | Fair and Chuq von Rospach, without whose inspiration this whole thing 1510 | would not have been necessary. 1511 | 1512 | 7. Notes 1513 | 1514 | <1> UNIX is a trademark of Bell Laboratories. 1515 | 1516 | 1517 | 1518 | 1519 | 1520 | 1521 | 1522 | 1523 | 1524 | 1525 | 1526 | 1527 | 1528 | 1529 | 1530 | 1531 | 1532 | 1533 | 1534 | 1535 | 1536 | 1537 | 1538 | Kantor & Lapsley [Page 27] 1539 | 1540 | -------------------------------------------------------------------------------- /rfc2980.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Network Working Group S. Barber 8 | Request for Comments: 2980 Academ Consulting Services 9 | Category: Informational October 2000 10 | 11 | 12 | Common NNTP Extensions 13 | 14 | Status of this Memo 15 | 16 | This memo provides information for the Internet community. It does 17 | not specify an Internet standard of any kind. Distribution of this 18 | memo is unlimited. 19 | 20 | Copyright Notice 21 | 22 | Copyright (C) The Internet Society (2000). All Rights Reserved. 23 | 24 | Abstract 25 | 26 | In this document, a number of popular extensions to the Network News 27 | Transfer Protocol (NNTP) protocol defined in RFC 977 are documented 28 | and discussed. While this document is not intended to serve as a 29 | standard of any kind, it will hopefully serve as a reference document 30 | for future implementers of the NNTP protocol. In the role, this 31 | document would hopefully create the possibility for some level of 32 | interoperability among implementations that make use of extensions. 33 | 34 | Introduction 35 | 36 | RFC 977 [1] defines the NNTP protocol and was released over a decade 37 | ago. Since then, NNTP has become one of the most popular protocols 38 | in use on the Internet. Many implementations of the protocol have 39 | been created on many different platforms and operating systems. With 40 | the growth in use of the protocol, work began on a revision to NNTP 41 | in 1991, but that work did not result in a new standard protocol 42 | specification. However, many ideas from that working group did find 43 | their way into many implementations of NNTP. Additionally, many 44 | other extensions, often created by newsreader authors, are also in 45 | use. This document will capture and define all known extensions to 46 | NNTP available in official NNTP server releases of some type as of 47 | this writing. Where possible, the server software first implementing 48 | a particular extension will be noted. It is the hope of the author 49 | that using this document in tandem with RFC 977 will limit the 50 | addition of new extensions that essentially do the same thing. 51 | Software developers may wish to use this document and others [2] as a 52 | resource for the development of new software. 53 | 54 | 55 | 56 | 57 | 58 | Barber Informational [Page 1] 59 | 60 | RFC 2980 Common NNTP Extensions October 2000 61 | 62 | 63 | This document does not specify an Internet Standard of any kind. It 64 | only attempts to document current practices. While this document may 65 | clarify some ambiguity in RFC 977, RFC 977 should be regarded as 66 | authoritative in all cases. There are some implementations that are 67 | not strictly RFC 977 compliant and where necessary, these deviations 68 | from the standard will be noted. This document does reflect the work 69 | of the IETF NNTP-EXT working group chaired by Ned Freed and Stan 70 | Barber. 71 | 72 | This document is provided to help implementers have a uniform source 73 | of information about extensions, however, it is important for any 74 | prospective implementer to understand that the extensions listed here 75 | are NOT part of any current standard for NNTP. In fact, some of the 76 | ones listed in this document should not be included in new NNTP 77 | implementations as they should no longer be used modern NNTP 78 | environments. Such commands should be considered historic and are 79 | documented as such in this document. 80 | 81 | Extensions fall into three categories: transport, newsreader and 82 | other. Transport extensions are additions to the NNTP specification 83 | that were made specifically to move news articles from one server to 84 | another server. Newsreader extensions are additions to the NNTP 85 | specification that were made to assist NNTP clients in selecting and 86 | retrieving news articles from servers. Other extensions to the NNTP 87 | specification are those which did not specifically fall into either 88 | of the other two categories. Examples of other extensions include 89 | authentication and time-of-day extensions. For each command, the 90 | format of section 3 of RFC 977 will be used. 91 | 92 | 1. Transport Extensions 93 | 94 | A transport extension is one which is primarily used in inter-server 95 | communications. Following are the descriptions of each transport 96 | extension commands and the responses which will be returned by those 97 | commands. 98 | 99 | Each command is shown in upper case for clarity, although case is 100 | ignored in the interpretation of commands by the NNTP server. Any 101 | parameters are shown in lower case. A parameter shown in [square 102 | brackets] is optional. For example, [GMT] indicates that the 103 | triglyph GMT may present or omitted. A parameter that may be 104 | repeated is followed by an ellipsis. 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | Barber Informational [Page 2] 115 | 116 | RFC 2980 Common NNTP Extensions October 2000 117 | 118 | 119 | 1.1.1 The CHECK command 120 | 121 | CHECK 122 | 123 | CHECK is used by a peer to discover if the article with the specified 124 | message-id should be sent to the server using the TAKETHIS command. 125 | The peer does not have to wait for a response from the server before 126 | sending the next command. 127 | 128 | From using the responses to the sequence of CHECK commands, a list of 129 | articles to be sent can be constructed for subsequent use by the 130 | TAKETHIS command. 131 | 132 | The use of the CHECK command for streaming is optional. Some 133 | implementations will directly use the TAKETHIS command and send all 134 | articles in the send queue on that peer for the server. 135 | 136 | On some implementations, the use of the CHECK command is not 137 | permitted when the server is in slave mode (via the SLAVE command). 138 | 139 | Responses that are of the form X3X must specify the message-id in the 140 | response. 141 | 142 | 1.1.2. Responses 143 | 144 | 238 no such article found, please send it to me 145 | 400 not accepting articles 146 | 431 try sending it again later 147 | 438 already have it, please don't send it to me 148 | 480 Transfer permission denied 149 | 500 Command not understood 150 | 151 | 1.2.1 The MODE STREAM command 152 | 153 | MODE STREAM 154 | 155 | MODE STREAM is used by a peer to indicate to the server that it would 156 | like to suspend the lock step conversational nature of NNTP and send 157 | commands in streams. This command should be used before TAKETHIS and 158 | CHECK. See the section on the commands TAKETHIS and CHECK for more 159 | details. 160 | 161 | 1.2.2. Responses 162 | 163 | 203 Streaming is OK 164 | 500 Command not understood 165 | 166 | 167 | 168 | 169 | 170 | Barber Informational [Page 3] 171 | 172 | RFC 2980 Common NNTP Extensions October 2000 173 | 174 | 175 | 1.3.1 The TAKETHIS command 176 | 177 | TAKETHIS 178 | 179 | TAKETHIS is used to send articles to a server when in streaming mode. 180 | The entire article (header and body, in that sequence) is sent 181 | immediately after the peer sends the TAKETHIS command. The peer does 182 | not have to wait for a response from the server before sending the 183 | next command and the associated article. 184 | 185 | During transmission of the article, the peer should send the entire 186 | article, including header and body, in the manner specified for text 187 | transmission from the server. See RFC 977, Section 2.4.1 for 188 | details. 189 | 190 | Responses that are of the form X3X must specify the message-id in the 191 | response. 192 | 193 | 1.3.2. Responses 194 | 195 | 239 article transferred ok 196 | 400 not accepting articles 197 | 439 article transfer failed 198 | 480 Transfer permission denied 199 | 500 Command not understood 200 | 201 | 1.4.1 The XREPLIC command 202 | 203 | XREPLIC ggg:nnn[,ggg:nnn...] 204 | 205 | The XREPLIC command makes is possible to exactly duplicate the news 206 | spool structure of one server in another server. It first appeared 207 | in INN. 208 | 209 | This command works similarly to the IHAVE command as specified in RFC 210 | 977. The same response codes are used. The command line arguments 211 | consist of entries separated by a single comma. Each entry consists 212 | of a news group name, a colon, and an article number. If the server 213 | responds with a 335 response, the article should be filed in the news 214 | group(s) and article number(s) specified in the XREPLIC command line. 215 | If the server cannot do successfully install the article once it has 216 | accepted it, a 436 or 437 response code can be used to indicate the 217 | failure. 218 | 219 | This command should only be used when the receiving server is being 220 | fed by only one other server. It is likely that when used with 221 | servers that have multiple feeds that this command will frequently 222 | fail. 223 | 224 | 225 | 226 | Barber Informational [Page 4] 227 | 228 | RFC 2980 Common NNTP Extensions October 2000 229 | 230 | 231 | XREPLIC slaving has been deprecated in INN version 1.7.2 and later. 232 | INN now has the ability to slave servers via transparent means, 233 | simply by having the article's Xref header transferred. (In previous 234 | versions, this header was generated locally and stripped off on 235 | outgoing feeds.) 236 | 237 | It is likely that future versions of INN will no longer support 238 | XREPLIC. 239 | 240 | 1.4.2. Responses 241 | 242 | 235 article transferred ok 243 | 335 send article to be transferred. End with . 244 | 435 article not wanted - do not send it 245 | 436 transfer failed - try again later 246 | 437 article rejected - do not try again 247 | 248 | 2. Newsreader Extensions 249 | 250 | Newsreader extensions are those which are primarily used by 251 | newsreading clients. Following are the descriptions of each 252 | newsreader extension commands and the responses which will be 253 | returned by those commands. 254 | 255 | Each command is shown in upper case for clarity, although case is 256 | ignored in the interpretation of commands by the NNTP server. Any 257 | parameters are shown in lower case. A parameter shown in [square 258 | brackets] is optional. For example, [GMT] indicates that the 259 | triglyph GMT may present or omitted. A parameter that may be 260 | repeated is followed by an ellipsis. Mutually exclusive parameters 261 | are separated by a vertical bar (|) character. For example, 262 | ggg| indicates that a group name or a may 263 | be specified, but not both. Some parameters, notably , 264 | is case specific. See RFC 1036 for these details. 265 | 266 | Also, certain commands make use of a pattern for selection of 267 | multiple news groups. The pattern in all cases is based on the 268 | wildmat [4] format introduced by Rich Salz in 1986. Arguments 269 | expected to be in wildmat format will be represented by the string 270 | wildmat. This format is discussed in detail in section 3.3 of this 271 | document. 272 | 273 | 2.1.1 Extensions to the LIST command 274 | 275 | The original LIST command took no arguments in RFC 977 and returned 276 | the contents of the active file in a specific format. Since the 277 | original newsreaders made use of other information available in the 278 | news transport software in addition to the active file, extensions to 279 | 280 | 281 | 282 | Barber Informational [Page 5] 283 | 284 | RFC 2980 Common NNTP Extensions October 2000 285 | 286 | 287 | the LIST command were created to make that information available to 288 | NNTP newsreaders. There may be other extensions to the LIST command 289 | that simply return the contents of a file. This approach is 290 | suggested over the addition of over verbs. For example, LIST MOTD 291 | could be used instead of adding XMOTD. 292 | 293 | 2.1.2 LIST ACTIVE 294 | 295 | LIST ACTIVE [wildmat] 296 | 297 | LIST ACTIVE is exactly the same as the LIST command specified in RFC 298 | 977. The responses and the format should exactly match the LIST 299 | command without arguments. If the optional matching parameter is 300 | specified, the list is limited to only the groups that match the 301 | pattern. Specifying a single group is usually very efficient for the 302 | server, and multiple groups may be specified by using wildmat 303 | patterns (described later in this document), not regular expressions. 304 | If nothing is matched an empty list is returned, not an error. This 305 | command first appeared in the UNIX reference version. 306 | 307 | 2.1.3 LIST ACTIVE.TIMES 308 | 309 | LIST ACTIVE.TIMES 310 | 311 | The active.times file is maintained by some news transports systems 312 | to contain information about the when and who created a particular 313 | news group. The format of this file generally include three fields. 314 | The first field is the name of the news group. The second is the 315 | time when this group was created on this news server measured in 316 | seconds since January 1, 1970. The third is the email address of the 317 | entity that created the news group. When executed, the information 318 | is displayed following the 215 response. When display is completed, 319 | the server will send a period on a line by itself. If the 320 | information is not available, the server will return the 503 error 321 | response. This command first appeared in the UNIX reference version. 322 | 323 | 2.1.3.1 Responses 324 | 325 | 215 information follows 326 | 503 program error, function not performed 327 | 328 | 2.1.4 LIST DISTRIBUTIONS 329 | 330 | LIST DISTRIBUTIONS 331 | 332 | The distributions file is maintained by some news transport systems 333 | to contain information about valid values for the Distribution: line 334 | in a news article header and about what the values mean. Each line 335 | 336 | 337 | 338 | Barber Informational [Page 6] 339 | 340 | RFC 2980 Common NNTP Extensions October 2000 341 | 342 | 343 | contains two fields, the value and a short explanation on the meaning 344 | of the value. When executed, the information is displayed following 345 | the 215 response. When display is completed, the server will send a 346 | period on a line by itself. If the information is not available, the 347 | server will return the 503 error response. This command first 348 | appeared in the UNIX reference version. 349 | 350 | 2.1.4.1 Responses 351 | 352 | 215 information follows 353 | 503 program error, function not performed 354 | 355 | 2.1.5 LIST DISTRIB.PATS 356 | 357 | LIST DISTRIB.PATS 358 | 359 | The distrib.pats file is maintained by some news transport systems to 360 | contain default values for the Distribution: line in a news article 361 | header when posting to particular news groups. This information 362 | could be used to provide a default value for the Distribution: line 363 | in the header when posting an article. The information returned 364 | involves three fields separated by colons. The first column is a 365 | weight. The second is a group name or a pattern that can be used to 366 | match a group name in the wildmat format. The third is the value of 367 | the Distribution: line that should be used when the group name 368 | matches and the weight value is the highest. All this processing is 369 | done by the news posting client and not by the server itself. The 370 | server just provides this information to the client for it to use or 371 | ignore as it chooses. When executed, the information is displayed 372 | following the 215 response. When display is completed, the server 373 | will send a period on a line by itself. If the information is not 374 | available, the server will return the 503 error response. This 375 | command first appeared in INN. 376 | 377 | 2.1.5.1 Responses 378 | 379 | 215 information follows 380 | 503 program error, function not performed 381 | 382 | 2.1.6 LIST NEWSGROUPS 383 | 384 | LIST NEWSGROUPS [wildmat] 385 | 386 | The newsgroups file is maintained by some news transport systems to 387 | contain the name of each news group which is active on the server and 388 | a short description about the purpose of each news group. Each line 389 | in the file contains two fields, the news group name and a short 390 | explanation of the purpose of that news group. When executed, the 391 | 392 | 393 | 394 | Barber Informational [Page 7] 395 | 396 | RFC 2980 Common NNTP Extensions October 2000 397 | 398 | 399 | information is displayed following the 215 response. When display is 400 | completed, the server will send a period on a line by itself. If the 401 | information is not available, the server will return the 503 402 | response. If the optional matching parameter is specified, the list 403 | is limited to only the groups that match the pattern (no matching is 404 | done on the group descriptions). Specifying a single group is 405 | usually very efficient for the server, and multiple groups may be 406 | specified by using wildmat patterns (similar to file globbing), not 407 | regular expressions. If nothing is matched an empty list is 408 | returned, not an error. 409 | 410 | When the optional parameter is specified, this command is equivalent 411 | to the XGTITLE command, though the response code are different. 412 | 413 | 215 information follows 414 | 503 program error, function not performed 415 | 416 | 2.1.7 LIST OVERVIEW.FMT 417 | 418 | LIST OVERVIEW.FMT 419 | 420 | The overview.fmt file is maintained by some news transport systems to 421 | contain the order in which header information is stored in the 422 | overview databases for each news group. When executed, news article 423 | header fields are displayed one line at a time in the order in which 424 | they are stored in the overview database [5] following the 215 425 | response. When display is completed, the server will send a period 426 | on a line by itself. If the information is not available, the server 427 | will return the 503 response. 428 | 429 | Please note that if the header has the word "full" (without quotes) 430 | after the colon, the header's name is prepended to its field in the 431 | output returned by the server. 432 | 433 | Many newsreaders work better if Xref: is one of the optional fields. 434 | 435 | It is STRONGLY recommended that this command be implemented in any 436 | server that implements the XOVER command. See section 2.8 for more 437 | details about the XOVER command. 438 | 439 | 2.1.7.1 Responses 440 | 441 | 215 information follows 442 | 503 program error, function not performed 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | Barber Informational [Page 8] 451 | 452 | RFC 2980 Common NNTP Extensions October 2000 453 | 454 | 455 | 2.1.8 LIST SUBSCRIPTIONS 456 | 457 | LIST SUBSCRIPTIONS 458 | 459 | This command is used to get a default subscription list for new users 460 | of this server. The order of groups is significant. 461 | 462 | When this list is available, it is preceded by the 215 response and 463 | followed by a period on a line by itself. When this list is not 464 | available, the server returns a 503 response code. 465 | 466 | 2.1.8.1 Responses 467 | 468 | 215 information follows 469 | 503 program error, function not performed 470 | 471 | 2.2 LISTGROUP 472 | 473 | LISTGROUP [ggg] 474 | 475 | The LISTGROUP command is used to get a listing of all the article 476 | numbers in a particular news group. 477 | 478 | The optional parameter ggg is the name of the news group to be 479 | selected (e.g. "news.software.b"). A list of valid news groups may 480 | be obtained from the LIST command. If no group is specified, the 481 | current group is used as the default argument. 482 | 483 | The successful selection response will be a list of the article 484 | numbers in the group followed by a period on a line by itself. 485 | 486 | When a valid group is selected by means of this command, the 487 | internally maintained "current article pointer" is set to the first 488 | article in the group. If an invalid group is specified, the 489 | previously selected group and article remain selected. If an empty 490 | news group is selected, the "current article pointer" is in an 491 | indeterminate state and should not be used. 492 | 493 | Note that the name of the news group is not case-dependent. It must 494 | otherwise match a news group obtained from the LIST command or an 495 | error will result. 496 | 497 | 2.2.1 Responses 498 | 499 | 211 list of article numbers follow 500 | 412 Not currently in newsgroup 501 | 502 no permission 502 | 503 | 504 | 505 | 506 | Barber Informational [Page 9] 507 | 508 | RFC 2980 Common NNTP Extensions October 2000 509 | 510 | 511 | 2.3 MODE READER 512 | 513 | MODE READER is used by the client to indicate to the server that it 514 | is a news reading client. Some implementations make use of this 515 | information to reconfigure themselves for better performance in 516 | responding to news reader commands. This command can be contrasted 517 | with the SLAVE command in RFC 977, which was not widely implemented. 518 | MODE READER was first available in INN. 519 | 520 | 2.3.1 Responses 521 | 522 | 200 Hello, you can post 523 | 201 Hello, you can't post 524 | 525 | 2.4 XGTITLE 526 | 527 | XGTITLE [wildmat] 528 | 529 | The XGTITLE command is used to retrieve news group descriptions for 530 | specific news groups. 531 | 532 | This extension first appeared in ANU-NEWS, an NNTP implementation for 533 | DEC's VMS. The optional parameter is a pattern in wildmat format. 534 | When executed, a 282 response is given followed by lines that have 535 | two fields, the news group name (which matches the pattern in the 536 | argument) and a short explanation of the purpose of the news group. 537 | When no argument is specified, the default argument is the current 538 | group name. When display is completed, the server sends a period on 539 | a line by itself. 540 | 541 | Please note that this command and the LIST NEWSGROUP command provide 542 | the same functionality with different response codes. 543 | 544 | Since this command provides the same functionality as LIST NEWSGROUP 545 | it is suggested that this extension be deprecated and no longer be 546 | used in newsreading clients. 547 | 548 | Note that there is a conflict in one of the response codes from 549 | XGTITLE and some of the authentication extensions. 550 | 551 | 2.5.1 Responses 552 | 553 | 481 Groups and descriptions unavailable 554 | 282 list of groups and descriptions follows 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | Barber Informational [Page 10] 563 | 564 | RFC 2980 Common NNTP Extensions October 2000 565 | 566 | 567 | 2.6 XHDR 568 | 569 | XHDR header [range|] 570 | 571 | The XHDR command is used to retrieve specific headers from specific 572 | articles. 573 | 574 | The required parameter is the name of a header line (e.g. "subject") 575 | in a news group article. See RFC 1036 for a list of valid header 576 | lines. The optional range argument may be any of the following: 577 | 578 | an article number 579 | an article number followed by a dash to indicate 580 | all following 581 | an article number followed by a dash followed by 582 | another article number 583 | 584 | The optional message-id argument indicates a specific article. The 585 | range and message-id arguments are mutually exclusive. If no 586 | argument is specified, then information from the current article is 587 | displayed. Successful responses start with a 221 response followed 588 | by a the matched headers from all matched messages. Each line 589 | containing matched headers returned by the server has an article 590 | number (or message ID, if a message ID was specified in the command), 591 | then one or more spaces, then the value of the requested header in 592 | that article. Once the output is complete, a period is sent on a 593 | line by itself. If the optional argument is a message-id and no such 594 | article exists, the 430 error response is returned. If a range is 595 | specified, a news group must have been selected earlier, else a 412 596 | error response is returned. If no articles are in the range 597 | specified, a 420 error response is returned by the server. A 502 598 | response will be returned if the client only has permission to 599 | transfer articles. 600 | 601 | Some implementations will return "(none)" followed by a period on a 602 | line by itself if no headers match in any of the articles searched. 603 | Others return the 221 response code followed by a period on a line by 604 | itself. 605 | 606 | The XHDR command has been available in the UNIX reference 607 | implementation from its first release. However, until now, it has 608 | been documented only in the source for the server. 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | Barber Informational [Page 11] 619 | 620 | RFC 2980 Common NNTP Extensions October 2000 621 | 622 | 623 | 2.6.1 Responses 624 | 625 | 221 Header follows 626 | 412 No news group current selected 627 | 420 No current article selected 628 | 430 no such article 629 | 502 no permission 630 | 631 | 2.7 XINDEX 632 | 633 | XINDEX ggg 634 | 635 | The XINDEX command is used to retrieve an index file in the format of 636 | originally created for use by the TIN [6] news reader. 637 | 638 | The required parameter ggg is the name of the news group to be 639 | selected (e.g. "news.software.b"). A list of valid news groups may 640 | be obtained from the LIST command. 641 | 642 | The successful selection response will return index file in the 643 | format used by the TIN news reader followed by a period on a line by 644 | itself. 645 | 646 | When a valid group is selected by means of this command, the 647 | internally maintained "current article pointer" is set to the first 648 | article in the group. If an invalid group is specified, the 649 | previously selected group and article remain selected. If an empty 650 | news group is selected, the "current article pointer" is in an 651 | indeterminate state and should not be used. 652 | 653 | Note that the name of the news group is not case-dependent. It must 654 | otherwise match a news group obtained from the LIST command or an 655 | error will result. 656 | 657 | The format of the tin-style index file is discussed in the 658 | documentation for the TIN newsreader. Since more recent versions of 659 | TIN support the news overview (NOV) format, it is recommended that 660 | this extension become historic and no longer be used in current 661 | servers or future implementations. 662 | 663 | 2.7.1 Responses 664 | 665 | 218 tin-style index follows 666 | 418 no tin-style index is available for this news group 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | Barber Informational [Page 12] 675 | 676 | RFC 2980 Common NNTP Extensions October 2000 677 | 678 | 679 | 2.8 XOVER 680 | 681 | XOVER [range] 682 | 683 | The XOVER command returns information from the overview database for 684 | the article(s) specified. This command was originally suggested as 685 | part of the OVERVIEW work described in "The Design of a Common 686 | Newsgroup Overview Database for Newsreaders" by Geoff Collyer. This 687 | document is distributed in the Cnews distribution. The optional 688 | range argument may be any of the following: 689 | 690 | an article number 691 | an article number followed by a dash to indicate 692 | all following 693 | an article number followed by a dash followed by 694 | another article number 695 | 696 | If no argument is specified, then information from the current 697 | article is displayed. Successful responses start with a 224 response 698 | followed by the overview information for all matched messages. Once 699 | the output is complete, a period is sent on a line by itself. If no 700 | argument is specified, the information for the current article is 701 | returned. A news group must have been selected earlier, else a 412 702 | error response is returned. If no articles are in the range 703 | specified, a 420 error response is returned by the server. A 502 704 | response will be returned if the client only has permission to 705 | transfer articles. 706 | 707 | Each line of output will be formatted with the article number, 708 | followed by each of the headers in the overview database or the 709 | article itself (when the data is not available in the overview 710 | database) for that article separated by a tab character. The 711 | sequence of fields must be in this order: subject, author, date, 712 | message-id, references, byte count, and line count. Other optional 713 | fields may follow line count. Other optional fields may follow line 714 | count. These fields are specified by examining the response to the 715 | LIST OVERVIEW.FMT command. Where no data exists, a null field must 716 | be provided (i.e. the output will have two tab characters adjacent to 717 | each other). Servers should not output fields for articles that have 718 | been removed since the XOVER database was created. 719 | 720 | The LIST OVERVIEW.FMT command should be implemented if XOVER is 721 | implemented. A client can use LIST OVERVIEW.FMT to determine what 722 | optional fields and in which order all fields will be supplied by 723 | the XOVER command. See Section 2.1.7 for more details about the LIST 724 | OVERVIEW.FMT command. 725 | 726 | 727 | 728 | 729 | 730 | Barber Informational [Page 13] 731 | 732 | RFC 2980 Common NNTP Extensions October 2000 733 | 734 | 735 | Note that any tab and end-of-line characters in any header data that 736 | is returned will be converted to a space character. 737 | 738 | 2.8.1 Responses 739 | 740 | 224 Overview information follows 741 | 412 No news group current selected 742 | 420 No article(s) selected 743 | 502 no permission 744 | 745 | 2.9 XPAT 746 | 747 | XPAT header range| pat [pat...] 748 | 749 | The XPAT command is used to retrieve specific headers from specific 750 | articles, based on pattern matching on the contents of the header. 751 | This command was first available in INN. 752 | 753 | The required header parameter is the name of a header line (e.g. 754 | "subject") in a news group article. See RFC 1036 for a list of valid 755 | header lines. The required range argument may be any of the 756 | following: 757 | 758 | an article number 759 | an article number followed by a dash to indicate 760 | all following 761 | an article number followed by a dash followed by 762 | another article number 763 | 764 | The required message-id argument indicates a specific article. The 765 | range and message-id arguments are mutually exclusive. At least one 766 | pattern in wildmat must be specified as well. If there are 767 | additional arguments the are joined together separated by a single 768 | space to form one complete pattern. Successful responses start with 769 | a 221 response followed by a the headers from all messages in which 770 | the pattern matched the contents of the specified header line. This 771 | includes an empty list. Once the output is complete, a period is 772 | sent on a line by itself. If the optional argument is a message-id 773 | and no such article exists, the 430 error response is returned. A 774 | 502 response will be returned if the client only has permission to 775 | transfer articles. 776 | 777 | 2.9.1 Responses 778 | 779 | 221 Header follows 780 | 430 no such article 781 | 502 no permission 782 | 783 | 784 | 785 | 786 | Barber Informational [Page 14] 787 | 788 | RFC 2980 Common NNTP Extensions October 2000 789 | 790 | 791 | 2.10 The XPATH command 792 | 793 | XPATH 794 | 795 | The XPATH command is used to determine the filenames in which an 796 | article is filed. It first appeared in INN. 797 | 798 | The required parameter message-id is the message id of an article as 799 | shown in that article's message-id header. According to RFC 1036 800 | [3], all message ids for all articles within the netnews environment 801 | are unique, but articles may be crossposted to multiple groups. The 802 | response to an XPATH command will include a listing of all filenames 803 | in which an article is stored separated by spaces or a response 804 | indicating that no article with the specified message-id exists. The 805 | returned data is only useful if the news client knows the 806 | implementation details of the server. Because of this, it is 807 | recommended that client avoid using this command. 808 | 809 | 2.10.1 Responses 810 | 811 | 223 path1[ path2 ...] 812 | 430 no such article on server 813 | 814 | 2.11 The XROVER command 815 | 816 | XROVER [range] 817 | 818 | The XROVER command returns reference information from the overview 819 | database for the article(s) specified. This command first appeared 820 | in the Unix reference implementation. The optional range argument 821 | may be any of the following: 822 | 823 | an article number 824 | an article number followed by a dash to indicate 825 | all following 826 | an article number followed by a dash followed by 827 | another article number 828 | 829 | Successful responses start with a 224 response followed by the 830 | contents of reference information for all matched messages. Once the 831 | output is complete, a period is sent on a line by itself. If no 832 | argument is specified, the information for the current article is 833 | returned. A news group must have been selected earlier, else a 412 834 | error response is returned. If no articles are in the range 835 | specified, a 420 error response is returned by the server. A 502 836 | response will be returned if the client only has permission to 837 | transfer articles. 838 | 839 | 840 | 841 | 842 | Barber Informational [Page 15] 843 | 844 | RFC 2980 Common NNTP Extensions October 2000 845 | 846 | 847 | The output will be formatted with the article number, followed by the 848 | contents of the References: line for that article, but does not 849 | contain the field name itself. 850 | 851 | This command provides the same basic functionality as using the XHDR 852 | command and "references" as the header argument. 853 | 854 | 2.11.1 Responses 855 | 856 | 224 Overview information follows 857 | 412 No news group current selected 858 | 420 No article(s) selected 859 | 502 no permission 860 | 861 | 2.12 XTHREAD 862 | 863 | XTHREAD [DBINIT|THREAD] 864 | 865 | The XTHREAD command is used to retrieve threading information 866 | in format of originally created for use by the TRN [6] news 867 | reader. 868 | 869 | The command XTHREAD DBINIT may be issued prior to entering 870 | any groups to see if a thread database exists. If it does, 871 | the database's byte order and version number are returned 872 | as binary data. 873 | 874 | If no parameter is given, XTHREAD THREAD is assumed. 875 | 876 | To use XTHREAD THREAD, a news group must have been selected 877 | earlier, else a 412 error response is returned. 878 | 879 | A 502 response will be returned if the client only has 880 | permission to transfer articles. A 503 response is returned 881 | if the threading files are not available. 882 | 883 | The format of the trn-style thread format is discussed in 884 | the documentation for the TRN newsreader. Since more recent 885 | versions of TRN support the news overview (NOV) format, it 886 | is recommended that this extension become historic and no 887 | longer be used in current servers or future implementations. 888 | 889 | 2.12.1 Responses 890 | 891 | 288 Binary data to follow 892 | 412 No newsgroup current selected 893 | 502 No permission 894 | 503 program error, function not performed 895 | 896 | 897 | 898 | Barber Informational [Page 16] 899 | 900 | RFC 2980 Common NNTP Extensions October 2000 901 | 902 | 903 | 3. Other Extensions 904 | 905 | 3.1 AUTHINFO 906 | 907 | AUTHINFO is used to inform a server about the identity of a user of 908 | the server. In all cases, clients must provide this information when 909 | requested by the server. Servers are not required to accept 910 | authentication information that is volunteered by the client. 911 | Clients must accommodate servers that reject any authentication 912 | information volunteered by the client. 913 | 914 | There are three forms of AUTHINFO in use. The original version, an 915 | NNTP v2 revision called AUTHINFO SIMPLE and a more recent version 916 | which is called AUTHINFO GENERIC. 917 | 918 | 3.1.1 Original AUTHINFO 919 | 920 | AUTHINFO USER username 921 | AUTHINFO PASS password 922 | 923 | The original AUTHINFO is used to identify a specific entity to the 924 | server using a simple username/password combination. It first 925 | appeared in the UNIX reference implementation. 926 | 927 | When authorization is required, the server will send a 480 response 928 | requesting authorization from the client. The client must enter 929 | AUTHINFO USER followed by the username. Once sent, the server will 930 | cache the username and may send a 381 response requesting the 931 | password associated with that username. Should the server request a 932 | password using the 381 response, the client must enter AUTHINFO PASS 933 | followed by a password and the server will then check the 934 | authentication database to see if the username/password combination 935 | is valid. If the combination is valid or if no password is required, 936 | the server will return a 281 response. The client should then retry 937 | the original command to which the server responded with the 480 938 | response. The command should then be processed by the server 939 | normally. If the combination is not valid, the server will return a 940 | 502 response. 941 | 942 | Clients must provide authentication when requested by the server. It 943 | is possible that some implementations will accept authentication 944 | information at the beginning of a session, but this was not the 945 | original intent of the specification. If a client attempts to 946 | reauthenticate, the server may return 482 response indicating that 947 | the new authentication data is rejected by the server. The 482 code 948 | will also be returned when the AUTHINFO commands are not entered in 949 | the correct sequence (like two AUTHINFO USERs in a row, or AUTHINFO 950 | PASS preceding AUTHINFO USER). 951 | 952 | 953 | 954 | Barber Informational [Page 17] 955 | 956 | RFC 2980 Common NNTP Extensions October 2000 957 | 958 | 959 | All information is passed in cleartext. 960 | 961 | When authentication succeeds, the server will create an email address 962 | for the client from the user name supplied in the AUTHINFO USER 963 | command and the hostname generated by a reverse lookup on the IP 964 | address of the client. If the reverse lookup fails, the IP address, 965 | represented in dotted-quad format, will be used. Once authenticated, 966 | the server shall generate a Sender: line using the email address 967 | provided by authentication if it does not match the client-supplied 968 | From: line. Additionally, the server should log the event, including 969 | the email address. This will provide a means by which subsequent 970 | statistics generation can associate newsgroup references with unique 971 | entities - not necessarily by name. 972 | 973 | 3.1.1.1 Responses 974 | 975 | 281 Authentication accepted 976 | 381 More authentication information required 977 | 480 Authentication required 978 | 482 Authentication rejected 979 | 502 No permission 980 | 981 | 3.1.2 AUTHINFO SIMPLE 982 | 983 | AUTHINFO SIMPLE 984 | user password 985 | 986 | This version of AUTHINFO was part of a proposed NNTP V2 987 | specification, which was started in 1991 but never completed, and is 988 | implemented in some servers and clients. It is a refinement of the 989 | original AUTHINFO and provides the same basic functionality, but the 990 | sequence of commands is much simpler. 991 | 992 | When authorization is required, the server sends a 450 response 993 | requesting authorization from the client. The client must enter 994 | AUTHINFO SIMPLE. If the server will accept this form of 995 | authentication, the server responds with a 350 response. The client 996 | must then send the username followed by one or more space characters 997 | followed by the password. If accepted, the server returns a 250 998 | response and the client should then retry the original command to 999 | which the server responded with the 450 response. The command should 1000 | then be processed by the server normally. If the combination is not 1001 | valid, the server will return a 452 response. 1002 | 1003 | Note that the response codes used here were part of the proposed NNTP 1004 | V2 specification and are violations of RFC 977. It is recommended 1005 | that this command not be implemented, but use either or both of the 1006 | other forms of AUTHINFO if such functionality if required. 1007 | 1008 | 1009 | 1010 | Barber Informational [Page 18] 1011 | 1012 | RFC 2980 Common NNTP Extensions October 2000 1013 | 1014 | 1015 | 3.1.2.1 Responses 1016 | 1017 | 250 Authorization accepted 1018 | 350 Continue with authorization sequence 1019 | 450 Authorization required for this command 1020 | 452 Authorization rejected 1021 | 1022 | 3.1.3 AUTHINFO GENERIC 1023 | 1024 | AUTHINFO GENERIC authenticator arguments... 1025 | 1026 | AUTHINFO GENERIC is used to identify a specific entity to the server 1027 | using arbitrary authentication or identification protocols. The 1028 | desired protocol is indicated by the authenticator parameter, and any 1029 | number of parameters can be passed to the authenticator. 1030 | 1031 | When authorization is required, the server will send a 480 response 1032 | requesting authorization from the client. The client should enter 1033 | AUTHINFO GENERIC followed by the authenticator name, and the 1034 | arguments if any. The authenticator and arguments must not contain 1035 | the sequence "..". 1036 | 1037 | The server will attempt to engage the server end authenticator, 1038 | similarly, the client should engage the client end authenticator. 1039 | The server end authenticator will then initiate authentication using 1040 | the NNTP sockets (if appropriate for that authentication protocol), 1041 | using the protocol specified by the authenticator name. These 1042 | authentication protocols are not included in this document, but are 1043 | similar in structure to those referenced in RFC 1731 [8] for the 1044 | IMAP-4 protocol. 1045 | 1046 | If the server returns 501, this means that the authenticator 1047 | invocation was syntactically incorrect, or that AUTHINFO GENERIC is 1048 | not supported. The client should retry using the AUTHINFO USER 1049 | command. 1050 | 1051 | If the requested authenticator capability is not found, the server 1052 | returns the 503 response code. 1053 | 1054 | If there is some other unspecified server program error, the server 1055 | returns the 500 response code. 1056 | 1057 | The authenticators converse using their protocol until complete. If 1058 | the authentication succeeds, the server authenticator will terminate 1059 | with a 281, and the client can continue by reissuing the command that 1060 | prompted the 380. If the authentication fails, the server will 1061 | respond with a 502. 1062 | 1063 | 1064 | 1065 | 1066 | Barber Informational [Page 19] 1067 | 1068 | RFC 2980 Common NNTP Extensions October 2000 1069 | 1070 | 1071 | The client must provide authentication when requested by the server. 1072 | The server may request authentication at any time. Servers may 1073 | request authentication more than once during a single session. 1074 | 1075 | When the server authenticator completes, it provides to the server 1076 | (by a mechanism herein undefined) the email address of the user, and 1077 | potentially what the user is allowed to access. Once authenticated, 1078 | the server shall generate a Sender: line using the email address 1079 | provided by the authenticator if it does not match the user-supplied 1080 | From: line. Additionally, the server should log the event, including 1081 | the user's authenticated email address (if available). This will 1082 | provide a means by which subsequent statistics generation can 1083 | associate newsgroup references with unique entities - not necessarily 1084 | by name. 1085 | 1086 | Some implementations make it possible to obtain a list of 1087 | authentication procedures available by sending the server AUTHINFO 1088 | GENERIC with no arguments. The server then returns a list of 1089 | supported mechanisms followed by a period on a line by itself. 1090 | 1091 | 3.1.3.1 Responses 1092 | 1093 | 281 Authentication succeeded 1094 | 480 Authentication required 1095 | 500 Command not understood 1096 | 501 Command not supported 1097 | 502 No permission 1098 | 503 Program error, function not performed 1099 | nnn authenticator-specific protocol. 1100 | 1101 | 3.2 DATE 1102 | 1103 | DATE 1104 | 1105 | The first NNTP working group discussed and proposed a syntax for this 1106 | command to help clients find out the current time from the server's 1107 | perspective. At the time this command was discussed (1991-1992), the 1108 | Network Time Protocol [9] (NTP) was not yet in wide use and there was 1109 | also some concern that small systems may not be able to make 1110 | effective use of NTP. 1111 | 1112 | This command returns a one-line response code of 111 followed by the 1113 | GMT date and time on the server in the form YYYYMMDDhhmmss. 1114 | 1115 | 3.2.1 Responses 1116 | 1117 | 111 YYYYMMDDhhmmss 1118 | 1119 | 1120 | 1121 | 1122 | Barber Informational [Page 20] 1123 | 1124 | RFC 2980 Common NNTP Extensions October 2000 1125 | 1126 | 1127 | 3.3 The WILDMAT format 1128 | 1129 | The WILDMAT format was first developed by Rich Salz based on the 1130 | format used in the UNIX "find" command to articulate file names. It 1131 | was developed to provide a uniform mechanism for matching patterns in 1132 | the same manner that the UNIX shell matches filenames. Patterns are 1133 | implicitly anchored at the beginning and end of each string when 1134 | testing for a match. There are five pattern matching operations 1135 | other than a strict one-to-one match between the pattern and the 1136 | source to be checked for a match. The first is an asterisk (*) to 1137 | match any sequence of zero or more characters. The second is a 1138 | question mark (?) to match any single character. The third specifies 1139 | a specific set of characters. The set is specified as a list of 1140 | characters, or as a range of characters where the beginning and end 1141 | of the range are separated by a minus (or dash) character, or as any 1142 | combination of lists and ranges. The dash can also be included in 1143 | the set as a character it if is the beginning or end of the set. 1144 | This set is enclosed in square brackets. The close square bracket 1145 | (]) may be used in a set if it is the first character in the set. 1146 | The fourth operation is the same as the logical not of the third 1147 | operation and is specified the same way as the third with the 1148 | addition of a caret character (^) at the beginning of the test string 1149 | just inside the open square bracket. The final operation uses the 1150 | backslash character to invalidate the special meaning of the a open 1151 | square bracket ([), the asterisk, backslash or the question mark. 1152 | Two backslashes in sequence will result in the evaluation of the 1153 | backslash as a character with no special meaning. 1154 | 1155 | 3.3.1 Examples 1156 | 1157 | a. [^]-] -- matches any single character other than a close square 1158 | bracket or a minus sign/dash. 1159 | 1160 | b. *bdc -- matches any string that ends with the string "bdc" 1161 | including the string "bdc" (without quotes). 1162 | 1163 | c. [0-9a-zA-Z] -- matches any single printable alphanumeric ASCII 1164 | character. 1165 | 1166 | d. a??d -- matches any four character string which begins 1167 | with a and ends with d. 1168 | 1169 | 1170 | 1171 | 1172 | 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | Barber Informational [Page 21] 1179 | 1180 | RFC 2980 Common NNTP Extensions October 2000 1181 | 1182 | 1183 | 3.4 Additional Headers 1184 | 1185 | Many NNTP implementations add headers to Usenet articles when then 1186 | are POSTed via NNTP. These headers are discussed in this section. 1187 | None of these headers conflict with those specified in RFC 1036 and 1188 | should be passed unchanged by Usenet transports conforming to RFC 1189 | 1036. 1190 | 1191 | 3.4.1 NNTP-Posting-Host 1192 | 1193 | This line is added to the header of a posted article by the server. 1194 | The contents of the header is either the IP address or the fully 1195 | qualified domain name of the client host posting the article. The 1196 | fully qualified domain name should be determined by doing a reverse 1197 | lookup in the DNS on the IP address of the client. If the client 1198 | article contains this line, it is removed by the server before 1199 | acceptance of the article by the Usenet transport system. 1200 | 1201 | This header provides some idea of the actual host posting the article 1202 | as opposed to information in the Sender or From lines that may be 1203 | present in the article. This is not a fool-proof methodology since 1204 | reverse lookups in the DNS are vulnerable to certain types of 1205 | spoofing, but such discussions are outside the scope of this 1206 | document. 1207 | 1208 | 3.4.2 X-Newsreader and others 1209 | 1210 | 1211 | There are other lines that are added by clients as well. Most of 1212 | these indicate the type of newsreader software that is posting the 1213 | article. 1214 | 1215 | 4.0 Common Implementation Issues 1216 | 1217 | Many NNTP implementations do not follow the specifications in RFC 1218 | 977. In this section, some common implementation issues are 1219 | summarized. 1220 | 1221 | 4.1 The Response to the LIST command 1222 | 1223 | RFC 977 says that the fourth field of the "list of valid newsgroups 1224 | associated information" returned must be "either 'y' or 'n' 1225 | indicating whether posting to this newsgroup is allowed ('y') or 1226 | prohibited ('n'). Most implementations simply output the exact 1227 | contents of the transport system's active newsgroup list. For more 1228 | implementations, the fourth field usually has more values that 'y' or 1229 | 'n'. 1230 | 1231 | 1232 | 1233 | 1234 | Barber Informational [Page 22] 1235 | 1236 | RFC 2980 Common NNTP Extensions October 2000 1237 | 1238 | 1239 | 4.2 The Required Headers in an Article and the POST command 1240 | 1241 | RFC 977 notes in section 3.10.1 that articles presented "should 1242 | include all required header lines." In fact, modern implementations 1243 | only require From, Subject, and Newsgroups header lines and will 1244 | supply the rest; further, many implementers believe that it is best 1245 | for clients to generate as few headers as possible, since clients 1246 | often do not format other headers correctly. 1247 | 1248 | This implementation behavior is consistent with both Bnews and Cnews 1249 | which would supply missing headers for articles directly submitted to 1250 | them. 1251 | 1252 | 4.3 Article Numbering 1253 | 1254 | RFC 977 does not directly address the rules concerning articles 1255 | number. However, the current practice is simple: article numbers are 1256 | monotonically increasing, articles may disappear, and therefore the 1257 | high and low water marks returned in a GROUP command should be 1258 | treated as maximum minima, and minimum maxima, respectively. 1259 | 1260 | 4.4 Availability of commands defined in RFC 977 1261 | 1262 | Some implementations permit administrators to disable commands 1263 | defined RFC 977. Some implementations have some set of commands 1264 | disabled by default. This means that client implementations cannot 1265 | depend on the availability of the disabled set of commands. This 1266 | increases the complexity of the client and does not encourage 1267 | implementors to optimize the implementation of commands that don't 1268 | perform well. 1269 | 1270 | NEWNEWS is one of the commands frequently disabled. 1271 | 1272 | 4.5 The Distribution header and NEWNEWS 1273 | 1274 | In section 12.4 of RFC 977, the optional distributions argument is 1275 | described. This argument, according to RFC 977, would limit the 1276 | responses to articles that were in newsgroups with prefixes that 1277 | matched the optional distributions argument. 1278 | 1279 | Some implementations implement this by matching the Distributions 1280 | header in articles to the distribution argument. Others do the match 1281 | against segments of the newsgroup's name. 1282 | 1283 | This variation is probably best explained by the evolution of the 1284 | USENET article format. At the time RFC 977 was specified, the 1285 | newsgroup name defined how the group was distributed throughout 1286 | USENET. RFC 1036 changed this convention. So, those that are 1287 | 1288 | 1289 | 1290 | Barber Informational [Page 23] 1291 | 1292 | RFC 2980 Common NNTP Extensions October 2000 1293 | 1294 | 1295 | strictly implementing RFC 977 would match the newsgroup name prefix 1296 | against the distribution argument and only display matches. Those 1297 | that implement against the intent of the command (as modified by the 1298 | redefinition of the article format)would match the Distributions 1299 | header against the distribution argument and only display those 1300 | matches. 1301 | 1302 | 5.0 Further Work 1303 | 1304 | With the continued use of NNTP on the Internet, there remains an 1305 | interest in creating an optimized transport protocol for server-to- 1306 | server transfers and an optimized client protocol for client-to- 1307 | server interactions. There is also considerable interest is building 1308 | better mechanisms to provide audit information on which news groups 1309 | are being read by which users. 1310 | 1311 | An IETF working group has been formed and it is the hope of this 1312 | author that these issues will be addressed in that forum. 1313 | 1314 | 6.0 Security Considerations 1315 | 1316 | The use of the AUTHINFO is optional. This command as documented has 1317 | a number of security implications. In the original and simple forms, 1318 | all passwords are passed in plaintext and could be discovered by 1319 | various forms of network or system surveillance. The AUTHINFO 1320 | GENERIC command has the potential for the same problems if a 1321 | mechanism is used that also passes cleartext passwords. RFC 1731 [8] 1322 | discusses these issues in greater detail. 1323 | 1324 | 7.0 References 1325 | 1326 | [1] Kantor, B and P. Lapsley, "Network News Transfer Protocol", RFC 1327 | 977, February 1986. 1328 | 1329 | [2] Limoncelli, Tom, "Read This Before You Write a Newsreader", 1330 | http://mars.superlink.net/tal/news-software-authors.html, June, 1331 | 1996. 1332 | 1333 | [3] Horton, M. and R. Adams, "Standard for interchange of USENET 1334 | messages", RFC 1036, December 1987. 1335 | 1336 | [4] Salz, Rich, Manual Page for wildmat(3) from the INN 1.4 1337 | distribution, UUNET Technologies, Revision 1.10, April, 1992. 1338 | 1339 | [5] Robertson, Rob, "FAQ: Overview database / NOV General 1340 | Information", ftp://ftp.uu.net/networking/news/nntp/inn/faq- 1341 | nov.Z, January, 1995. 1342 | 1343 | 1344 | 1345 | 1346 | Barber Informational [Page 24] 1347 | 1348 | RFC 2980 Common NNTP Extensions October 2000 1349 | 1350 | 1351 | [6] Lea, Iain, "FAQ about the TIN newsreader", 1352 | http://www.cs.unca.edu/~davidson/handouts/tinfaq.html 1353 | 1354 | [7] Kappesser, Peter, "[news.software.readers] trn newsreader FAQ", 1355 | 2 parts, ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/news/ 1356 | software/readers/%5Bnews.software.readers%5D_trn_newsreader 1357 | _FAQ%2C_part_1%3A_Basics and ftp://rtfm.mit.edu/pub/usenet-by 1358 | -hierarchy/news/software/readers/%5Bnews.software.readers 1359 | %5D_trn_news-reader_FAQ%2C_part_2%3A_Advanced, February, 1995. 1360 | 1361 | [8] Meyers, J., "IMAP4 Authentication Mechanisms", RFC 1731, 1362 | December 1994. 1363 | 1364 | [9] Mills, D., "Network Time Protocol (Version 3), Specification, 1365 | Implementation and Analysis", RFC 1305, March 1992. 1366 | 1367 | 8.0 Notes 1368 | 1369 | DEC is a registered trademark of Compaq Computer Corporation. UNIX 1370 | is a registered trademark of The Open Group. VMS is a registered 1371 | trademark of Compaq Computer Corporation. 1372 | 1373 | 9.0 Acknowledgments 1374 | 1375 | The author gratefully acknowledges the comments and additional 1376 | information provided by the following individuals: 1377 | 1378 | Wayne Davison 1379 | Chris Lewis 1380 | Tom Limoncelli 1381 | Eric Schnoebelen 1382 | Rich Salz 1383 | 1384 | This work was precipitated by the work of various newsreader authors 1385 | and newsserver authors which includes those listed below: 1386 | 1387 | Rick Adams -- Original author of the NNTP extensions to the RN 1388 | newsreader and last maintainer of Bnews 1389 | Stan Barber -- Original author of the NNTP extensions to the 1390 | newsreaders that are part of Bnews. 1391 | Geoff Collyer -- Original author of the OVERVIEW database proposal and 1392 | one of the original authors of CNEWS 1393 | Dan Curry -- Original author of the xvnews newsreader 1394 | Wayne Davison -- Author of the first threading extensions to the 1395 | RN newsreader (commonly called TRN). 1396 | Geoff Huston -- Original author of ANU NEWS 1397 | 1398 | 1399 | 1400 | 1401 | 1402 | Barber Informational [Page 25] 1403 | 1404 | RFC 2980 Common NNTP Extensions October 2000 1405 | 1406 | 1407 | Phil Lapsey -- Original author of the UNIX reference 1408 | implementation 1409 | Iain Lea -- Original maintainer of the TIN newsreader 1410 | Chris Lewis -- First known implementor of the AUTHINFO GENERIC 1411 | extension 1412 | Rich Salz -- Original author of INN 1413 | Henry Spencer -- One of the original authors of CNEWS 1414 | Kim Storm -- Original author of the NN newsreader 1415 | 1416 | 10.0 Author's Address 1417 | 1418 | Stan Barber 1419 | P.O. Box 300481 1420 | Houston, Texas, 77230 1421 | 1422 | EMail: sob@academ.com 1423 | 1424 | 1425 | 1426 | 1427 | 1428 | 1429 | 1430 | 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | 1442 | 1443 | 1444 | 1445 | 1446 | 1447 | 1448 | 1449 | 1450 | 1451 | 1452 | 1453 | 1454 | 1455 | 1456 | 1457 | 1458 | Barber Informational [Page 26] 1459 | 1460 | RFC 2980 Common NNTP Extensions October 2000 1461 | 1462 | 1463 | 11.0 Full Copyright Statement 1464 | 1465 | Copyright (C) The Internet Society (2000). All Rights Reserved. 1466 | 1467 | This document and translations of it may be copied and furnished to 1468 | others, and derivative works that comment on or otherwise explain it 1469 | or assist in its implementation may be prepared, copied, published 1470 | and distributed, in whole or in part, without restriction of any 1471 | kind, provided that the above copyright notice and this paragraph are 1472 | included on all such copies and derivative works. However, this 1473 | document itself may not be modified in any way, such as by removing 1474 | the copyright notice or references to the Internet Society or other 1475 | Internet organizations, except as needed for the purpose of 1476 | developing Internet standards in which case the procedures for 1477 | copyrights defined in the Internet Standards process must be 1478 | followed, or as required to translate it into languages other than 1479 | English. 1480 | 1481 | The limited permissions granted above are perpetual and will not be 1482 | revoked by the Internet Society or its successors or assigns. 1483 | 1484 | This document and the information contained herein is provided on an 1485 | "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING 1486 | TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING 1487 | BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION 1488 | HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 1489 | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 1490 | 1491 | Acknowledgement 1492 | 1493 | Funding for the RFC Editor function is currently provided by the 1494 | Internet Society. 1495 | 1496 | 1497 | 1498 | 1499 | 1500 | 1501 | 1502 | 1503 | 1504 | 1505 | 1506 | 1507 | 1508 | 1509 | 1510 | 1511 | 1512 | 1513 | 1514 | Barber Informational [Page 27] 1515 | 1516 | --------------------------------------------------------------------------------