|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.