source: trunk/src/gcc/fastjar/jargrep.c@ 2

Last change on this file since 2 was 2, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 21.9 KB
Line 
1/*
2 jargrep.c - main functions for jargrep utility
3 Copyright (C) 2002 Free Software Foundation
4 Copyright (C) 1999, 2000 Bryan Burns
5 Copyright (C) 2000 Cory Hollingsworth
6
7 Parts of this program are base on Bryan Burns work with fastjar
8 Copyright (C) 1999.
9
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23*/
24
25/* Id: jargrep.c,v 1.5 2002/01/03 04:57:56 rodrigc Exp
26
27Log: jargrep.c,v
28Revision 1.5 2002/01/03 04:57:56 rodrigc
292001-01-02 Craig Rodrigues <rodrigc@gcc.gnu.org>
30
31 PR bootstrap/5117
32 * configure.in (AC_CHECK_HEADERS): Check for stdlib.h.
33 * Makefile.am: Move grepjar to bin_PROGRAMS.
34 * config.h.in: Regenerated.
35 * Makefile.in: Regenerated.
36 * aclocal.m4: Regenerated.
37 * jargrep.c: Eliminate some signed/unsigned and default
38 uninitialized warnings. Use HAVE_STDLIB_H instead of
39 STDC_HEADERS macro.
40 * jartool.c: Likewise.
41 * compress.c: Likewise.
42
43Revision 1.4 2000/12/15 18:45:09 tromey
44 * jargrep.c: Include getopt.h if it exists.
45 (optind): Declare.
46 * configure, config.h: Rebuilt.
47 * configure.in: Check for getopt.h.
48
49Revision 1.3 2000/12/14 18:45:35 ghazi
50Warning fixes:
51
52 * compress.c: Include stdlib.h and compress.h.
53 (rcsid): Delete.
54 (report_str_error): Make static.
55 (ez_inflate_str): Delete unused variable. Add parens in if-stmt.
56 (hrd_inflate_str): Likewise.
57
58 * compress.h (init_compression, end_compression, init_inflation,
59 end_inflation): Prototype void arguments.
60
61 * dostime.c (rcsid): Delete.
62
63 * jargrep.c: Include ctype.h, stdlib.h, zlib.h and compress.h.
64 Make functions static. Cast ctype function argument to `unsigned
65 char'. Add parens in if-stmts. Constify.
66 (Usage): Change into a macro.
67 (jargrep): Remove unused parameter.
68
69 * jartool.c: Constify. Add parens in if-stmts. Align
70 signed/unsigned char pointers in functions calls using casts.
71 (rcsid): Delete.
72 (list_jar): Fix printf format specifier.
73 (usage): Chop long string into bits. Reformat.
74
75 * pushback.c (rcsid): Delete.
76
77Revision 1.2 2000/12/11 02:59:55 apbianco
782000-12-10 Robert Lipe <robertlipe@usa.net>
79
80 * jargrep.c (jargrep): Added null statement after case.
81
822000-12-10 Alexandre Petit-Bianco <apbianco@cygnus.com>
83
84 * Makefile: Removed.
85 * Makefile.in: Rebuilt with `-i' and `--enable-foreign'.
86
87(http://gcc.gnu.org/ml/gcc/2000-12/msg00294.html)
88
89Revision 1.1 2000/12/09 03:08:23 apbianco
902000-12-08 Alexandre Petit-Bianco <apbianco@cygnus.com>
91
92 * fastjar: Imported.
93
94Revision 1.8 2000/09/13 14:02:02 cory
95Reformatted some of the code to more closly match the layout of the orriginal
96fastjar utility.
97
98Revision 1.7 2000/09/12 22:29:36 cory
99Jargrep now seems to do what I want it to do. Performs properly on Linux x86,
100will test some other platforms later.
101
102
103*/
104
105#include "config.h"
106#include <stdio.h>
107#include <unistd.h>
108#include <regex.h>
109#include <errno.h>
110#include <string.h>
111#include <sys/types.h>
112#include <sys/stat.h>
113#include <fcntl.h>
114#include <ctype.h>
115#ifdef HAVE_STDLIB_H
116#include <stdlib.h>
117#endif
118#include "jargrep.h"
119#include "jartool.h"
120#include "pushback.h"
121#include "zipfile.h"
122#include "zlib.h"
123#include "compress.h"
124#include <getopt.h>
125
126void version(void);
127void help(const char *name);
128
129#define Usage "Usage: %s [-bcinsw] <-e PATTERN | PATTERN> FILE ...\n"
130
131/*
132Function name: opt_valid
133arg: options Bitfield flag that contains the command line options of grepjar.
134purpose: To guard agains the occurance of certain incompatible flags being used
135together.
136returns: TRUE if options are valid, FALSE otherwise.
137*/
138
139static int opt_valid(int options) {
140 int retflag;
141
142 if((options & JG_PRINT_COUNT) &&
143 (options & (JG_PRINT_BYTEOFFSET | JG_PRINT_LINE_NUMBER)))
144 {
145 retflag = FALSE;
146 }
147 else retflag = TRUE;
148
149 return retflag;
150}
151
152/*
153Function name: create_regexp
154args: regstr String containing the uncompiled regular expression. This may be the
155 expression as is passed in through argv.
156 options This is the flag containing the commandline options that have been
157 parsed by getopt.
158purpose: Handle the exception handling involved with setting upt a new regular
159expression.
160returns: Newly allocated compile regular expression ready to be used in an regexec call.
161*/
162
163static regex_t *create_regexp(const char *regstr, int options) {
164 regex_t *exp;
165 int errcode;
166 int msgsize;
167 char *errmsg;
168
169 if((exp = (regex_t *) malloc(sizeof(regex_t))))
170 {
171 if((errcode = regcomp(exp, regstr, (options & JG_IGNORE_CASE) ? REG_ICASE : 0))) {
172 fprintf(stderr, "regcomp of regex failed,\n");
173 if((errmsg = (char *) malloc(msgsize = regerror(errcode, exp, NULL, 0) + 1))) {
174 regerror(errcode, exp, errmsg, msgsize);
175 fprintf(stderr, "Error: %s\n", errmsg);
176 free(exp);
177 free(errmsg);
178 exit(1);
179 }
180 else {
181 fprintf(stderr, "Malloc of errmsg failed.\n");
182 fprintf(stderr, "Error: %s\n", strerror(errno));
183 free(exp);
184 exit(1);
185 }
186 }
187 }
188 else {
189 fprintf(stderr, "Malloc of regex failed,\n");
190 fprintf(stderr, "Error: %s\n", strerror(errno));
191 exit(1);
192 }
193
194 return exp;
195}
196
197/*
198Function name: check_sig
199args: scratch Pointer to array of bytes containing signature.
200 pbf Pointer to push back handle for jar file.
201purpose: Verify that checksum is correct.
202returns: 0, 1, or 2. 0 means we are ready to read embedded file information. 1 means
203we have read beyound the embedded file list and can exit knowing we have read all the
204relevent information. 2 means we still haven't reached embdedded file list and need to
205do some more reading.
206*/
207static int check_sig(ub1 *scratch, pb_file *pbfp) {
208 ub4 signature;
209 int retflag = 0;
210
211 signature = UNPACK_UB4(scratch, 0);
212
213#ifdef DEBUG
214 printf("signature is %x\n", signature);
215#endif
216 if(signature == 0x08074b50){
217#ifdef DEBUG
218 printf("skipping data descriptor\n");
219#endif
220 pb_read(pbfp, scratch, 12);
221 retflag = 2;
222 } else if(signature == 0x02014b50){
223#ifdef DEBUG
224 printf("Central header reached.. we're all done!\n");
225#endif
226 retflag = 1;
227 }else if(signature != 0x04034b50){
228 printf("Ick! %#x\n", signature);
229 retflag = 1;
230 }
231
232 return retflag;
233}
234
235/*
236Function name: decd_siz
237args csize Pointer to embedded file's compressed size.
238 usize Pointer to embedded file's uncmpressed size.
239 fnlen Pointer to embedded file's file name length.
240 elfen Pointer to length of extra fields in jar file.
241 flags Pointer to bitmapped flags.
242 method Pointer to indicator of storage method of embedded file.
243 file_header Pointer to string containing the above values to be unbacked.
244Purpose: Unpack the series of values from file_header.
245*/
246
247static void decd_siz(ub4 *csize, ub4 *usize, ub2 *fnlen, ub2 *eflen, ub2 *flags, ub2 *method, ub1 *file_header) {
248 *csize = UNPACK_UB4(file_header, LOC_CSIZE);
249#ifdef DEBUG
250 printf("Compressed size is %u\n", *csize);
251#endif
252
253 *usize = UNPACK_UB4(file_header, LOC_USIZE);
254#ifdef DEBUG
255 printf("Uncompressed size is %u\n", *usize);
256#endif
257
258 *fnlen = UNPACK_UB2(file_header, LOC_FNLEN);
259#ifdef DEBUG
260 printf("Filename length is %hu\n", *fnlen);
261#endif
262
263 *eflen = UNPACK_UB2(file_header, LOC_EFLEN);
264#ifdef DEBUG
265 printf("Extra field length is %hu\n", *eflen);
266#endif
267
268 *flags = UNPACK_UB2(file_header, LOC_EXTRA);
269#ifdef DEBUG
270 printf("Flags are %#hx\n", *flags);
271#endif
272
273 *method = UNPACK_UB2(file_header, LOC_COMP);
274#ifdef DEBUG
275 printf("Compression method is %#hx\n", *method);
276#endif
277
278}
279
280/*
281Function name: new_filename
282args: pbf Pointer to push back file handle. Used for reading input file.
283 len Length of file name to be read.
284purpose: Read in the embedded file name from jar file.
285returns: Pointer to newly allocated string containing file name.
286*/
287
288static char *new_filename(pb_file *pbf, ub4 len) {
289 char *filename;
290
291 if(!(filename = (char *) malloc(len + 1))) {
292 fprintf(stderr, "Malloc failed of filename\n");
293 fprintf(stderr, "Error: %s\n", strerror(errno));
294 }
295 pb_read(pbf, filename, len);
296 filename[len] = '\0';
297
298#ifdef DEBUG
299 printf("filename is %s\n", filename);
300#endif
301
302 return filename;
303}
304
305/*
306Funtion name: read_string
307args: pbf Pointer to push back file handle. Used for reading input file.
308 size Size of embedded file in bytes.
309purpose: Create a string containing the contents of the embedded noncompressed file.
310returns: Pointer to newly allocated string containing embedded file contents.
311*/
312
313static char *read_string(pb_file *pbf, int size) {
314 char *page;
315
316 if((page = (char *) malloc(size + 1))) {
317 pb_read(pbf, page, size);
318 page[size] = '\0';
319 }
320 else {
321 fprintf(stderr, "Malloc of page buffer failed.\n");
322 fprintf(stderr, "Error: %s\n", strerror(errno));
323 exit(1);
324 }
325
326 return page;
327}
328
329/*
330Function name: extract_line
331args: stream String containing the full contents of a file which is to be substringed
332 in order to provide line representing our grep output.
333 begin Index into stream which regular expression first matches.
334 end Index into stream which end of match to the regular expression.
335 b Pointer to the index of what will be the beginning of the line when
336 string is returned. Used for -b option.
337purpose: Create a string that can be printed by jargrep from the long string stream.
338The matching line that is printed out by jargrep is generated by this function.
339returns: Pointer to newly allocated string containing matched expression.
340*/
341
342static char *extract_line(const char *stream, regoff_t begin, regoff_t end, int *b) {
343 int e;
344 int length;
345 char *retstr;
346
347 for(*b = begin; *b >= 0 && !iscntrl((unsigned char)stream[*b]); (*b)--);
348 (*b)++;
349 for(e = end; stream[e] == '\t' || !iscntrl((unsigned char)stream[e]); e++);
350 length = e - *b;
351 if((retstr = (char *) malloc(length + 1))) {
352 sprintf(retstr, "%d:", *b);
353 strncpy(retstr, &(stream[*b]), length);
354 retstr[length] = '\0';
355 }
356 else {
357 fprintf(stderr, "Malloc failed of output string.\n");
358 fprintf(stderr, "Error: %s\n", strerror(errno));
359 exit(1);
360 }
361
362 return retstr;
363}
364
365/*
366Function name: chk_wrd
367args: exp Pointer to compiled POSIX style regular expression of search target.
368 str String known to contain at least one match of exp.
369purpose: Verify that the occurance of the regular expression in str occurs as a whole
370word and not a substring of another word.
371returns: TRUE if it is a word, FALSE of it is a substring.
372*/
373
374static int chk_wrd(regex_t *exp, const char *str) {
375 int wrd_fnd = FALSE;
376 int regflag;
377 int frnt_ok;
378 int bck_ok;
379 const char *str2;
380 regmatch_t match;
381
382 str2 = str;
383 frnt_ok = bck_ok = FALSE;
384 while(!wrd_fnd && !(regflag = regexec(exp, str2, 1, &match, 0))) {
385 if(!match.rm_so && (str2 == str)) frnt_ok = TRUE;
386 else if(!isalnum((unsigned char)str2[match.rm_so - 1])
387 && str2[match.rm_so - 1] != '_')
388 frnt_ok = TRUE;
389 else frnt_ok = FALSE;
390 if(frnt_ok) {
391 if(str2[match.rm_eo] == '\0') bck_ok = TRUE;
392 else if(!isalnum((unsigned char)str2[match.rm_eo])
393 && str2[match.rm_eo] != '_')
394 bck_ok = TRUE;
395 else bck_ok = FALSE;
396 }
397 wrd_fnd = frnt_ok && bck_ok;
398 str2 = &(str2[match.rm_eo]);
399 }
400
401 return wrd_fnd;
402}
403
404/*
405Function name: prnt_mtchs
406args: exp Pointer to compiled POSIX style regular expression of search target.
407 filename String containing the name of the embedded file which matches have
408 been found in.
409 stream String containing the processed contents of the embedded jar file
410 represended with filename.
411 pmatch Array of regmatch_t matches into stream.
412 nl_offset Array of offsets of '\n' characters in stream. May be NULL if -n is
413 not set on command line.
414 num Number of matches in pmatch array.
415 lines Number of lines in file. Not set if -n is not set on command line.
416 options Bitwise flag containing flags set to represent the command line
417 options.
418purpose: Control output of jargrep. Output is controlled by which options have been
419set at the command line.
420*/
421
422static void prnt_mtchs(regex_t *exp, const char *filename, const char *stream, regmatch_t *pmatch, regmatch_t *nl_offset, int num, int lines, int options) {
423 int i;
424 int j = 0;
425 int ln_cnt;
426 int begin;
427 int o_begin;
428 char *str;
429
430 o_begin = -1;
431 ln_cnt = 0;
432 for(i = 0; i < num; i++) {
433 str = extract_line(stream, pmatch[i].rm_so, pmatch[i].rm_eo, &begin);
434 if(begin > o_begin) {
435 if(!(options & JG_WORD_EXPRESSIONS) || chk_wrd(exp, str)) {
436 ln_cnt++;
437 if(!(options & JG_PRINT_COUNT)) {
438 printf("%s:", filename);
439 if(options & JG_PRINT_LINE_NUMBER) {
440 for(; j < lines && nl_offset[j].rm_so < begin; j++);
441 printf("%d:", j + 1);
442 }
443 if(options & JG_PRINT_BYTEOFFSET) printf("%d:", begin);
444 printf("%s\n", str);
445 }
446 }
447 }
448 o_begin = begin;
449 free(str);
450 }
451 if(options & JG_PRINT_COUNT) printf("%s:%d\n", filename, ln_cnt);
452}
453
454/*
455Function name: check_crc
456args: pbf Pointer to pushback file pointer for jar file.
457 stream String containing the non modified contents fo the extraced file entry.
458 usize Size of file in bytes.
459purpose: Verify the CRC matches that as what is stored in the jar file.
460*/
461
462static void check_crc(pb_file *pbf, const char *stream, ub4 usize) {
463 ub4 crc=0;
464 ub4 lcrc;
465 ub1 scratch[16];
466
467 crc = crc32(crc, NULL, 0);
468 crc = crc32(crc, (const unsigned char *)stream, usize);
469 if(pb_read(pbf, scratch, 16) != 16) {
470 perror("read");
471 exit(1);
472 }
473 if(UNPACK_UB4(scratch, 0) != 0x08074b50) {
474 fprintf(stderr, "Error! Missing data descriptor!\n");
475 exit(1);
476 }
477 lcrc = UNPACK_UB4(scratch, 4);
478 if(crc != lcrc){
479 fprintf(stderr, "Error! CRCs do not match! Got %x, expected %x\n",
480 crc, lcrc);
481 exit(1);
482 }
483}
484
485/*
486Function name mk_ascii
487args: stream String that contains the contents of the extraced file entry.
488 usize String size.
489purpose: Make certain that the contents of the file are ASCII, not binary. This
490permits grepping of binary files as well by converting non ASCII and control characters
491into '\n'.
492*/
493
494static void mk_ascii(char *stream, size_t usize) {
495 size_t i;
496
497 for(i = 0; i < usize; i++)
498 if(stream[i] != '\t'
499 && (iscntrl((unsigned char)stream[i])
500 || (unsigned char) stream[i] >= 128))
501 stream[i] = '\n';
502}
503
504/*
505Funtion name: fnd_match
506args: exp Pointer to compiled POSIX style regular expression of search target.
507 str_stream String that contains the contents of the extracted file entry.
508 i Pointer to counter and index of matches.
509purpose: Search str_stream for occurances of the regular expression exp and create
510an array of matches.
511returns: Pointer to newly allocated array of regmatch_t which gives indexes to start
512and end of matches. NULL is returned upon no matches found.
513*/
514
515static regmatch_t *fnd_match(regex_t *exp, const char *str_stream, int *i) {
516 int regflag;
517 regmatch_t match;
518 regmatch_t *match_array;
519 regmatch_t *tmp;
520
521 match_array = NULL;
522 for(*i = 0, regflag = regexec(exp, str_stream, 1, &match, 0); !regflag;
523 regflag = regexec(exp, &(str_stream[match.rm_eo]), 1, &match, 0), (*i)++)
524 {
525 if((tmp = (regmatch_t *)
526 realloc(match_array, sizeof(regmatch_t) * ((*i) + 1))))
527 {
528 match_array = tmp;
529 if(*i) {
530 match.rm_so += match_array[(*i) - 1].rm_eo;
531 match.rm_eo += match_array[(*i) - 1].rm_eo;
532 }
533 match_array[*i] = match;
534 }
535 else {
536 fprintf(stderr, "Realloc of match_array failed.\n");
537 fprintf(stderr, "Error: %s\n", strerror(errno));
538 exit(1);
539 }
540 }
541
542 return match_array;
543}
544
545/*
546Function name: cont_grep
547args: exp Pointer to compiled POSIX style regular expression of search target.
548 nl_exp Pointer to compiled POSIX style regular expression of newlines. This
549 argument is NULL unless the -n option is used on the command line.
550 fd File descriptor of the jar file being grepped.
551 pbf Pointer to pushback file style file stream. This is for use with
552 the pushback.c file io funtions.
553 options Bitwise flag containing flags set to represent the command line options.
554purpose: This function handles single entries in an open jar file. The header is
555read and then the embeded file is extracted and grepped.
556returns: FALSE upon failure, TRUE otherwise.
557*/
558
559static int cont_grep(regex_t *exp, regex_t *nl_exp, int fd, pb_file *pbf, int options) {
560 int retflag = TRUE;
561 int i;
562 int j;
563 ub4 csize;
564 ub4 usize;
565 ub2 fnlen;
566 ub2 eflen;
567 ub2 flags;
568 ub2 method;
569 ub1 file_header[30];
570 char *filename;
571 char *str_stream;
572 regmatch_t *match_array;
573 regmatch_t *nl_offsets=0;
574
575 if(pb_read(pbf, (file_header + 4), 26) != 26) {
576 perror("read");
577 retflag = FALSE;
578 }
579 else {
580 decd_siz(&csize, &usize, &fnlen, &eflen, &flags, &method, file_header);
581 filename = new_filename(pbf, fnlen);
582 lseek(fd, eflen, SEEK_CUR);
583 if(filename[fnlen - 1] != '/') {
584 str_stream = (method == 8 || (flags & 0x0008)) ?
585 (char *) inflate_string(pbf, &csize, &usize) :
586 read_string(pbf, csize);
587 if(flags & 0x008) check_crc(pbf, str_stream, usize);
588 mk_ascii(str_stream, usize);
589 match_array = fnd_match(exp, str_stream, &i);
590 if((options & JG_PRINT_LINE_NUMBER) && i)
591 nl_offsets = fnd_match(nl_exp, str_stream, &j);
592 prnt_mtchs(exp, filename, str_stream, match_array, nl_offsets, i, j, options);
593 if(match_array) free(match_array);
594 free(str_stream);
595 }
596 free(filename);
597 retflag = TRUE;
598 }
599
600 return retflag;
601}
602
603/*
604Funtion name: jargrep
605args: exp Pointer to compiled POSIX style regular expression of search target.
606 nl_exp Pointer to compiled regular expression for newlines or NULL. Only set
607 if -n option is present at command line.
608 jarfile Filename of jar file to be searched.
609 options Bitwise flag containing flags set to represent the command line options.
610purpose: Open jar file. Check signatures. When right signature is found go to deeper
611grep routine.
612*/
613
614static void jargrep(regex_t *exp, regex_t *nl_exp, const char *jarfile, int options){
615 int fd;
616 int floop = TRUE;
617 pb_file pbf;
618 ub1 scratch[16];
619
620 if((fd = open(jarfile, O_RDONLY)) == -1) {
621 if(!(options & JG_SUPRESS_ERROR))
622 fprintf(stderr, "Error reading file '%s': %s\n", jarfile, strerror(errno));
623 }
624 else {
625 pb_init(&pbf, fd);
626
627 do {
628 if(pb_read(&pbf, scratch, 4) != 4) {
629 perror("read");
630 floop = FALSE;
631 }
632 else {
633 switch (check_sig(scratch, &pbf)) {
634 case 0:
635 floop = cont_grep(exp, nl_exp, fd, &pbf, options);
636 break;
637 case 1:
638 floop = FALSE;
639 break;
640 case 2:
641 /* fall through continue */
642 ;
643 }
644 }
645 } while(floop);
646 }
647}
648
649/* This is used to mark options with no short value. */
650#define LONG_OPT(Num) ((Num) + 128)
651
652#define OPT_HELP LONG_OPT (0)
653
654static const struct option option_vec[] =
655{
656 { "help", no_argument, NULL, OPT_HELP },
657 { "version", no_argument, NULL, 'V' },
658 { NULL, no_argument, NULL, 0 }
659};
660
661/*
662Funtion Name: main
663args: argc number of in coming args.
664 argv array of strings.
665purpose: Entry point of the program. Parse command line arguments and set options.
666Set up regular expressions. Call grep routines for each file as input.
667returns: 1 on error 0 on success.
668*/
669
670int main(int argc, char **argv) {
671 int c;
672 int retval = 0;
673 int fileindex;
674 int options = 0;
675 regex_t *regexp;
676 regex_t *nl_exp = NULL;
677 char *regexpstr = NULL;
678
679 while((c = getopt_long(argc, argv, "bce:insVw",
680 option_vec, NULL)) != -1) {
681 switch(c) {
682 case 'b':
683 options |= JG_PRINT_BYTEOFFSET;
684 break;
685 case 'c':
686 options |= JG_PRINT_COUNT;
687 break;
688 case 'e':
689 if(!(regexpstr = (char *) malloc(strlen(optarg) + 1))) {
690 fprintf(stderr, "Malloc failure.\n");
691 fprintf(stderr, "Error: %s\n", strerror(errno));
692 exit(1);
693 }
694 strcpy(regexpstr, optarg);
695 break;
696 case 'i':
697 options |= JG_IGNORE_CASE;
698 break;
699 case 'n':
700 options |= JG_PRINT_LINE_NUMBER;
701 break;
702 case 's':
703 options |= JG_SUPRESS_ERROR;
704 break;
705 case 'v':
706 options |= JG_INVERT;
707 break;
708 case 'V':
709 version ();
710 break;
711 case 'w':
712 options |= JG_WORD_EXPRESSIONS;
713 break;
714 case OPT_HELP:
715 help(argv[0]);
716 break;
717 default:
718 fprintf(stderr, Usage, argv[0]);
719 exit(1);
720 }
721 }
722 if(!regexpstr){
723 if(((argc - optind) >= 2)) {
724 regexpstr = argv[optind];
725 fileindex = optind + 1;
726 }
727 else {
728 fprintf(stderr, "Invalid arguments.\n");
729 fprintf(stderr, Usage, argv[0]);
730 exit(1);
731 }
732 }
733 else if((argc - optind) == 1) {
734 fileindex = optind;
735 }
736 else {
737 fprintf(stderr, "Invalid arguments.\n");
738 fprintf(stderr, Usage, argv[0]);
739 exit(1);
740 }
741
742 if(opt_valid(options)) {
743 regexp = create_regexp(regexpstr, options);
744 if(options & JG_PRINT_LINE_NUMBER) nl_exp = create_regexp("\n", 0);
745 init_inflation();
746 for(; fileindex < argc; fileindex++)
747 jargrep(regexp, nl_exp, argv[fileindex], options);
748 regfree(regexp);
749 if(options & JG_PRINT_LINE_NUMBER) regfree(nl_exp);
750 }
751 else {
752 retval = 1;
753 fprintf(stderr, "Error: Invalid combination of options.\n");
754 }
755
756 return retval;
757}
758
759void help(const char *filename)
760{
761 printf (Usage, filename);
762 printf ("\
763\n\
764Search files in a jar file for a pattern.\n\
765\n\
766 -b print byte offset of match\n\
767 -c print number of matches\n\
768 -i compare case-insensitively\n\
769 -n print line number of each match\n\
770 -s suppress error messages\n\
771 -w force PATTERN to match only whole words\n\
772 -e PATTERN use PATTERN as regular exprssion\n\
773");
774
775 exit (0);
776}
777
778void version ()
779{
780 printf("grepjar (%s) %s\n\n", PACKAGE, VERSION);
781 printf("Copyright 1999, 2000, 2001 Bryan Burns\n");
782 printf("Copyright 2000 Cory Hollingsworth\n");
783 printf("Copyright 2002 Free Software Foundation\n");
784 printf("\
785This is free software; see the source for copying conditions. There is NO\n\
786warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
787 exit (0);
788}
Note: See TracBrowser for help on using the repository browser.