source: trunk/third/gcc/fastjar/jargrep.c @ 18474

Revision 18474, 21.9 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18473, which included commits to RCS files with non-trunk default branches.
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.