blob: 6872ac271018987890685ca8a5d92eb3efcc7cde [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersencc8ed391999-10-05 16:24:54 +00002/*
Eric Andersen3e0fbae1999-10-19 06:02:44 +00003 * Mini grep implementation for busybox
Eric Andersencc8ed391999-10-05 16:24:54 +00004 *
Eric Andersenc4996011999-10-20 22:08:37 +00005 *
Erik Andersen61677fe2000-04-13 01:18:56 +00006 * Copyright (C) 1999,2000 by Lineo, inc.
Eric Andersenc4996011999-10-20 22:08:37 +00007 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
Eric Andersencc8ed391999-10-05 16:24:54 +00008 *
Eric Andersen3e0fbae1999-10-19 06:02:44 +00009 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
Eric Andersencc8ed391999-10-05 16:24:54 +000023 */
24
Erik Andersen3fe2ecf1999-12-21 08:52:04 +000025/*
26 18-Dec-1999 Konstantin Boldyshev <konst@voshod.com>
27
28 + -q option (be quiet)
29 + exit code depending on grep result (TRUE or FALSE)
30 (useful for scripts)
31*/
32
Eric Andersencc8ed391999-10-05 16:24:54 +000033#include "internal.h"
Eric Andersenaa0765e1999-10-22 04:30:20 +000034#include "regexp.h"
Eric Andersencc8ed391999-10-05 16:24:54 +000035#include <stdio.h>
36#include <dirent.h>
37#include <errno.h>
38#include <fcntl.h>
39#include <signal.h>
40#include <time.h>
41#include <ctype.h>
42
Eric Andersene77ae3a1999-10-19 20:03:34 +000043static const char grep_usage[] =
Erik Andersen7ab9c7e2000-05-12 19:41:47 +000044 "grep [OPTIONS]... PATTERN [FILE]...\n"
45#ifndef BB_FEATURE_TRIVIAL_HELP
46 "\nSearch for PATTERN in each FILE or standard input.\n\n"
Erik Andersene49d5ec2000-02-08 19:58:47 +000047 "OPTIONS:\n"
48 "\t-h\tsuppress the prefixing filename on output\n"
49 "\t-i\tignore case distinctions\n"
50 "\t-n\tprint line number with output lines\n"
John Beppuf93a95d2000-04-24 18:07:30 +000051 "\t-q\tbe quiet. Returns 0 if result was found, 1 otherwise\n"
52 "\t-v\tselect non-matching lines\n\n"
Eric Andersenaa0765e1999-10-22 04:30:20 +000053#if defined BB_REGEXP
Erik Andersene49d5ec2000-02-08 19:58:47 +000054 "This version of grep matches full regular expresions.\n";
Eric Andersenaa0765e1999-10-22 04:30:20 +000055#else
Erik Andersen7ab9c7e2000-05-12 19:41:47 +000056 "This version of grep matches strings (not regular expresions).\n"
Eric Andersenaa0765e1999-10-22 04:30:20 +000057#endif
Erik Andersen7ab9c7e2000-05-12 19:41:47 +000058#endif
59 ;
Eric Andersencc8ed391999-10-05 16:24:54 +000060
Erik Andersen3fe2ecf1999-12-21 08:52:04 +000061static int match = FALSE, beQuiet = FALSE;
Eric Andersenfbb39c81999-11-08 17:00:52 +000062
Erik Andersene49d5ec2000-02-08 19:58:47 +000063static void do_grep(FILE * fp, char *needle, char *fileName, int tellName,
John Beppuf93a95d2000-04-24 18:07:30 +000064 int ignoreCase, int tellLine, int invertSearch)
Eric Andersenfbb39c81999-11-08 17:00:52 +000065{
Erik Andersene49d5ec2000-02-08 19:58:47 +000066 char *cp;
67 long line = 0;
68 char haystack[BUF_SIZE];
John Beppuf93a95d2000-04-24 18:07:30 +000069 int truth = !invertSearch;
Eric Andersenfbb39c81999-11-08 17:00:52 +000070
Erik Andersene49d5ec2000-02-08 19:58:47 +000071 while (fgets(haystack, sizeof(haystack), fp)) {
72 line++;
73 cp = &haystack[strlen(haystack) - 1];
Eric Andersenfbb39c81999-11-08 17:00:52 +000074
Erik Andersene49d5ec2000-02-08 19:58:47 +000075 if (*cp != '\n')
76 fprintf(stderr, "%s: Line too long\n", fileName);
Eric Andersenfbb39c81999-11-08 17:00:52 +000077
John Beppuf93a95d2000-04-24 18:07:30 +000078 if (find_match(haystack, needle, ignoreCase) == truth) {
Erik Andersene49d5ec2000-02-08 19:58:47 +000079 if (tellName == TRUE)
80 printf("%s:", fileName);
Eric Andersenfbb39c81999-11-08 17:00:52 +000081
Erik Andersene49d5ec2000-02-08 19:58:47 +000082 if (tellLine == TRUE)
83 printf("%ld:", line);
Eric Andersenfbb39c81999-11-08 17:00:52 +000084
Erik Andersene49d5ec2000-02-08 19:58:47 +000085 if (beQuiet == FALSE)
86 fputs(haystack, stdout);
Erik Andersen3fe2ecf1999-12-21 08:52:04 +000087
Erik Andersene49d5ec2000-02-08 19:58:47 +000088 match = TRUE;
89 }
Eric Andersenfbb39c81999-11-08 17:00:52 +000090 }
91}
92
Eric Andersencc8ed391999-10-05 16:24:54 +000093
Erik Andersene49d5ec2000-02-08 19:58:47 +000094extern int grep_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000095{
Erik Andersene49d5ec2000-02-08 19:58:47 +000096 FILE *fp;
97 char *cp;
98 char *needle;
99 char *fileName;
John Beppuf93a95d2000-04-24 18:07:30 +0000100 int tellName = TRUE;
101 int ignoreCase = FALSE;
102 int tellLine = FALSE;
103 int invertSearch = FALSE;
Eric Andersencc8ed391999-10-05 16:24:54 +0000104
105 argc--;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000106 argv++;
107 if (argc < 1) {
Eric Andersen3e0fbae1999-10-19 06:02:44 +0000108 usage(grep_usage);
Eric Andersenfbb39c81999-11-08 17:00:52 +0000109 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000110
111 if (**argv == '-') {
112 argc--;
113 cp = *argv++;
114
115 while (*++cp)
116 switch (*cp) {
117 case 'i':
118 ignoreCase = TRUE;
119 break;
120
121 case 'h':
122 tellName = FALSE;
123 break;
124
125 case 'n':
126 tellLine = TRUE;
127 break;
128
129 case 'q':
130 beQuiet = TRUE;
131 break;
132
John Beppuf93a95d2000-04-24 18:07:30 +0000133 case 'v':
134 invertSearch = TRUE;
135 break;
136
Erik Andersene49d5ec2000-02-08 19:58:47 +0000137 default:
138 usage(grep_usage);
139 }
140 }
141
142 needle = *argv++;
143 argc--;
144
145 if (argc == 0) {
John Beppuf93a95d2000-04-24 18:07:30 +0000146 do_grep(stdin, needle, "stdin", FALSE, ignoreCase, tellLine, invertSearch);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000147 } else {
148 /* Never print the filename for just one file */
149 if (argc == 1)
150 tellName = FALSE;
151 while (argc-- > 0) {
152 fileName = *argv++;
153
154 fp = fopen(fileName, "r");
155 if (fp == NULL) {
156 perror(fileName);
157 continue;
158 }
159
John Beppuf93a95d2000-04-24 18:07:30 +0000160 do_grep(fp, needle, fileName, tellName, ignoreCase, tellLine, invertSearch);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000161
162 if (ferror(fp))
163 perror(fileName);
164 fclose(fp);
165 }
166 }
167 exit(match);
Eric Andersencc8ed391999-10-05 16:24:54 +0000168}
169
170
Eric Andersencc8ed391999-10-05 16:24:54 +0000171/* END CODE */