source: branches/libc-0.6/src/gcc/fastjar/jargrep.c

Last change on this file was 1394, checked in by bird, 21 years ago

#1040: Joined the GCC 3.3.3 with the trunk.

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