sub mic_new ($$$$) {
my ($self, $mic_arg, $sec, $uri) = @_;
- my %socks;
- my $sa = $self->{imap_opt}->{$sec}->{-proxy_cfg} || $self->{-proxy_cli};
+ my %mic_arg = %$mic_arg;
+ my $sa = $self->{cfg_opt}->{$sec}->{-proxy_cfg} || $self->{-proxy_cli};
if ($sa) {
my %opt = %$sa;
- $opt{ConnectAddr} = delete $mic_arg->{Server};
- $opt{ConnectPort} = delete $mic_arg->{Port};
- $socks{Socket} = IO::Socket::Socks->new(%opt) or die
+ $opt{ConnectAddr} = delete $mic_arg{Server};
+ $opt{ConnectPort} = delete $mic_arg{Port};
+ $mic_arg{Socket} = IO::Socket::Socks->new(%opt) or die
"E: <$$uri> ".eval('$IO::Socket::Socks::SOCKS_ERROR');
}
- PublicInbox::IMAPClient->new(%$mic_arg, %socks);
+ PublicInbox::IMAPClient->new(%mic_arg, Keepalive => 1);
}
sub auth_anon_cb { '' }; # for Mail::IMAPClient::Authcallback
Port => $uri->port,
Server => $host,
Ssl => $uri->scheme eq 'imaps',
- Keepalive => 1, # SO_KEEPALIVE
%$common, # may set Starttls, Compress, Debug ....
};
+ $mic_arg->{Ssl} = 1 if $uri->scheme eq 'imaps';
require PublicInbox::IMAPClient;
my $mic = mic_new($self, $mic_arg, $sec, $uri) or
die "E: <$uri> new: $@\n";
$cred = undef;
}
if ($cred) {
- $cred->check_netrc unless defined $cred->{password};
- $cred->fill($lei); # may prompt user here
+ my $p = $cred->{password} // $cred->check_netrc;
+ $cred->fill($lei) unless defined($p); # may prompt user here
$mic->User($mic_arg->{User} = $cred->{username});
$mic->Password($mic_arg->{Password} = $cred->{password});
} else { # AUTH=ANONYMOUS
}
$mic = undef;
}
- $cred->run($mic ? 'approve' : 'reject') if $cred;
+ $cred->run($mic ? 'approve' : 'reject') if $cred && $cred->{filled};
if ($err) {
$lei ? $lei->fail($err) : warn($err);
}
}
sub nn_new ($$$) {
- my ($nn_arg, $nntp_opt, $uri) = @_;
+ my ($nn_arg, $nntp_cfg, $uri) = @_;
my $nn;
if (defined $nn_arg->{ProxyAddr}) {
require PublicInbox::NetNNTPSocks;
# default to using STARTTLS if it's available, but allow
# it to be disabled for localhost/VPN users
if (!$nn_arg->{SSL} && $nn->can('starttls')) {
- if (!defined($nntp_opt->{starttls}) &&
+ if (!defined($nntp_cfg->{starttls}) &&
try_starttls($nn_arg->{Host})) {
# soft fail by default
$nn->starttls or warn <<"";
W: <$uri> STARTTLS tried and failed (not requested)
- } elsif ($nntp_opt->{starttls}) {
+ } elsif ($nntp_cfg->{starttls}) {
# hard fail if explicitly configured
$nn->starttls or die <<"";
E: <$uri> STARTTLS requested and failed
}
- } elsif ($nntp_opt->{starttls}) {
+ } elsif ($nntp_cfg->{starttls}) {
$nn->can('starttls') or
die "E: <$uri> Net::NNTP too old for STARTTLS\n";
$nn->starttls or die <<"";
sub nn_for ($$$$) { # nn = Net::NNTP
my ($self, $uri, $nn_args, $lei) = @_;
my $sec = uri_section($uri);
- my $nntp_opt = $self->{nntp_opt}->{$sec} //= {};
+ my $nntp_cfg = $self->{cfg_opt}->{$sec} //= {};
my $host = $uri->host;
# Net::NNTP and Net::Netrc both mishandle `0', so we pass `127.0.0.1'
$host = '127.0.0.1' if $host eq '0';
}, 'PublicInbox::GitCredential';
($u, $p) = split(/:/, $ui, 2);
($cred->{username}, $cred->{password}) = ($u, $p);
- $cred->check_netrc unless defined $p;
+ $p //= $cred->check_netrc;
}
my $common = $nn_args->{$sec} // {};
my $nn_arg = {
Port => $uri->port,
Host => $host,
- SSL => $uri->secure, # snews == nntps
%$common, # may Debug ....
};
+ $nn_arg->{SSL} = 1 if $uri->secure; # snews == nntps
my $sa = $self->{-proxy_cli};
%$nn_arg = (%$nn_arg, %$sa) if $sa;
- my $nn = nn_new($nn_arg, $nntp_opt, $uri);
+ my $nn = nn_new($nn_arg, $nntp_cfg, $uri);
if ($cred) {
- $cred->fill($lei); # may prompt user here
+ $cred->fill($lei) unless defined($p); # may prompt user here
if ($nn->authinfo($u, $p)) {
- push @{$nntp_opt->{-postconn}}, [ 'authinfo', $u, $p ];
+ push @{$nntp_cfg->{-postconn}}, [ 'authinfo', $u, $p ];
} else {
warn "E: <$uri> AUTHINFO $u XXXX failed\n";
$nn = undef;
}
}
- if ($nntp_opt->{compress}) {
+ if ($nntp_cfg->{compress}) {
# https://rt.cpan.org/Ticket/Display.html?id=129967
if ($nn->can('compress')) {
if ($nn->compress) {
- push @{$nntp_opt->{-postconn}}, [ 'compress' ];
+ push @{$nntp_cfg->{-postconn}}, [ 'compress' ];
} else {
warn "W: <$uri> COMPRESS failed\n";
}
} else {
- delete $nntp_opt->{compress};
+ delete $nntp_cfg->{compress};
warn <<"";
W: <$uri> COMPRESS not supported by Net::NNTP
W: see https://rt.cpan.org/Ticket/Display.html?id=129967 for updates
}
$self->{nn_arg}->{$sec} = $nn_arg;
- $cred->run($nn ? 'approve' : 'reject') if $cred;
+ $cred->run($nn ? 'approve' : 'reject') if $cred && $cred->{filled};
$nn;
}
my $to = cfg_intvl($cfg, 'imap.timeout', $$uri);
$mic_args->{$sec}->{Timeout} = $to if $to;
my $sa = socks_args($cfg->urlmatch('imap.Proxy', $$uri));
- $self->{imap_opt}->{$sec}->{-proxy_cfg} = $sa if $sa;
+ $self->{cfg_opt}->{$sec}->{-proxy_cfg} = $sa if $sa;
for my $k (qw(pollInterval idleInterval)) {
$to = cfg_intvl($cfg, "imap.$k", $$uri) // next;
- $self->{imap_opt}->{$sec}->{$k} = $to;
+ $self->{cfg_opt}->{$sec}->{$k} = $to;
}
my $k = 'imap.fetchBatchSize';
my $bs = $cfg->urlmatch($k, $$uri) // next;
if ($bs =~ /\A([0-9]+)\z/) {
- $self->{imap_opt}->{$sec}->{batch_size} = $bs;
+ $self->{cfg_opt}->{$sec}->{batch_size} = $bs;
} else {
warn "$k=$bs is not an integer\n";
}
# Net::NNTP post-connect commands
for my $k (qw(starttls compress)) {
$v = cfg_bool($cfg, "nntp.$k", $$uri) // next;
- $self->{nntp_opt}->{$sec}->{$k} = $v;
+ $self->{cfg_opt}->{$sec}->{$k} = $v;
}
# -watch internal option
for my $k (qw(pollInterval)) {
$to = cfg_intvl($cfg, "nntp.$k", $$uri) // next;
- $self->{nntp_opt}->{$sec}->{$k} = $to;
+ $self->{cfg_opt}->{$sec}->{$k} = $to;
}
}
# make sure we can connect and cache the credentials in memory
my ($self, $uri, $uid, $raw, $flags) = @_;
# our target audience expects LF-only, save storage
$$raw =~ s/\r\n/\n/sg;
- my $kw = flags2kw($self, $uri, $uid, $flags) // return;
+ my $kw = defined($flags) ?
+ (flags2kw($self, $uri, $uid, $flags) // return) : undef;
my ($eml_cb, @args) = @{$self->{eml_each}};
$eml_cb->($uri, $uid, $kw, PublicInbox::Eml->new($raw), @args);
}
my ($self, $mic, $uri, $l_uid) = @_;
$l_uid ||= 1;
my $sec = uri_section($uri);
- my $bs = $self->{imap_opt}->{$sec}->{batch_size} // 10000;
+ my $bs = ($self->{cfg_opt}->{$sec}->{batch_size} // 1) * 10000;
my ($eml_cb, @args) = @{$self->{eml_each}};
+ $self->{quiet} or warn "# $uri syncing flags 1:$l_uid\n";
for (my $n = 1; $n <= $l_uid; $n += $bs) {
my $end = $n + $bs;
$end = $l_uid if $end > $l_uid;
undef;
}
+# may be overridden in NetWriter or Watch
+sub folder_select { $_[0]->{each_old} ? 'select' : 'examine' }
+
sub _imap_fetch_all ($$$) {
my ($self, $mic, $orig_uri) = @_;
my $sec = uri_section($orig_uri);
# we need to check for mailbox writability to see if we care about
# FLAGS from already-imported messages.
- my $cmd = $self->{each_old} ? 'select' : 'examine';
+ my $cmd = $self->folder_select;
$mic->$cmd($mbx) or return "E: \U$cmd\E $mbx ($sec) failed: $!";
my ($r_uidval, $r_uidnext, $perm_fl);
EOF
$mic->Uid(1); # the default, we hope
my $err;
- if (!defined($single_uid) && $self->{each_old} &&
- perm_fl_ok($perm_fl)) {
+ my $use_fl = perm_fl_ok($perm_fl);
+ if (!defined($single_uid) && $self->{each_old} && $use_fl) {
$err = each_old_flags($self, $mic, $uri, $l_uid);
return $err if $err;
}
my $m = $mod ? " [(UID % $mod) == $shard]" : '';
warn "# $uri fetching UID $l_uid:$r_uid$m\n";
}
- my $bs = $self->{imap_opt}->{$sec}->{batch_size} // 1;
+ my $bs = $self->{cfg_opt}->{$sec}->{batch_size} // 1;
my $req = $mic->imap4rev1 ? 'BODY.PEEK[]' : 'RFC822.PEEK';
my $key = $req;
$key =~ s/\.PEEK//;
# messages get deleted, so holes appear
my $per_uid = delete $r->{$uid} // next;
my $raw = delete($per_uid->{$key}) // next;
- _imap_do_msg($self, $uri, $uid, \$raw,
- $per_uid->{FLAGS});
+ my $fl = $use_fl ? $per_uid->{FLAGS} : undef;
+ _imap_do_msg($self, $uri, $uid, \$raw, $fl);
$last_uid = $uid;
last if $self->{quit};
}
$nn = delete($cached->{$sec}) and return $nn;
my $nn_arg = $self->{nn_arg}->{$sec} or
die "BUG: no Net::NNTP->new arg for $sec";
- my $nntp_opt = $self->{nntp_opt}->{$sec};
- $nn = nn_new($nn_arg, $nntp_opt, $uri) or return;
- if (my $postconn = $nntp_opt->{-postconn}) {
+ my $nntp_cfg = $self->{cfg_opt}->{$sec};
+ $nn = nn_new($nn_arg, $nntp_cfg, $uri) or return;
+ if (my $postconn = $nntp_cfg->{-postconn}) {
for my $m_arg (@$postconn) {
my ($method, @args) = @$m_arg;
$nn->$method(@args) and next;