From 8c4505904f84411442b8b855a111da1461b57c45 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 13 Jul 2019 21:42:46 +0000 Subject: nntp: support optional [range] arg in LISTGROUP RFC3977 6.1.2.2 LISTGROUP allows a [range] arg after [group], and supporting it allows NNTP support in neomutt to work again. Tested with NeoMutt 20170113 (1.7.2) on Debian stretch (oldstable) --- lib/PublicInbox/Msgmap.pm | 7 ++++--- lib/PublicInbox/NNTP.pm | 34 +++++++++++++++++++++++----------- t/nntpd.t | 1 + 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/lib/PublicInbox/Msgmap.pm b/lib/PublicInbox/Msgmap.pm index 5a89b85a..e74a3aef 100644 --- a/lib/PublicInbox/Msgmap.pm +++ b/lib/PublicInbox/Msgmap.pm @@ -211,11 +211,12 @@ ORDER BY num ASC LIMIT 1000 } sub msg_range { - my ($self, $beg, $end) = @_; + my ($self, $beg, $end, $cols) = @_; + $cols //= 'num,mid'; my $dbh = $self->{dbh}; my $attr = { Columns => [] }; - my $mids = $dbh->selectall_arrayref(<<'', $attr, $$beg, $end); -SELECT num,mid FROM msgmap WHERE num >= ? AND num <= ? + my $mids = $dbh->selectall_arrayref(<<"", $attr, $$beg, $end); +SELECT $cols FROM msgmap WHERE num >= ? AND num <= ? ORDER BY num ASC LIMIT 1000 $$beg = $mids->[-1]->[0] + 1 if @$mids; diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index 800ce926..7c3f68a2 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -221,22 +221,34 @@ sub cmd_list ($;$$) { '.' } -sub cmd_listgroup ($;$) { - my ($self, $group) = @_; +sub cmd_listgroup ($;$$) { + my ($self, $group, $range) = @_; if (defined $group) { my $res = cmd_group($self, $group); return $res if ($res !~ /\A211 /); more($self, $res); } - - $self->{ng} or return '412 no newsgroup selected'; - my $n = 0; - long_response($self, sub { - my $ary = $self->{ng}->mm->ids_after(\$n); - scalar @$ary or return; - more($self, join("\r\n", @$ary)); - 1; - }); + my $ng = $self->{ng} or return '412 no newsgroup selected'; + my $mm = $ng->mm; + if (defined $range) { + my $r = get_range($self, $range); + return $r unless ref $r; + my ($beg, $end) = @$r; + long_response($self, sub { + $r = $mm->msg_range(\$beg, $end, 'num'); + scalar(@$r) or return; + more($self, join("\r\n", map { "$_->[0]\r\n" } @$r)); + 1; + }); + } else { # grab every article number + my $n = 0; + long_response($self, sub { + my $ary = $mm->ids_after(\$n); + scalar(@$ary) or return; + more($self, join("\r\n", @$ary)); + 1; + }); + } } sub parse_time ($$;$) { diff --git a/t/nntpd.t b/t/nntpd.t index bebecc69..b47cf7db 100644 --- a/t/nntpd.t +++ b/t/nntpd.t @@ -100,6 +100,7 @@ EOF is_deeply($list, { $group => [ qw(1 1 n) ] }, 'LIST works'); is_deeply([$n->group($group)], [ qw(0 1 1), $group ], 'GROUP works'); is_deeply($n->listgroup($group), [1], 'listgroup OK'); + # TODO: Net::NNTP::listgroup does not support range at the moment { my $expect = [ qw(Subject: From: Date: Message-ID: -- cgit v1.2.3-24-ge0c7