X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FLeiExportKw.pm;h=d2396fa7d697bb7b8b9ddf092ff27de65230f350;hb=0054246c2d03fcc91bc899da5ef41a68f505e542;hp=8c5fbc13079eedc83445df7382a3432a3f268ec6;hpb=47d4e53734820b4e5a2f6cfa29056329e387ef22;p=public-inbox.git diff --git a/lib/PublicInbox/LeiExportKw.pm b/lib/PublicInbox/LeiExportKw.pm index 8c5fbc13..d2396fa7 100644 --- a/lib/PublicInbox/LeiExportKw.pm +++ b/lib/PublicInbox/LeiExportKw.pm @@ -7,6 +7,7 @@ use strict; use v5.10.1; use parent qw(PublicInbox::IPC PublicInbox::LeiInput); use Errno qw(EEXIST ENOENT); +use PublicInbox::Syscall qw(rename_noreplace); sub export_kw_md { # LeiMailSync->each_src callback my ($oidbin, $id, $self, $mdir) = @_; @@ -30,30 +31,22 @@ sub export_kw_md { # LeiMailSync->each_src callback my $lei = $self->{lei}; for my $d (@try) { my $src = "$mdir/$d/$$id"; - - # we use link(2) + unlink(2) since rename(2) may - # inadvertently clobber if the "uniquefilename" part wasn't - # actually unique. - if (link($src, $dst)) { # success - # unlink(2) may ENOENT from parallel invocation, - # ignore it, but not other serious errors - if (!unlink($src) and $! != ENOENT) { - $lei->child_error(1, "E: unlink($src): $!"); - } + if (rename_noreplace($src, $dst)) { # success $self->{lms}->mv_src("maildir:$mdir", $oidbin, $id, $bn); - return; # success anyways if link(2) worked + return; # success } elsif ($! == EEXIST) { # lost race with lei/store? return; } elsif ($! != ENOENT) { - $lei->child_error(1, "E: link($src -> $dst): $!"); + $lei->child_error(1, + "E: rename_noreplace($src -> $dst): $!"); } # else loop @try } my $e = $!; # both tries failed my $oidhex = unpack('H*', $oidbin); my $src = "$mdir/{".join(',', @try)."}/$$id"; - $lei->child_error(1, "link($src -> $dst) ($oidhex): $e"); + $lei->child_error(1, "rename_noreplace($src -> $dst) ($oidhex): $e"); for (@try) { return if -e "$mdir/$_/$$id" } $self->{lms}->clear_src("maildir:$mdir", $id); } @@ -75,8 +68,22 @@ sub input_path_url { } elsif ($input =~ m!\Aimaps?://!i) { my $uri = PublicInbox::URIimap->new($input); my $mic = $self->{nwr}->mic_for_folder($uri); - $self->{lms}->each_src($$uri, \&export_kw_imap, $self, $mic); - $mic->expunge; + if ($mic && !$self->{nwr}->can_store_flags($mic)) { + my $m = "$input does not support PERMANENTFLAGS"; + if (defined $self->{lei}->{opt}->{all}) { + $self->{lei}->qerr("# $m"); + } else { # set error code if user explicitly requested + $self->{lei}->child_error(0, "E: $m"); + } + return; + } + if ($mic) { + $self->{lms}->each_src($$uri, \&export_kw_imap, + $self, $mic); + $mic->expunge; + } else { + $self->{lei}->child_error(0, "$input unavailable: $@"); + } } else { die "BUG: $input not supported" } } @@ -92,9 +99,7 @@ EOM $lms->group2folders($lei, $all, \@folders) or return; @folders = grep(/\A(?:maildir|imaps?):/i, @folders); } else { - my $err = $lms->arg2folder($lei, \@folders); - $lei->qerr(@{$err->{qerr}}) if $err->{qerr}; - return $lei->fail($err->{fail}) if $err->{fail}; + $lms->arg2folder($lei, \@folders); # may die } $lms->lms_pause; my $self = bless { lse => $sto->search, lms => $lms }, __PACKAGE__; @@ -117,21 +122,21 @@ EOM $self->{nwr} = bless $net, 'PublicInbox::NetWriter'; $self->{imap_mod_kw} = $net->can($self->{-merge_kw} ? 'imap_add_kw' : 'imap_set_kw'); + $self->{nwr}->{-skip_creat} = 1; } - my $ops = {}; - $lei->{auth}->op_merge($ops, $self) if $lei->{auth}; - (my $op_c, $ops) = $lei->workers_start($self, 1, $ops); - $lei->{wq1} = $self; $lei->{-err_type} = 'non-fatal'; - net_merge_all_done($self) unless $lei->{auth}; - $lei->wait_wq_events($op_c, $ops); # net_merge_all_done if !{auth} + $lei->wq1_start($self); } sub _complete_export_kw { my ($lei, @argv) = @_; - my $lms = $lei->lms or return; + my $lms = $lei->lms or return (); my $match_cb = $lei->complete_url_prepare(\@argv); - map { $match_cb->($_) } $lms->folders; + # filter-out read-only sources: + my @k = grep(m!(?:maildir|imaps?):!, + $lms->folders($argv[-1] // undef, 1)); + my @m = map { $match_cb->($_) } @k; + @m ? @m : @k; } no warnings 'once';