summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gnu/usr.bin/grep/Makefile16
-rw-r--r--gnu/usr.bin/grep/grep.116
-rw-r--r--gnu/usr.bin/grep/grep.c166
3 files changed, 131 insertions, 67 deletions
diff --git a/gnu/usr.bin/grep/Makefile b/gnu/usr.bin/grep/Makefile
index 0cfcf6b..40aafc0 100644
--- a/gnu/usr.bin/grep/Makefile
+++ b/gnu/usr.bin/grep/Makefile
@@ -1,8 +1,13 @@
+# $Id$
+
+GREP_LIBZ= YES
+GREP_FTS= YES
+
PROG= grep
SRCS= dfa.c grep.c getopt.c kwset.c obstack.c search.c
CFLAGS+=-DGREP -DHAVE_STRING_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_UNISTD_H=1 \
-DHAVE_GETPAGESIZE=1 -DHAVE_MEMCHR=1 -DHAVE_STRERROR=1 \
- -DHAVE_VALLOC=1 -DHAVE_MMAP=1 -DHAVE_FTS=1
+ -DHAVE_VALLOC=1
LINKS+= ${BINDIR}/grep ${BINDIR}/egrep \
${BINDIR}/grep ${BINDIR}/fgrep
@@ -11,6 +16,15 @@ MLINKS= grep.1 egrep.1 grep.1 fgrep.1
DPADD+= ${LIBGNUREGEX}
LDADD+= -lgnuregex
+.if defined(GREP_LIBZ) && !empty(GREP_LIBZ)
+LDADD+= -lz
+DPADD+= ${LIBZ}
+CFLAGS+= -DHAVE_LIBZ=1
+.endif
+.if defined(GREP_FTS) && !empty(GREP_FTS)
+CFLAGS+= -DHAVE_FTS=1
+.endif
+
check: all
sh ${.CURDIR}/tests/check.sh ${.CURDIR}/tests
diff --git a/gnu/usr.bin/grep/grep.1 b/gnu/usr.bin/grep/grep.1
index 1a7d621..75a15a7 100644
--- a/gnu/usr.bin/grep/grep.1
+++ b/gnu/usr.bin/grep/grep.1
@@ -161,7 +161,7 @@ characters are letters, digits, and the underscore.
Select only those matches that exactly match the whole line.
.PP
-Following options only available if compiled with FTS library:
+Following options are only available if compiled with FTS library:
.PD 0
.TP
.BI \-H
@@ -171,24 +171,30 @@ option is specified, symbolic links on the command line
are followed. (Symbolic links encountered in the tree traversal
are not followed.)
.TP
-
.BI \-L
If the
.I \-R
option is specified, all symbolic links are followed.
.TP
-
.BI \-P
If the
.I \-R
option is specified, no symbolic links are followed.
.TP
-
.BI \-R
Search in the file hierarchies
rooted in the files instead of just the files themselves.
-.TP
+.LP
+Following option is only available if compiled with zlib library:
+.PD 0
+.TP
+.BI \-Z
+If the
+.I \-Z
+option is specified, the input data will be
+decompressed before searching.
+.TP
.PD
.SH "REGULAR EXPRESSIONS"
.PP
diff --git a/gnu/usr.bin/grep/grep.c b/gnu/usr.bin/grep/grep.c
index 8e93267..82a8403 100644
--- a/gnu/usr.bin/grep/grep.c
+++ b/gnu/usr.bin/grep/grep.c
@@ -15,7 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- Written July 1992 by Mike Haertel. */
+ Written July 1992 by Mike Haertel.
+
+ Recursive searching and builtin decompression (libz)
+ 1996/1997 by Wolfram Schneider <wosch@FreeBSD.org>. */
#include <errno.h>
#include <stdio.h>
@@ -96,7 +99,7 @@ memchr(vp, c, n)
#endif
/* traverse a file hierarchy library */
-#ifdef HAVE_FTS
+#if HAVE_FTS > 0
#include <sys/types.h>
#include <sys/stat.h>
#include <fts.h>
@@ -211,6 +214,12 @@ static struct stat bufstat; /* From fstat(). */
static off_t bufoffset; /* What read() normally remembers. */
#endif
+#if HAVE_LIBZ > 0
+#include <zlib.h>
+static gzFile gzbufdesc; /* zlib file descriptor. */
+static int Zflag; /* uncompress before searching */
+#endif
+
/* Reset the buffer for a new file. Initialize
on the first time through. */
void
@@ -237,9 +246,20 @@ reset(fd)
bufbeg = buffer;
buflim = buffer;
}
- bufdesc = fd;
+#if HAVE_LIBZ > 0
+ if (Zflag) {
+ gzbufdesc = gzdopen(fd, "r");
+ if (gzbufdesc == NULL)
+ fatal("memory exhausted", 0);
+ }
+#endif
+ bufdesc = fd;
#if defined(HAVE_WORKING_MMAP)
- if (fstat(fd, &bufstat) < 0 || !S_ISREG(bufstat.st_mode))
+ if (
+#if HAVE_LIBZ > 0
+ Zflag ||
+#endif
+ fstat(fd, &bufstat) < 0 || !S_ISREG(bufstat.st_mode))
bufmapped = 0;
else
{
@@ -323,10 +343,20 @@ fillbuf(save)
bufmapped = 0;
lseek(bufdesc, bufoffset, 0);
}
- cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
+#if HAVE_LIBZ > 0
+ if (Zflag)
+ cc = gzread(gzbufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
+ else
+#endif
+ cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
}
#else
- cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
+#if HAVE_LIBZ > 0
+ if (Zflag)
+ cc = gzread(gzbufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
+ else
+#endif
+ cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
#endif
if (cc > 0)
buflim = buffer + bufsalloc + cc;
@@ -513,32 +543,22 @@ grepbuf(beg, lim)
/*
- * try to guess if fd belong to a binary file
+ * try to guess if buf belong to a binary file
*/
-int isBinaryFile(fd)
- int fd;
+int isBinaryFile(buf, len)
+ char *buf;
+ int len;
{
#define BINARY_BUF_LEN 32
- static unsigned char buf[BINARY_BUF_LEN];
- int i, n;
-
- /* pipe, socket, fifo */
- if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1)
- return(0);
+ int i;
- if ((n =(int) read(fd, buf, (size_t)BINARY_BUF_LEN)) == -1)
- return(0);
+ len = (len < BINARY_BUF_LEN ? len : BINARY_BUF_LEN);
/* look for non-printable chars */
- for(i = 0; i < n; i++)
- if (!isprint((unsigned char)buf[i]) && !isspace((unsigned char)buf[i]))
+ for(i = 0; i < len; i++, buf++)
+ if (!isprint(*buf) && !isspace(*buf))
return(1);
-
- /* reset fd to begin of file */
- if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1)
- return(0);
-
return(0);
}
@@ -553,10 +573,7 @@ grep(fd)
int nlines, i;
size_t residue, save;
char *beg, *lim;
-
- /* skip binary files */
- if (aflag && isBinaryFile(fd))
- return(0);
+ int first, cc;
reset(fd);
@@ -568,14 +585,22 @@ grep(fd)
nlines = 0;
residue = 0;
save = 0;
+ first = 0;
+ cc = 0;
for (;;)
{
- if (fillbuf(save) < 0)
+ if ((cc = fillbuf(save)) < 0)
{
error(filename, errno);
return nlines;
}
+
+ /* skip binary files */
+ if (!first && aflag && isBinaryFile(bufbeg, cc))
+ return(0);
+ first++;
+
lastnl = bufbeg;
if (lastout)
lastout = bufbeg;
@@ -620,21 +645,25 @@ grep(fd)
}
static char version[] = "GNU grep version 2.0";
-
-#ifdef HAVE_FTS
-#define USAGE \
-"usage: %s [-[AB] <num>] [-HRPS] [-CEFGLVabchilnqsvwx]\n\
- [-e <expr>] [-f file] [files ...]\n"
+
+#define GETOPT_STD "0123456789A:B:CEFGLVX:abce:f:hilnqsvwxy"
+#if HAVE_FTS > 0
+#define GETOPT_FTS "HPRS"
+#else
+#define GETOPT_FTS ""
+#endif
+#if HAVE_LIBZ > 0
+#define GETOPT_Z "Z"
#else
-#define USAGE \
-"usage: %s [-[AB] <num>] [-CEFGLVabchilnqsvwx]\n\
- [-e <expr>] [-f file] [files ...]\n"
+#define GETOPT_Z ""
#endif
static void
usage()
{
- fprintf(stderr, USAGE, prog);
+ fprintf(stderr, "usage: %s [-[AB] <num>] [-CEFGLVX%s%s%s",
+ prog, GETOPT_FTS, GETOPT_Z,
+ "abchilnqsvwxy]\n [-e <expr>] [-f file] [files ...]\n");
exit(2);
}
@@ -656,6 +685,8 @@ setmatcher(name)
return 0;
}
+
+
int
main(argc, argv)
int argc;
@@ -668,7 +699,7 @@ main(argc, argv)
FILE *fp;
extern char *optarg;
extern int optind;
-#ifdef HAVE_FTS
+#if HAVE_FTS > 0
int Rflag, Hflag, Pflag, Lflag;
FTS *ftsp;
FTSENT *ftsent;
@@ -691,19 +722,12 @@ main(argc, argv)
suppress_errors = 0;
matcher = NULL;
aflag = 0;
-#ifdef HAVE_FTS
+#if HAVE_FTS > 0
Rflag = Hflag = Pflag = Lflag = 0;
#endif
while ((opt = getopt(argc, argv,
-
-#ifndef HAVE_FTS
-"0123456789A:B:CEFGVX:abce:f:hiLlnqsvwxy"
-#else
-"0123456789A:B:CEFGHLPRSVX:abce:f:hiLlnqsvwxy?"
-#endif
-
-)) != EOF)
+ GETOPT_STD/**/GETOPT_FTS/**/GETOPT_Z)) != -1)
switch (opt)
{
case '0':
@@ -755,8 +779,12 @@ main(argc, argv)
fatal("matcher already specified", 0);
matcher = optarg;
break;
-
-#ifdef HAVE_FTS
+#if HAVE_LIBZ > 0
+ case 'Z':
+ Zflag = 1;
+ break;
+#endif
+#if HAVE_FTS > 0
/* symbolic links on the command line are followed */
case 'H':
Hflag = 1;
@@ -880,16 +908,16 @@ main(argc, argv)
(*compile)(keys, keycc);
-#ifndef HAVE_FTS
- if (argc - optind > 1 && !no_filenames)
-#else
+#if HAVE_FTS > 0
if ((argc - optind > 1 || Rflag) && !no_filenames)
+#else
+ if (argc - optind > 1 && !no_filenames)
#endif
out_file = 1;
status = 1;
-#if HAVE_FTS
+#if HAVE_FTS > 0
if (Rflag) {
fts_options = FTS_PHYSICAL | FTS_NOCHDIR;
@@ -984,8 +1012,14 @@ main(argc, argv)
else if (list_files == -1)
printf("%s\n", filename);
- if (desc != STDIN_FILENO)
+ if (desc != STDIN_FILENO) {
+#if HAVE_LIBZ > 0
+ if (Zflag)
+ gzclose(gzbufdesc);
+ else
+#endif
close(desc);
+ }
}
if (fts_close(ftsp) == -1)
@@ -1002,7 +1036,8 @@ main(argc, argv)
while (optind < argc)
{
- desc = strcmp(argv[optind], "-") ? open(argv[optind], O_RDONLY) : 0;
+ desc = strcmp(argv[optind], "-") ?
+ open(argv[optind], O_RDONLY) : STDIN_FILENO;
if (desc < 0)
{
if (!suppress_errors)
@@ -1010,7 +1045,8 @@ main(argc, argv)
}
else
{
- filename = desc == 0 ? "(standard input)" : argv[optind];
+ filename = desc == STDIN_FILENO ?
+ "(standard input)" : argv[optind];
count = grep(desc);
if (count_matches)
{
@@ -1026,9 +1062,17 @@ main(argc, argv)
}
else if (list_files == -1)
printf("%s\n", filename);
- }
- if (desc != 0)
- close(desc);
+
+ if (desc != STDIN_FILENO) {
+#if HAVE_LIBZ > 0
+ if (Zflag)
+ gzclose(gzbufdesc);
+ else
+#endif
+ close(desc);
+
+ }
+ }
++optind;
}
@@ -1036,7 +1080,7 @@ main(argc, argv)
else
{
filename = "(standard input)";
- count = grep(0);
+ count = grep(STDIN_FILENO);
if (count_matches)
printf("%d\n", count);
if (count)
OpenPOWER on IntegriCloud