xref: /onnv-gate/usr/src/cmd/grep/grep.c (revision 0)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate /*	Copyright (c) 1987, 1988 Microsoft Corporation	*/
31*0Sstevel@tonic-gate /*	  All Rights Reserved	*/
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate /*
36*0Sstevel@tonic-gate  * grep -- print lines matching (or not matching) a pattern
37*0Sstevel@tonic-gate  *
38*0Sstevel@tonic-gate  *	status returns:
39*0Sstevel@tonic-gate  *		0 - ok, and some matches
40*0Sstevel@tonic-gate  *		1 - ok, but no matches
41*0Sstevel@tonic-gate  *		2 - some error
42*0Sstevel@tonic-gate  */
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate #include <sys/types.h>
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate #include <ctype.h>
47*0Sstevel@tonic-gate #include <fcntl.h>
48*0Sstevel@tonic-gate #include <locale.h>
49*0Sstevel@tonic-gate #include <memory.h>
50*0Sstevel@tonic-gate #include <regexpr.h>
51*0Sstevel@tonic-gate #include <stdio.h>
52*0Sstevel@tonic-gate #include <stdlib.h>
53*0Sstevel@tonic-gate #include <string.h>
54*0Sstevel@tonic-gate #include <unistd.h>
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate static const char * const errstr[] = {
57*0Sstevel@tonic-gate 	"Range endpoint too large.",
58*0Sstevel@tonic-gate 	"Bad number.",
59*0Sstevel@tonic-gate 	"``\\digit'' out of range.",
60*0Sstevel@tonic-gate 	"No remembered search string.",
61*0Sstevel@tonic-gate 	"\\( \\) imbalance.",
62*0Sstevel@tonic-gate 	"Too many \\(.",
63*0Sstevel@tonic-gate 	"More than 2 numbers given in \\{ \\}.",
64*0Sstevel@tonic-gate 	"} expected after \\.",
65*0Sstevel@tonic-gate 	"First number exceeds second in \\{ \\}.",
66*0Sstevel@tonic-gate 	"[ ] imbalance.",
67*0Sstevel@tonic-gate 	"Regular expression overflow.",
68*0Sstevel@tonic-gate 	"Illegal byte sequence.",
69*0Sstevel@tonic-gate 	"Unknown regexp error code!!",
70*0Sstevel@tonic-gate 	NULL
71*0Sstevel@tonic-gate };
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate #define	errmsg(msg, arg)	(void) fprintf(stderr, gettext(msg), arg)
74*0Sstevel@tonic-gate #define	BLKSIZE	512
75*0Sstevel@tonic-gate #define	GBUFSIZ	8192
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate static int	temp;
78*0Sstevel@tonic-gate static long long	lnum;
79*0Sstevel@tonic-gate static char	*linebuf;
80*0Sstevel@tonic-gate static char	*prntbuf = NULL;
81*0Sstevel@tonic-gate static long	fw_lPrntBufLen = 0;
82*0Sstevel@tonic-gate static int	nflag;
83*0Sstevel@tonic-gate static int	bflag;
84*0Sstevel@tonic-gate static int	lflag;
85*0Sstevel@tonic-gate static int	cflag;
86*0Sstevel@tonic-gate static int	vflag;
87*0Sstevel@tonic-gate static int	sflag;
88*0Sstevel@tonic-gate static int	iflag;
89*0Sstevel@tonic-gate static int	wflag;
90*0Sstevel@tonic-gate static int	hflag;
91*0Sstevel@tonic-gate static int	errflg;
92*0Sstevel@tonic-gate static int	nfile;
93*0Sstevel@tonic-gate static long long	tln;
94*0Sstevel@tonic-gate static int	nsucc;
95*0Sstevel@tonic-gate static int	nlflag;
96*0Sstevel@tonic-gate static char	*ptr, *ptrend;
97*0Sstevel@tonic-gate static char	*expbuf;
98*0Sstevel@tonic-gate 
99*0Sstevel@tonic-gate static void	execute(char *);
100*0Sstevel@tonic-gate static void	regerr(int);
101*0Sstevel@tonic-gate static int	succeed(char *);
102*0Sstevel@tonic-gate 
103*0Sstevel@tonic-gate int
104*0Sstevel@tonic-gate main(
105*0Sstevel@tonic-gate     int		argc,
106*0Sstevel@tonic-gate     char 	**argv)
107*0Sstevel@tonic-gate {
108*0Sstevel@tonic-gate 	int	c;
109*0Sstevel@tonic-gate 	char	*arg;
110*0Sstevel@tonic-gate 	extern int	optind;
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
113*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
114*0Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
115*0Sstevel@tonic-gate #endif
116*0Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
117*0Sstevel@tonic-gate 
118*0Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "hblcnsviyw")) != -1)
119*0Sstevel@tonic-gate 		switch (c) {
120*0Sstevel@tonic-gate 		case 'h':
121*0Sstevel@tonic-gate 			hflag++;
122*0Sstevel@tonic-gate 			break;
123*0Sstevel@tonic-gate 		case 'v':
124*0Sstevel@tonic-gate 			vflag++;
125*0Sstevel@tonic-gate 			break;
126*0Sstevel@tonic-gate 		case 'c':
127*0Sstevel@tonic-gate 			cflag++;
128*0Sstevel@tonic-gate 			break;
129*0Sstevel@tonic-gate 		case 'n':
130*0Sstevel@tonic-gate 			nflag++;
131*0Sstevel@tonic-gate 			break;
132*0Sstevel@tonic-gate 		case 'b':
133*0Sstevel@tonic-gate 			bflag++;
134*0Sstevel@tonic-gate 			break;
135*0Sstevel@tonic-gate 		case 's':
136*0Sstevel@tonic-gate 			sflag++;
137*0Sstevel@tonic-gate 			break;
138*0Sstevel@tonic-gate 		case 'l':
139*0Sstevel@tonic-gate 			lflag++;
140*0Sstevel@tonic-gate 			break;
141*0Sstevel@tonic-gate 		case 'y':
142*0Sstevel@tonic-gate 		case 'i':
143*0Sstevel@tonic-gate 			iflag++;
144*0Sstevel@tonic-gate 			break;
145*0Sstevel@tonic-gate 		case 'w':
146*0Sstevel@tonic-gate 			wflag++;
147*0Sstevel@tonic-gate 			break;
148*0Sstevel@tonic-gate 		case '?':
149*0Sstevel@tonic-gate 			errflg++;
150*0Sstevel@tonic-gate 		}
151*0Sstevel@tonic-gate 
152*0Sstevel@tonic-gate 	if (errflg || (optind >= argc)) {
153*0Sstevel@tonic-gate 		errmsg("Usage: grep -hblcnsviw pattern file . . .\n",
154*0Sstevel@tonic-gate 			(char *)NULL);
155*0Sstevel@tonic-gate 		exit(2);
156*0Sstevel@tonic-gate 	}
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate 	argv = &argv[optind];
159*0Sstevel@tonic-gate 	argc -= optind;
160*0Sstevel@tonic-gate 	nfile = argc - 1;
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate 	if (strrchr(*argv, '\n') != NULL)
163*0Sstevel@tonic-gate 		regerr(41);
164*0Sstevel@tonic-gate 
165*0Sstevel@tonic-gate 	if (iflag) {
166*0Sstevel@tonic-gate 		for (arg = *argv; *arg != NULL; ++arg)
167*0Sstevel@tonic-gate 			*arg = (char)tolower((int)((unsigned char)*arg));
168*0Sstevel@tonic-gate 	}
169*0Sstevel@tonic-gate 
170*0Sstevel@tonic-gate 	if (wflag) {
171*0Sstevel@tonic-gate 		unsigned int	wordlen;
172*0Sstevel@tonic-gate 		char		*wordbuf;
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 		wordlen = strlen(*argv) + 4;
175*0Sstevel@tonic-gate 		if ((wordbuf = malloc(wordlen)) == NULL) {
176*0Sstevel@tonic-gate 			errmsg("grep: Out of memory for word\n", (char *)NULL);
177*0Sstevel@tonic-gate 			exit(2);
178*0Sstevel@tonic-gate 		}
179*0Sstevel@tonic-gate 
180*0Sstevel@tonic-gate 		(void) strcpy(wordbuf, "\\<");
181*0Sstevel@tonic-gate 		(void) strcat(wordbuf, *argv);
182*0Sstevel@tonic-gate 		(void) strcat(wordbuf, "\\>");
183*0Sstevel@tonic-gate 		*argv = wordbuf;
184*0Sstevel@tonic-gate 	}
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate 	expbuf = compile(*argv, (char *)0, (char *)0);
187*0Sstevel@tonic-gate 	if (regerrno)
188*0Sstevel@tonic-gate 		regerr(regerrno);
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	if (--argc == 0)
191*0Sstevel@tonic-gate 		execute(NULL);
192*0Sstevel@tonic-gate 	else
193*0Sstevel@tonic-gate 		while (argc-- > 0)
194*0Sstevel@tonic-gate 			execute(*++argv);
195*0Sstevel@tonic-gate 
196*0Sstevel@tonic-gate 	return (nsucc == 2 ? 2 : (nsucc == 0 ? 1 : 0));
197*0Sstevel@tonic-gate }
198*0Sstevel@tonic-gate 
199*0Sstevel@tonic-gate static void
200*0Sstevel@tonic-gate execute(
201*0Sstevel@tonic-gate     char	*file)
202*0Sstevel@tonic-gate {
203*0Sstevel@tonic-gate 	char	*lbuf, *p;
204*0Sstevel@tonic-gate 	long	count;
205*0Sstevel@tonic-gate 	long	offset = 0;
206*0Sstevel@tonic-gate 	char	*next_ptr = NULL;
207*0Sstevel@tonic-gate 	long	next_count = 0;
208*0Sstevel@tonic-gate 
209*0Sstevel@tonic-gate 	tln = 0;
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate 	if (prntbuf == NULL) {
212*0Sstevel@tonic-gate 		fw_lPrntBufLen = GBUFSIZ + 1;
213*0Sstevel@tonic-gate 		if ((prntbuf = malloc(fw_lPrntBufLen)) == NULL) {
214*0Sstevel@tonic-gate 			exit(2); /* out of memory - BAIL */
215*0Sstevel@tonic-gate 		}
216*0Sstevel@tonic-gate 		if ((linebuf = malloc(fw_lPrntBufLen)) == NULL) {
217*0Sstevel@tonic-gate 			exit(2); /* out of memory - BAIL */
218*0Sstevel@tonic-gate 		}
219*0Sstevel@tonic-gate 	}
220*0Sstevel@tonic-gate 
221*0Sstevel@tonic-gate 	if (file == NULL)
222*0Sstevel@tonic-gate 		temp = 0;
223*0Sstevel@tonic-gate 	else if ((temp = open(file, O_RDONLY)) == -1) {
224*0Sstevel@tonic-gate 		if (!sflag)
225*0Sstevel@tonic-gate 			errmsg("grep: can't open %s\n", file);
226*0Sstevel@tonic-gate 		nsucc = 2;
227*0Sstevel@tonic-gate 		return;
228*0Sstevel@tonic-gate 	}
229*0Sstevel@tonic-gate 
230*0Sstevel@tonic-gate 	/* read in first block of bytes */
231*0Sstevel@tonic-gate 	if ((count = read(temp, prntbuf, GBUFSIZ)) <= 0) {
232*0Sstevel@tonic-gate 		(void) close(temp);
233*0Sstevel@tonic-gate 
234*0Sstevel@tonic-gate 		if (cflag) {
235*0Sstevel@tonic-gate 			if (nfile > 1 && !hflag && file)
236*0Sstevel@tonic-gate 				(void) fprintf(stdout, "%s:", file);
237*0Sstevel@tonic-gate 			(void) fprintf(stdout, "%lld\n", tln);
238*0Sstevel@tonic-gate 		}
239*0Sstevel@tonic-gate 		return;
240*0Sstevel@tonic-gate 	}
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 	lnum = 0;
243*0Sstevel@tonic-gate 	ptr = prntbuf;
244*0Sstevel@tonic-gate 	for (;;) {
245*0Sstevel@tonic-gate 		/* look for next newline */
246*0Sstevel@tonic-gate 		if ((ptrend = memchr(ptr + offset, '\n', count)) == NULL) {
247*0Sstevel@tonic-gate 			offset += count;
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate 			/*
250*0Sstevel@tonic-gate 			 * shift unused data to the beginning of the buffer
251*0Sstevel@tonic-gate 			 */
252*0Sstevel@tonic-gate 			if (ptr > prntbuf) {
253*0Sstevel@tonic-gate 				(void) memmove(prntbuf, ptr, offset);
254*0Sstevel@tonic-gate 				ptr = prntbuf;
255*0Sstevel@tonic-gate 			}
256*0Sstevel@tonic-gate 
257*0Sstevel@tonic-gate 			/*
258*0Sstevel@tonic-gate 			 * re-allocate a larger buffer if this one is full
259*0Sstevel@tonic-gate 			 */
260*0Sstevel@tonic-gate 			if (offset + GBUFSIZ > fw_lPrntBufLen) {
261*0Sstevel@tonic-gate 				/*
262*0Sstevel@tonic-gate 				 * allocate a new buffer and preserve the
263*0Sstevel@tonic-gate 				 * contents...
264*0Sstevel@tonic-gate 				 */
265*0Sstevel@tonic-gate 				fw_lPrntBufLen += GBUFSIZ;
266*0Sstevel@tonic-gate 				if ((prntbuf = realloc(prntbuf,
267*0Sstevel@tonic-gate 				    fw_lPrntBufLen)) == NULL)
268*0Sstevel@tonic-gate 					exit(2);
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate 				/*
271*0Sstevel@tonic-gate 				 * set up a bigger linebuffer (this is only used
272*0Sstevel@tonic-gate 				 * for case insensitive operations). Contents do
273*0Sstevel@tonic-gate 				 * not have to be preserved.
274*0Sstevel@tonic-gate 				 */
275*0Sstevel@tonic-gate 				free(linebuf);
276*0Sstevel@tonic-gate 				if ((linebuf = malloc(fw_lPrntBufLen)) == NULL)
277*0Sstevel@tonic-gate 					exit(2);
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate 				ptr = prntbuf;
280*0Sstevel@tonic-gate 			}
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate 			p = prntbuf + offset;
283*0Sstevel@tonic-gate 			if ((count = read(temp, p, GBUFSIZ)) > 0)
284*0Sstevel@tonic-gate 				continue;
285*0Sstevel@tonic-gate 
286*0Sstevel@tonic-gate 			if (offset == 0)
287*0Sstevel@tonic-gate 				/* end of file already reached */
288*0Sstevel@tonic-gate 				break;
289*0Sstevel@tonic-gate 
290*0Sstevel@tonic-gate 			/* last line of file has no newline */
291*0Sstevel@tonic-gate 			ptrend = ptr + offset;
292*0Sstevel@tonic-gate 			nlflag = 0;
293*0Sstevel@tonic-gate 		} else {
294*0Sstevel@tonic-gate 			next_ptr = ptrend + 1;
295*0Sstevel@tonic-gate 			next_count = offset + count - (next_ptr - ptr);
296*0Sstevel@tonic-gate 			nlflag = 1;
297*0Sstevel@tonic-gate 		}
298*0Sstevel@tonic-gate 		lnum++;
299*0Sstevel@tonic-gate 		*ptrend = '\0';
300*0Sstevel@tonic-gate 
301*0Sstevel@tonic-gate 		if (iflag) {
302*0Sstevel@tonic-gate 			/*
303*0Sstevel@tonic-gate 			 * Make a lower case copy of the record
304*0Sstevel@tonic-gate 			 */
305*0Sstevel@tonic-gate 			p = ptr;
306*0Sstevel@tonic-gate 			for (lbuf = linebuf; p < ptrend; )
307*0Sstevel@tonic-gate 				*lbuf++ = (char)tolower((int)
308*0Sstevel@tonic-gate 				    (unsigned char)*p++);
309*0Sstevel@tonic-gate 			*lbuf = '\0';
310*0Sstevel@tonic-gate 			lbuf = linebuf;
311*0Sstevel@tonic-gate 		} else
312*0Sstevel@tonic-gate 			/*
313*0Sstevel@tonic-gate 			 * Use record as is
314*0Sstevel@tonic-gate 			 */
315*0Sstevel@tonic-gate 			lbuf = ptr;
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 		/* lflag only once */
318*0Sstevel@tonic-gate 		if ((step(lbuf, expbuf) ^ vflag) && succeed(file) == 1)
319*0Sstevel@tonic-gate 			break;
320*0Sstevel@tonic-gate 
321*0Sstevel@tonic-gate 		if (!nlflag)
322*0Sstevel@tonic-gate 			break;
323*0Sstevel@tonic-gate 
324*0Sstevel@tonic-gate 		ptr = next_ptr;
325*0Sstevel@tonic-gate 		count = next_count;
326*0Sstevel@tonic-gate 		offset = 0;
327*0Sstevel@tonic-gate 	}
328*0Sstevel@tonic-gate 	(void) close(temp);
329*0Sstevel@tonic-gate 
330*0Sstevel@tonic-gate 	if (cflag) {
331*0Sstevel@tonic-gate 		if (nfile > 1 && !hflag && file)
332*0Sstevel@tonic-gate 			(void) fprintf(stdout, "%s:", file);
333*0Sstevel@tonic-gate 		(void) fprintf(stdout, "%lld\n", tln);
334*0Sstevel@tonic-gate 	}
335*0Sstevel@tonic-gate }
336*0Sstevel@tonic-gate 
337*0Sstevel@tonic-gate static int
338*0Sstevel@tonic-gate succeed(
339*0Sstevel@tonic-gate     char	*f)
340*0Sstevel@tonic-gate {
341*0Sstevel@tonic-gate 	int nchars;
342*0Sstevel@tonic-gate 	nsucc = (nsucc == 2) ? 2 : 1;
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate 	if (f == NULL)
345*0Sstevel@tonic-gate 		f = "<stdin>";
346*0Sstevel@tonic-gate 
347*0Sstevel@tonic-gate 	if (cflag) {
348*0Sstevel@tonic-gate 		tln++;
349*0Sstevel@tonic-gate 		return (0);
350*0Sstevel@tonic-gate 	}
351*0Sstevel@tonic-gate 
352*0Sstevel@tonic-gate 	if (lflag) {
353*0Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\n", f);
354*0Sstevel@tonic-gate 		return (1);
355*0Sstevel@tonic-gate 	}
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate 	if (nfile > 1 && !hflag)
358*0Sstevel@tonic-gate 		/* print filename */
359*0Sstevel@tonic-gate 		(void) fprintf(stdout, "%s:", f);
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate 	if (bflag)
362*0Sstevel@tonic-gate 		/* print block number */
363*0Sstevel@tonic-gate 		(void) fprintf(stdout, "%lld:", (offset_t)
364*0Sstevel@tonic-gate 			((lseek(temp, (off_t)0, SEEK_CUR) - 1) / BLKSIZE));
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate 	if (nflag)
367*0Sstevel@tonic-gate 		/* print line number */
368*0Sstevel@tonic-gate 		(void) fprintf(stdout, "%lld:", lnum);
369*0Sstevel@tonic-gate 
370*0Sstevel@tonic-gate 	if (nlflag) {
371*0Sstevel@tonic-gate 		/* newline at end of line */
372*0Sstevel@tonic-gate 		*ptrend = '\n';
373*0Sstevel@tonic-gate 		nchars = ptrend - ptr + 1;
374*0Sstevel@tonic-gate 	} else {
375*0Sstevel@tonic-gate 		/* don't write sentinel \0 */
376*0Sstevel@tonic-gate 		nchars = ptrend - ptr;
377*0Sstevel@tonic-gate 	}
378*0Sstevel@tonic-gate 
379*0Sstevel@tonic-gate 	(void) fwrite(ptr, 1, nchars, stdout);
380*0Sstevel@tonic-gate 	return (0);
381*0Sstevel@tonic-gate }
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate static void
384*0Sstevel@tonic-gate regerr(
385*0Sstevel@tonic-gate     int	err)
386*0Sstevel@tonic-gate {
387*0Sstevel@tonic-gate 	errmsg("grep: RE error %d: ", err);
388*0Sstevel@tonic-gate 	switch (err) {
389*0Sstevel@tonic-gate 		case 11:
390*0Sstevel@tonic-gate 			err = 0;
391*0Sstevel@tonic-gate 			break;
392*0Sstevel@tonic-gate 		case 16:
393*0Sstevel@tonic-gate 			err = 1;
394*0Sstevel@tonic-gate 			break;
395*0Sstevel@tonic-gate 		case 25:
396*0Sstevel@tonic-gate 			err = 2;
397*0Sstevel@tonic-gate 			break;
398*0Sstevel@tonic-gate 		case 41:
399*0Sstevel@tonic-gate 			err = 3;
400*0Sstevel@tonic-gate 			break;
401*0Sstevel@tonic-gate 		case 42:
402*0Sstevel@tonic-gate 			err = 4;
403*0Sstevel@tonic-gate 			break;
404*0Sstevel@tonic-gate 		case 43:
405*0Sstevel@tonic-gate 			err = 5;
406*0Sstevel@tonic-gate 			break;
407*0Sstevel@tonic-gate 		case 44:
408*0Sstevel@tonic-gate 			err = 6;
409*0Sstevel@tonic-gate 			break;
410*0Sstevel@tonic-gate 		case 45:
411*0Sstevel@tonic-gate 			err = 7;
412*0Sstevel@tonic-gate 			break;
413*0Sstevel@tonic-gate 		case 46:
414*0Sstevel@tonic-gate 			err = 8;
415*0Sstevel@tonic-gate 			break;
416*0Sstevel@tonic-gate 		case 49:
417*0Sstevel@tonic-gate 			err = 9;
418*0Sstevel@tonic-gate 			break;
419*0Sstevel@tonic-gate 		case 50:
420*0Sstevel@tonic-gate 			err = 10;
421*0Sstevel@tonic-gate 			break;
422*0Sstevel@tonic-gate 		case 67:
423*0Sstevel@tonic-gate 			err = 11;
424*0Sstevel@tonic-gate 			break;
425*0Sstevel@tonic-gate 		default:
426*0Sstevel@tonic-gate 			err = 12;
427*0Sstevel@tonic-gate 			break;
428*0Sstevel@tonic-gate 	}
429*0Sstevel@tonic-gate 
430*0Sstevel@tonic-gate 	errmsg("%s\n", gettext(errstr[err]));
431*0Sstevel@tonic-gate 	exit(2);
432*0Sstevel@tonic-gate }
433