X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FLEI.pm;h=28fe0c836d7a3e842217b9bfd3cf63ac8ece2bf8;hb=b6eb866869609afef72c77f41507905828014673;hp=79dc9bf9972c7a23e89b9c0bd9fc0af87c09699e;hpb=d99020ac3612308d04e3760bd780417218748168;p=public-inbox.git diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 79dc9bf9..28fe0c83 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -37,6 +37,7 @@ $GLP_PASS->configure(qw(gnu_getopt no_ignore_case auto_abbrev pass_through)); our %PATH2CFG; # persistent for socket daemon our $MDIR2CFGPATH; # /path/to/maildir => { /path/to/config => [ ino watches ] } +our %LIVE_SOCK; # "GLOB(0x....)" => $lei->{sock} # TBD: this is a documentation mechanism to show a subcommand # (may) pass options through to another command: @@ -485,6 +486,12 @@ sub err ($;@) { sub qerr ($;@) { $_[0]->{opt}->{quiet} or err(shift, @_) } +sub qfin { # show message on finalization (LeiFinmsg) + my ($lei, $msg) = @_; + return if $lei->{opt}->{quiet}; + $lei->{fmsg} ? push(@{$lei->{fmsg}}, "$msg\n") : qerr($lei, $msg); +} + sub fail_handler ($;$$) { my ($lei, $code, $io) = @_; close($io) if $io; # needed to avoid warnings on SIGPIPE @@ -565,6 +572,7 @@ sub _lei_atfork_child { $dir_idle->force_close if $dir_idle; %PATH2CFG = (); $MDIR2CFGPATH = {}; + %LIVE_SOCK = (); eval 'no warnings; undef $PublicInbox::LeiNoteEvent::to_flush'; undef $errors_log; $quit = \&CORE::exit; @@ -1370,6 +1378,14 @@ sub cancel_maildir_watch ($$) { for my $x (@{$w // []}) { $x->cancel } } +sub add_maildir_watch ($$) { + my ($d, $cfg_f) = @_; + if (!exists($MDIR2CFGPATH->{$d}->{$cfg_f})) { + my @w = $dir_idle->add_watches(["$d/cur", "$d/new"], 1); + push @{$MDIR2CFGPATH->{$d}->{$cfg_f}}, @w if @w; + } +} + sub refresh_watches { my ($lei) = @_; my $cfg = _lei_cfg($lei) or return; @@ -1380,7 +1396,7 @@ sub refresh_watches { for my $w (grep(/\Awatch\..+\.state\z/, keys %$cfg)) { my $url = substr($w, length('watch.'), -length('.state')); require PublicInbox::LeiWatch; - my $lw = $watches->{$url} //= PublicInbox::LeiWatch->new($url); + $watches->{$url} //= PublicInbox::LeiWatch->new($url); $seen{$url} = undef; my $state = $cfg->get_1("watch.$url", 'state'); if (!watch_state_ok($state)) { @@ -1391,16 +1407,37 @@ sub refresh_watches { my $d = canonpath_harder($1); if ($state eq 'pause') { cancel_maildir_watch($d, $cfg_f); - } elsif (!exists($MDIR2CFGPATH->{$d}->{$cfg_f})) { - my @w = $dir_idle->add_watches( - ["$d/cur", "$d/new"], 1); - push @{$MDIR2CFGPATH->{$d}->{$cfg_f}}, @w if @w; + } else { + add_maildir_watch($d, $cfg_f); } } else { # TODO: imap/nntp/jmap - $lei->child_error(1, - "E: watch $url not supported, yet"); + $lei->child_error(1, "E: watch $url not supported, yet") + } + } + + # add all known Maildir folders as implicit watches + my $sto = $lei->_lei_store; + my $renames = 0; + if (my $lms = $sto ? $sto->search->lms : undef) { + for my $d ($lms->folders('maildir:')) { + substr($d, 0, length('maildir:')) = ''; + my $cd = canonpath_harder($d); + my $f = "maildir:$cd"; + + # fixup old bugs while we're iterating: + if ($d ne $cd) { + $sto->ipc_do('lms_rename_folder', + "maildir:$d", $f); + ++$renames; + } + next if $watches->{$f}; # may be set to pause + require PublicInbox::LeiWatch; + $watches->{$f} = PublicInbox::LeiWatch->new($f); + $seen{$f} = undef; + add_maildir_watch($cd, $cfg_f); } } + $lei->sto_done_request if $renames; if ($old) { # cull old non-existent entries for my $url (keys %$old) { next if exists $seen{$url}; @@ -1434,4 +1471,19 @@ sub lms { # read-only LeiMailSync $lse ? $lse->lms : undef; } +sub sto_done_request { # only call this from lei-daemon process (not workers) + my ($lei, $sock) = @_; + if ($sock //= $lei->{sock}) { + $LIVE_SOCK{"$sock"} = $sock; + $lei->{sto}->ipc_do('done', "$sock"); # issue, async wait + } else { # forcibly wait + my $wait = $lei->{sto}->ipc_do('done'); + } +} + +sub sto_done_complete { # called in lei-daemon when LeiStore->done is complete + my ($sock_str) = @_; + delete $LIVE_SOCK{$sock_str}; # frees {sock} for waiting lei clients +} + 1;