-# 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>
#
# Each instance of this represents a NNTP client socket
package PublicInbox::NNTP;
($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) {
$YYYY += int($cur_year / 1000) * 1000 - 100;
}
}
my $err;
do {
- eval { $cb->(\$beg) };
+ eval { $cb->(\$beg, \$lim) };
} until (($err = $@) || $self->{closed} ||
- ++$beg > $end || !--$lim || $self->{write_buf_size});
+ ++$beg > $end || --$lim < 0 ||
+ $self->{write_buf_size});
if ($err || $self->{closed}) {
$self->{long_res} = undef;
update_idle_time($self);
$self->watch_read(1);
}
- } elsif (!$lim || $self->{write_buf_size}) {
+ } elsif ($lim < 0 || $self->{write_buf_size}) {
# no recursion, schedule another call ASAP
# but only after all pending writes are done
update_idle_time($self);
more($self, $xhdr ? r221 : r225);
my $off = 0;
long_response($self, $beg, $end, sub {
- my ($i) = @_;
+ my ($i, $lim) = @_;
my $res = $srch->query_xover($beg, $end, $off);
my $msgs = $res->{msgs};
my $nr = scalar @$msgs or return;
$off += $nr;
+ $$lim -= $nr;
my $tmp = '';
foreach my $s (@$msgs) {
$tmp .= $s->num . ' ' . $s->$field . "\r\n";
my $srch = $self->{ng}->search;
my $off = 0;
long_response($self, $beg, $end, sub {
- my ($i) = @_;
+ my ($i, $lim) = @_;
my $res = $srch->query_xover($beg, $end, $off);
my $msgs = $res->{msgs};
my $nr = scalar @$msgs or return;
$off += $nr;
+ $$lim -= $nr;
# OVERVIEW.FMT
more($self, join("\r\n", map {
sub event_read {
my ($self) = @_;
use constant LINE_MAX => 512; # RFC 977 section 2.3
- my $r = 1;
- my $buf = $self->read(LINE_MAX) or return $self->close;
- $self->{rbuf} .= $$buf;
+ if (index($self->{rbuf}, "\n") < 0) {
+ my $buf = $self->read(LINE_MAX) or return $self->close;
+ $self->{rbuf} .= $$buf;
+ }
+ my $r = 1;
while ($r > 0 && $self->{rbuf} =~ s/\A\s*([^\r\n]+)\r?\n//) {
my $line = $1;
return $self->close if $line =~ /[[:cntrl:]]/s;