blob: d8d2f1837389321ac982423a42508d2513c95fe6 [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 *
6 * Copyright (C) 1999 by Lineo, inc.
7 * 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 Andersene49d5ec2000-02-08 19:58:47 +000044 "grep [OPTIONS]... PATTERN [FILE]...\n\n"
45 "Search for PATTERN in each FILE or standard input.\n\n"
46 "OPTIONS:\n"
47 "\t-h\tsuppress the prefixing filename on output\n"
48 "\t-i\tignore case distinctions\n"
49 "\t-n\tprint line number with output lines\n"
50 "\t-q\tbe quiet. Returns 0 if result was found, 1 otherwise\n\n"
Eric Andersenaa0765e1999-10-22 04:30:20 +000051#if defined BB_REGEXP
Erik Andersene49d5ec2000-02-08 19:58:47 +000052 "This version of grep matches full regular expresions.\n";
Eric Andersenaa0765e1999-10-22 04:30:20 +000053#else
Erik Andersene49d5ec2000-02-08 19:58:47 +000054 "This version of grep matches strings (not regular expresions).\n";
Eric Andersenaa0765e1999-10-22 04:30:20 +000055#endif
Eric Andersencc8ed391999-10-05 16:24:54 +000056
Erik Andersen3fe2ecf1999-12-21 08:52:04 +000057static int match = FALSE, beQuiet = FALSE;
Eric Andersenfbb39c81999-11-08 17:00:52 +000058
Erik Andersene49d5ec2000-02-08 19:58:47 +000059static void do_grep(FILE * fp, char *needle, char *fileName, int tellName,
60 int ignoreCase, int tellLine)
Eric Andersenfbb39c81999-11-08 17:00:52 +000061{
Erik Andersene49d5ec2000-02-08 19:58:47 +000062 char *cp;
63 long line = 0;
64 char haystack[BUF_SIZE];
Eric Andersenfbb39c81999-11-08 17:00:52 +000065
Erik Andersene49d5ec2000-02-08 19:58:47 +000066 while (fgets(haystack, sizeof(haystack), fp)) {
67 line++;
68 cp = &haystack[strlen(haystack) - 1];
Eric Andersenfbb39c81999-11-08 17:00:52 +000069
Erik Andersene49d5ec2000-02-08 19:58:47 +000070 if (*cp != '\n')
71 fprintf(stderr, "%s: Line too long\n", fileName);
Eric Andersenfbb39c81999-11-08 17:00:52 +000072
Erik Andersene49d5ec2000-02-08 19:58:47 +000073 if (find_match(haystack, needle, ignoreCase) == TRUE) {
74 if (tellName == TRUE)
75 printf("%s:", fileName);
Eric Andersenfbb39c81999-11-08 17:00:52 +000076
Erik Andersene49d5ec2000-02-08 19:58:47 +000077 if (tellLine == TRUE)
78 printf("%ld:", line);
Eric Andersenfbb39c81999-11-08 17:00:52 +000079
Erik Andersene49d5ec2000-02-08 19:58:47 +000080 if (beQuiet == FALSE)
81 fputs(haystack, stdout);
Erik Andersen3fe2ecf1999-12-21 08:52:04 +000082
Erik Andersene49d5ec2000-02-08 19:58:47 +000083 match = TRUE;
84 }
Eric Andersenfbb39c81999-11-08 17:00:52 +000085 }
86}
87
Eric Andersencc8ed391999-10-05 16:24:54 +000088
Erik Andersene49d5ec2000-02-08 19:58:47 +000089extern int grep_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000090{
Erik Andersene49d5ec2000-02-08 19:58:47 +000091 FILE *fp;
92 char *cp;
93 char *needle;
94 char *fileName;
95 int tellName = TRUE;
96 int ignoreCase = TRUE;
97 int tellLine = FALSE;
Eric Andersen50d63601999-11-09 01:47:36 +000098
Eric Andersencc8ed391999-10-05 16:24:54 +000099
Erik Andersene49d5ec2000-02-08 19:58:47 +0000100 ignoreCase = FALSE;
101 tellLine = FALSE;
Eric Andersencc8ed391999-10-05 16:24:54 +0000102
103 argc--;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000104 argv++;
105 if (argc < 1) {
Eric Andersen3e0fbae1999-10-19 06:02:44 +0000106 usage(grep_usage);
Eric Andersenfbb39c81999-11-08 17:00:52 +0000107 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000108
109 if (**argv == '-') {
110 argc--;
111 cp = *argv++;
112
113 while (*++cp)
114 switch (*cp) {
115 case 'i':
116 ignoreCase = TRUE;
117 break;
118
119 case 'h':
120 tellName = FALSE;
121 break;
122
123 case 'n':
124 tellLine = TRUE;
125 break;
126
127 case 'q':
128 beQuiet = TRUE;
129 break;
130
131 default:
132 usage(grep_usage);
133 }
134 }
135
136 needle = *argv++;
137 argc--;
138
139 if (argc == 0) {
140 do_grep(stdin, needle, "stdin", FALSE, ignoreCase, tellLine);
141 } else {
142 /* Never print the filename for just one file */
143 if (argc == 1)
144 tellName = FALSE;
145 while (argc-- > 0) {
146 fileName = *argv++;
147
148 fp = fopen(fileName, "r");
149 if (fp == NULL) {
150 perror(fileName);
151 continue;
152 }
153
154 do_grep(fp, needle, fileName, tellName, ignoreCase, tellLine);
155
156 if (ferror(fp))
157 perror(fileName);
158 fclose(fp);
159 }
160 }
161 exit(match);
Eric Andersencc8ed391999-10-05 16:24:54 +0000162}
163
164
Eric Andersencc8ed391999-10-05 16:24:54 +0000165/* END CODE */