17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 2355f91622Sceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* Copyright (c) 1987, 1988 Microsoft Corporation */ 317c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 327c478bd9Sstevel@tonic-gate 333ed621bcSAlexander Eremin /* Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate /* 36*41599e9fSDamian Bogel * Copyright 2013 Damian Bogel. All rights reserved. 37*41599e9fSDamian Bogel */ 38*41599e9fSDamian Bogel 39*41599e9fSDamian Bogel /* 407c478bd9Sstevel@tonic-gate * grep -- print lines matching (or not matching) a pattern 417c478bd9Sstevel@tonic-gate * 427c478bd9Sstevel@tonic-gate * status returns: 437c478bd9Sstevel@tonic-gate * 0 - ok, and some matches 447c478bd9Sstevel@tonic-gate * 1 - ok, but no matches 457c478bd9Sstevel@tonic-gate * 2 - some error 467c478bd9Sstevel@tonic-gate */ 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate #include <sys/types.h> 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #include <ctype.h> 517c478bd9Sstevel@tonic-gate #include <fcntl.h> 527c478bd9Sstevel@tonic-gate #include <locale.h> 537c478bd9Sstevel@tonic-gate #include <memory.h> 547c478bd9Sstevel@tonic-gate #include <regexpr.h> 557c478bd9Sstevel@tonic-gate #include <stdio.h> 567c478bd9Sstevel@tonic-gate #include <stdlib.h> 577c478bd9Sstevel@tonic-gate #include <string.h> 587c478bd9Sstevel@tonic-gate #include <unistd.h> 59e52fb54bSAlexander Eremin #include <ftw.h> 60e52fb54bSAlexander Eremin #include <limits.h> 61e52fb54bSAlexander Eremin #include <sys/param.h> 627c478bd9Sstevel@tonic-gate 6355f91622Sceastha static const char *errstr[] = { 647c478bd9Sstevel@tonic-gate "Range endpoint too large.", 657c478bd9Sstevel@tonic-gate "Bad number.", 667c478bd9Sstevel@tonic-gate "``\\digit'' out of range.", 677c478bd9Sstevel@tonic-gate "No remembered search string.", 687c478bd9Sstevel@tonic-gate "\\( \\) imbalance.", 697c478bd9Sstevel@tonic-gate "Too many \\(.", 707c478bd9Sstevel@tonic-gate "More than 2 numbers given in \\{ \\}.", 717c478bd9Sstevel@tonic-gate "} expected after \\.", 727c478bd9Sstevel@tonic-gate "First number exceeds second in \\{ \\}.", 737c478bd9Sstevel@tonic-gate "[ ] imbalance.", 747c478bd9Sstevel@tonic-gate "Regular expression overflow.", 757c478bd9Sstevel@tonic-gate "Illegal byte sequence.", 767c478bd9Sstevel@tonic-gate "Unknown regexp error code!!", 777c478bd9Sstevel@tonic-gate NULL 787c478bd9Sstevel@tonic-gate }; 797c478bd9Sstevel@tonic-gate 80*41599e9fSDamian Bogel #define STDIN_FILENAME gettext("(standard input)") 81*41599e9fSDamian Bogel 827c478bd9Sstevel@tonic-gate #define errmsg(msg, arg) (void) fprintf(stderr, gettext(msg), arg) 837c478bd9Sstevel@tonic-gate #define BLKSIZE 512 847c478bd9Sstevel@tonic-gate #define GBUFSIZ 8192 85e52fb54bSAlexander Eremin #define MAX_DEPTH 1000 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate static int temp; 887c478bd9Sstevel@tonic-gate static long long lnum; 897c478bd9Sstevel@tonic-gate static char *linebuf; 907c478bd9Sstevel@tonic-gate static char *prntbuf = NULL; 917c478bd9Sstevel@tonic-gate static long fw_lPrntBufLen = 0; 927c478bd9Sstevel@tonic-gate static int nflag; 937c478bd9Sstevel@tonic-gate static int bflag; 947c478bd9Sstevel@tonic-gate static int lflag; 957c478bd9Sstevel@tonic-gate static int cflag; 96e52fb54bSAlexander Eremin static int rflag; 97e52fb54bSAlexander Eremin static int Rflag; 987c478bd9Sstevel@tonic-gate static int vflag; 997c478bd9Sstevel@tonic-gate static int sflag; 1007c478bd9Sstevel@tonic-gate static int iflag; 1017c478bd9Sstevel@tonic-gate static int wflag; 1027c478bd9Sstevel@tonic-gate static int hflag; 103*41599e9fSDamian Bogel static int Hflag; 1043ed621bcSAlexander Eremin static int qflag; 1057c478bd9Sstevel@tonic-gate static int errflg; 1067c478bd9Sstevel@tonic-gate static int nfile; 1077c478bd9Sstevel@tonic-gate static long long tln; 1087c478bd9Sstevel@tonic-gate static int nsucc; 109e52fb54bSAlexander Eremin static int outfn = 0; 1107c478bd9Sstevel@tonic-gate static int nlflag; 1117c478bd9Sstevel@tonic-gate static char *ptr, *ptrend; 1127c478bd9Sstevel@tonic-gate static char *expbuf; 1137c478bd9Sstevel@tonic-gate 114e52fb54bSAlexander Eremin static void execute(const char *, int); 1157c478bd9Sstevel@tonic-gate static void regerr(int); 116e52fb54bSAlexander Eremin static void prepare(const char *); 117e52fb54bSAlexander Eremin static int recursive(const char *, const struct stat *, int, struct FTW *); 118e52fb54bSAlexander Eremin static int succeed(const char *); 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate int 12155f91622Sceastha main(int argc, char **argv) 1227c478bd9Sstevel@tonic-gate { 1237c478bd9Sstevel@tonic-gate int c; 1247c478bd9Sstevel@tonic-gate char *arg; 1257c478bd9Sstevel@tonic-gate extern int optind; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1287c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 1297c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 1307c478bd9Sstevel@tonic-gate #endif 1317c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1327c478bd9Sstevel@tonic-gate 133*41599e9fSDamian Bogel while ((c = getopt(argc, argv, "hHqblcnRrsviyw")) != -1) 1347c478bd9Sstevel@tonic-gate switch (c) { 135*41599e9fSDamian Bogel /* based on options order h or H is set as in GNU grep */ 1367c478bd9Sstevel@tonic-gate case 'h': 1377c478bd9Sstevel@tonic-gate hflag++; 138*41599e9fSDamian Bogel Hflag = 0; /* h excludes H */ 139*41599e9fSDamian Bogel break; 140*41599e9fSDamian Bogel case 'H': 141*41599e9fSDamian Bogel if (!lflag) /* H is excluded by l */ 142*41599e9fSDamian Bogel Hflag++; 143*41599e9fSDamian Bogel hflag = 0; /* H excludes h */ 1447c478bd9Sstevel@tonic-gate break; 1453ed621bcSAlexander Eremin case 'q': /* POSIX: quiet: status only */ 1463ed621bcSAlexander Eremin qflag++; 1473ed621bcSAlexander Eremin break; 1487c478bd9Sstevel@tonic-gate case 'v': 1497c478bd9Sstevel@tonic-gate vflag++; 1507c478bd9Sstevel@tonic-gate break; 1517c478bd9Sstevel@tonic-gate case 'c': 1527c478bd9Sstevel@tonic-gate cflag++; 1537c478bd9Sstevel@tonic-gate break; 1547c478bd9Sstevel@tonic-gate case 'n': 1557c478bd9Sstevel@tonic-gate nflag++; 1567c478bd9Sstevel@tonic-gate break; 157e52fb54bSAlexander Eremin case 'R': 158e52fb54bSAlexander Eremin Rflag++; 159e52fb54bSAlexander Eremin /* FALLTHROUGH */ 160e52fb54bSAlexander Eremin case 'r': 161e52fb54bSAlexander Eremin rflag++; 162e52fb54bSAlexander Eremin break; 1637c478bd9Sstevel@tonic-gate case 'b': 1647c478bd9Sstevel@tonic-gate bflag++; 1657c478bd9Sstevel@tonic-gate break; 1667c478bd9Sstevel@tonic-gate case 's': 1677c478bd9Sstevel@tonic-gate sflag++; 1687c478bd9Sstevel@tonic-gate break; 1697c478bd9Sstevel@tonic-gate case 'l': 1707c478bd9Sstevel@tonic-gate lflag++; 171*41599e9fSDamian Bogel Hflag = 0; /* l excludes H */ 1727c478bd9Sstevel@tonic-gate break; 1737c478bd9Sstevel@tonic-gate case 'y': 1747c478bd9Sstevel@tonic-gate case 'i': 1757c478bd9Sstevel@tonic-gate iflag++; 1767c478bd9Sstevel@tonic-gate break; 1777c478bd9Sstevel@tonic-gate case 'w': 1787c478bd9Sstevel@tonic-gate wflag++; 1797c478bd9Sstevel@tonic-gate break; 1807c478bd9Sstevel@tonic-gate case '?': 1817c478bd9Sstevel@tonic-gate errflg++; 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (errflg || (optind >= argc)) { 185*41599e9fSDamian Bogel errmsg("Usage: grep [-c|-l|-q] [-r|-R] -hHbnsviw " 186e52fb54bSAlexander Eremin "pattern file . . .\n", 1877c478bd9Sstevel@tonic-gate (char *)NULL); 1887c478bd9Sstevel@tonic-gate exit(2); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate argv = &argv[optind]; 1927c478bd9Sstevel@tonic-gate argc -= optind; 1937c478bd9Sstevel@tonic-gate nfile = argc - 1; 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate if (strrchr(*argv, '\n') != NULL) 1967c478bd9Sstevel@tonic-gate regerr(41); 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate if (iflag) { 1997c478bd9Sstevel@tonic-gate for (arg = *argv; *arg != NULL; ++arg) 2007c478bd9Sstevel@tonic-gate *arg = (char)tolower((int)((unsigned char)*arg)); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate if (wflag) { 2047c478bd9Sstevel@tonic-gate unsigned int wordlen; 2057c478bd9Sstevel@tonic-gate char *wordbuf; 2067c478bd9Sstevel@tonic-gate 20755f91622Sceastha wordlen = strlen(*argv) + 5; /* '\\' '<' *argv '\\' '>' '\0' */ 2087c478bd9Sstevel@tonic-gate if ((wordbuf = malloc(wordlen)) == NULL) { 2097c478bd9Sstevel@tonic-gate errmsg("grep: Out of memory for word\n", (char *)NULL); 2107c478bd9Sstevel@tonic-gate exit(2); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate (void) strcpy(wordbuf, "\\<"); 2147c478bd9Sstevel@tonic-gate (void) strcat(wordbuf, *argv); 2157c478bd9Sstevel@tonic-gate (void) strcat(wordbuf, "\\>"); 2167c478bd9Sstevel@tonic-gate *argv = wordbuf; 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate expbuf = compile(*argv, (char *)0, (char *)0); 2207c478bd9Sstevel@tonic-gate if (regerrno) 2217c478bd9Sstevel@tonic-gate regerr(regerrno); 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate if (--argc == 0) 224e52fb54bSAlexander Eremin execute(NULL, 0); 2257c478bd9Sstevel@tonic-gate else 2267c478bd9Sstevel@tonic-gate while (argc-- > 0) 227e52fb54bSAlexander Eremin prepare(*++argv); 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate return (nsucc == 2 ? 2 : (nsucc == 0 ? 1 : 0)); 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate static void 233e52fb54bSAlexander Eremin prepare(const char *path) 234e52fb54bSAlexander Eremin { 235e52fb54bSAlexander Eremin struct stat st; 236e52fb54bSAlexander Eremin int walkflags = FTW_CHDIR; 237e52fb54bSAlexander Eremin char *buf = NULL; 238e52fb54bSAlexander Eremin 239e52fb54bSAlexander Eremin if (rflag) { 240e52fb54bSAlexander Eremin if (stat(path, &st) != -1 && 241e52fb54bSAlexander Eremin (st.st_mode & S_IFMT) == S_IFDIR) { 242e52fb54bSAlexander Eremin outfn = 1; 243e52fb54bSAlexander Eremin 244e52fb54bSAlexander Eremin /* 245e52fb54bSAlexander Eremin * Add trailing slash if arg 246e52fb54bSAlexander Eremin * is directory, to resolve symlinks. 247e52fb54bSAlexander Eremin */ 248e52fb54bSAlexander Eremin if (path[strlen(path) - 1] != '/') { 249e52fb54bSAlexander Eremin (void) asprintf(&buf, "%s/", path); 250e52fb54bSAlexander Eremin if (buf != NULL) 251e52fb54bSAlexander Eremin path = buf; 252e52fb54bSAlexander Eremin } 253e52fb54bSAlexander Eremin 254e52fb54bSAlexander Eremin /* 255e52fb54bSAlexander Eremin * Search through subdirs if path is directory. 256e52fb54bSAlexander Eremin * Don't follow symlinks if Rflag is not set. 257e52fb54bSAlexander Eremin */ 258e52fb54bSAlexander Eremin if (!Rflag) 259e52fb54bSAlexander Eremin walkflags |= FTW_PHYS; 260e52fb54bSAlexander Eremin 261e52fb54bSAlexander Eremin if (nftw(path, recursive, MAX_DEPTH, walkflags) != 0) { 262e52fb54bSAlexander Eremin if (!sflag) 263e52fb54bSAlexander Eremin errmsg("grep: can't open %s\n", path); 264e52fb54bSAlexander Eremin nsucc = 2; 265e52fb54bSAlexander Eremin } 266e52fb54bSAlexander Eremin return; 267e52fb54bSAlexander Eremin } 268e52fb54bSAlexander Eremin } 269e52fb54bSAlexander Eremin execute(path, 0); 270e52fb54bSAlexander Eremin } 271e52fb54bSAlexander Eremin 272e52fb54bSAlexander Eremin static int 273e52fb54bSAlexander Eremin recursive(const char *name, const struct stat *statp, int info, struct FTW *ftw) 274e52fb54bSAlexander Eremin { 275e52fb54bSAlexander Eremin /* 276e52fb54bSAlexander Eremin * process files and follow symlinks if Rflag set. 277e52fb54bSAlexander Eremin */ 278e52fb54bSAlexander Eremin if (info != FTW_F) { 279e52fb54bSAlexander Eremin if (!sflag && 280e52fb54bSAlexander Eremin (info == FTW_SLN || info == FTW_DNR || info == FTW_NS)) { 281e52fb54bSAlexander Eremin /* report broken symlinks and unreadable files */ 282e52fb54bSAlexander Eremin errmsg("grep: can't open %s\n", name); 283e52fb54bSAlexander Eremin } 284e52fb54bSAlexander Eremin return (0); 285e52fb54bSAlexander Eremin } 286e52fb54bSAlexander Eremin 287e52fb54bSAlexander Eremin /* skip devices and pipes if Rflag is not set */ 288e52fb54bSAlexander Eremin if (!Rflag && !S_ISREG(statp->st_mode)) 289e52fb54bSAlexander Eremin return (0); 290e52fb54bSAlexander Eremin 291e52fb54bSAlexander Eremin /* pass offset to relative name from FTW_CHDIR */ 292e52fb54bSAlexander Eremin execute(name, ftw->base); 293e52fb54bSAlexander Eremin return (0); 294e52fb54bSAlexander Eremin } 295e52fb54bSAlexander Eremin 296e52fb54bSAlexander Eremin static void 297e52fb54bSAlexander Eremin execute(const char *file, int base) 2987c478bd9Sstevel@tonic-gate { 2997c478bd9Sstevel@tonic-gate char *lbuf, *p; 3007c478bd9Sstevel@tonic-gate long count; 3017c478bd9Sstevel@tonic-gate long offset = 0; 3027c478bd9Sstevel@tonic-gate char *next_ptr = NULL; 3037c478bd9Sstevel@tonic-gate long next_count = 0; 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate tln = 0; 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate if (prntbuf == NULL) { 3087c478bd9Sstevel@tonic-gate fw_lPrntBufLen = GBUFSIZ + 1; 3097c478bd9Sstevel@tonic-gate if ((prntbuf = malloc(fw_lPrntBufLen)) == NULL) { 3107c478bd9Sstevel@tonic-gate exit(2); /* out of memory - BAIL */ 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate if ((linebuf = malloc(fw_lPrntBufLen)) == NULL) { 3137c478bd9Sstevel@tonic-gate exit(2); /* out of memory - BAIL */ 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate 317*41599e9fSDamian Bogel if (file == NULL) { 3187c478bd9Sstevel@tonic-gate temp = 0; 319*41599e9fSDamian Bogel file = STDIN_FILENAME; 320*41599e9fSDamian Bogel } else if ((temp = open(file + base, O_RDONLY)) == -1) { 3217c478bd9Sstevel@tonic-gate if (!sflag) 3227c478bd9Sstevel@tonic-gate errmsg("grep: can't open %s\n", file); 3237c478bd9Sstevel@tonic-gate nsucc = 2; 3247c478bd9Sstevel@tonic-gate return; 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate /* read in first block of bytes */ 3287c478bd9Sstevel@tonic-gate if ((count = read(temp, prntbuf, GBUFSIZ)) <= 0) { 3297c478bd9Sstevel@tonic-gate (void) close(temp); 3307c478bd9Sstevel@tonic-gate 3313ed621bcSAlexander Eremin if (cflag && !qflag) { 332*41599e9fSDamian Bogel if (Hflag || (nfile > 1 && !hflag)) 3337c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%s:", file); 334e52fb54bSAlexander Eremin if (!rflag) 3357c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%lld\n", tln); 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate return; 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate lnum = 0; 3417c478bd9Sstevel@tonic-gate ptr = prntbuf; 3427c478bd9Sstevel@tonic-gate for (;;) { 3437c478bd9Sstevel@tonic-gate /* look for next newline */ 3447c478bd9Sstevel@tonic-gate if ((ptrend = memchr(ptr + offset, '\n', count)) == NULL) { 3457c478bd9Sstevel@tonic-gate offset += count; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate /* 3487c478bd9Sstevel@tonic-gate * shift unused data to the beginning of the buffer 3497c478bd9Sstevel@tonic-gate */ 3507c478bd9Sstevel@tonic-gate if (ptr > prntbuf) { 3517c478bd9Sstevel@tonic-gate (void) memmove(prntbuf, ptr, offset); 3527c478bd9Sstevel@tonic-gate ptr = prntbuf; 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate /* 3567c478bd9Sstevel@tonic-gate * re-allocate a larger buffer if this one is full 3577c478bd9Sstevel@tonic-gate */ 3587c478bd9Sstevel@tonic-gate if (offset + GBUFSIZ > fw_lPrntBufLen) { 3597c478bd9Sstevel@tonic-gate /* 3607c478bd9Sstevel@tonic-gate * allocate a new buffer and preserve the 3617c478bd9Sstevel@tonic-gate * contents... 3627c478bd9Sstevel@tonic-gate */ 3637c478bd9Sstevel@tonic-gate fw_lPrntBufLen += GBUFSIZ; 3647c478bd9Sstevel@tonic-gate if ((prntbuf = realloc(prntbuf, 3657c478bd9Sstevel@tonic-gate fw_lPrntBufLen)) == NULL) 3667c478bd9Sstevel@tonic-gate exit(2); 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate /* 3697c478bd9Sstevel@tonic-gate * set up a bigger linebuffer (this is only used 3707c478bd9Sstevel@tonic-gate * for case insensitive operations). Contents do 3717c478bd9Sstevel@tonic-gate * not have to be preserved. 3727c478bd9Sstevel@tonic-gate */ 3737c478bd9Sstevel@tonic-gate free(linebuf); 3747c478bd9Sstevel@tonic-gate if ((linebuf = malloc(fw_lPrntBufLen)) == NULL) 3757c478bd9Sstevel@tonic-gate exit(2); 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate ptr = prntbuf; 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate p = prntbuf + offset; 3817c478bd9Sstevel@tonic-gate if ((count = read(temp, p, GBUFSIZ)) > 0) 3827c478bd9Sstevel@tonic-gate continue; 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate if (offset == 0) 3857c478bd9Sstevel@tonic-gate /* end of file already reached */ 3867c478bd9Sstevel@tonic-gate break; 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate /* last line of file has no newline */ 3897c478bd9Sstevel@tonic-gate ptrend = ptr + offset; 3907c478bd9Sstevel@tonic-gate nlflag = 0; 3917c478bd9Sstevel@tonic-gate } else { 3927c478bd9Sstevel@tonic-gate next_ptr = ptrend + 1; 3937c478bd9Sstevel@tonic-gate next_count = offset + count - (next_ptr - ptr); 3947c478bd9Sstevel@tonic-gate nlflag = 1; 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate lnum++; 3977c478bd9Sstevel@tonic-gate *ptrend = '\0'; 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate if (iflag) { 4007c478bd9Sstevel@tonic-gate /* 4017c478bd9Sstevel@tonic-gate * Make a lower case copy of the record 4027c478bd9Sstevel@tonic-gate */ 4037c478bd9Sstevel@tonic-gate p = ptr; 4047c478bd9Sstevel@tonic-gate for (lbuf = linebuf; p < ptrend; ) 4057c478bd9Sstevel@tonic-gate *lbuf++ = (char)tolower((int) 4067c478bd9Sstevel@tonic-gate (unsigned char)*p++); 4077c478bd9Sstevel@tonic-gate *lbuf = '\0'; 4087c478bd9Sstevel@tonic-gate lbuf = linebuf; 4097c478bd9Sstevel@tonic-gate } else 4107c478bd9Sstevel@tonic-gate /* 4117c478bd9Sstevel@tonic-gate * Use record as is 4127c478bd9Sstevel@tonic-gate */ 4137c478bd9Sstevel@tonic-gate lbuf = ptr; 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate /* lflag only once */ 4167c478bd9Sstevel@tonic-gate if ((step(lbuf, expbuf) ^ vflag) && succeed(file) == 1) 4177c478bd9Sstevel@tonic-gate break; 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate if (!nlflag) 4207c478bd9Sstevel@tonic-gate break; 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate ptr = next_ptr; 4237c478bd9Sstevel@tonic-gate count = next_count; 4247c478bd9Sstevel@tonic-gate offset = 0; 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate (void) close(temp); 4277c478bd9Sstevel@tonic-gate 4283ed621bcSAlexander Eremin if (cflag && !qflag) { 429*41599e9fSDamian Bogel if (Hflag || (!hflag && ((nfile > 1) || 430*41599e9fSDamian Bogel (rflag && outfn)))) 4317c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%s:", file); 4327c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%lld\n", tln); 4337c478bd9Sstevel@tonic-gate } 4347c478bd9Sstevel@tonic-gate } 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate static int 437e52fb54bSAlexander Eremin succeed(const char *f) 4387c478bd9Sstevel@tonic-gate { 4397c478bd9Sstevel@tonic-gate int nchars; 4407c478bd9Sstevel@tonic-gate nsucc = (nsucc == 2) ? 2 : 1; 4417c478bd9Sstevel@tonic-gate 4423ed621bcSAlexander Eremin if (qflag) { 4433ed621bcSAlexander Eremin /* no need to continue */ 4443ed621bcSAlexander Eremin return (1); 4453ed621bcSAlexander Eremin } 4463ed621bcSAlexander Eremin 4477c478bd9Sstevel@tonic-gate if (cflag) { 4487c478bd9Sstevel@tonic-gate tln++; 4497c478bd9Sstevel@tonic-gate return (0); 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate if (lflag) { 4537c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%s\n", f); 4547c478bd9Sstevel@tonic-gate return (1); 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate 457*41599e9fSDamian Bogel if (Hflag || (!hflag && (nfile > 1 || (rflag && outfn)))) { 4587c478bd9Sstevel@tonic-gate /* print filename */ 4597c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%s:", f); 460e52fb54bSAlexander Eremin } 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate if (bflag) 4637c478bd9Sstevel@tonic-gate /* print block number */ 4647c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%lld:", (offset_t) 4657c478bd9Sstevel@tonic-gate ((lseek(temp, (off_t)0, SEEK_CUR) - 1) / BLKSIZE)); 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate if (nflag) 4687c478bd9Sstevel@tonic-gate /* print line number */ 4697c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%lld:", lnum); 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate if (nlflag) { 4727c478bd9Sstevel@tonic-gate /* newline at end of line */ 4737c478bd9Sstevel@tonic-gate *ptrend = '\n'; 4747c478bd9Sstevel@tonic-gate nchars = ptrend - ptr + 1; 4757c478bd9Sstevel@tonic-gate } else { 4767c478bd9Sstevel@tonic-gate /* don't write sentinel \0 */ 4777c478bd9Sstevel@tonic-gate nchars = ptrend - ptr; 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate (void) fwrite(ptr, 1, nchars, stdout); 4817c478bd9Sstevel@tonic-gate return (0); 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate static void 48555f91622Sceastha regerr(int err) 4867c478bd9Sstevel@tonic-gate { 4877c478bd9Sstevel@tonic-gate errmsg("grep: RE error %d: ", err); 4887c478bd9Sstevel@tonic-gate switch (err) { 4897c478bd9Sstevel@tonic-gate case 11: 4907c478bd9Sstevel@tonic-gate err = 0; 4917c478bd9Sstevel@tonic-gate break; 4927c478bd9Sstevel@tonic-gate case 16: 4937c478bd9Sstevel@tonic-gate err = 1; 4947c478bd9Sstevel@tonic-gate break; 4957c478bd9Sstevel@tonic-gate case 25: 4967c478bd9Sstevel@tonic-gate err = 2; 4977c478bd9Sstevel@tonic-gate break; 4987c478bd9Sstevel@tonic-gate case 41: 4997c478bd9Sstevel@tonic-gate err = 3; 5007c478bd9Sstevel@tonic-gate break; 5017c478bd9Sstevel@tonic-gate case 42: 5027c478bd9Sstevel@tonic-gate err = 4; 5037c478bd9Sstevel@tonic-gate break; 5047c478bd9Sstevel@tonic-gate case 43: 5057c478bd9Sstevel@tonic-gate err = 5; 5067c478bd9Sstevel@tonic-gate break; 5077c478bd9Sstevel@tonic-gate case 44: 5087c478bd9Sstevel@tonic-gate err = 6; 5097c478bd9Sstevel@tonic-gate break; 5107c478bd9Sstevel@tonic-gate case 45: 5117c478bd9Sstevel@tonic-gate err = 7; 5127c478bd9Sstevel@tonic-gate break; 5137c478bd9Sstevel@tonic-gate case 46: 5147c478bd9Sstevel@tonic-gate err = 8; 5157c478bd9Sstevel@tonic-gate break; 5167c478bd9Sstevel@tonic-gate case 49: 5177c478bd9Sstevel@tonic-gate err = 9; 5187c478bd9Sstevel@tonic-gate break; 5197c478bd9Sstevel@tonic-gate case 50: 5207c478bd9Sstevel@tonic-gate err = 10; 5217c478bd9Sstevel@tonic-gate break; 5227c478bd9Sstevel@tonic-gate case 67: 5237c478bd9Sstevel@tonic-gate err = 11; 5247c478bd9Sstevel@tonic-gate break; 5257c478bd9Sstevel@tonic-gate default: 5267c478bd9Sstevel@tonic-gate err = 12; 5277c478bd9Sstevel@tonic-gate break; 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate errmsg("%s\n", gettext(errstr[err])); 5317c478bd9Sstevel@tonic-gate exit(2); 5327c478bd9Sstevel@tonic-gate } 533