about summary refs log tree commit homepage
path: root/lib/PublicInbox/LeiExportKw.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/LeiExportKw.pm')
-rw-r--r--lib/PublicInbox/LeiExportKw.pm49
1 files changed, 26 insertions, 23 deletions
diff --git a/lib/PublicInbox/LeiExportKw.pm b/lib/PublicInbox/LeiExportKw.pm
index cea9beeb..16f069da 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(0,
+                                "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(0, "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" }
 }
 
@@ -115,14 +122,10 @@ 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 {
@@ -130,8 +133,8 @@ sub _complete_export_kw {
         my $lms = $lei->lms or return ();
         my $match_cb = $lei->complete_url_prepare(\@argv);
         # filter-out read-only sources:
-        my @k = grep(!m!(?://;AUTH=ANONYMOUS\@|\A(?:nntps?|s?news)://)!,
-                        $lms->folders($argv[-1], 1));
+        my @k = grep(m!(?:maildir|imaps?):!,
+                        $lms->folders($argv[-1] // undef, 1));
         my @m = map { $match_cb->($_) } @k;
         @m ? @m : @k;
 }