Annotation of src/usr.bin/grep/file.c, Revision 1.2
1.1 deraadt 1: /*-
2: * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24: * SUCH DAMAGE.
25: *
26: * $Id$
27: */
28:
29: #include <sys/param.h>
30:
31: #include <err.h>
32: #include <stdio.h>
33: #include <stdlib.h>
34: #include <zlib.h>
35:
36: #include "grep.h"
37:
38: static char fname[MAXPATHLEN];
39: static char *lnbuf;
1.2 ! deraadt 40: static size_t lnbuflen;
1.1 deraadt 41:
42: #define FILE_STDIO 0
43: #define FILE_MMAP 1
44: #define FILE_GZIP 2
45:
46: struct file {
47: int type;
48: FILE *f;
49: mmf_t *mmf;
50: gzFile *gzf;
51: };
52:
1.2 ! deraadt 53: #ifndef NOZ
1.1 deraadt 54: static char *
55: gzfgetln(gzFile *f, size_t *len)
56: {
57: size_t n;
58: int c;
59:
60: for (n = 0; ; ++n) {
61: c = gzgetc(f);
62: if (c == -1) {
63: const char *gzerrstr;
64: int gzerr;
65:
66: if (gzeof(f))
67: break;
1.2 ! deraadt 68:
1.1 deraadt 69: gzerrstr = gzerror(f, &gzerr);
70: if (gzerr == Z_ERRNO)
71: err(1, "%s", fname);
72: else
73: errx(1, "%s: %s", fname, gzerrstr);
74: }
75: if (c == '\n')
76: break;
77: if (n >= lnbuflen) {
78: lnbuflen *= 2;
79: lnbuf = grep_realloc(lnbuf, ++lnbuflen);
80: }
81: lnbuf[n] = c;
82: }
83:
84: if (gzeof(f) && n == 0)
85: return NULL;
86: *len = n;
87: return lnbuf;
88: }
1.2 ! deraadt 89: #endif
1.1 deraadt 90:
91: file_t *
92: grep_fdopen(int fd, char *mode)
93: {
94: file_t *f;
95:
96: if (fd == 0)
1.2 ! deraadt 97: snprintf(fname, sizeof fname, "(standard input)");
1.1 deraadt 98: else
1.2 ! deraadt 99: snprintf(fname, sizeof fname, "(fd %d)", fd);
! 100:
1.1 deraadt 101: f = grep_malloc(sizeof *f);
1.2 ! deraadt 102:
! 103: #ifndef NOZ
1.1 deraadt 104: if (Zflag) {
105: f->type = FILE_GZIP;
106: if ((f->gzf = gzdopen(fd, mode)) != NULL)
107: return f;
1.2 ! deraadt 108: } else
! 109: #endif
! 110: {
1.1 deraadt 111: f->type = FILE_STDIO;
112: if ((f->f = fdopen(fd, mode)) != NULL)
113: return f;
114: }
1.2 ! deraadt 115:
1.1 deraadt 116: free(f);
117: return NULL;
118: }
119:
120: file_t *
121: grep_open(char *path, char *mode)
122: {
123: file_t *f;
124:
1.2 ! deraadt 125: snprintf(fname, sizeof fname, "%s", path);
! 126:
1.1 deraadt 127: f = grep_malloc(sizeof *f);
1.2 ! deraadt 128:
! 129: #ifndef NOZ
1.1 deraadt 130: if (Zflag) {
131: f->type = FILE_GZIP;
132: if ((f->gzf = gzopen(fname, mode)) != NULL)
133: return f;
1.2 ! deraadt 134: } else
! 135: #endif
! 136: {
1.1 deraadt 137: /* try mmap first; if it fails, try stdio */
138: if ((f->mmf = mmopen(fname, mode)) != NULL) {
139: f->type = FILE_MMAP;
140: return f;
141: }
142: f->type = FILE_STDIO;
143: if ((f->f = fopen(path, mode)) != NULL)
144: return f;
145: }
1.2 ! deraadt 146:
1.1 deraadt 147: free(f);
148: return NULL;
149: }
150:
151: int
152: grep_bin_file(file_t *f)
153: {
154: switch (f->type) {
155: case FILE_STDIO:
156: return bin_file(f->f);
157: case FILE_MMAP:
158: return mmbin_file(f->mmf);
1.2 ! deraadt 159: #ifndef NOZ
1.1 deraadt 160: case FILE_GZIP:
161: return gzbin_file(f->gzf);
1.2 ! deraadt 162: #endif
1.1 deraadt 163: default:
164: /* can't happen */
165: errx(1, "invalid file type");
166: }
167: }
168:
169: long
170: grep_tell(file_t *f)
171: {
172: switch (f->type) {
173: case FILE_STDIO:
174: return ftell(f->f);
175: case FILE_MMAP:
176: return mmtell(f->mmf);
1.2 ! deraadt 177: #ifndef NOZ
1.1 deraadt 178: case FILE_GZIP:
179: return gztell(f->gzf);
1.2 ! deraadt 180: #endif
1.1 deraadt 181: default:
182: /* can't happen */
183: errx(1, "invalid file type");
184: }
185: }
186:
187: char *
188: grep_fgetln(file_t *f, size_t *l)
189: {
190: switch (f->type) {
191: case FILE_STDIO:
192: return fgetln(f->f, l);
193: case FILE_MMAP:
194: return mmfgetln(f->mmf, l);
1.2 ! deraadt 195: #ifndef NOZ
1.1 deraadt 196: case FILE_GZIP:
197: return gzfgetln(f->gzf, l);
1.2 ! deraadt 198: #endif
1.1 deraadt 199: default:
200: /* can't happen */
201: errx(1, "invalid file type");
202: }
203: }
204:
205: void
206: grep_close(file_t *f)
207: {
208: switch (f->type) {
209: case FILE_STDIO:
210: fclose(f->f);
211: break;
212: case FILE_MMAP:
213: mmclose(f->mmf);
214: break;
1.2 ! deraadt 215: #ifndef NOZ
1.1 deraadt 216: case FILE_GZIP:
217: gzclose(f->gzf);
218: break;
1.2 ! deraadt 219: #endif
1.1 deraadt 220: default:
221: /* can't happen */
222: errx(1, "invalid file type");
223: }
224: }