[exim-cvs] Bug 1334: AutoDetect compression type in exigrep

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Bug 1334: AutoDetect compression type in exigrep
Gitweb: http://git.exim.org/exim.git/commitdiff/89b68021dc688d91f57e0e20432477a57bfcf5ec
Commit:     89b68021dc688d91f57e0e20432477a57bfcf5ec
Parent:     7245734e71c1a30f1c25a2af279242de7d00c3b2
Author:     Todd Lyons <tlyons@???>
AuthorDate: Sat Oct 12 09:42:31 2013 -0700
Committer:  Todd Lyons <tlyons@???>
CommitDate: Fri Nov 8 19:07:15 2013 -0800


    Bug 1334: AutoDetect compression type in exigrep


    Does not use any extra perl modules.
    Attempts hard coded types first, so no extra code for the standard
      case.
    Easy to add more compression types.
---
 src/src/exigrep.src |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)


diff --git a/src/src/exigrep.src b/src/src/exigrep.src
index 0950b58..d22d362 100644
--- a/src/src/exigrep.src
+++ b/src/src/exigrep.src
@@ -124,6 +124,54 @@ elsif ( ($invert && (($insensitive && !/$pattern/io) || !/$pattern/o)) ||
{ print "$_\n"; }
}

+# Rotated log files are frequently compressed and there are a variety of
+# formats it could be compressed with. Rather than use just one that is
+# detected and hardcoded at Exim compile time, detect and use what the
+# logfile is compressed with on the fly.
+#
+# List of known compression extensions and their associated commands:
+my $compressors = {
+  gz   => { cmd => 'zcat',  args => '' },
+  bz2  => { cmd => 'bzcat', args => '' },
+  xz   => { cmd => 'xzcat', args => '' },
+  lzma => { cmd => 'lzma',  args => '-dc' }
+};
+my $csearch = 0;
+
+sub detect_compressor_bin
+  {
+  my $ext = shift();
+  my $c = $compressors->{$ext}->{cmd};
+  $compressors->{$ext}->{bin} = `which $c 2>/dev/null`;
+  chomp($compressors->{$ext}->{bin});
+  }
+
+sub detect_compressor_capable
+  {
+  my $filename = shift();
+  map { &detect_compressor_bin($_) } keys %$compressors
+    if (!$csearch);
+  $csearch = 1;
+  return undef
+    unless (grep {$filename =~ /\.(?:$_)$/} keys %$compressors);
+  # Loop through them, figure out which one it detected,
+  # and build the commandline.
+  my $cmdline = undef;
+  foreach my $ext (keys %$compressors)
+    {
+    if ($filename =~ /\.(?:$ext)$/)
+      {
+      # Just die if compressor not found; if this occurrs in the middle of
+      # two valid files with a lot of matches, error could easily be missed.
+      die("Didn't find $ext decompressor for $filename\n")
+        if ($compressors->{$ext}->{bin} eq '');
+      $cmdline = $compressors->{$ext}->{bin} ." ".
+                   $compressors->{$ext}->{args};
+      last;
+      }
+    }
+  return $cmdline;
+  }


 # The main program. Extract the pattern and make sure any relevant characters
 # are quoted if the -l flag is given. The -t flag gives a time-on-queue value
@@ -154,6 +202,11 @@ if (@ARGV)
       open(LOG, "ZCAT_COMMAND $filename |") ||
         die "Unable to zcat $filename: $!\n";
       }
+    elsif (my $cmdline = &detect_compressor_capable($filename))
+      {
+      open(LOG, "$cmdline $filename |") ||
+        die "Unable to decompress $filename: $!\n";
+      }
     else
       {
       open(LOG, "<$filename") || die "Unable to open $filename: $!\n";