X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FMboxReader.pm;h=beffabe8e55c3160a14afb74dfc3b3276c7a94cc;hb=23af251dd607c4e75ab1e68063f2c885c48cc035;hp=9291f00b67145b84c5de7d43dc7504e9be59d56b;hpb=49b036771ef3bf45cdbfd90ac282dd922f9ad5ac;p=public-inbox.git diff --git a/lib/PublicInbox/MboxReader.pm b/lib/PublicInbox/MboxReader.pm index 9291f00b..beffabe8 100644 --- a/lib/PublicInbox/MboxReader.pm +++ b/lib/PublicInbox/MboxReader.pm @@ -41,7 +41,7 @@ sub _mbox_from { $raw =~ s/^\r?\n\z//ms; $raw =~ s/$from_re/$1/gms; my $eml = PublicInbox::Eml->new(\$raw); - $eml_cb->($eml, @arg); + $eml_cb->($eml, @arg) if $eml->raw_size; } return if $r == 0; # EOF } @@ -96,6 +96,7 @@ sub _mbox_cl ($$$;@) { $$hdr =~ s/\A[\r\n]*From [^\n]*\n//s or die "E: no 'From ' line in:\n", Dumper($hdr); my $eml = PublicInbox::Eml->new($hdr); + next unless $eml->raw_size; my @cl = $eml->header_raw('Content-Length'); my $n = scalar(@cl); $n == 0 and die "E: Content-Length missing in:\n", @@ -143,7 +144,7 @@ sub reads { # { foo => '' } means "--foo" is passed to the command-line, # otherwise { foo => '--bar' } passes "--bar" my %zsfx2cmd = ( - gz => [ qw(GZIP pigz gzip), { rsyncable => '' } ], + gz => [ qw(GZIP pigz gzip) ], bz2 => [ 'bzip2', {} ], xz => [ 'xz', {} ], # don't add new entries here unless MUA support is widely available @@ -159,7 +160,7 @@ sub zsfx2cmd ($$$) { my ($zsfx, $decompress, $lei) = @_; my $x = $zsfx2cmd{$zsfx} // die "BUG: no support for suffix=.$zsfx"; my @info = @$x; - my $cmd_opt = pop @info; + my $cmd_opt = ref($info[-1]) ? pop(@info) : undef; my @cmd = (undef, $decompress ? qw(-dc) : qw(-c)); require PublicInbox::Spawn; for my $exe (@info) { @@ -171,9 +172,23 @@ sub zsfx2cmd ($$$) { $cmd[0] = PublicInbox::Spawn::which($exe) and last; } $cmd[0] // die join(' or ', @info)." missing for .$zsfx"; - # push @cmd, @{$cmd_opt->{-default}} if $cmd_opt->{-default}; - for my $bool (qw(rsyncable)) { - my $switch = $cmd_opt->{rsyncable} // next; + + # not all gzip support --rsyncable, FreeBSD gzip doesn't even exit + # with an error code + if (!$decompress && $cmd[0] =~ m!/gzip\z! && !defined($cmd_opt)) { + pipe(my ($r, $w)) or die "pipe: $!"; + open my $null, '+>', '/dev/null' or die "open: $!"; + my $rdr = { 0 => $null, 1 => $null, 2 => $w }; + my $tst = [ $cmd[0], '--rsyncable' ]; + my $pid = PublicInbox::Spawn::spawn($tst, undef, $rdr); + close $w; + my $err = do { local $/; <$r> }; + waitpid($pid, 0) == $pid or die "BUG: waitpid: $!"; + $cmd_opt = $err ? {} : { rsyncable => '' }; + push(@$x, $cmd_opt); + } + for my $bool (keys %$cmd_opt) { + my $switch = $cmd_opt->{$bool} // next; push @cmd, '--'.($switch || $bool); } for my $key (qw(rsyncable)) { # support compression level?