1: static char *rcsid = "$Header$";
2: /*
3: * pgrep - search files in a project for a pattern
4: *
5: * Author: Peter J. Nicklin
6: */
7: #include <sys/param.h>
8: #include <stdio.h>
9: #include "getarg.h"
10: #include "null.h"
11: #include "path.h"
12: #include "spms.h"
13: #include "system.h"
14:
15: #define CMDBUFSIZE 1024
16: #define MAXPXARGV 12
17:
18: char *PGN = "pgrep"; /* program name */
19:
20: main(argc, argv)
21: int argc;
22: char **argv;
23: {
24: register char *gp; /* pointer to grep command buffer */
25: register char **px; /* pointer to pexec command args */
26: char cwd[PATHSIZE]; /* current working directory pathname */
27: char *getwd(); /* get current working directory */
28: char gpcmdbuf[CMDBUFSIZE]; /* SPMSLIB/grep command buffer */
29: char *patfile = NULL; /* pattern file name */
30: char *pathcat(); /* pathname concatenation */
31: char pexeccmd[PATHSIZE]; /* location of pexec command */
32: char *pxargv[MAXPXARGV]; /* pexec command and args */
33: char *strpcpy(); /* copy string and update pointer */
34: int command; /* execute command on files? */
35: int pid; /* process identity */
36: int readmf; /* read makefile for source files? */
37: int status = 0; /* exit status */
38: int strlen(); /* string length */
39: int w; /* a child id */
40:
41: pathcat(pexeccmd, SPMSBIN, "pexec");
42: pathcat(gpcmdbuf, SPMSLIB, "pgrep");
43: gp = gpcmdbuf + strlen(gpcmdbuf);
44: px = pxargv;
45: *px++ = "pexec";
46: *px++ = "-iX2"; /* ignore non-zero return codes */
47: /* set pexec error code to 2 */
48: command = 0;
49: readmf = 0;
50: {
51: register char *s; /* option pointer */
52: while (--argc > 0 && **++argv == '-')
53: {
54: for (s = argv[0]+1; *s != '\0'; s++)
55: switch (*s)
56: {
57: case 'C':
58: command++;
59: gp = strpcpy(gp, " -C\"");
60: gp = strpcpy(gp, GETARG(s));
61: gp = strpcpy(gp, "\"");
62: goto endfor;
63: case 'D':
64: *px++ = "-D";
65: break;
66: case 'F':
67: gp = strpcpy(gp, " -F");
68: patfile = GETARG(s);
69: if (*patfile != _RDIRC)
70: {
71: if (getwd(cwd) == NULL)
72: {
73: warn(cwd);
74: status = 1;
75: }
76: gp = strpcpy(gp, cwd);
77: gp = strpcpy(gp, PATHSEP);
78: }
79: gp = strpcpy(gp, patfile);
80: goto endfor;
81: case 'P':
82: *px++ = "-P";
83: *px++ = GETARG(s);
84: goto endfor;
85: case 'T':
86: *px++ = "-T";
87: *px++ = GETARG(s);
88: goto endfor;
89: case 'e':
90: gp = strpcpy(gp, " -e");
91: break;
92: case 'f':
93: gp = strpcpy(gp, " -f");
94: gp = strpcpy(gp, GETARG(s));
95: gp = strpcpy(gp, " -m");
96: readmf++;
97: goto endfor;
98: case 'i':
99: gp = strpcpy(gp, " -i");
100: break;
101: case 'l':
102: gp = strpcpy(gp, " -l");
103: break;
104: case 'm':
105: gp = strpcpy(gp, " -m");
106: readmf++;
107: break;
108: case 'n':
109: gp = strpcpy(gp, " -n");
110: break;
111: case 'w':
112: gp = strpcpy(gp, " -w");
113: break;
114: default:
115: warn("bad option -%c", *s);
116: status = 1;
117: goto endfor;
118: }
119: endfor: continue;
120: }
121: }
122: if (status == 1 ||
123: (argc < 1 && patfile == NULL) ||
124: (argc < 2 && !readmf && patfile == NULL))
125: {
126: warn("usage: pgrep [-eilmnw] [-f makefile] [-C command] [-F patfile]\n [-P pdirname] [-T typexpr] [pattern [file ...]]");
127: exit(2);
128: }
129:
130: if (!command) /* turn off quit query if no command */
131: *px++ = "-?";
132: if (patfile == NULL)
133: {
134: gp = strpcpy(gp, " \"");
135: gp = strpcpy(gp, *argv);
136: gp = strpcpy(gp, "\"");
137: argv++, argc--;
138: }
139: while (argc-- > 0)
140: {
141: gp = strpcpy(gp, " ");
142: gp = strpcpy(gp, *argv++);
143: }
144:
145: *px++ = gpcmdbuf;
146: *px = NULL;
147:
148: if ((pid = FORK()) == 0)
149: {
150: execv(pexeccmd, pxargv);
151: if (*PGN != '\0')
152: fprintf(stderr, "%s: ", PGN);
153: fprintf(stderr, "can't exec %s\n", pexeccmd);
154: exit(2);
155: }
156: while ((w = wait(&status)) != pid && w != -1)
157: continue;
158: status >>= NBBY;
159: status &= 0xff;
160: /*
161: * Because pexec clobbers grep's "matches found" zero exit status
162: * (with the "no matches found" exit status, which will probably
163: * occur in some directories), lib/pgrep reverses these two statuses.
164: * Hence, we have to reverse them back here.
165: */
166: switch (status)
167: {
168: case 0:
169: status = 1;
170: break;
171: case 1:
172: status = 0;
173: break;
174: }
175: exit(status);
176: }
Defined functions
main
defined in line
20;
never used
Defined variables
PGN
defined in line
18; used 2 times
rcsid
defined in line
1;
never used
Defined macros