1#!/bin/sh
2#
3# Copyright (c) 2003 Thomas Klausner.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8# 1. Redistributions of source code must retain the above copyright
9#    notice, this list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright
11#    notice, this list of conditions and the following disclaimer in the
12#    documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24#
25
26set -u
27grep=grep
28zcat=zstdcat
29
30endofopts=0
31pattern_file=0
32pattern_found=0
33grep_args=""
34hyphen=0
35silent=0
36
37prg=${0##*/}
38
39# handle being called 'zegrep' or 'zfgrep'
40case ${prg} in
41*egrep)
42	grep_args="-E";;
43*fgrep)
44	grep_args="-F";;
45esac
46
47catargs="-f"
48case ${prg} in
49zstd*)
50	cattool="/usr/bin/zstdcat"
51	catargs="-fq"
52	;;
53bz*)
54	cattool="/usr/bin/bzcat"
55	;;
56z*)
57	cattool="/usr/bin/zcat"
58	;;
59xz*)
60	cattool="/usr/bin/xzcat"
61	;;
62lz*)
63	cattool="/usr/bin/lzcat"
64	;;
65*)
66	echo "Invalid command: ${prg}" >&2
67	exit 1
68	;;
69esac
70
71# skip all options and pass them on to grep taking care of options
72# with arguments, and if -e was supplied
73
74while [ $# -gt 0 -a ${endofopts} -eq 0 ]
75do
76    case $1 in
77    # from GNU grep-2.5.1 -- keep in sync!
78	--)
79	    shift
80	    endofopts=1
81	    ;;
82	--file=*)
83	    pattern_file=1
84	    grep_args="${grep_args} ${1}"
85	    shift
86	    ;;
87	--regexp=*)
88	    pattern="${1#--regexp=}"
89	    pattern_found=1
90	    shift
91	    ;;
92	-h|--no-filename)
93	    silent=1
94	    shift
95	    ;;
96	-V|--version)
97	    exec ${grep} -V
98	    ;;
99	--*)
100	    grep_args="${grep_args} $1"
101	    shift
102	    ;;
103	-*[ABCDXdefm])
104	    if [ $# -lt 2 ]
105		then
106		echo "${prg}: missing argument for $1 flag" >&2
107		exit 1
108	    fi
109	    case $1 in
110		-*e)
111		    pattern="$2"
112		    pattern_found=1
113		    shift 2
114		    continue
115		    ;;
116		-*f)
117		    pattern_file=1
118		    ;;
119		*)
120		    ;;
121	    esac
122	    grep_args="${grep_args} $1 $2"
123	    shift 2
124	    ;;
125	-)
126	    hyphen=1
127	    shift
128	    ;;
129	-r|-R)
130	    echo "${prg}: the ${1} flag is not currently supported" >&2
131	    exit 1
132	    ;;
133	-*)
134	    grep_args="${grep_args} $1"
135	    shift
136	    ;;
137	*)
138	    # pattern to grep for
139	    endofopts=1
140	    ;;
141    esac
142done
143
144# if no -e option was found, take next argument as grep-pattern
145if [ ${pattern_file} -eq 0 -a ${pattern_found} -eq 0 ]
146then
147    if [ $# -ge 1 ]; then
148	pattern="$1"
149	shift
150    elif [ ${hyphen} -gt 0 ]; then
151	pattern="-"
152    else
153	echo "${prg}: missing pattern" >&2
154	exit 1
155    fi
156    pattern_found=1
157fi
158
159# call grep ...
160if [ $# -lt 1 ]
161then
162    # ... on stdin
163    if [ ${pattern_file} -eq 0 ]; then
164	${cattool} ${catargs} - | ${grep} ${grep_args} -- "${pattern}" -
165    else
166	${cattool} ${catargs} - | ${grep} ${grep_args} -- -
167    fi
168    ret=$?
169else
170    # ... on all files given on the command line
171    if [ ${silent} -lt 1 -a $# -gt 1 ]; then
172	grep_args="-H ${grep_args}"
173    fi
174    # Succeed if any file matches.  First assume no match.
175    ret=1
176    for file; do
177	if [ ${pattern_file} -eq 0 ]; then
178	    ${cattool} ${catargs} -- "${file}" |
179		${grep} --label="${file}" ${grep_args} -- "${pattern}" -
180	else
181	    ${cattool} ${catargs} -- "${file}" |
182		${grep} --label="${file}" ${grep_args} -- -
183	fi
184	this_ret=$?
185	# A match (0) overrides a no-match (1).  An error (>=2) overrides all.
186	if [ ${this_ret} -eq 0 -a ${ret} -eq 1 ] || [ ${this_ret} -ge 2 ]; then
187	    ret=${this_ret}
188	fi
189    done
190fi
191
192exit ${ret}
193