--- grep-2.5.1a/configure.in 2002-03-26 16:48:16.000000000 +0100 +++ /home/drizzt/grep-2.5.1a/configure.in 2006-10-14 14:57:51.000000000 +0200 @@ -141,4 +141,39 @@ AC_CHECK_LIB(pcre, pcre_exec) fi +dnl check for bzip2 and zlib +AC_ARG_ENABLE(bzip2, +AC_HELP_STRING([--enable-bzip2], [Enable bzip2 support. (default: yes)]), + bzip2=$enableval, bzip2=yes) + +AC_ARG_ENABLE(gzip, +AC_HELP_STRING([--enable-gzip], [Enable gzip support. (default: yes)]), + gzip=$enableval, gzip=yes) + +dnl bz2 +if test "$bzip2" = yes; then + AC_CHECK_LIB(bz2, BZ2_bzopen, bzip_l=yes, bzip_l=no) + AC_CHECK_HEADER(bzlib.h, bzip_h=yes, bzip_h=no) + if test "$bzip_l" = yes && test "$bzip_h" = yes; then + AC_MSG_NOTICE([bzip2 support is enabled.]) + AC_DEFINE(HAVE_LIBBZ2,,[Enable bzip2 support]) + LIBS+=" -lbz2" + else + AC_MSG_NOTICE([bzip2 support is disabled.]) + fi +fi + +dnl gz +if test "$gzip" = yes; then + AC_CHECK_LIB(z, gzopen, gzip_l=yes, gzip_l=no) + AC_CHECK_HEADER(zlib.h, gzip_h=yes, gzip_h=no) + if test "$gzip_l" = yes && test "$gzip_h" = yes; then + AC_MSG_NOTICE([gzip support is enabled.]) + AC_DEFINE(HAVE_LIBZ,,[Enable gzip support]) + LIBS+=" -lz" + else + AC_MSG_NOTICE([gzip support is disabled.]) + fi +fi + AC_OUTPUT(Makefile lib/Makefile lib/posix/Makefile src/Makefile tests/Makefile po/Makefile.in intl/Makefile doc/Makefile m4/Makefile vms/Makefile bootstrap/Makefile, [sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile; echo timestamp > stamp-h]) --- grep-2.5.1a/src/grep.c 2006-10-14 15:03:03.000000000 +0200 +++ /home/drizzt/grep-2.5.1a/src/grep.c 2006-10-14 14:54:41.000000000 +0200 @@ -17,6 +17,9 @@ 02111-1307, USA. */ /* Written July 1992 by Mike Haertel. */ +/* Builtin decompression 1997 by Wolfram Schneider . */ + +/* $FreeBSD: src/gnu/usr.bin/grep/grep.c,v 1.31.2.1 2005/10/26 21:13:30 jkim Exp $ */ #ifdef HAVE_CONFIG_H # include @@ -72,6 +75,9 @@ /* If nonzero, use mmap if possible. */ static int mmap_option; +/* If zero, output nulls after filenames. */ +static int filename_mask; + /* If nonzero, use grep_color marker. */ static int color_option; @@ -86,7 +92,11 @@ static struct exclude *included_patterns; /* Short options. */ static char const short_options[] = +#if defined(HAVE_LIBBZ2) +"0123456789A:B:C:D:EFGHIJPUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz"; +#else "0123456789A:B:C:D:EFGHIPUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz"; +#endif /* Non-boolean long options that have no corresponding short equivalents. */ enum @@ -133,7 +143,15 @@ {"mmap", no_argument, &mmap_option, 1}, {"no-filename", no_argument, NULL, 'h'}, {"no-messages", no_argument, NULL, 's'}, +#if defined(HAVE_LIBBZ2) + {"bz2decompress", no_argument, NULL, 'J'}, +#endif +#if defined(HAVE_LIBZ) + {"decompress", no_argument, NULL, 'Z'}, + {"null", no_argument, &filename_mask, 0}, +#else {"null", no_argument, NULL, 'Z'}, +#endif {"null-data", no_argument, NULL, 'z'}, {"only-matching", no_argument, NULL, 'o'}, {"perl-regexp", no_argument, NULL, 'P'}, @@ -236,6 +254,17 @@ # define bufmapped 0 #endif +#if defined(HAVE_LIBBZ2) +#include +static BZFILE* bzbufdesc; /* libbz2 file handle. */ +static int BZflag; /* uncompress before searching. */ +#endif +#if defined(HAVE_LIBZ) +#include +static gzFile gzbufdesc; /* zlib file descriptor. */ +static int Zflag; /* uncompress before searching. */ +#endif + /* Return VAL aligned to the next multiple of ALIGNMENT. VAL can be an integer or a pointer. Both args must be free of side effects. */ #define ALIGN_TO(val, alignment) \ @@ -256,12 +285,48 @@ bufalloc = ALIGN_TO (INITIAL_BUFSIZE, pagesize) + pagesize + 1; buffer = xmalloc (bufalloc); } +#if defined(HAVE_LIBBZ2) + if (BZflag) + { + bzbufdesc = BZ2_bzdopen(fd, "r"); + if (bzbufdesc == NULL) + error(2, 0, _("memory exhausted")); + } +#endif +#if defined(HAVE_LIBZ) + if (Zflag) + { + gzbufdesc = gzdopen(fd, "r"); + if (gzbufdesc == NULL) + error(2, 0, _("memory exhausted")); + } +#endif bufbeg = buflim = ALIGN_TO (buffer + 1, pagesize); bufbeg[-1] = eolbyte; bufdesc = fd; - if (S_ISREG (stats->stat.st_mode)) + if (fstat (fd, &stats->stat) != 0) + { + error (0, errno, "fstat"); + return 0; + } + if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode)) + return 0; +#ifndef DJGPP + if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode) || S_ISSOCK(stats->stat.st_mode))) +#else + if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode))) +#endif + return 0; + if ( +#if defined(HAVE_LIBBZ2) + BZflag || +#endif +#if defined(HAVE_LIBZ) + Zflag || +#endif + S_ISREG (stats->stat.st_mode)) { if (file) bufoffset = 0; @@ -401,9 +466,38 @@ if (! fillsize) { ssize_t bytesread; - while ((bytesread = read (bufdesc, readbuf, readsize)) < 0 - && errno == EINTR) - continue; + do +#if defined(HAVE_LIBBZ2) + if (BZflag && bzbufdesc) + { + int bzerr; + bytesread = BZ2_bzRead (&bzerr, bzbufdesc, readbuf, readsize); + + switch (bzerr) + { + case BZ_OK: + case BZ_STREAM_END: + /* ok */ + break; + case BZ_DATA_ERROR_MAGIC: + BZ2_bzReadClose (&bzerr, bzbufdesc); bzbufdesc = NULL; + lseek (bufdesc, 0, SEEK_SET); + bytesread = read (bufdesc, readbuf, readsize); + break; + default: + bytesread = 0; + break; + } + } + else +#endif +#if defined(HAVE_LIBZ) + if (Zflag) + bytesread = gzread (gzbufdesc, readbuf, readsize); + else +#endif + bytesread = read (bufdesc, readbuf, readsize); + while (bytesread < 0 && errno == EINTR); if (bytesread < 0) cc = 0; else @@ -551,33 +645,6 @@ { size_t match_size; size_t match_offset; - if(match_icase) - { - /* Yuck, this is tricky */ - char *buf = (char*) xmalloc (lim - beg); - char *ibeg = buf; - char *ilim = ibeg + (lim - beg); - int i; - for (i = 0; i < lim - beg; i++) - ibeg[i] = tolower (beg[i]); - while ((match_offset = (*execute) (ibeg, ilim-ibeg, &match_size, 1)) - != (size_t) -1) - { - char const *b = beg + match_offset; - if (b == lim) - break; - fwrite (beg, sizeof (char), match_offset, stdout); - printf ("\33[%sm", grep_color); - fwrite (b, sizeof (char), match_size, stdout); - fputs ("\33[00m", stdout); - beg = b + match_size; - ibeg = ibeg + match_offset + match_size; - } - fwrite (beg, 1, lim - beg, stdout); - free (buf); - lastout = lim; - return; - } while (lim-beg && (match_offset = (*execute) (beg, lim - beg, &match_size, 1)) != (size_t) -1) { @@ -763,6 +830,16 @@ { /* Close fd now, so that we don't open a lot of file descriptors when we recurse deeply. */ +#if defined(HAVE_LIBBZ2) + if (BZflag && bzbufdesc) + BZ2_bzclose(bzbufdesc); + else +#endif +#if defined(HAVE_LIBZ) + if (Zflag) + gzclose(gzbufdesc); + else +#endif if (close (fd) != 0) error (0, errno, "%s", file); return grepdir (file, stats) - 2; @@ -889,19 +966,6 @@ } else { - if (stat (file, &stats->stat) != 0) - { - suppressible_error (file, errno); - return 1; - } - if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode)) - return 1; -#ifndef DJGPP - if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode) || S_ISSOCK(stats->stat.st_mode) || S_ISFIFO(stats->stat.st_mode))) -#else - if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode))) -#endif - return 1; while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR) continue; @@ -968,6 +1032,16 @@ if (list_files == 1 - 2 * status) printf ("%s%c", filename, '\n' & filename_mask); +#if defined(HAVE_LIBBZ2) + if (BZflag && bzbufdesc) + BZ2_bzclose(bzbufdesc); + else +#endif +#if defined(HAVE_LIBZ) + if (Zflag) + gzclose(gzbufdesc); + else +#endif if (! file) { off_t required_offset = outleft ? bufoffset : after_last_match; @@ -1003,7 +1077,7 @@ && ancestor->stat.st_dev == stats->stat.st_dev) { if (!suppress_errors) - error (0, 0, _("warning: %s: %s\n"), dir, + error (0, 0, _("warning: %s: %s"), dir, _("recursive directory loop")); return 1; } @@ -1084,6 +1158,8 @@ -v, --invert-match select non-matching lines\n\ -V, --version print version information and exit\n\ --help display this help and exit\n\ + -J, --bz2decompress decompress bzip2'ed input before searching\n\ + -Z, --decompress decompress input before searching\n\ --mmap use memory-mapped input if possible\n")); printf (_("\ \n\ @@ -1112,7 +1188,7 @@ -L, --files-without-match only print FILE names containing no match\n\ -l, --files-with-matches only print FILE names containing matches\n\ -c, --count only print a count of matching lines per FILE\n\ - -Z, --null print 0 byte after FILE name\n")); + --null print 0 byte after FILE name\n")); printf (_("\ \n\ Context control:\n\ @@ -1130,7 +1206,7 @@ With no FILE, or when FILE is -, read standard input. If less than\n\ two FILEs given, assume -h. Exit status is 0 if match, 1 if no match,\n\ and 2 if trouble.\n")); - printf (_("\nReport bugs to .\n")); + printf (_("\nReport bugs to .\n")); } exit (status); } @@ -1301,10 +1377,18 @@ if (program_name && strrchr (program_name, '/')) program_name = strrchr (program_name, '/') + 1; - if (!strcmp(program_name, "egrep")) - setmatcher ("egrep"); - if (!strcmp(program_name, "fgrep")) - setmatcher ("fgrep"); +#if defined(HAVE_LIBBZ2) + if (program_name[0] == 'b' && program_name[1] == 'z') { + BZflag = 1; + program_name += 2; + } +#endif +#if defined(HAVE_LIBZ) + else if (program_name[0] == 'z') { + Zflag = 1; + ++program_name; + } +#endif #if defined(__MSDOS__) || defined(_WIN32) /* DOS and MS-Windows use backslashes as directory separators, and usually @@ -1408,6 +1492,18 @@ case 'I': binary_files = WITHOUT_MATCH_BINARY_FILES; break; + case 'J': +#if defined(HAVE_LIBZ) + if (Zflag) + { + printf (_("Cannot mix -Z and -J.\n")); + usage (2); + } +#endif +#if defined(HAVE_LIBBZ2) + BZflag = 1; +#endif + break; case 'U': #if defined(HAVE_DOS_FILE_CONTENTS) @@ -1556,7 +1652,16 @@ break; case 'Z': - filename_mask = 0; +#if defined(HAVE_LIBBZ2) + if (BZflag) + { + printf (_("Cannot mix -J and -Z.\n")); + usage (2); + } +#endif +#if defined(HAVE_LIBZ) + Zflag = 1; +#endif break; case 'z': @@ -1662,7 +1767,7 @@ } if (! matcher) - matcher = "grep"; + matcher = program_name; if (show_version) {