Package: grep
Version: 2.5.3~dfsg-6
Severity: minor
Tags: patch

Attached is a patch against grep CVS to support transparent decompression.

This is on the grep to-do list and has been accepted in principle for
inclusion upstream, but I'm posting it here because that was two years
ago, and I'm still waiting for upstream to answer questions (I do remind
them from time to time!). It would be nice if it could be offered to at
least some users before then.

The Savannah item tracking this is https://savannah.gnu.org/patch/?6107

I attach the current version of the patch. At the moment it only patches
the code; if you're interested in applying it I'll be happy to write a
documentation patch too.

-- System Information:
Debian Release: 5.0.1
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-1-686 (SMP w/1 CPU core)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages grep depends on:
ii  libc6                         2.7-18     GNU C Library: Shared libraries

grep recommends no packages.

grep suggests no packages.

-- no debconf information
? INSTALL
? automake.patch
? config.guess
? config.status.lineno
? config.sub
? depcomp
? install-sh
? mkinstalldirs
? doc/mdate-sh
? doc/texinfo.tex
Index: configure.ac.in
===================================================================
RCS file: /sources/grep/grep/configure.ac.in,v
retrieving revision 1.14
diff -u -r1.14 configure.ac.in
--- configure.ac.in	10 Feb 2009 05:51:34 -0000	1.14
+++ configure.ac.in	8 May 2009 12:32:38 -0000
@@ -37,6 +37,14 @@
   *)   AC_MSG_ERROR(bad value ${enableval} for --disable-perl-regexp) ;;
  esac],[testpcre=yes])
 
+AC_ARG_ENABLE(decompress,
+ [  --disable-decompress            disable decompress],
+ [case "${enableval}" in
+  yes) testzlib=yes ;;
+  no)  testzlib=no ;;
+  *)   AC_MSG_ERROR(bad value ${enableval} for --disable-decompress) ;;
+ esac],[testzlib=yes])
+
 dnl Checks for programs.
 AC_CANONICAL_HOST
 AC_PROG_AWK
@@ -139,7 +147,7 @@
 dnl knows that the grep may be invoked on other hosts with buggy libraries,
 dnl then the installer should configure --with-included-regex.
 if test "$jm_with_regex" = no; then
-	AC_MSG_WARN(Included lib/regex.c not used)
+        AC_MSG_WARN(Included lib/regex.c not used)
 fi
 
 dnl These are the prerequisite macros for GNU's error.c file.
@@ -153,23 +161,28 @@
 
 # support for pcre
 if test x"$testpcre" = x"yes"; then
-	if pcre-config --cflags >/dev/null 2>&1; then
-		CPPFLAGS="$CPPFLAGS `pcre-config --cflags`"
-		LIBS="$LIBS `pcre-config --libs`"
-	fi
-	AC_CHECK_LIB(pcre, pcre_exec)
+        if pcre-config --cflags >/dev/null 2>&1; then
+                CPPFLAGS="$CPPFLAGS `pcre-config --cflags`"
+                LIBS="$LIBS `pcre-config --libs`"
+        fi
+        AC_CHECK_LIB(pcre, pcre_exec)
+fi
+
+# support for zlib
+if test x"$testzlib" = x"yes"; then
+        AC_CHECK_LIB(z, gzdopen)
 fi
 
 AC_CONFIG_FILES([Makefile
-				 lib/Makefile
-				 lib/posix/Makefile
-				 src/Makefile
-				 tests/Makefile
-				 po/Makefile.in
-				 intl/Makefile
-				 doc/Makefile
-				 m4/Makefile
-				 vms/Makefile
-				 bootstrap/Makefile])
+                                 lib/Makefile
+                                 lib/posix/Makefile
+                                 src/Makefile
+                                 tests/Makefile
+                                 po/Makefile.in
+                                 intl/Makefile
+                                 doc/Makefile
+                                 m4/Makefile
+                                 vms/Makefile
+                                 bootstrap/Makefile])
 AC_CONFIG_COMMANDS([stamp-h], [echo timestamp > stamp-h])
 AC_OUTPUT
Index: src/grep.c
===================================================================
RCS file: /sources/grep/grep/src/grep.c,v
retrieving revision 1.132
diff -u -r1.132 grep.c
--- src/grep.c	1 Feb 2009 22:09:26 -0000	1.132
+++ src/grep.c	8 May 2009 12:32:39 -0000
@@ -37,6 +37,10 @@
 # include <wctype.h>
 #endif
 #include <stdio.h>
+#if defined(HAVE_LIBZ)
+# include <zlib.h>
+# include <dlfcn.h>
+#endif
 #include "system.h"
 #include "getopt.h"
 #include "getpagesize.h"
@@ -48,6 +52,28 @@
 #include "exclude.h"
 #include "closeout.h"
 
