]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/LEI.pm
lei: rename ls-sync to ls-mail-sync
[public-inbox.git] / lib / PublicInbox / LEI.pm
index 403f9ed8872a1226839d26bcf79d3e388c6baa3a..5d701d5e14e817ac0b5120eb5ed10bab28608c05 100644 (file)
@@ -144,8 +144,8 @@ our %CMD = ( # sorted in order of importance/use:
        @lxs_opt,
        qw(save output|mfolder|o=s format|f=s dedupe|d=s threads|t+
        sort|s=s reverse|r offset=i pretty jobs|j=s globoff|g augment|a
-       import-before! lock=s@ rsyncable alert=s@ mua=s verbose|v+), @c_opt,
-       opt_dash('limit|n=i', '[0-9]+') ],
+       import-before! lock=s@ rsyncable alert=s@ mua=s verbose|v+
+       color!), @c_opt, opt_dash('limit|n=i', '[0-9]+') ],
 
 'up' => [ 'OUTPUT|--all', 'update saved search',
        qw(jobs|j=s lock=s@ alert=s@ mua=s verbose|v+ all:s), @c_opt ],
@@ -155,8 +155,8 @@ our %CMD = ( # sorted in order of importance/use:
        # some of these options are ridiculous for lcat
        @lxs_opt, qw(output|mfolder|o=s format|f=s dedupe|d=s threads|t+
        sort|s=s reverse|r offset=i jobs|j=s globoff|g augment|a
-       import-before! lock=s@ rsyncable alert=s@ mua=s verbose|v+), @c_opt,
-       opt_dash('limit|n=i', '[0-9]+') ],
+       import-before! lock=s@ rsyncable alert=s@ mua=s verbose|v+
+       color!), @c_opt, opt_dash('limit|n=i', '[0-9]+') ],
 
 'blob' => [ 'OID', 'show a git blob, reconstructing from mail if necessary',
        qw(git-dir=s@ cwd! verbose|v+ mail! oid-a|A=s path-a|a=s path-b|b=s),
@@ -170,7 +170,7 @@ our %CMD = ( # sorted in order of importance/use:
 'ls-external' => [ '[FILTER]', 'list publicinbox|extindex locations',
        qw(format|f=s z|0 globoff|g invert-match|v local remote), @c_opt ],
 'ls-label' => [ '', 'list labels', qw(z|0 stats:s), @c_opt ],
-'ls-sync' => [ '', 'list sync folders',
+'ls-mail-sync' => [ '', 'list mail sync folders',
                qw(z|0 z|0 globoff|g invert-match|v local remote), @c_opt ],
 'forget-external' => [ 'LOCATION...|--prune',
        'exclude further results from a publicinbox|extindex',
@@ -188,7 +188,8 @@ our %CMD = ( # sorted in order of importance/use:
        qw(stdin| threads|t from|f=s mid=s oid=s), @c_opt ],
 'tag' => [ 'KEYWORDS...',
        'set/unset keywords and/or labels on message(s)',
-       qw(stdin| in-format|F=s input|i=s@ oid=s@ mid=s@), @c_opt,
+       qw(stdin| in-format|F=s input|i=s@ oid=s@ mid=s@),
+       qw(no-torsocks torsocks=s), PublicInbox::LeiQuery::curl_opt(), @c_opt,
        pass_through('-kw:foo for delete') ],
 'forget' => [ '[--stdin|--oid=OID|--by-mid=MID]',
        "exclude message(s) on stdin from `q' search results",
@@ -211,11 +212,12 @@ our %CMD = ( # sorted in order of importance/use:
 'import' => [ 'LOCATION...|--stdin',
        'one-time import/update from URL or filesystem',
        qw(stdin| offset=i recursive|r exclude=s include|I=s
-       lock=s@ in-format|F=s kw! verbose|v+ incremental! sync!), @c_opt ],
+       lock=s@ in-format|F=s kw! verbose|v+ incremental! mail-sync!),
+       qw(no-torsocks torsocks=s), PublicInbox::LeiQuery::curl_opt(), @c_opt ],
 'convert' => [ 'LOCATION...|--stdin',
        'one-time conversion from URL or filesystem to another format',
-       qw(stdin| in-format|F=s out-format|f=s output|mfolder|o=s
-       lock=s@ kw!), @c_opt ],
+       qw(stdin| in-format|F=s out-format|f=s output|mfolder|o=s lock=s@ kw!),
+       qw(no-torsocks torsocks=s), PublicInbox::LeiQuery::curl_opt(), @c_opt ],
 'p2q' => [ 'FILE|COMMIT_OID|--stdin',
        "use a patch to generate a query for `lei q --stdin'",
        qw(stdin| want|w=s@ uri debug), @c_opt ],
@@ -268,6 +270,7 @@ my %OPTDESC = (
 'incremental!  import' => 'import already seen IMAP and NNTP articles',
 'globoff|g' => "do not match locations using '*?' wildcards ".
                "and\xa0'[]'\x{a0}ranges",
+'color!' => 'disable color (for --format=text)',
 'verbose|v+' => 'be more verbose',
 'external!' => 'do not use externals',
 'mail!' => 'do not look in mail storage for OID',
@@ -276,6 +279,8 @@ my %OPTDESC = (
 'path-a|a=s' => 'pre-image pathname associated with OID',
 'path-b|b=s' => 'post-image pathname associated with OID',
 'git-dir=s@' => 'additional git repository to scan',
+'proxy=s' => [ 'PROTO://HOST[:PORT]', # shared with curl(1)
+       "proxy for (e.g. `socks5h://0:9050')" ],
 'torsocks=s' => ['VAL|auto|no|yes',
                'whether or not to wrap git and curl commands with torsocks'],
 'no-torsocks' => 'alias for --torsocks=no',
@@ -386,7 +391,14 @@ my @WQ_KEYS = qw(lxs l2m wq1); # internal workers
 
 sub _drop_wq {
        my ($self) = @_;
-       for my $wq (grep(defined, delete(@$self{@WQ_KEYS}))) { $wq->DESTROY }
+       for my $wq (grep(defined, delete(@$self{@WQ_KEYS}))) {
+               if ($wq->wq_kill) {
+                       $wq->wq_close(0, undef, $self);
+               } elsif ($wq->wq_kill_old) {
+                       $wq->wq_wait_old(undef, $self);
+               }
+               $wq->DESTROY;
+       }
 }
 
 # pronounced "exit": x_it(1 << 8) => exit(1); x_it(13) => SIGPIPE
@@ -486,19 +498,15 @@ sub _lei_atfork_child {
        # we need to explicitly close things which are on stack
        if ($persist) {
                chdir '/' or die "chdir(/): $!";
-               my @io = delete @$self{qw(0 1 2 sock)};
-               unless ($self->{oneshot}) {
-                       close($_) for @io;
-               }
+               close($_) for (grep(defined, delete @$self{qw(0 1 2 sock)}));
                if (my $cfg = $self->{cfg}) {
                        delete $cfg->{-lei_store};
                }
        } else { # worker, Net::NNTP (Net::Cmd) uses STDERR directly
                open STDERR, '+>&='.fileno($self->{2}) or warn "open $!";
+               STDERR->autoflush(1);
        }
-       for (delete @$self{qw(3 old_1 au_done)}) {
-               close($_) if defined($_);
-       }
+       close($_) for (grep(defined, delete @$self{qw(3 old_1 au_done)}));
        if (my $op_c = delete $self->{pkt_op_c}) {
                close(delete $op_c->{sock});
        }
@@ -673,6 +681,7 @@ sub lazy_cb ($$$) {
 sub dispatch {
        my ($self, $cmd, @argv) = @_;
        local $current_lei = $self; # for __WARN__
+       $self->{2}->autoflush(1); # keep stdout buffered until x_it|DESTROY
        dump_and_clear_log("from previous run\n");
        return _help($self, 'no command given') unless defined($cmd);
        # do not support Getopt bundling for this
@@ -1003,7 +1012,6 @@ sub accept_dispatch { # Listener {post_accept} callback
                }
                $i == 4 or return send($sock, 'not enough FDs='.($i-1), MSG_EOR)
        }
-       $self->{2}->autoflush(1); # keep stdout buffered until x_it|DESTROY
        # $ENV_STR = join('', map { "\0$_=$ENV{$_}" } keys %ENV);
        # $buf = "$argc\0".join("\0", @ARGV).$ENV_STR."\0\0";
        substr($buf, -2, 2, '') eq "\0\0" or  # s/\0\0\z//
@@ -1212,13 +1220,8 @@ sub oneshot {
        local $quit = $exit if $exit;
        local %PATH2CFG;
        umask(077) // die("umask(077): $!");
-       my $self = bless {
-               oneshot => 1,
-               0 => *STDIN{GLOB},
-               1 => *STDOUT{GLOB},
-               2 => *STDERR{GLOB},
-               env => \%ENV
-       }, __PACKAGE__;
+       my $self = bless { oneshot => 1, env => \%ENV }, __PACKAGE__;
+       for (0..2) { open($self->{$_}, '+<&=', $_) or die "open fd=$_: $!" }
        dispatch($self, @ARGV);
        x_it($self, $self->{child_error}) if $self->{child_error};
 }