-# Copyright (C) 2015 all contributors <meta@public-inbox.org>
-# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+# Copyright (C) 2015-2018 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
use constant {
r501 => '501 command syntax error',
r221 => '221 Header follows',
use constant {
r501 => '501 command syntax error',
r221 => '221 Header follows',
my $res = eval { $req->($self, @args) };
my $err = $@;
if ($err && !$self->{closed}) {
my $res = eval { $req->($self, @args) };
my $err = $@;
if ($err && !$self->{closed}) {
chomp($l);
err($self, 'error from: %s (%s)', $l, $err);
$res = '503 program fault - command not performed';
chomp($l);
err($self, 'error from: %s (%s)', $l, $err);
$res = '503 program fault - command not performed';
my ($hh, $mm, $ss) = unpack('A2A2A2', $time);
if (defined $gmt) {
$gmt =~ /\A(?:UTC|GMT)\z/i or die "GM invalid: $gmt";
my ($hh, $mm, $ss) = unpack('A2A2A2', $time);
if (defined $gmt) {
$gmt =~ /\A(?:UTC|GMT)\z/i or die "GM invalid: $gmt";
($YYYY, $MM, $DD) = unpack('A4A2A2', $date);
} else { # legacy clients send YYMMDD
($YYYY, $MM, $DD) = unpack('A2A2A2', $date);
($YYYY, $MM, $DD) = unpack('A4A2A2', $date);
} else { # legacy clients send YYMMDD
($YYYY, $MM, $DD) = unpack('A2A2A2', $date);
- if ($YYYY > strftime('%y', @now)) {
- my $cur_year = $now[5] + 1900;
+ my $cur_year = $now[5] + 1900;
+ if ($YYYY > $cur_year) {
- Time::Local::timegm($ss, $mm, $hh, $DD, $MM - 1, $YYYY);
+ timegm($ss, $mm, $hh, $DD, $MM - 1, $YYYY);
- Time::Local::timelocal($ss, $mm, $hh, $DD, $MM - 1, $YYYY);
+ timelocal($ss, $mm, $hh, $DD, $MM - 1, $YYYY);
long_response($self, 0, long_response_limit, sub {
my ($i) = @_;
my $srch = $srch[0];
long_response($self, 0, long_response_limit, sub {
my ($i) = @_;
my $srch = $srch[0];
- my $res = $srch->query($ts, $opts);
- my $msgs = $res->{msgs};
- if (my $nr = scalar @$msgs) {
+ my $msgs = $srch->query_ts($ts, $prev);
+ if (scalar @$msgs) {
$hdr->header_set('Xref', xref($ng, $n));
header_append($hdr, 'List-Post', "<mailto:$ng->{-primary_address}>");
if (my $url = $ng->base_url) {
$hdr->header_set('Xref', xref($ng, $n));
header_append($hdr, 'List-Post', "<mailto:$ng->{-primary_address}>");
if (my $url = $ng->base_url) {
header_append($hdr, 'Archived-At', "<$url$mid/>");
header_append($hdr, 'List-Archive', "<$url>");
}
header_append($hdr, 'Archived-At', "<$url$mid/>");
header_append($hdr, 'List-Archive', "<$url>");
}
- my $bytes;
- my $s = eval { $ng->msg_by_mid($mid, \$bytes) } or return $err;
- $s = Email::Simple->new($s);
- my $lines;
+ my $smsg = $ng->search->{over_ro}->get_art($n) or return $err;
+ my $msg = $ng->msg_by_smsg($smsg) or return $err;
+ my $s = Email::Simple->new($msg);
if ($set_headers) {
set_nntp_headers($s->header_obj, $ng, $n, $mid);
if ($set_headers) {
set_nntp_headers($s->header_obj, $ng, $n, $mid);
- [ $n, $mid, $s, $bytes, $lines, $ng ];
+ [ $n, $mid, $s, $smsg->bytes, $smsg->lines, $ng ];
$self->{long_res} = sub {
# limit our own running time for fairness with other
# clients and to avoid buffering too much:
$self->{long_res} = sub {
# limit our own running time for fairness with other
# clients and to avoid buffering too much:
- my ($srch, $mid, $field) = @_;
- my $smsg = $srch->lookup_mail($mid) or return;
- $smsg->$field;
+ my ($srch, $num, $field) = @_;
+ my $smsg = $srch->{over_ro}->get_art($num) or return;
+ return PublicInbox::SearchMsg::date($smsg) if $field eq 'date';
+ $smsg->{$field};
}
sub hdr_searchmsg ($$$$) {
my ($self, $xhdr, $field, $range) = @_;
if (defined $range && $range =~ /\A<(.+)>\z/) { # Message-ID
my ($ng, $n) = mid_lookup($self, $1);
}
sub hdr_searchmsg ($$$$) {
my ($self, $xhdr, $field, $range) = @_;
if (defined $range && $range =~ /\A<(.+)>\z/) { # Message-ID
my ($ng, $n) = mid_lookup($self, $1);
- return r430 unless $n;
- my $v = search_header_for($ng->search, $range, $field);
+ return r430 unless defined $n;
+ my $v = search_header_for($ng->search, $n, $field);
hdr_mid_response($self, $xhdr, $ng, $n, $range, $v);
} else { # numeric range
$range = $self->{article} unless defined $range;
hdr_mid_response($self, $xhdr, $ng, $n, $range, $v);
} else { # numeric range
$range = $self->{article} unless defined $range;
- my $off = 0;
- long_response($self, $beg, $end, sub {
+ my $cur = $beg;
+ long_response($self, 0, long_response_limit, sub {
- my $res = $srch->query_xover($beg, $end, $off);
- my $msgs = $res->{msgs};
- my $nr = scalar @$msgs or return;
- $off += $nr;
+ my $msgs = $srch->query_xover($cur, $end);
+ my $nr = scalar @$msgs or
+ return ($$i = long_response_limit);
more($self, '224 Overview information follows');
long_response($self, $beg, $end, sub {
my ($i) = @_;
more($self, '224 Overview information follows');
long_response($self, $beg, $end, sub {
my ($i) = @_;
- my $mid = $mm->mid_for($$i) or return;
- my $h = search_header_for($srch, $mid, 'references');
- more($self, "$$i $h");
+ my $num = $$i;
+ my $h = search_header_for($srch, $num, 'references');
+ defined $h or return;
+ more($self, "$num $h");
my ($self, $range) = @_;
if ($range && $range =~ /\A<(.+)>\z/) {
my ($ng, $n) = mid_lookup($self, $1);
my ($self, $range) = @_;
if ($range && $range =~ /\A<(.+)>\z/) {
my ($ng, $n) = mid_lookup($self, $1);
more($self, '224 Overview information follows (multi-line)');
# Only set article number column if it's the current group
more($self, '224 Overview information follows (multi-line)');
# Only set article number column if it's the current group
my ($beg, $end) = @$r;
more($self, "224 Overview information follows for $beg to $end");
my $srch = $self->{ng}->search;
my ($beg, $end) = @$r;
more($self, "224 Overview information follows for $beg to $end");
my $srch = $self->{ng}->search;
- my $off = 0;
- long_response($self, $beg, $end, sub {
+ my $cur = $beg;
+ long_response($self, 0, long_response_limit, sub {
- my $res = $srch->query_xover($beg, $end, $off);
- my $msgs = $res->{msgs};
- my $nr = scalar @$msgs or return;
- $off += $nr;
+ my $msgs = $srch->query_xover($cur, $end);
+ my $nr = scalar @$msgs or return ($$i = long_response_limit);
# Do not watch for readability if we have data in the queue,
# instead re-enable watching for readability when we can
# Do not watch for readability if we have data in the queue,
# instead re-enable watching for readability when we can