+
+#if defined(HAVE_LIBZ)
+static int (*dl_gzdopen)(int fd, const char *mode);
+
+static int map_libz(void)
+{
+  static int library_mapped = 0;
+  void *library;
+
+  if (library_mapped)
+    return 0;
+
+  library = dlopen("libz.so", RTLD_NOW);
+
+  if (!(dl_gzdopen = dlsym(library, "gzdopen")))
+    return -1;
+
+  library_mapped = 1;
+  return 0;
+}
+#endif
+
 #undef MAX
 #define MAX(A,B) ((A) > (B) ? (A) : (B))
 
@@ -82,6 +108,9 @@
 /* If nonzero, show only the part of a line matching the expression. */
 static int only_matching;
 
+/* Auto-decompress. */
+static int do_decompress;
+
 /* If nonzero, make sure first content char in a line is on a tab stop. */
 static int align_tabs;
 
@@ -284,7 +313,8 @@
   EXCLUDE_FROM_OPTION,
   LINE_BUFFERED_OPTION,
   LABEL_OPTION,
-  EXCLUDE_DIRECTORY_OPTION
+  EXCLUDE_DIRECTORY_OPTION,
+  DECOMPRESS_OPTION
 };
 
 /* Long options equivalences. */
@@ -337,6 +367,7 @@
   {"text", no_argument, NULL, 'a'},
   {"binary", no_argument, NULL, 'U'},
   {"unix-byte-offsets", no_argument, NULL, 'u'},
+  {"decompress", no_argument, NULL, DECOMPRESS_OPTION},
   {"version", no_argument, NULL, 'V'},
   {"with-filename", no_argument, NULL, 'H'},
   {"word-regexp", no_argument, NULL, 'w'},
@@ -421,6 +452,7 @@
 static off_t after_last_match;	/* Pointer after last matching line that
 				   would have been output if we were
 				   outputting characters. */
+static gzFile bufgz;		/* zlib compressed file descriptor. */
 
 #if defined(HAVE_MMAP)
 static int bufmapped;		/* True if buffer is memory-mapped.  */
@@ -478,6 +510,22 @@
       bufmapped = 0;
 #endif
     }
+
+#if defined(HAVE_LIBZ)
+  if (do_decompress)
+    {
+      if (map_libz())
+          error (2, 0, _("--decompress is not supported"));
+      bufgz = dl_gzdopen (fd, "rb");
+      if (bufgz == NULL)
+        {
+          if (errno != 0)
+            error (0, errno, "gzdopen");
+          return 0;
+        }
+    }
+#endif
+
   return 1;
 }
 
@@ -594,8 +642,8 @@
   if (! fillsize)
     {
       ssize_t bytesread;
-      while ((bytesread = read (bufdesc, readbuf, readsize)) < 0
-	     && errno == EINTR)
+      while ((bytesread = ((bufgz ? gzread (bufgz, readbuf, readsize) : read (bufdesc, readbuf, readsize)))) < 0
+             && errno == EINTR)
 	continue;
       if (bytesread < 0)
 	cc = 0;
@@ -1321,14 +1369,16 @@
 	    error (0, errno, "%s", filename);
 	}
       else
-	while (close (desc) != 0)
-	  if (errno != EINTR)
-	    {
-	      error (0, errno, "%s", file);
-	      break;
-	    }
+        while ((bufgz ? gzclose (bufgz) : close (desc)) != 0)
+          if (errno != EINTR)
+            {
+              error (0, errno, "%s", file);
+              break;
+            }
     }
 
+  bufgz = NULL;
+
   return status;
 }
 
@@ -1341,7 +1391,7 @@
   if ( excluded_directory_patterns &&
        excluded_filename (excluded_directory_patterns, dir, 0)  ) {
        return 1;
-  }	
+  }
 
 
   /* Mingw32 does not support st_ino.  No known working hosts use zero
@@ -1464,6 +1514,7 @@
                             TYPE is `binary', `text', or `without-match'\n\
   -a, --text                equivalent to --binary-files=text\n\
   -I                        equivalent to --binary-files=without-match\n\
+      --decompress          decompress compressed input\n\
   -d, --directories=ACTION  how to handle directories;\n\
                             ACTION is `read', `recurse', or `skip'\n\
   -D, --devices=ACTION      how to handle devices, FIFOs and sockets;\n\
@@ -1909,6 +1960,10 @@
 
       case 'X': /* undocumented on purpose */
 	setmatcher (optarg);
+        break;
+
+      case DECOMPRESS_OPTION:
+        do_decompress = 1;
 	break;
 #endif /* GREP_PROGRAM */
 
@@ -2130,15 +2185,15 @@
         if (!excluded_directory_patterns)
 	  excluded_directory_patterns = new_exclude ();
 	add_exclude (excluded_directory_patterns, optarg);
-        break;	
-	
+        break;
+
       case INCLUDE_OPTION:
 	if (!included_patterns)
 	  included_patterns = new_exclude ();
 	add_exclude (included_patterns, optarg);
 	break;
-	
-	
+
+
 
       case LINE_BUFFERED_OPTION:
 	line_buffered = 1;

Reply via email to