1: static char *rcsid = "$Header$";
2: /*
3: * pgrep - search files for a pattern
4: *
5: * Author: Peter J. Nicklin
6: */
7: #include <sys/param.h>
8: #include <stdio.h>
9: #include "bin.h"
10: #include "getarg.h"
11: #include "null.h"
12: #include "path.h"
13: #include "slist.h"
14: #include "spms.h"
15: #include "system.h"
16: #include "yesno.h"
17:
18: char *PGN; /* pointer to program name */
19: char PGNAME[PATHSIZE]; /* program name buffer */
20: int READMF; /* read makefile for source files? */
21:
22: /*
23: * grep options
24: */
25: char *_PATFILE = NULL; /* file containing patterns */
26: int _IGNORECASE; /* ignore letter case */
27: int _LIST; /* list file names only */
28: int _LINE; /* precede matched lines by line nos */
29: int _WORD; /* search for pattern as a word */
30:
31: main(argc, argv)
32: int argc;
33: char **argv;
34: {
35: char *buildcmd(); /* build command to execute on files */
36: char **buildgrepargv(); /* build grep command args */
37: char *command; /* command to execute on files */
38: char **grepargv; /* grep command args pointer array */
39: char *grepcmd; /* search command */
40: char *greppath; /* location of grep command */
41: char *makefile; /* makefile name */
42: char *pathcat(); /* pathname concatenation */
43: char *pattern; /* pattern command line argument */
44: char *slappend(); /* append key */
45: int forkgrep(); /* fork grep command */
46: int readmf(); /* read makefile */
47: int status = 0; /* exit status */
48: SLIST *filelist; /* list of file names */
49: SLIST *grep(); /* capture file names from grep */
50: SLIST *slinit(); /* initialize list */
51: void slrm(); /* remove list item */
52:
53: PGN = pathcat(PGNAME, SPMSLIB, "pgrep");
54:
55: command = NULL;
56: grepcmd = "grep";
57: greppath = GREP;
58: makefile = NULL;
59:
60: {
61: register char *s; /* option pointer */
62: while (--argc > 0 && **++argv == '-')
63: {
64: for (s = argv[0]+1; *s != '\0'; s++)
65: switch (*s)
66: {
67: case 'C':
68: command = GETARG(s);
69: _LIST++;
70: goto endfor;
71: case 'F':
72: _PATFILE = GETARG(s);
73: goto endfor;
74: case 'e':
75: grepcmd = "egrep";
76: greppath = EGREP;
77: break;
78: case 'f':
79: makefile = GETARG(s);
80: goto endfor;
81: case 'i':
82: _IGNORECASE++;
83: break;
84: case 'l':
85: _LIST++;
86: break;
87: case 'm':
88: READMF++;
89: break;
90: case 'n':
91: _LINE++;
92: break;
93: case 'w':
94: _WORD++;
95: break;
96: default:
97: warn("bad option -%c", *s);
98: status = 1;
99: goto endfor;
100: }
101: endfor: continue;
102: }
103: }
104: if (status == 1 ||
105: (argc < 1 && _PATFILE == NULL) ||
106: (argc < 2 && !READMF && _PATFILE == NULL))
107: {
108: warn("usage: %s [-eilmnw] [-f makefile] [-C command] [-F patfile] [pattern [file ...]]", PGN);
109: exit(2);
110: }
111:
112: if (_PATFILE == NULL) /* pattern is a command line argument */
113: {
114: pattern = *argv;
115: argv++, argc--;
116: }
117:
118: /* read file names from command line */
119: filelist = slinit();
120: while (argc-- > 0)
121: if (slappend(*argv++, filelist) == NULL)
122: exit(2);
123:
124: /* read file names from makefile */
125: if (READMF)
126: {
127: /* get name of makefile */
128: if (makefile == NULL)
129: makefile = "makefile";
130: if (!FILEXIST(makefile))
131: {
132: makefile = "Makefile";
133: if (!FILEXIST(makefile))
134: {
135: perror("pgrep: makefile");
136: exit(2);
137: }
138: }
139:
140: /* get file names from makefile */
141: if (readmf(makefile, filelist) == NO)
142: exit(2);
143: }
144: if (SLNUM(filelist) == 0)
145: exit(status);
146:
147: if ((grepargv = buildgrepargv(grepcmd, pattern, filelist)) == NULL)
148: exit(2);
149: if (command != NULL)
150: {
151: slrm(CNULL, filelist);
152: if ((filelist = grep(greppath, grepargv)) == NULL)
153: exit(2);
154: if (SLNUM(filelist) > 0)
155: {
156: system(buildcmd(command, filelist));
157: status = 1;
158: }
159: }
160: else {
161: status = forkgrep(greppath, grepargv);
162: }
163: exit(status);
164: }
165:
166:
167:
168: /*
169: * buildcmd() creates a command string to submit to a shell. Returns
170: * command string, or NULL if out of memory.
171: */
172: char *
173: buildcmd(command, filelist)
174: char *command; /* command to execute */
175: SLIST *filelist; /* list of files to run command on */
176: {
177: char **argv; /* command argument list */
178: char *argvtos(); /* convert cmd args to string */
179: char *malloc(); /* memory allocator */
180: char **sargv; /* start of command argument list */
181: char *slget(); /* get next key */
182: int argc; /* number of args in command */
183: void slrewind(); /* rewind list */
184:
185: if ((argv = (char **) malloc((unsigned)(SLNUM(filelist)+2)*sizeof(char *))) == NULL)
186: {
187: warn("out of memory");
188: return(NULL);
189: }
190: sargv = argv;
191: *argv++ = command;
192: argc = 1;
193: slrewind(filelist);
194: while ((*argv++ = slget(filelist)) != NULL)
195: argc++;
196: return(argvtos(argc, sargv));
197: }
198:
199:
200:
201: /*
202: * buildgrepargv() creates an argv string pointer array for the grep
203: * command to pass to execv(). Returns argv, or NULL if out of memory.
204: */
205: char **
206: buildgrepargv(grepcmd, pattern, filelist)
207: char *grepcmd; /* name of grep command */
208: char *pattern; /* search pattern */
209: SLIST *filelist; /* list of files to search */
210: {
211: char **argv; /* command argument list */
212: char *malloc(); /* memory allocator */
213: char **sargv; /* start of command argument list */
214: char *slget(); /* get next key */
215: void slrewind(); /* rewind list */
216:
217: if ((argv = (char **) malloc((unsigned)(SLNUM(filelist)+8)*sizeof(char *))) == NULL)
218: {
219: warn("out of memory");
220: return(NULL);
221: }
222: sargv = argv;
223: *argv++ = grepcmd;
224: if (_IGNORECASE)
225: *argv++ = "-i";
226: if (_LIST)
227: *argv++ = "-l";
228: if (_LINE)
229: *argv++ = "-n";
230: if (_WORD)
231: *argv++ = "-w";
232: if (_PATFILE != NULL)
233: {
234: *argv++ = "-f";
235: *argv++ = _PATFILE;
236: }
237: else {
238: *argv++ = pattern;
239: }
240: slrewind(filelist);
241: while ((*argv++ = slget(filelist)) != NULL)
242: continue;
243: return(sargv);
244: }
245:
246:
247:
248: /*
249: * forkgrep() forks a grep command.
250: */
251: forkgrep(greppath, grepargv)
252: char **grepargv; /* grep command args pointer array */
253: char *greppath; /* location of grep command */
254: {
255: int pid; /* process identity */
256: int status; /* child return status */
257: int w; /* a child id */
258:
259: if ((pid = FORK()) == 0)
260: {
261: execv(greppath, grepargv);
262: if (*PGN != '\0')
263: fprintf(stderr, "%s: ", PGN);
264: fprintf(stderr, "can't exec %s\n", greppath);
265: exit(2);
266: }
267: while ((w = wait(&status)) != pid && w != -1)
268: continue;
269: status >>= NBBY;
270: status &= 0xff;
271: /*
272: * Because pexec clobbers grep's "matches found" zero exit status
273: * (with the "no matches found" exit status, which will probably
274: * occur in some directories), lib/pgrep reverses these two statuses.
275: * /bin/pgrep restores them.
276: */
277: switch (status)
278: {
279: case 0:
280: status = 1;
281: break;
282: case 1:
283: status = 0;
284: break;
285: }
286: return(status);
287: }
Defined functions
main
defined in line
31;
never used
Defined variables
PGN
defined in line
18; used 4 times
_LINE
defined in line
28; used 2 times
_LIST
defined in line
27; used 3 times
_WORD
defined in line
29; used 2 times
rcsid
defined in line
1;
never used