1 /* $NetBSD: grep.c,v 1.2 2016/01/10 22:16:40 christos Exp $ */ 2 3 /* grep.c - main driver file for grep. 4 Copyright 1992, 1997-1999, 2000 Free Software Foundation, Inc. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 19 02111-1307, USA. */ 20 21 /* Written July 1992 by Mike Haertel. */ 22 23 #ifdef HAVE_CONFIG_H 24 # include <config.h> 25 #endif 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 #if defined(HAVE_MMAP) 29 # include <sys/mman.h> 30 #endif 31 #if defined(HAVE_SETRLIMIT) 32 # include <sys/time.h> 33 # include <sys/resource.h> 34 #endif 35 #include <stdio.h> 36 #include "system.h" 37 #include "getopt.h" 38 #include "getpagesize.h" 39 #include "grep.h" 40 #include "savedir.h" 41 #include "xstrtol.h" 42 #include "xalloc.h" 43 #include "error.h" 44 #include "exclude.h" 45 #include "closeout.h" 46 47 #undef MAX 48 #define MAX(A,B) ((A) > (B) ? (A) : (B)) 49 50 struct stats 51 { 52 struct stats const *parent; 53 struct stat stat; 54 }; 55 56 #include <limits.h> 57 #define MAX_OFF_T (sizeof(off_t) == sizeof(char) ? INT_MAX : \ 58 (sizeof(off_t) == sizeof(short) ? SHRT_MAX : \ 59 (sizeof(off_t) == sizeof(int) ? INT_MAX : \ 60 (sizeof(off_t) == sizeof(long) ? LONG_MAX : \ 61 (sizeof(off_t) == sizeof(long long) ? LLONG_MAX : INTMAX_MAX))))) 62 63 /* base of chain of stat buffers, used to detect directory loops */ 64 static struct stats stats_base; 65 66 /* if non-zero, display usage information and exit */ 67 static int show_help; 68 69 /* If non-zero, print the version on standard output and exit. */ 70 static int show_version; 71 72 /* If nonzero, suppress diagnostics for nonexistent or unreadable files. */ 73 static int suppress_errors; 74 75 /* If nonzero, use mmap if possible. */ 76 static int mmap_option; 77 78 /* If nonzero, use grep_color marker. */ 79 static int color_option; 80 81 /* If nonzero, show only the part of a line matching the expression. */ 82 static int only_matching; 83 84 /* The color string used. The user can overwrite it using the environment 85 variable GREP_COLOR. The default is to print red. */ 86 static const char *grep_color = "01;31"; 87 88 static struct exclude *excluded_patterns; 89 static struct exclude *included_patterns; 90 /* Short options. */ 91 static char const short_options[] = 92 "0123456789A:B:C:D:EFGHIPUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz"; 93 94 /* Non-boolean long options that have no corresponding short equivalents. */ 95 enum 96 { 97 BINARY_FILES_OPTION = CHAR_MAX + 1, 98 COLOR_OPTION, 99 INCLUDE_OPTION, 100 EXCLUDE_OPTION, 101 EXCLUDE_FROM_OPTION, 102 LINE_BUFFERED_OPTION, 103 LABEL_OPTION 104 }; 105 106 /* Long options equivalences. */ 107 static struct option const long_options[] = 108 { 109 {"after-context", required_argument, NULL, 'A'}, 110 {"basic-regexp", no_argument, NULL, 'G'}, 111 {"before-context", required_argument, NULL, 'B'}, 112 {"binary-files", required_argument, NULL, BINARY_FILES_OPTION}, 113 {"byte-offset", no_argument, NULL, 'b'}, 114 {"context", required_argument, NULL, 'C'}, 115 {"color", optional_argument, NULL, COLOR_OPTION}, 116 {"colour", optional_argument, NULL, COLOR_OPTION}, 117 {"count", no_argument, NULL, 'c'}, 118 {"devices", required_argument, NULL, 'D'}, 119 {"directories", required_argument, NULL, 'd'}, 120 {"extended-regexp", no_argument, NULL, 'E'}, 121 {"exclude", required_argument, NULL, EXCLUDE_OPTION}, 122 {"exclude-from", required_argument, NULL, EXCLUDE_FROM_OPTION}, 123 {"file", required_argument, NULL, 'f'}, 124 {"files-with-matches", no_argument, NULL, 'l'}, 125 {"files-without-match", no_argument, NULL, 'L'}, 126 {"fixed-regexp", no_argument, NULL, 'F'}, 127 {"fixed-strings", no_argument, NULL, 'F'}, 128 {"help", no_argument, &show_help, 1}, 129 {"include", required_argument, NULL, INCLUDE_OPTION}, 130 {"ignore-case", no_argument, NULL, 'i'}, 131 {"label", required_argument, NULL, LABEL_OPTION}, 132 {"line-buffered", no_argument, NULL, LINE_BUFFERED_OPTION}, 133 {"line-number", no_argument, NULL, 'n'}, 134 {"line-regexp", no_argument, NULL, 'x'}, 135 {"max-count", required_argument, NULL, 'm'}, 136 {"mmap", no_argument, &mmap_option, 1}, 137 {"no-filename", no_argument, NULL, 'h'}, 138 {"no-messages", no_argument, NULL, 's'}, 139 {"null", no_argument, NULL, 'Z'}, 140 {"null-data", no_argument, NULL, 'z'}, 141 {"only-matching", no_argument, NULL, 'o'}, 142 {"perl-regexp", no_argument, NULL, 'P'}, 143 {"quiet", no_argument, NULL, 'q'}, 144 {"recursive", no_argument, NULL, 'r'}, 145 {"recursive", no_argument, NULL, 'R'}, 146 {"regexp", required_argument, NULL, 'e'}, 147 {"invert-match", no_argument, NULL, 'v'}, 148 {"silent", no_argument, NULL, 'q'}, 149 {"text", no_argument, NULL, 'a'}, 150 {"binary", no_argument, NULL, 'U'}, 151 {"unix-byte-offsets", no_argument, NULL, 'u'}, 152 {"version", no_argument, NULL, 'V'}, 153 {"with-filename", no_argument, NULL, 'H'}, 154 {"word-regexp", no_argument, NULL, 'w'}, 155 {0, 0, 0, 0} 156 }; 157 158 /* Define flags declared in grep.h. */ 159 int match_icase; 160 int match_words; 161 int match_lines; 162 unsigned char eolbyte; 163 164 /* For error messages. */ 165 /* The name the program was run with, stripped of any leading path. */ 166 char *program_name; 167 static char const *filename; 168 static int errseen; 169 170 /* How to handle directories. */ 171 static enum 172 { 173 READ_DIRECTORIES, 174 RECURSE_DIRECTORIES, 175 SKIP_DIRECTORIES 176 } directories = READ_DIRECTORIES; 177 178 /* How to handle devices. */ 179 static enum 180 { 181 READ_DEVICES, 182 SKIP_DEVICES 183 } devices = READ_DEVICES; 184 185 static int grepdir PARAMS ((char const *, struct stats const *)); 186 #if defined(HAVE_DOS_FILE_CONTENTS) 187 static inline int undossify_input PARAMS ((register char *, size_t)); 188 #endif 189 190 /* Functions we'll use to search. */ 191 static void (*compile) PARAMS ((char const *, size_t)); 192 static size_t (*execute) PARAMS ((char const *, size_t, size_t *, int)); 193 194 /* Like error, but suppress the diagnostic if requested. */ 195 static void 196 suppressible_error (char const *mesg, int errnum) 197 { 198 if (! suppress_errors) 199 error (0, errnum, "%s", mesg); 200 errseen = 1; 201 } 202 203 /* Convert STR to a positive integer, storing the result in *OUT. 204 STR must be a valid context length argument; report an error if it 205 isn't. */ 206 static void 207 context_length_arg (char const *str, int *out) 208 { 209 uintmax_t value; 210 if (! (xstrtoumax (str, 0, 10, &value, "") == LONGINT_OK 211 && 0 <= (*out = value) 212 && *out == value)) 213 { 214 error (2, 0, "%s: %s", str, _("invalid context length argument")); 215 } 216 } 217 218 219 /* Hairy buffering mechanism for grep. The intent is to keep 220 all reads aligned on a page boundary and multiples of the 221 page size, unless a read yields a partial page. */ 222 223 static char *buffer; /* Base of buffer. */ 224 static size_t bufalloc; /* Allocated buffer size, counting slop. */ 225 #define INITIAL_BUFSIZE 32768 /* Initial buffer size, not counting slop. */ 226 static int bufdesc; /* File descriptor. */ 227 static char *bufbeg; /* Beginning of user-visible stuff. */ 228 static char *buflim; /* Limit of user-visible stuff. */ 229 static size_t pagesize; /* alignment of memory pages */ 230 static off_t bufoffset; /* Read offset; defined on regular files. */ 231 static off_t after_last_match; /* Pointer after last matching line that 232 would have been output if we were 233 outputting characters. */ 234 235 #if defined(HAVE_MMAP) 236 static int bufmapped; /* True if buffer is memory-mapped. */ 237 static off_t initial_bufoffset; /* Initial value of bufoffset. */ 238 #else 239 # define bufmapped 0 240 #endif 241 242 /* Return VAL aligned to the next multiple of ALIGNMENT. VAL can be 243 an integer or a pointer. Both args must be free of side effects. */ 244 #define ALIGN_TO(val, alignment) \ 245 ((size_t) (val) % (alignment) == 0 \ 246 ? (val) \ 247 : (val) + ((alignment) - (size_t) (val) % (alignment))) 248 249 /* Reset the buffer for a new file, returning zero if we should skip it. 250 Initialize on the first time through. */ 251 static int 252 reset (int fd, char const *file, struct stats *stats) 253 { 254 if (! pagesize) 255 { 256 pagesize = getpagesize (); 257 if (pagesize == 0 || 2 * pagesize + 1 <= pagesize) 258 abort (); 259 bufalloc = ALIGN_TO (INITIAL_BUFSIZE, pagesize) + pagesize + 1; 260 buffer = xmalloc (bufalloc); 261 } 262 263 bufbeg = buflim = ALIGN_TO (buffer + 1, pagesize); 264 bufbeg[-1] = eolbyte; 265 bufdesc = fd; 266 267 if (fstat (fd, &stats->stat) != 0) 268 { 269 error (0, errno, "fstat"); 270 return 0; 271 } 272 if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode)) 273 return 0; 274 #ifndef DJGPP 275 if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode) || S_ISSOCK(stats->stat.st_mode))) 276 #else 277 if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode))) 278 #endif 279 return 0; 280 if (S_ISREG (stats->stat.st_mode)) 281 { 282 if (file) 283 bufoffset = 0; 284 else 285 { 286 bufoffset = lseek (fd, 0, SEEK_CUR); 287 if (bufoffset < 0) 288 { 289 error (0, errno, "lseek"); 290 return 0; 291 } 292 } 293 #if defined(HAVE_MMAP) 294 initial_bufoffset = bufoffset; 295 bufmapped = mmap_option && bufoffset % pagesize == 0; 296 #endif 297 } 298 else 299 { 300 #if defined(HAVE_MMAP) 301 bufmapped = 0; 302 #endif 303 } 304 return 1; 305 } 306 307 /* Read new stuff into the buffer, saving the specified 308 amount of old stuff. When we're done, 'bufbeg' points 309 to the beginning of the buffer contents, and 'buflim' 310 points just after the end. Return zero if there's an error. */ 311 static int 312 fillbuf (size_t save, struct stats const *stats) 313 { 314 size_t fillsize = 0; 315 int cc = 1; 316 char *readbuf; 317 size_t readsize; 318 319 /* Offset from start of buffer to start of old stuff 320 that we want to save. */ 321 size_t saved_offset = buflim - save - buffer; 322 323 if (pagesize <= buffer + bufalloc - buflim) 324 { 325 readbuf = buflim; 326 bufbeg = buflim - save; 327 } 328 else 329 { 330 size_t minsize = save + pagesize; 331 size_t newsize; 332 size_t newalloc; 333 char *newbuf; 334 335 /* Grow newsize until it is at least as great as minsize. */ 336 for (newsize = bufalloc - pagesize - 1; newsize < minsize; newsize *= 2) 337 if (newsize * 2 < newsize || newsize * 2 + pagesize + 1 < newsize * 2) 338 xalloc_die (); 339 340 /* Try not to allocate more memory than the file size indicates, 341 as that might cause unnecessary memory exhaustion if the file 342 is large. However, do not use the original file size as a 343 heuristic if we've already read past the file end, as most 344 likely the file is growing. */ 345 if (S_ISREG (stats->stat.st_mode)) 346 { 347 off_t to_be_read = stats->stat.st_size - bufoffset; 348 off_t maxsize_off = save + to_be_read; 349 if (0 <= to_be_read && to_be_read <= maxsize_off 350 && maxsize_off == (size_t) maxsize_off 351 && minsize <= (size_t) maxsize_off 352 && (size_t) maxsize_off < newsize) 353 newsize = maxsize_off; 354 } 355 356 /* Add enough room so that the buffer is aligned and has room 357 for byte sentinels fore and aft. */ 358 newalloc = newsize + pagesize + 1; 359 360 newbuf = bufalloc < newalloc ? xmalloc (bufalloc = newalloc) : buffer; 361 readbuf = ALIGN_TO (newbuf + 1 + save, pagesize); 362 bufbeg = readbuf - save; 363 memmove (bufbeg, buffer + saved_offset, save); 364 bufbeg[-1] = eolbyte; 365 if (newbuf != buffer) 366 { 367 free (buffer); 368 buffer = newbuf; 369 } 370 } 371 372 readsize = buffer + bufalloc - readbuf; 373 readsize -= readsize % pagesize; 374 375 #if defined(HAVE_MMAP) 376 if (bufmapped) 377 { 378 size_t mmapsize = readsize; 379 380 /* Don't mmap past the end of the file; some hosts don't allow this. 381 Use `read' on the last page. */ 382 if (stats->stat.st_size - bufoffset < mmapsize) 383 { 384 mmapsize = stats->stat.st_size - bufoffset; 385 mmapsize -= mmapsize % pagesize; 386 } 387 388 if (mmapsize 389 && (mmap ((caddr_t) readbuf, mmapsize, 390 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, 391 bufdesc, bufoffset) 392 != (caddr_t) -1)) 393 { 394 /* Do not bother to use madvise with MADV_SEQUENTIAL or 395 MADV_WILLNEED on the mmapped memory. One might think it 396 would help, but it slows us down about 30% on SunOS 4.1. */ 397 fillsize = mmapsize; 398 } 399 else 400 { 401 /* Stop using mmap on this file. Synchronize the file 402 offset. Do not warn about mmap failures. On some hosts 403 (e.g. Solaris 2.5) mmap can fail merely because some 404 other process has an advisory read lock on the file. 405 There's no point alarming the user about this misfeature. */ 406 bufmapped = 0; 407 if (bufoffset != initial_bufoffset 408 && lseek (bufdesc, bufoffset, SEEK_SET) < 0) 409 { 410 error (0, errno, "lseek"); 411 cc = 0; 412 } 413 } 414 } 415 #endif /*HAVE_MMAP*/ 416 417 if (! fillsize) 418 { 419 ssize_t bytesread; 420 while ((bytesread = read (bufdesc, readbuf, readsize)) < 0 421 && errno == EINTR) 422 continue; 423 if (bytesread < 0) 424 cc = 0; 425 else 426 fillsize = bytesread; 427 } 428 429 bufoffset += fillsize; 430 #if defined(HAVE_DOS_FILE_CONTENTS) 431 if (fillsize) 432 fillsize = undossify_input (readbuf, fillsize); 433 #endif 434 buflim = readbuf + fillsize; 435 return cc; 436 } 437 438 /* Flags controlling the style of output. */ 439 static enum 440 { 441 BINARY_BINARY_FILES, 442 TEXT_BINARY_FILES, 443 WITHOUT_MATCH_BINARY_FILES 444 } binary_files; /* How to handle binary files. */ 445 446 static int filename_mask; /* If zero, output nulls after filenames. */ 447 static int out_quiet; /* Suppress all normal output. */ 448 static int out_invert; /* Print nonmatching stuff. */ 449 static int out_file; /* Print filenames. */ 450 static int out_line; /* Print line numbers. */ 451 static int out_byte; /* Print byte offsets. */ 452 static int out_before; /* Lines of leading context. */ 453 static int out_after; /* Lines of trailing context. */ 454 static int count_matches; /* Count matching lines. */ 455 static int list_files; /* List matching files. */ 456 static int no_filenames; /* Suppress file names. */ 457 static off_t max_count; /* Stop after outputting this many 458 lines from an input file. */ 459 static int line_buffered; /* If nonzero, use line buffering, i.e. 460 fflush everyline out. */ 461 static char *label = NULL; /* Fake filename for stdin */ 462 463 464 /* Internal variables to keep track of byte count, context, etc. */ 465 static uintmax_t totalcc; /* Total character count before bufbeg. */ 466 static char const *lastnl; /* Pointer after last newline counted. */ 467 static char const *lastout; /* Pointer after last character output; 468 NULL if no character has been output 469 or if it's conceptually before bufbeg. */ 470 static uintmax_t totalnl; /* Total newline count before lastnl. */ 471 static off_t outleft; /* Maximum number of lines to be output. */ 472 static int pending; /* Pending lines of output. 473 Always kept 0 if out_quiet is true. */ 474 static int done_on_match; /* Stop scanning file on first match. */ 475 static int exit_on_match; /* Exit on first match. */ 476 477 #if defined(HAVE_DOS_FILE_CONTENTS) 478 # include "dosbuf.c" 479 #endif 480 481 /* Add two numbers that count input bytes or lines, and report an 482 error if the addition overflows. */ 483 static uintmax_t 484 add_count (uintmax_t a, uintmax_t b) 485 { 486 uintmax_t sum = a + b; 487 if (sum < a) 488 error (2, 0, _("input is too large to count")); 489 return sum; 490 } 491 492 static void 493 nlscan (char const *lim) 494 { 495 size_t newlines = 0; 496 char const *beg; 497 for (beg = lastnl; beg != lim; beg = memchr (beg, eolbyte, lim - beg), beg++) 498 newlines++; 499 totalnl = add_count (totalnl, newlines); 500 lastnl = lim; 501 } 502 503 /* Print a byte offset, followed by a character separator. */ 504 static void 505 print_offset_sep (uintmax_t pos, char sep) 506 { 507 /* Do not rely on printf to print pos, since uintmax_t may be longer 508 than long, and long long is not portable. */ 509 510 char buf[sizeof pos * CHAR_BIT]; 511 char *p = buf + sizeof buf - 1; 512 *p = sep; 513 514 do 515 *--p = '0' + pos % 10; 516 while ((pos /= 10) != 0); 517 518 fwrite (p, 1, buf + sizeof buf - p, stdout); 519 } 520 521 static void 522 prline (char const *beg, char const *lim, int sep) 523 { 524 if (out_file) 525 printf ("%s%c", filename, sep & filename_mask); 526 if (out_line) 527 { 528 nlscan (beg); 529 totalnl = add_count (totalnl, 1); 530 print_offset_sep (totalnl, sep); 531 lastnl = lim; 532 } 533 if (out_byte) 534 { 535 uintmax_t pos = add_count (totalcc, beg - bufbeg); 536 #if defined(HAVE_DOS_FILE_CONTENTS) 537 pos = dossified_pos (pos); 538 #endif 539 print_offset_sep (pos, sep); 540 } 541 if (only_matching) 542 { 543 size_t match_size; 544 size_t match_offset; 545 while ((match_offset = (*execute) (beg, lim - beg, &match_size, 1)) 546 != (size_t) -1) 547 { 548 char const *b = beg + match_offset; 549 if (b == lim) 550 break; 551 if (match_size == 0) 552 { 553 beg++; 554 continue; 555 } 556 if(color_option) 557 printf("\33[%sm", grep_color); 558 fwrite(b, sizeof (char), match_size, stdout); 559 if(color_option) 560 fputs("\33[00m", stdout); 561 fputs("\n", stdout); 562 beg = b + match_size; 563 } 564 lastout = lim; 565 if(line_buffered) 566 fflush(stdout); 567 return; 568 } 569 if (color_option) 570 { 571 size_t match_size; 572 size_t match_offset; 573 if(match_icase) 574 { 575 /* Yuck, this is tricky */ 576 char *buf = (char*) xmalloc (lim - beg); 577 char *ibeg = buf; 578 char *ilim = ibeg + (lim - beg); 579 int i; 580 for (i = 0; i < lim - beg; i++) 581 ibeg[i] = tolower (beg[i]); 582 while ((match_offset = (*execute) (ibeg, ilim-ibeg, &match_size, 1)) 583 != (size_t) -1) 584 { 585 char const *b = beg + match_offset; 586 if (b == lim) 587 break; 588 fwrite (beg, sizeof (char), match_offset, stdout); 589 printf ("\33[%sm", grep_color); 590 fwrite (b, sizeof (char), match_size, stdout); 591 fputs ("\33[00m", stdout); 592 beg = b + match_size; 593 ibeg = ibeg + match_offset + match_size; 594 } 595 fwrite (beg, 1, lim - beg, stdout); 596 free (buf); 597 lastout = lim; 598 return; 599 } 600 while (lim-beg && (match_offset = (*execute) (beg, lim - beg, &match_size, 1)) 601 != (size_t) -1) 602 { 603 char const *b = beg + match_offset; 604 /* Avoid matching the empty line at the end of the buffer. */ 605 if (b == lim) 606 break; 607 /* Avoid hanging on grep --color "" foo */ 608 if (match_size == 0) 609 break; 610 fwrite (beg, sizeof (char), match_offset, stdout); 611 printf ("\33[%sm", grep_color); 612 fwrite (b, sizeof (char), match_size, stdout); 613 fputs ("\33[00m", stdout); 614 beg = b + match_size; 615 } 616 } 617 fwrite (beg, 1, lim - beg, stdout); 618 if (ferror (stdout)) 619 error (0, errno, _("writing output")); 620 lastout = lim; 621 if (line_buffered) 622 fflush (stdout); 623 } 624 625 /* Print pending lines of trailing context prior to LIM. Trailing context ends 626 at the next matching line when OUTLEFT is 0. */ 627 static void 628 prpending (char const *lim) 629 { 630 if (!lastout) 631 lastout = bufbeg; 632 while (pending > 0 && lastout < lim) 633 { 634 char const *nl = memchr (lastout, eolbyte, lim - lastout); 635 size_t match_size; 636 --pending; 637 if (outleft 638 || (((*execute) (lastout, nl - lastout, &match_size, 0) == (size_t) -1) 639 == !out_invert)) 640 prline (lastout, nl + 1, '-'); 641 else 642 pending = 0; 643 } 644 } 645 646 /* Print the lines between BEG and LIM. Deal with context crap. 647 If NLINESP is non-null, store a count of lines between BEG and LIM. */ 648 static void 649 prtext (char const *beg, char const *lim, int *nlinesp) 650 { 651 static int used; /* avoid printing "--" before any output */ 652 char const *bp, *p; 653 char eol = eolbyte; 654 int i, n; 655 656 if (!out_quiet && pending > 0) 657 prpending (beg); 658 659 p = beg; 660 661 if (!out_quiet) 662 { 663 /* Deal with leading context crap. */ 664 665 bp = lastout ? lastout : bufbeg; 666 for (i = 0; i < out_before; ++i) 667 if (p > bp) 668 do 669 --p; 670 while (p[-1] != eol); 671 672 /* We only print the "--" separator if our output is 673 discontiguous from the last output in the file. */ 674 if ((out_before || out_after) && used && p != lastout) 675 puts ("--"); 676 677 while (p < beg) 678 { 679 char const *nl = memchr (p, eol, beg - p); 680 nl++; 681 prline (p, nl, '-'); 682 p = nl; 683 } 684 } 685 686 if (nlinesp) 687 { 688 /* Caller wants a line count. */ 689 for (n = 0; p < lim && n < outleft; n++) 690 { 691 char const *nl = memchr (p, eol, lim - p); 692 nl++; 693 if (!out_quiet) 694 prline (p, nl, ':'); 695 p = nl; 696 } 697 *nlinesp = n; 698 699 /* relying on it that this function is never called when outleft = 0. */ 700 after_last_match = bufoffset - (buflim - p); 701 } 702 else 703 if (!out_quiet) 704 prline (beg, lim, ':'); 705 706 pending = out_quiet ? 0 : out_after; 707 used = 1; 708 } 709 710 /* Scan the specified portion of the buffer, matching lines (or 711 between matching lines if OUT_INVERT is true). Return a count of 712 lines printed. */ 713 static int 714 grepbuf (char const *beg, char const *lim) 715 { 716 int nlines, n; 717 register char const *p; 718 size_t match_offset; 719 size_t match_size; 720 721 nlines = 0; 722 p = beg; 723 while ((match_offset = (*execute) (p, lim - p, &match_size, 0)) != (size_t) -1) 724 { 725 char const *b = p + match_offset; 726 char const *endp = b + match_size; 727 /* Avoid matching the empty line at the end of the buffer. */ 728 if (b == lim) 729 break; 730 if (!out_invert) 731 { 732 prtext (b, endp, (int *) 0); 733 nlines++; 734 outleft--; 735 if (!outleft || done_on_match) 736 { 737 if (exit_on_match) 738 exit (0); 739 after_last_match = bufoffset - (buflim - endp); 740 return nlines; 741 } 742 } 743 else if (p < b) 744 { 745 prtext (p, b, &n); 746 nlines += n; 747 outleft -= n; 748 if (!outleft) 749 return nlines; 750 } 751 p = endp; 752 } 753 if (out_invert && p < lim) 754 { 755 prtext (p, lim, &n); 756 nlines += n; 757 outleft -= n; 758 } 759 return nlines; 760 } 761 762 /* Search a given file. Normally, return a count of lines printed; 763 but if the file is a directory and we search it recursively, then 764 return -2 if there was a match, and -1 otherwise. */ 765 static int 766 grep (int fd, char const *file, struct stats *stats) 767 { 768 int nlines, i; 769 int not_text; 770 size_t residue, save; 771 char oldc; 772 char *beg; 773 char *lim; 774 char eol = eolbyte; 775 776 if (!reset (fd, file, stats)) 777 return 0; 778 779 if (file && directories == RECURSE_DIRECTORIES 780 && S_ISDIR (stats->stat.st_mode)) 781 { 782 /* Close fd now, so that we don't open a lot of file descriptors 783 when we recurse deeply. */ 784 if (close (fd) != 0) 785 error (0, errno, "%s", file); 786 return grepdir (file, stats) - 2; 787 } 788 789 totalcc = 0; 790 lastout = 0; 791 totalnl = 0; 792 outleft = max_count; 793 after_last_match = 0; 794 pending = 0; 795 796 nlines = 0; 797 residue = 0; 798 save = 0; 799 800 if (! fillbuf (save, stats)) 801 { 802 if (! is_EISDIR (errno, file)) 803 suppressible_error (filename, errno); 804 return 0; 805 } 806 807 not_text = (((binary_files == BINARY_BINARY_FILES && !out_quiet) 808 || binary_files == WITHOUT_MATCH_BINARY_FILES) 809 && memchr (bufbeg, eol ? '\0' : '\200', buflim - bufbeg)); 810 if (not_text && binary_files == WITHOUT_MATCH_BINARY_FILES) 811 return 0; 812 done_on_match += not_text; 813 out_quiet += not_text; 814 815 for (;;) 816 { 817 lastnl = bufbeg; 818 if (lastout) 819 lastout = bufbeg; 820 821 beg = bufbeg + save; 822 823 /* no more data to scan (eof) except for maybe a residue -> break */ 824 if (beg == buflim) 825 break; 826 827 /* Determine new residue (the length of an incomplete line at the end of 828 the buffer, 0 means there is no incomplete last line). */ 829 oldc = beg[-1]; 830 beg[-1] = eol; 831 for (lim = buflim; lim[-1] != eol; lim--) 832 continue; 833 beg[-1] = oldc; 834 if (lim == beg) 835 lim = beg - residue; 836 beg -= residue; 837 residue = buflim - lim; 838 839 if (beg < lim) 840 { 841 if (outleft) 842 nlines += grepbuf (beg, lim); 843 if (pending) 844 prpending (lim); 845 if((!outleft && !pending) || (nlines && done_on_match && !out_invert)) 846 goto finish_grep; 847 } 848 849 /* The last OUT_BEFORE lines at the end of the buffer will be needed as 850 leading context if there is a matching line at the begin of the 851 next data. Make beg point to their begin. */ 852 i = 0; 853 beg = lim; 854 while (i < out_before && beg > bufbeg && beg != lastout) 855 { 856 ++i; 857 do 858 --beg; 859 while (beg[-1] != eol); 860 } 861 862 /* detect if leading context is discontinuous from last printed line. */ 863 if (beg != lastout) 864 lastout = 0; 865 866 /* Handle some details and read more data to scan. */ 867 save = residue + lim - beg; 868 if (out_byte) 869 totalcc = add_count (totalcc, buflim - bufbeg - save); 870 if (out_line) 871 nlscan (beg); 872 if (! fillbuf (save, stats)) 873 { 874 if (! is_EISDIR (errno, file)) 875 suppressible_error (filename, errno); 876 goto finish_grep; 877 } 878 } 879 if (residue) 880 { 881 *buflim++ = eol; 882 if (outleft) 883 nlines += grepbuf (bufbeg + save - residue, buflim); 884 if (pending) 885 prpending (buflim); 886 } 887 888 finish_grep: 889 done_on_match -= not_text; 890 out_quiet -= not_text; 891 if ((not_text & ~out_quiet) && nlines != 0) 892 printf (_("Binary file %s matches\n"), filename); 893 return nlines; 894 } 895 896 static int 897 grepfile (char const *file, struct stats *stats) 898 { 899 int desc; 900 int count; 901 int status; 902 903 if (! file) 904 { 905 desc = 0; 906 filename = label ? label : _("(standard input)"); 907 } 908 else 909 { 910 while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR) 911 continue; 912 913 if (desc < 0) 914 { 915 int e = errno; 916 917 if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES) 918 { 919 if (stat (file, &stats->stat) != 0) 920 { 921 error (0, errno, "%s", file); 922 return 1; 923 } 924 925 return grepdir (file, stats); 926 } 927 928 if (!suppress_errors) 929 { 930 if (directories == SKIP_DIRECTORIES) 931 switch (e) 932 { 933 #if defined(EISDIR) 934 case EISDIR: 935 return 1; 936 #endif 937 case EACCES: 938 /* When skipping directories, don't worry about 939 directories that can't be opened. */ 940 if (isdir (file)) 941 return 1; 942 break; 943 } 944 } 945 946 suppressible_error (file, e); 947 return 1; 948 } 949 950 filename = file; 951 } 952 953 #if defined(SET_BINARY) 954 /* Set input to binary mode. Pipes are simulated with files 955 on DOS, so this includes the case of "foo | grep bar". */ 956 if (!isatty (desc)) 957 SET_BINARY (desc); 958 #endif 959 960 count = grep (desc, file, stats); 961 if (count < 0) 962 status = count + 2; 963 else 964 { 965 if (count_matches) 966 { 967 if (out_file) 968 printf ("%s%c", filename, ':' & filename_mask); 969 printf ("%d\n", count); 970 } 971 972 status = !count; 973 if (list_files == 1 - 2 * status) 974 printf ("%s%c", filename, '\n' & filename_mask); 975 976 if (! file) 977 { 978 off_t required_offset = outleft ? bufoffset : after_last_match; 979 if ((bufmapped || required_offset != bufoffset) 980 && lseek (desc, required_offset, SEEK_SET) < 0 981 && S_ISREG (stats->stat.st_mode)) 982 error (0, errno, "%s", filename); 983 } 984 else 985 while (close (desc) != 0) 986 if (errno != EINTR) 987 { 988 error (0, errno, "%s", file); 989 break; 990 } 991 } 992 993 return status; 994 } 995 996 static int 997 grepdir (char const *dir, struct stats const *stats) 998 { 999 int status = 1; 1000 struct stats const *ancestor; 1001 char *name_space; 1002 1003 /* Mingw32 does not support st_ino. No known working hosts use zero 1004 for st_ino, so assume that the Mingw32 bug applies if it's zero. */ 1005 if (stats->stat.st_ino) 1006 for (ancestor = stats; (ancestor = ancestor->parent) != 0; ) 1007 if (ancestor->stat.st_ino == stats->stat.st_ino 1008 && ancestor->stat.st_dev == stats->stat.st_dev) 1009 { 1010 if (!suppress_errors) 1011 error (0, 0, _("warning: %s: %s"), dir, 1012 _("recursive directory loop")); 1013 return 1; 1014 } 1015 1016 name_space = savedir (dir, stats->stat.st_size, included_patterns, 1017 excluded_patterns); 1018 1019 if (! name_space) 1020 { 1021 if (errno) 1022 suppressible_error (dir, errno); 1023 else 1024 xalloc_die (); 1025 } 1026 else 1027 { 1028 size_t dirlen = strlen (dir); 1029 int needs_slash = ! (dirlen == FILESYSTEM_PREFIX_LEN (dir) 1030 || IS_SLASH (dir[dirlen - 1])); 1031 char *file = NULL; 1032 char const *namep = name_space; 1033 struct stats child; 1034 child.parent = stats; 1035 out_file += !no_filenames; 1036 while (*namep) 1037 { 1038 size_t namelen = strlen (namep); 1039 file = xrealloc (file, dirlen + 1 + namelen + 1); 1040 strcpy (file, dir); 1041 file[dirlen] = '/'; 1042 strcpy (file + dirlen + needs_slash, namep); 1043 namep += namelen + 1; 1044 status &= grepfile (file, &child); 1045 } 1046 out_file -= !no_filenames; 1047 if (file) 1048 free (file); 1049 free (name_space); 1050 } 1051 1052 return status; 1053 } 1054 1055 static void 1056 usage (int status) 1057 { 1058 if (status != 0) 1059 { 1060 fprintf (stderr, _("Usage: %s [OPTION]... PATTERN [FILE]...\n"), 1061 program_name); 1062 fprintf (stderr, _("Try `%s --help' for more information.\n"), 1063 program_name); 1064 } 1065 else 1066 { 1067 printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), program_name); 1068 printf (_("\ 1069 Search for PATTERN in each FILE or standard input.\n\ 1070 Example: %s -i 'hello world' menu.h main.c\n\ 1071 \n\ 1072 Regexp selection and interpretation:\n"), program_name); 1073 printf (_("\ 1074 -E, --extended-regexp PATTERN is an extended regular expression\n\ 1075 -F, --fixed-strings PATTERN is a set of newline-separated strings\n\ 1076 -G, --basic-regexp PATTERN is a basic regular expression\n")); 1077 #if HAVE_LIBPCRE 1078 printf (_("\ 1079 -P, --perl-regexp PATTERN is a Perl regular expression\n")); 1080 #endif 1081 printf (_("\ 1082 -e, --regexp=PATTERN use PATTERN as a regular expression\n\ 1083 -f, --file=FILE obtain PATTERN from FILE\n\ 1084 -i, --ignore-case ignore case distinctions\n\ 1085 -w, --word-regexp force PATTERN to match only whole words\n\ 1086 -x, --line-regexp force PATTERN to match only whole lines\n\ 1087 -z, --null-data a data line ends in 0 byte, not newline\n")); 1088 printf (_("\ 1089 \n\ 1090 Miscellaneous:\n\ 1091 -s, --no-messages suppress error messages\n\ 1092 -v, --invert-match select non-matching lines\n\ 1093 -V, --version print version information and exit\n\ 1094 --help display this help and exit\n\ 1095 --mmap use memory-mapped input if possible\n")); 1096 printf (_("\ 1097 \n\ 1098 Output control:\n\ 1099 -m, --max-count=NUM stop after NUM matches\n\ 1100 -b, --byte-offset print the byte offset with output lines\n\ 1101 -n, --line-number print line number with output lines\n\ 1102 --line-buffered flush output on every line\n\ 1103 -H, --with-filename print the filename for each match\n\ 1104 -h, --no-filename suppress the prefixing filename on output\n\ 1105 --label=LABEL print LABEL as filename for standard input\n\ 1106 -o, --only-matching show only the part of a line matching PATTERN\n\ 1107 -q, --quiet, --silent suppress all normal output\n\ 1108 --binary-files=TYPE assume that binary files are TYPE\n\ 1109 TYPE is 'binary', 'text', or 'without-match'\n\ 1110 -a, --text equivalent to --binary-files=text\n\ 1111 -I equivalent to --binary-files=without-match\n\ 1112 -d, --directories=ACTION how to handle directories\n\ 1113 ACTION is 'read', 'recurse', or 'skip'\n\ 1114 -D, --devices=ACTION how to handle devices, FIFOs and sockets\n\ 1115 ACTION is 'read' or 'skip'\n\ 1116 -R, -r, --recursive equivalent to --directories=recurse\n\ 1117 --include=PATTERN files that match PATTERN will be examined\n\ 1118 --exclude=PATTERN files that match PATTERN will be skipped.\n\ 1119 --exclude-from=FILE files that match PATTERN in FILE will be skipped.\n\ 1120 -L, --files-without-match only print FILE names containing no match\n\ 1121 -l, --files-with-matches only print FILE names containing matches\n\ 1122 -c, --count only print a count of matching lines per FILE\n\ 1123 -Z, --null print 0 byte after FILE name\n")); 1124 printf (_("\ 1125 \n\ 1126 Context control:\n\ 1127 -B, --before-context=NUM print NUM lines of leading context\n\ 1128 -A, --after-context=NUM print NUM lines of trailing context\n\ 1129 -C, --context=NUM print NUM lines of output context\n\ 1130 -NUM same as --context=NUM\n\ 1131 --color[=WHEN],\n\ 1132 --colour[=WHEN] use markers to distinguish the matching string\n\ 1133 WHEN may be `always', `never' or `auto'.\n\ 1134 -U, --binary do not strip CR characters at EOL (MSDOS)\n\ 1135 -u, --unix-byte-offsets report offsets as if CRs were not there (MSDOS)\n\ 1136 \n\ 1137 `egrep' means `grep -E'. `fgrep' means `grep -F'.\n\ 1138 With no FILE, or when FILE is -, read standard input. If less than\n\ 1139 two FILEs given, assume -h. Exit status is 0 if match, 1 if no match,\n\ 1140 and 2 if trouble.\n")); 1141 printf (_("\nReport bugs to <bug-grep@gnu.org>.\n")); 1142 } 1143 exit (status); 1144 } 1145 1146 /* Set the matcher to M, reporting any conflicts. */ 1147 static void 1148 setmatcher (char const *m) 1149 { 1150 if (matcher && strcmp (matcher, m) != 0) 1151 error (2, 0, _("conflicting matchers specified")); 1152 matcher = m; 1153 } 1154 1155 /* Go through the matchers vector and look for the specified matcher. 1156 If we find it, install it in compile and execute, and return 1. */ 1157 static int 1158 install_matcher (char const *name) 1159 { 1160 int i; 1161 #if defined(HAVE_SETRLIMIT) 1162 struct rlimit rlim; 1163 #endif 1164 1165 for (i = 0; matchers[i].compile; i++) 1166 if (strcmp (name, matchers[i].name) == 0) 1167 { 1168 compile = matchers[i].compile; 1169 execute = matchers[i].execute; 1170 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK) 1171 /* I think every platform needs to do this, so that regex.c 1172 doesn't oveflow the stack. The default value of 1173 `re_max_failures' is too large for some platforms: it needs 1174 more than 3MB-large stack. 1175 1176 The test for HAVE_SETRLIMIT should go into `configure'. */ 1177 if (!getrlimit (RLIMIT_STACK, &rlim)) 1178 { 1179 long newlim; 1180 extern long int re_max_failures; /* from regex.c */ 1181 1182 /* Approximate the amount regex.c needs, plus some more. */ 1183 newlim = re_max_failures * 2 * 20 * sizeof (char *); 1184 if (newlim > rlim.rlim_max) 1185 { 1186 newlim = rlim.rlim_max; 1187 re_max_failures = newlim / (2 * 20 * sizeof (char *)); 1188 } 1189 if (rlim.rlim_cur < newlim) 1190 { 1191 rlim.rlim_cur = newlim; 1192 setrlimit (RLIMIT_STACK, &rlim); 1193 } 1194 } 1195 #endif 1196 return 1; 1197 } 1198 return 0; 1199 } 1200 1201 /* Find the white-space-separated options specified by OPTIONS, and 1202 using BUF to store copies of these options, set ARGV[0], ARGV[1], 1203 etc. to the option copies. Return the number N of options found. 1204 Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0] 1205 etc. Backslash can be used to escape whitespace (and backslashes). */ 1206 static int 1207 prepend_args (char const *options, char *buf, char **argv) 1208 { 1209 char const *o = options; 1210 char *b = buf; 1211 int n = 0; 1212 1213 for (;;) 1214 { 1215 while (ISSPACE ((unsigned char) *o)) 1216 o++; 1217 if (!*o) 1218 return n; 1219 if (argv) 1220 argv[n] = b; 1221 n++; 1222 1223 do 1224 if ((*b++ = *o++) == '\\' && *o) 1225 b[-1] = *o++; 1226 while (*o && ! ISSPACE ((unsigned char) *o)); 1227 1228 *b++ = '\0'; 1229 } 1230 } 1231 1232 /* Prepend the whitespace-separated options in OPTIONS to the argument 1233 vector of a main program with argument count *PARGC and argument 1234 vector *PARGV. */ 1235 static void 1236 prepend_default_options (char const *options, int *pargc, char ***pargv) 1237 { 1238 if (options) 1239 { 1240 char *buf = xmalloc (strlen (options) + 1); 1241 int prepended = prepend_args (options, buf, (char **) NULL); 1242 int argc = *pargc; 1243 char * const *argv = *pargv; 1244 char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp); 1245 *pargc = prepended + argc; 1246 *pargv = pp; 1247 *pp++ = *argv++; 1248 pp += prepend_args (options, buf, pp); 1249 while ((*pp++ = *argv++)) 1250 continue; 1251 } 1252 } 1253 1254 /* Get the next non-digit option from ARGC and ARGV. 1255 Return -1 if there are no more options. 1256 Process any digit options that were encountered on the way, 1257 and store the resulting integer into *DEFAULT_CONTEXT. */ 1258 static int 1259 get_nondigit_option (int argc, char *const *argv, int *default_context) 1260 { 1261 int opt; 1262 char buf[sizeof (uintmax_t) * CHAR_BIT + 4]; 1263 char *p = buf; 1264 1265 /* Set buf[0] to anything but '0', for the leading-zero test below. */ 1266 buf[0] = '\0'; 1267 1268 while (opt = getopt_long (argc, argv, short_options, long_options, NULL), 1269 '0' <= opt && opt <= '9') 1270 { 1271 /* Suppress trivial leading zeros, to avoid incorrect 1272 diagnostic on strings like 00000000000. */ 1273 p -= buf[0] == '0'; 1274 1275 *p++ = opt; 1276 if (p == buf + sizeof buf - 4) 1277 { 1278 /* Too many digits. Append "..." to make context_length_arg 1279 complain about "X...", where X contains the digits seen 1280 so far. */ 1281 strcpy (p, "..."); 1282 p += 3; 1283 break; 1284 } 1285 } 1286 if (p != buf) 1287 { 1288 *p = '\0'; 1289 context_length_arg (buf, default_context); 1290 } 1291 1292 return opt; 1293 } 1294 1295 int 1296 main (int argc, char **argv) 1297 { 1298 char *keys; 1299 size_t cc, keycc, oldcc, keyalloc; 1300 int with_filenames; 1301 int opt, status; 1302 int default_context; 1303 FILE *fp; 1304 extern char *optarg; 1305 extern int optind; 1306 #ifdef __NetBSD__ 1307 extern char *__progname; 1308 #endif 1309 1310 initialize_main (&argc, &argv); 1311 program_name = argv[0]; 1312 if (program_name && strrchr (program_name, '/')) 1313 program_name = strrchr (program_name, '/') + 1; 1314 1315 if (!strcmp(program_name, "egrep")) 1316 setmatcher ("egrep"); 1317 if (!strcmp(program_name, "fgrep")) 1318 setmatcher ("fgrep"); 1319 1320 #if defined(__MSDOS__) || defined(_WIN32) 1321 /* DOS and MS-Windows use backslashes as directory separators, and usually 1322 have an .exe suffix. They also have case-insensitive filesystems. */ 1323 if (program_name) 1324 { 1325 char *p = program_name; 1326 char *bslash = strrchr (argv[0], '\\'); 1327 1328 if (bslash && bslash >= program_name) /* for mixed forward/backslash case */ 1329 program_name = bslash + 1; 1330 else if (program_name == argv[0] 1331 && argv[0][0] && argv[0][1] == ':') /* "c:progname" */ 1332 program_name = argv[0] + 2; 1333 1334 /* Collapse the letter-case, so `strcmp' could be used hence. */ 1335 for ( ; *p; p++) 1336 if (*p >= 'A' && *p <= 'Z') 1337 *p += 'a' - 'A'; 1338 1339 /* Remove the .exe extension, if any. */ 1340 if ((p = strrchr (program_name, '.')) && strcmp (p, ".exe") == 0) 1341 *p = '\0'; 1342 } 1343 #endif 1344 1345 keys = NULL; 1346 keycc = 0; 1347 with_filenames = 0; 1348 eolbyte = '\n'; 1349 filename_mask = ~0; 1350 1351 max_count = MAX_OFF_T; 1352 1353 /* The value -1 means to use DEFAULT_CONTEXT. */ 1354 out_after = out_before = -1; 1355 /* Default before/after context: chaged by -C/-NUM options */ 1356 default_context = 0; 1357 /* Changed by -o option */ 1358 only_matching = 0; 1359 1360 /* Internationalization. */ 1361 #if defined(HAVE_SETLOCALE) 1362 setlocale (LC_ALL, ""); 1363 #endif 1364 #if defined(ENABLE_NLS) 1365 bindtextdomain (PACKAGE, LOCALEDIR); 1366 textdomain (PACKAGE); 1367 #endif 1368 1369 atexit (close_stdout); 1370 1371 prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv); 1372 1373 while ((opt = get_nondigit_option (argc, argv, &default_context)) != -1) 1374 switch (opt) 1375 { 1376 case 'A': 1377 context_length_arg (optarg, &out_after); 1378 break; 1379 1380 case 'B': 1381 context_length_arg (optarg, &out_before); 1382 break; 1383 1384 case 'C': 1385 /* Set output match context, but let any explicit leading or 1386 trailing amount specified with -A or -B stand. */ 1387 context_length_arg (optarg, &default_context); 1388 break; 1389 1390 case 'D': 1391 if (strcmp (optarg, "read") == 0) 1392 devices = READ_DEVICES; 1393 else if (strcmp (optarg, "skip") == 0) 1394 devices = SKIP_DEVICES; 1395 else 1396 error (2, 0, _("unknown devices method")); 1397 break; 1398 1399 case 'E': 1400 setmatcher ("egrep"); 1401 break; 1402 1403 case 'F': 1404 setmatcher ("fgrep"); 1405 break; 1406 1407 case 'P': 1408 setmatcher ("perl"); 1409 break; 1410 1411 case 'G': 1412 setmatcher ("grep"); 1413 break; 1414 1415 case 'H': 1416 with_filenames = 1; 1417 break; 1418 1419 case 'I': 1420 binary_files = WITHOUT_MATCH_BINARY_FILES; 1421 break; 1422 1423 case 'U': 1424 #if defined(HAVE_DOS_FILE_CONTENTS) 1425 dos_use_file_type = DOS_BINARY; 1426 #endif 1427 break; 1428 1429 case 'u': 1430 #if defined(HAVE_DOS_FILE_CONTENTS) 1431 dos_report_unix_offset = 1; 1432 #endif 1433 break; 1434 1435 case 'V': 1436 show_version = 1; 1437 break; 1438 1439 case 'X': 1440 setmatcher (optarg); 1441 break; 1442 1443 case 'a': 1444 binary_files = TEXT_BINARY_FILES; 1445 break; 1446 1447 case 'b': 1448 out_byte = 1; 1449 break; 1450 1451 case 'c': 1452 count_matches = 1; 1453 break; 1454 1455 case 'd': 1456 if (strcmp (optarg, "read") == 0) 1457 directories = READ_DIRECTORIES; 1458 else if (strcmp (optarg, "skip") == 0) 1459 directories = SKIP_DIRECTORIES; 1460 else if (strcmp (optarg, "recurse") == 0) 1461 directories = RECURSE_DIRECTORIES; 1462 else 1463 error (2, 0, _("unknown directories method")); 1464 break; 1465 1466 case 'e': 1467 cc = strlen (optarg); 1468 keys = xrealloc (keys, keycc + cc + 1); 1469 strcpy (&keys[keycc], optarg); 1470 keycc += cc; 1471 keys[keycc++] = '\n'; 1472 break; 1473 1474 case 'f': 1475 fp = strcmp (optarg, "-") != 0 ? fopen (optarg, "r") : stdin; 1476 if (!fp) 1477 error (2, errno, "%s", optarg); 1478 for (keyalloc = 1; keyalloc <= keycc + 1; keyalloc *= 2) 1479 ; 1480 keys = xrealloc (keys, keyalloc); 1481 oldcc = keycc; 1482 while (!feof (fp) 1483 && (cc = fread (keys + keycc, 1, keyalloc - 1 - keycc, fp)) > 0) 1484 { 1485 keycc += cc; 1486 if (keycc == keyalloc - 1) 1487 keys = xrealloc (keys, keyalloc *= 2); 1488 } 1489 if (fp != stdin) 1490 fclose(fp); 1491 /* Append final newline if file ended in non-newline. */ 1492 if (oldcc != keycc && keys[keycc - 1] != '\n') 1493 keys[keycc++] = '\n'; 1494 break; 1495 1496 case 'h': 1497 no_filenames = 1; 1498 break; 1499 1500 case 'i': 1501 case 'y': /* For old-timers . . . */ 1502 match_icase = 1; 1503 break; 1504 1505 case 'L': 1506 /* Like -l, except list files that don't contain matches. 1507 Inspired by the same option in Hume's gre. */ 1508 list_files = -1; 1509 break; 1510 1511 case 'l': 1512 list_files = 1; 1513 break; 1514 1515 case 'm': 1516 { 1517 uintmax_t value; 1518 switch (xstrtoumax (optarg, 0, 10, &value, "")) 1519 { 1520 case LONGINT_OK: 1521 max_count = value; 1522 if (0 <= max_count && max_count == value) 1523 break; 1524 /* Fall through. */ 1525 case LONGINT_OVERFLOW: 1526 max_count = MAX_OFF_T; 1527 break; 1528 1529 default: 1530 error (2, 0, _("invalid max count")); 1531 } 1532 } 1533 break; 1534 1535 case 'n': 1536 out_line = 1; 1537 break; 1538 1539 case 'o': 1540 only_matching = 1; 1541 break; 1542 1543 case 'q': 1544 exit_on_match = 1; 1545 close_stdout_set_status(0); 1546 break; 1547 1548 case 'R': 1549 case 'r': 1550 directories = RECURSE_DIRECTORIES; 1551 break; 1552 1553 case 's': 1554 suppress_errors = 1; 1555 break; 1556 1557 case 'v': 1558 out_invert = 1; 1559 break; 1560 1561 case 'w': 1562 match_words = 1; 1563 break; 1564 1565 case 'x': 1566 match_lines = 1; 1567 break; 1568 1569 case 'Z': 1570 filename_mask = 0; 1571 break; 1572 1573 case 'z': 1574 eolbyte = '\0'; 1575 break; 1576 1577 case BINARY_FILES_OPTION: 1578 if (strcmp (optarg, "binary") == 0) 1579 binary_files = BINARY_BINARY_FILES; 1580 else if (strcmp (optarg, "text") == 0) 1581 binary_files = TEXT_BINARY_FILES; 1582 else if (strcmp (optarg, "without-match") == 0) 1583 binary_files = WITHOUT_MATCH_BINARY_FILES; 1584 else 1585 error (2, 0, _("unknown binary-files type")); 1586 break; 1587 1588 case COLOR_OPTION: 1589 if(optarg) { 1590 if(!strcasecmp(optarg, "always") || !strcasecmp(optarg, "yes") || 1591 !strcasecmp(optarg, "force")) 1592 color_option = 1; 1593 else if(!strcasecmp(optarg, "never") || !strcasecmp(optarg, "no") || 1594 !strcasecmp(optarg, "none")) 1595 color_option = 0; 1596 else if(!strcasecmp(optarg, "auto") || !strcasecmp(optarg, "tty") || 1597 !strcasecmp(optarg, "if-tty")) 1598 color_option = 2; 1599 else 1600 show_help = 1; 1601 } else 1602 color_option = 2; 1603 if(color_option == 2) { 1604 if(isatty(STDOUT_FILENO) && getenv("TERM") && 1605 strcmp(getenv("TERM"), "dumb")) 1606 color_option = 1; 1607 else 1608 color_option = 0; 1609 } 1610 break; 1611 1612 case EXCLUDE_OPTION: 1613 if (!excluded_patterns) 1614 excluded_patterns = new_exclude (); 1615 add_exclude (excluded_patterns, optarg); 1616 break; 1617 1618 case EXCLUDE_FROM_OPTION: 1619 if (!excluded_patterns) 1620 excluded_patterns = new_exclude (); 1621 if (add_exclude_file (add_exclude, excluded_patterns, optarg, '\n') 1622 != 0) 1623 { 1624 error (2, errno, "%s", optarg); 1625 } 1626 break; 1627 1628 case INCLUDE_OPTION: 1629 if (!included_patterns) 1630 included_patterns = new_exclude (); 1631 add_exclude (included_patterns, optarg); 1632 break; 1633 1634 case LINE_BUFFERED_OPTION: 1635 line_buffered = 1; 1636 break; 1637 1638 case LABEL_OPTION: 1639 label = optarg; 1640 break; 1641 1642 case 0: 1643 /* long options */ 1644 break; 1645 1646 default: 1647 usage (2); 1648 break; 1649 1650 } 1651 1652 /* POSIX.2 says that -q overrides -l, which in turn overrides the 1653 other output options. */ 1654 if (exit_on_match) 1655 list_files = 0; 1656 if (exit_on_match | list_files) 1657 { 1658 count_matches = 0; 1659 done_on_match = 1; 1660 } 1661 out_quiet = count_matches | done_on_match; 1662 1663 if (out_after < 0) 1664 out_after = default_context; 1665 if (out_before < 0) 1666 out_before = default_context; 1667 1668 if (color_option) 1669 { 1670 char *userval = getenv ("GREP_COLOR"); 1671 if (userval != NULL && *userval != '\0') 1672 grep_color = userval; 1673 } 1674 1675 if (! matcher) 1676 #ifdef __NetBSD__ 1677 matcher = __progname; 1678 #else 1679 matcher = "grep"; 1680 #endif 1681 1682 if (show_version) 1683 { 1684 printf (_("%s (GNU grep) %s\n"), matcher, VERSION); 1685 printf ("\n"); 1686 printf (_("\ 1687 Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.\n")); 1688 printf (_("\ 1689 This is free software; see the source for copying conditions. There is NO\n\ 1690 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n")); 1691 printf ("\n"); 1692 exit (0); 1693 } 1694 1695 if (show_help) 1696 usage (0); 1697 1698 if (keys) 1699 { 1700 if (keycc == 0) 1701 { 1702 /* No keys were specified (e.g. -f /dev/null). Match nothing. */ 1703 out_invert ^= 1; 1704 match_lines = match_words = 0; 1705 } 1706 else 1707 /* Strip trailing newline. */ 1708 --keycc; 1709 } 1710 else 1711 if (optind < argc) 1712 { 1713 keys = argv[optind++]; 1714 keycc = strlen (keys); 1715 } 1716 else 1717 usage (2); 1718 1719 if (!install_matcher (matcher) && !install_matcher ("default")) 1720 abort (); 1721 1722 (*compile)(keys, keycc); 1723 1724 if ((argc - optind > 1 && !no_filenames) || with_filenames) 1725 out_file = 1; 1726 1727 #ifdef SET_BINARY 1728 /* Output is set to binary mode because we shouldn't convert 1729 NL to CR-LF pairs, especially when grepping binary files. */ 1730 if (!isatty (1)) 1731 SET_BINARY (1); 1732 #endif 1733 1734 if (max_count == 0) 1735 exit (1); 1736 1737 if (optind < argc) 1738 { 1739 status = 1; 1740 do 1741 { 1742 char *file = argv[optind]; 1743 if ((included_patterns || excluded_patterns) 1744 && !isdir (file)) 1745 { 1746 if (included_patterns && 1747 ! excluded_filename (included_patterns, file, 0)) 1748 continue; 1749 if (excluded_patterns && 1750 excluded_filename (excluded_patterns, file, 0)) 1751 continue; 1752 } 1753 status &= grepfile (strcmp (file, "-") == 0 ? (char *) NULL : file, 1754 &stats_base); 1755 } 1756 while ( ++optind < argc); 1757 } 1758 else 1759 { 1760 if (directories == RECURSE_DIRECTORIES) { 1761 error (0, 0, _("warning: recursive search of stdin")); 1762 } 1763 status = grepfile ((char *) NULL, &stats_base); 1764 } 1765 1766 /* We register via atexit() to test stdout. */ 1767 exit (errseen ? 2 : status); 1768 } 1769 /* vim:set shiftwidth=2: */ 1770