4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 /* file_access interface based heavily on zlib gzread.c and gzlib.c from zlib
22 * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
25 * This software is provided 'as-is', without any express or implied
26 * warranty. In no event will the authors be held liable for any damages
27 * arising from the use of this software.
29 * Permission is granted to anyone to use this software for any purpose,
30 * including commercial applications, and to alter it and redistribute it
31 * freely, subject to the following restrictions:
33 * 1. The origin of this software must not be misrepresented; you must not
34 * claim that you wrote the original software. If you use this software
35 * in a product, an acknowledgment in the product documentation would be
36 * appreciated but is not required.
37 * 2. Altered source versions must be plainly marked as such, and must not be
38 * misrepresented as being the original software.
39 * 3. This notice may not be removed or altered from any source distribution.
47 #include "file_wrappers.h"
48 #include <wsutil/file_util.h>
53 #endif /* HAVE_ZLIB */
56 * See RFC 1952 for a description of the gzip file format.
58 * Some other compressed file formats we might want to support:
60 * XZ format: http://tukaani.org/xz/
62 * Bzip2 format: http://bzip.org/
66 * List of extensions for compressed files.
67 * If we add support for more compressed file types, this table
68 * might be expanded to include routines to handle the various
71 const char *compressed_file_extension_table[] = {
78 /* #define GZBUFSIZE 8192 */
79 #define GZBUFSIZE 4096
81 /* values for wtap_reader compression */
83 UNKNOWN, /* unknown - look for a gzip header */
84 UNCOMPRESSED, /* uncompressed - copy input directly */
86 ZLIB, /* decompress a zlib stream */
92 int fd; /* file descriptor */
93 gint64 raw_pos; /* current position in file (just to not call lseek()) */
94 gint64 pos; /* current position in uncompressed data */
95 guint size; /* buffer size */
96 unsigned char *in; /* input buffer */
97 unsigned char *out; /* output buffer (double-sized when reading) */
98 unsigned char *next; /* next output data to deliver or write */
100 guint have; /* amount of output data unused at next */
101 gboolean eof; /* TRUE if end of input file reached */
102 gint64 start; /* where the gzip data started, for rewinding */
103 gint64 raw; /* where the raw data started, for seeking */
104 compression_t compression; /* type of compression, if any */
105 gboolean is_compressed; /* FALSE if completely uncompressed, TRUE otherwise */
107 gint64 skip; /* amount to skip (already rewound if backwards) */
108 gboolean seek_pending; /* TRUE if seek request pending */
109 /* error information */
110 int err; /* error code */
111 const char *err_info; /* additional error information string for some errors */
113 guint avail_in; /* number of bytes available at next_in */
114 unsigned char *next_in; /* next input byte */
116 /* zlib inflate stream */
117 z_stream strm; /* stream structure in-place (not a pointer) */
118 gboolean dont_check_crc; /* TRUE if we aren't supposed to check the CRC */
121 GPtrArray *fast_seek;
125 static int /* gz_load */
126 raw_read(FILE_T state, unsigned char *buf, unsigned int count, guint *have)
132 ret = ws_read(state->fd, buf + *have, count - *have);
135 *have += (unsigned)ret;
136 state->raw_pos += ret;
137 } while (*have < count);
140 state->err_info = NULL;
148 static int /* gz_avail */
149 fill_in_buffer(FILE_T state)
153 if (state->eof == 0) {
154 if (raw_read(state, state->in, state->size, &(state->avail_in)) == -1)
156 state->next_in = state->in;
161 #define ZLIB_WINSIZE 32768
163 struct fast_seek_point {
164 gint64 out; /* corresponding offset in uncompressed data */
165 gint64 in; /* offset in input file of first full byte */
167 compression_t compression;
170 #ifdef HAVE_INFLATEPRIME
171 int bits; /* number of bits (1-7) from byte at in - 1, or 0 */
173 unsigned char window[ZLIB_WINSIZE]; /* preceding 32K of uncompressed data */
175 /* be gentle with Z_STREAM_END, 8 bytes more... Another solution would be to comment checks out */
182 struct zlib_cur_seek_point {
183 unsigned char window[ZLIB_WINSIZE]; /* preceding 32K of uncompressed data */
188 #define SPAN G_GINT64_CONSTANT(1048576)
189 static struct fast_seek_point *
190 fast_seek_find(FILE_T file, gint64 pos)
192 struct fast_seek_point *smallest = NULL;
193 struct fast_seek_point *item;
196 if (!file->fast_seek)
199 for (low = 0, max = file->fast_seek->len; low < max; ) {
201 item = (struct fast_seek_point *)file->fast_seek->pdata[i];
205 else if (pos > item->out) {
216 fast_seek_header(FILE_T file, gint64 in_pos, gint64 out_pos,
217 compression_t compression)
219 struct fast_seek_point *item = NULL;
221 if (file->fast_seek->len != 0)
222 item = (struct fast_seek_point *)file->fast_seek->pdata[file->fast_seek->len - 1];
224 if (!item || item->out < out_pos) {
225 struct fast_seek_point *val = g_new(struct fast_seek_point,1);
228 val->compression = compression;
230 g_ptr_array_add(file->fast_seek, val);
243 if (state->compression == ZLIB && state->fast_seek_cur) {
244 struct zlib_cur_seek_point *cur = (struct zlib_cur_seek_point *) state->fast_seek_cur;
253 /* Get next byte from input, or -1 if end or error.
257 * 1) errors from raw_read(), and thus from fill_in_buffer(), are
258 * "sticky", and fill_in_buffer() won't do any reading if there's
261 * 2) GZ_GETC() returns -1 on an EOF;
263 * so it's safe to make multiple GZ_GETC() calls and only check the
264 * last one for an error. */
265 #define GZ_GETC() ((state->avail_in == 0 && fill_in_buffer(state) == -1) ? -1 : \
266 (state->avail_in == 0 ? -1 : \
267 (state->avail_in--, *(state->next_in)++)))
269 /* Get a one-byte integer and return 0 on success and the value in *ret.
270 Otherwise -1 is returned, state->err is set, and *ret is not modified. */
272 gz_next1(FILE_T state, guint8 *ret)
278 if (state->err == 0) {
280 state->err = WTAP_ERR_SHORT_READ;
281 state->err_info = NULL;
289 /* Get a two-byte little-endian integer and return 0 on success and the value
290 in *ret. Otherwise -1 is returned, state->err is set, and *ret is not
293 gz_next2(FILE_T state, guint16 *ret)
301 if (state->err == 0) {
303 state->err = WTAP_ERR_SHORT_READ;
304 state->err_info = NULL;
308 val += (guint16)ch << 8;
313 /* Get a four-byte little-endian integer and return 0 on success and the value
314 in *ret. Otherwise -1 is returned, state->err is set, and *ret is not
317 gz_next4(FILE_T state, guint32 *ret)
323 val += (unsigned)GZ_GETC() << 8;
324 val += (guint32)GZ_GETC() << 16;
327 if (state->err == 0) {
329 state->err = WTAP_ERR_SHORT_READ;
330 state->err_info = NULL;
334 val += (guint32)ch << 24;
339 /* Skip the specified number of bytes and return 0 on success. Otherwise -1
342 gz_skipn(FILE_T state, size_t n)
345 if (GZ_GETC() == -1) {
346 if (state->err == 0) {
348 state->err = WTAP_ERR_SHORT_READ;
349 state->err_info = NULL;
358 /* Skip a null-terminated string and return 0 on success. Otherwise -1
361 gz_skipzstr(FILE_T state)
365 /* It's null-terminated, so scan until we read a byte with
366 the value 0 or get an error. */
367 while ((ch = GZ_GETC()) > 0)
370 if (state->err == 0) {
372 state->err = WTAP_ERR_SHORT_READ;
373 state->err_info = NULL;
381 zlib_fast_seek_add(FILE_T file, struct zlib_cur_seek_point *point, int bits, gint64 in_pos, gint64 out_pos)
383 /* it's for sure after gzip header, so file->fast_seek->len != 0 */
384 struct fast_seek_point *item = (struct fast_seek_point *)file->fast_seek->pdata[file->fast_seek->len - 1];
386 #ifndef HAVE_INFLATEPRIME
391 /* Glib has got Balanced Binary Trees (GTree) but I couldn't find a way to do quick search for nearest (and smaller) value to seek (It's what fast_seek_find() do)
392 * Inserting value in middle of sorted array is expensive, so we want to add only in the end.
393 * It's not big deal, cause first-read don't usually invoke seeking
395 if (item->out + SPAN < out_pos) {
396 struct fast_seek_point *val = g_new(struct fast_seek_point,1);
399 val->compression = ZLIB;
400 #ifdef HAVE_INFLATEPRIME
401 val->data.zlib.bits = bits;
403 if (point->pos != 0) {
404 unsigned int left = ZLIB_WINSIZE - point->pos;
406 memcpy(val->data.zlib.window, point->window + point->pos, left);
407 memcpy(val->data.zlib.window + left, point->window, point->pos);
409 memcpy(val->data.zlib.window, point->window, ZLIB_WINSIZE);
412 * XXX - strm.adler is a uLong in at least some versions
413 * of zlib, and uLong is an unsigned long in at least
414 * some of those versions, which means it's 64-bit
415 * on LP64 platforms, even though the checksum is
416 * 32-bit. We assume the actual Adler checksum
417 * is in the lower 32 bits of strm.adler; as the
418 * checksum in the file is only 32 bits, we save only
419 * those lower 32 bits, and cast away any additional
420 * bits to squelch warnings.
422 * The same applies to strm.total_out.
424 val->data.zlib.adler = (guint32) file->strm.adler;
425 val->data.zlib.total_out = (guint32) file->strm.total_out;
426 g_ptr_array_add(file->fast_seek, val);
430 static void /* gz_decomp */
431 zlib_read(FILE_T state, unsigned char *buf, unsigned int count)
433 int ret = 0; /* XXX */
435 z_streamp strm = &(state->strm);
437 unsigned char *buf2 = buf;
438 unsigned int count2 = count;
440 strm->avail_out = count;
441 strm->next_out = buf;
443 /* fill output buffer up to end of deflate stream or error */
445 /* get more input for inflate() */
446 if (state->avail_in == 0 && fill_in_buffer(state) == -1)
448 if (state->avail_in == 0) {
450 state->err = WTAP_ERR_SHORT_READ;
451 state->err_info = NULL;
455 strm->avail_in = state->avail_in;
456 strm->next_in = state->next_in;
457 /* decompress and handle errors */
459 ret = inflate(strm, Z_BLOCK);
461 ret = inflate(strm, Z_NO_FLUSH);
463 state->avail_in = strm->avail_in;
466 state->next_in = (unsigned char *)strm->next_in;
469 state->next_in = strm->next_in;
471 if (ret == Z_STREAM_ERROR) {
472 state->err = WTAP_ERR_DECOMPRESS;
473 state->err_info = strm->msg;
476 if (ret == Z_NEED_DICT) {
477 state->err = WTAP_ERR_DECOMPRESS;
478 state->err_info = "preset dictionary needed";
481 if (ret == Z_MEM_ERROR) {
482 /* This means "not enough memory". */
484 state->err_info = NULL;
487 if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
488 state->err = WTAP_ERR_DECOMPRESS;
489 state->err_info = strm->msg;
496 strm->adler = crc32(strm->adler, buf2, count2 - strm->avail_out);
498 if (state->fast_seek_cur) {
499 struct zlib_cur_seek_point *cur = (struct zlib_cur_seek_point *) state->fast_seek_cur;
500 unsigned int ready = count2 - strm->avail_out;
502 if (ready < ZLIB_WINSIZE) {
503 guint left = ZLIB_WINSIZE - cur->pos;
506 memcpy(cur->window + cur->pos, buf2, left);
508 memcpy(cur->window, buf2 + left, ready - left);
510 cur->pos = ready - left;
513 memcpy(cur->window + cur->pos, buf2, ready);
518 if (cur->have >= ZLIB_WINSIZE)
519 cur->have = ZLIB_WINSIZE;
522 memcpy(cur->window, buf2 + (ready - ZLIB_WINSIZE), ZLIB_WINSIZE);
524 cur->have = ZLIB_WINSIZE;
527 if (cur->have >= ZLIB_WINSIZE && ret != Z_STREAM_END && (strm->data_type & 128) && !(strm->data_type & 64))
528 zlib_fast_seek_add(state, cur, (strm->data_type & 7), state->raw_pos - strm->avail_in, state->pos + (count - strm->avail_out));
531 buf2 = (buf2 + count2 - strm->avail_out);
532 count2 = strm->avail_out;
534 } while (strm->avail_out && ret != Z_STREAM_END);
536 /* update available output and crc check value */
538 state->have = count - strm->avail_out;
540 /* Check gzip trailer if at end of deflate stream.
541 We don't fail immediately here, we just set an error
542 indication, so that we try to process what data we
543 got before the error. The next attempt to read
544 something past that data will get the error. */
545 if (ret == Z_STREAM_END) {
546 if (gz_next4(state, &crc) != -1 &&
547 gz_next4(state, &len) != -1) {
548 if (crc != strm->adler && !state->dont_check_crc) {
549 state->err = WTAP_ERR_DECOMPRESS;
550 state->err_info = "bad CRC";
551 } else if (len != (strm->total_out & 0xffffffffUL)) {
552 state->err = WTAP_ERR_DECOMPRESS;
553 state->err_info = "length field wrong";
556 state->compression = UNKNOWN; /* ready for next stream, once have is 0 */
557 g_free(state->fast_seek_cur);
558 state->fast_seek_cur = NULL;
564 gz_head(FILE_T state)
566 /* get some data in the input buffer */
567 if (state->avail_in == 0) {
568 if (fill_in_buffer(state) == -1)
570 if (state->avail_in == 0)
574 /* look for the gzip magic header bytes 31 and 139 */
576 if (state->next_in[0] == 31) {
579 if (state->avail_in == 0 && fill_in_buffer(state) == -1)
581 if (state->avail_in && state->next_in[0] == 139) {
587 /* we have a gzip header, woo hoo! */
591 /* read rest of header */
593 /* compression method (CM) */
594 if (gz_next1(state, &cm) == -1)
597 state->err = WTAP_ERR_DECOMPRESS;
598 state->err_info = "unknown compression method";
603 if (gz_next1(state, &flags) == -1)
605 if (flags & 0xe0) { /* reserved flag bits */
606 state->err = WTAP_ERR_DECOMPRESS;
607 state->err_info = "reserved flag bits set";
611 /* modification time (MTIME) */
612 if (gz_skipn(state, 4) == -1)
615 /* extra flags (XFL) */
616 if (gz_skipn(state, 1) == -1)
619 /* operating system (OS) */
620 if (gz_skipn(state, 1) == -1)
624 /* extra field - get XLEN */
625 if (gz_next2(state, &len) == -1)
628 /* skip the extra field */
629 if (gz_skipn(state, len) == -1)
634 if (gz_skipzstr(state) == -1)
639 if (gz_skipzstr(state) == -1)
644 if (gz_next2(state, &hcrc) == -1)
646 /* XXX - check the CRC? */
649 /* set up for decompression */
650 inflateReset(&(state->strm));
651 state->strm.adler = crc32(0L, Z_NULL, 0);
652 state->compression = ZLIB;
653 state->is_compressed = TRUE;
655 if (state->fast_seek) {
656 struct zlib_cur_seek_point *cur = g_new(struct zlib_cur_seek_point,1);
658 cur->pos = cur->have = 0;
659 g_free(state->fast_seek_cur);
660 state->fast_seek_cur = cur;
661 fast_seek_header(state, state->raw_pos - state->avail_in, state->pos, GZIP_AFTER_HEADER);
667 /* not a gzip file -- save first byte (31) and fall to raw i/o */
674 /* { 0xFD, '7', 'z', 'X', 'Z', 0x00 } */
675 /* FD 37 7A 58 5A 00 */
677 if (state->fast_seek)
678 fast_seek_header(state, state->raw_pos - state->avail_in - state->have, state->pos, UNCOMPRESSED);
680 /* doing raw i/o, save start of raw data for seeking, copy any leftover
681 input to output -- this assumes that the output buffer is larger than
682 the input buffer, which also assures space for gzungetc() */
683 state->raw = state->pos;
684 state->next = state->out;
685 if (state->avail_in) {
686 memcpy(state->next + state->have, state->next_in, state->avail_in);
687 state->have += state->avail_in;
690 state->compression = UNCOMPRESSED;
694 static int /* gz_make */
695 fill_out_buffer(FILE_T state)
697 if (state->compression == UNKNOWN) { /* look for gzip header */
698 if (gz_head(state) == -1)
700 if (state->have) /* got some data from gz_head() */
703 if (state->compression == UNCOMPRESSED) { /* straight copy */
704 if (raw_read(state, state->out, state->size /* << 1 */, &(state->have)) == -1)
706 state->next = state->out;
709 else if (state->compression == ZLIB) { /* decompress */
710 zlib_read(state, state->out, state->size << 1);
717 gz_skip(FILE_T state, gint64 len)
721 /* skip over len bytes or reach end-of-file, whichever comes first */
724 /* We have stuff in the output buffer; skip over
726 n = (gint64)state->have > len ? (unsigned)len : state->have;
731 } else if (state->err) {
732 /* We have nothing in the output buffer, and
733 we have an error that may not have been
734 reported yet; that means we can't generate
735 any more data into the output buffer, so
736 return an error indication. */
738 } else if (state->eof && state->avail_in == 0) {
739 /* We have nothing in the output buffer, and
740 we're at the end of the input; just return. */
743 /* We have nothing in the output buffer, and
744 we can generate more data; get more output,
745 looking for header if required. */
746 if (fill_out_buffer(state) == -1)
753 gz_reset(FILE_T state)
755 state->have = 0; /* no output data available */
756 state->eof = FALSE; /* not at end of file */
757 state->compression = UNKNOWN; /* look for gzip header */
759 state->seek_pending = FALSE; /* no seek request pending */
760 state->err = 0; /* clear error */
761 state->err_info = NULL;
762 state->pos = 0; /* no uncompressed data yet */
763 state->avail_in = 0; /* no input data yet */
769 #ifdef _STATBUF_ST_BLKSIZE /* XXX, _STATBUF_ST_BLKSIZE portable? */
772 int want = GZBUFSIZE;
778 /* allocate FILE_T structure to return */
779 state = (FILE_T)g_try_malloc(sizeof *state);
783 state->fast_seek_cur = NULL;
784 state->fast_seek = NULL;
786 /* open the file with the appropriate mode (or just use fd) */
789 /* we don't yet know whether it's compressed */
790 state->is_compressed = FALSE;
792 /* save the current position for rewinding (only if reading) */
793 state->start = ws_lseek64(state->fd, 0, SEEK_CUR);
794 if (state->start == -1) state->start = 0;
795 state->raw_pos = state->start;
797 /* initialize stream */
800 #ifdef _STATBUF_ST_BLKSIZE
801 if (ws_fstat64(fd, &st) >= 0) {
803 * Yes, st_blksize can be bigger than an int; apparently,
804 * it's a long on LP64 Linux, for example.
806 * If the value is too big to fit into an int, just
809 if (st.st_blksize <= G_MAXINT)
810 want = (int)st.st_blksize;
811 /* XXX, verify result? */
815 /* allocate buffers */
816 state->in = (unsigned char *)g_try_malloc(want);
817 state->out = (unsigned char *)g_try_malloc(want << 1);
819 if (state->in == NULL || state->out == NULL) {
828 /* allocate inflate memory */
829 state->strm.zalloc = Z_NULL;
830 state->strm.zfree = Z_NULL;
831 state->strm.opaque = Z_NULL;
832 state->strm.avail_in = 0;
833 state->strm.next_in = Z_NULL;
834 if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */
842 /* for now, assume we should check the crc */
843 state->dont_check_crc = FALSE;
850 file_open(const char *path)
858 /* open file and do correct filename conversions.
860 XXX - do we need O_LARGEFILE? On UN*X, if we need to do
861 something special to get large file support, the configure
862 script should have set us up with the appropriate #defines,
863 so we should be getting a large-file-enabled file descriptor
864 here. Pre-Large File Summit UN*Xes, and possibly even some
865 post-LFS UN*Xes, might require O_LARGEFILE here, though.
866 If so, we should probably handle that in ws_open(). */
867 if ((fd = ws_open(path, O_RDONLY|O_BINARY, 0000)) == -1)
870 /* open file handle */
871 ft = file_fdopen(fd);
879 * If this file's name ends in ".caz", it's probably a compressed
880 * Windows Sniffer file. The compression is gzip, but if we
881 * process the CRC as specified by RFC 1952, the computed CRC
882 * doesn't match the stored CRC.
884 * Compressed Windows Sniffer files don't all have the same CRC
885 * value; is it just random crap, or are they running the CRC on
886 * a different set of data than you're supposed to (e.g., not
887 * CRCing some of the data), or something such as that?
889 * For now, we just set a flag to ignore CRC errors.
891 suffixp = strrchr(path, '.');
892 if (suffixp != NULL) {
893 if (g_ascii_strcasecmp(suffixp, ".caz") == 0)
894 ft->dont_check_crc = TRUE;
902 file_set_random_access(FILE_T stream, gboolean random_flag _U_, GPtrArray *seek)
904 stream->fast_seek = seek;
908 file_seek(FILE_T file, gint64 offset, int whence, int *err)
910 struct fast_seek_point *here;
913 if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) {
914 g_assert_not_reached();
921 /* Normalize offset to a SEEK_CUR specification */
922 if (whence == SEEK_END) {
923 /* Try skip until end-of-file */
924 if (gz_skip(file, G_MAXINT64) == -1) {
932 } else if (whence == SEEK_SET)
934 else if (file->seek_pending)
935 offset += file->skip;
936 file->seek_pending = FALSE;
939 * Are we seeking backwards and, if so, do we have data in the buffer?
941 if (offset < 0 && file->next) {
945 * This is guaranteed to fit in an unsigned int.
946 * To squelch compiler warnings, we cast the
949 guint had = (unsigned)(file->next - file->out);
952 * Do we have enough data before the current position in
953 * the buffer that we can seek backwards within the buffer?
955 if (-offset <= had) {
959 * Offset is negative, so -offset is
960 * non-negative, and -offset is
961 * <= an unsigned and thus fits in an
962 * unsigned. Get that value and
963 * adjust appropriately.
965 * (Casting offset to unsigned makes
966 * it positive, which is not what we
967 * would want, so we cast -offset
970 guint adjustment = (unsigned)(-offset);
971 file->have += adjustment;
972 file->next -= adjustment;
973 file->pos -= adjustment;
979 * No. Do we have "fast seek" data for the location to which we
984 if ((here = fast_seek_find(file, file->pos + offset)) && (offset < 0 || offset > SPAN || here->compression == UNCOMPRESSED)) {
988 * Yes. Use that data to do the seek.
989 * Note that this will be true only if file_set_random_access()
990 * has been called on this file, which should never be the case
994 if (here->compression == ZLIB) {
995 #ifdef HAVE_INFLATEPRIME
996 off = here->in - (here->data.zlib.bits ? 1 : 0);
1001 } else if (here->compression == GZIP_AFTER_HEADER) {
1007 off2 = (file->pos + offset);
1008 off = here->in + (off2 - here->out);
1011 if (ws_lseek64(file->fd, off, SEEK_SET) == -1) {
1015 fast_seek_reset(file);
1017 file->raw_pos = off;
1020 file->seek_pending = FALSE;
1022 file->err_info = NULL;
1026 if (here->compression == ZLIB) {
1027 z_stream *strm = &file->strm;
1030 strm->adler = here->data.zlib.adler;
1031 strm->total_out = here->data.zlib.total_out;
1032 #ifdef HAVE_INFLATEPRIME
1033 if (here->data.zlib.bits) {
1034 FILE_T state = file;
1035 int ret = GZ_GETC();
1038 if (state->err == 0) {
1040 *err = WTAP_ERR_SHORT_READ;
1045 (void)inflatePrime(strm, here->data.zlib.bits, ret >> (8 - here->data.zlib.bits));
1048 (void)inflateSetDictionary(strm, here->data.zlib.window, ZLIB_WINSIZE);
1049 file->compression = ZLIB;
1050 } else if (here->compression == GZIP_AFTER_HEADER) {
1051 z_stream *strm = &file->strm;
1054 strm->adler = crc32(0L, Z_NULL, 0);
1055 file->compression = ZLIB;
1058 file->compression = here->compression;
1060 offset = (file->pos + offset) - off2;
1062 /* g_print("OK! %ld\n", offset); */
1065 file->seek_pending = TRUE;
1066 file->skip = offset;
1068 return file->pos + offset;
1072 * Is this an uncompressed file, are we within the raw area,
1073 * are we either seeking backwards or seeking past the end
1074 * of the buffer, and are we set up for random access with
1075 * file_set_random_access()?
1077 * Again, note that this will never be true on a pipe, as
1078 * file_set_random_access() should never be called if we're
1079 * reading from a pipe.
1081 if (file->compression == UNCOMPRESSED && file->pos + offset >= file->raw
1082 && (offset < 0 || offset >= file->have)
1083 && (file->fast_seek))
1086 * Yes. Just seek there within the file.
1088 if (ws_lseek64(file->fd, offset - file->have, SEEK_CUR) == -1) {
1092 file->raw_pos += (offset - file->have);
1095 file->seek_pending = FALSE;
1097 file->err_info = NULL;
1099 file->pos += offset;
1104 * Are we seeking backwards?
1110 * Calculate the amount to skip forward after rewinding.
1112 offset += file->pos;
1113 if (offset < 0) { /* before start of file! */
1117 /* rewind, then skip to offset */
1119 /* back up and start over */
1120 if (ws_lseek64(file->fd, file->start, SEEK_SET) == -1) {
1124 fast_seek_reset(file);
1125 file->raw_pos = file->start;
1130 * No, we're skipping forwards.
1132 * Skip what's in output buffer (one less gzgetc() check).
1134 n = (gint64)file->have > offset ? (unsigned)offset : file->have;
1140 /* request skip (if not zero) */
1142 file->seek_pending = TRUE;
1143 file->skip = offset;
1145 return file->pos + offset;
1149 * Skip forward the specified number of bytes in the file.
1150 * Currently implemented as a wrapper around file_seek(),
1151 * but if, for example, we ever add support for reading
1152 * sequentially from a pipe, this could instead just skip
1153 * forward by reading the bytes in question.
1156 file_skip(FILE_T file, gint64 delta, int *err)
1158 if (file_seek(file, delta, SEEK_CUR, err) == -1)
1164 file_tell(FILE_T stream)
1166 /* return position */
1167 return stream->pos + (stream->seek_pending ? stream->skip : 0);
1171 file_tell_raw(FILE_T stream)
1173 return stream->raw_pos;
1177 file_fstat(FILE_T stream, ws_statb64 *statb, int *err)
1179 if (ws_fstat64(stream->fd, statb) == -1) {
1188 file_iscompressed(FILE_T stream)
1190 return stream->is_compressed;
1194 file_read(void *buf, unsigned int len, FILE_T file)
1198 /* if len is zero, avoid unnecessary operations */
1202 /* process a skip request */
1203 if (file->seek_pending) {
1204 file->seek_pending = FALSE;
1205 if (gz_skip(file, file->skip) == -1)
1209 /* get len bytes to buf, or less than len if at the end */
1213 /* We have stuff in the output buffer; copy
1215 n = file->have > len ? len : file->have;
1216 memcpy(buf, file->next, n);
1219 } else if (file->err) {
1220 /* We have nothing in the output buffer, and
1221 we have an error that may not have been
1222 reported yet; that means we can't generate
1223 any more data into the output buffer, so
1224 return an error indication. */
1226 } else if (file->eof && file->avail_in == 0) {
1227 /* We have nothing in the output buffer, and
1228 we're at the end of the input; just return
1229 with what we've gotten so far. */
1232 /* We have nothing in the output buffer, and
1233 we can generate more data; get more output,
1234 looking for header if required, and
1235 keep looping to process the new stuff
1236 in the output buffer. */
1237 if (fill_out_buffer(file) == -1)
1239 continue; /* no progress yet -- go back to memcpy() above */
1241 /* update progress */
1243 buf = (char *)buf + n;
1252 * XXX - this *peeks* at next byte, not a character.
1255 file_peekc(FILE_T file)
1259 /* check that we're reading and that there's no error */
1263 /* try output buffer (no need to check for skip request) */
1265 return *(file->next);
1268 /* process a skip request */
1269 if (file->seek_pending) {
1270 file->seek_pending = FALSE;
1271 if (gz_skip(file, file->skip) == -1)
1274 /* if we processed a skip request, there may be data in the buffer,
1275 * or an error could have occurred; likewise if we didn't do seek but
1276 * now call fill_out_buffer, the errors can occur. So we do this while
1277 * loop to check before and after - this is basically the logic from
1278 * file_read() but only for peeking not consuming a byte
1282 return *(file->next);
1284 else if (file->err) {
1287 else if (file->eof && file->avail_in == 0) {
1290 else if (fill_out_buffer(file) == -1) {
1294 /* it's actually impossible to get here */
1299 * XXX - this gets a byte, not a character.
1302 file_getc(FILE_T file)
1304 unsigned char buf[1];
1307 /* check that we're reading and that there's no error */
1311 /* try output buffer (no need to check for skip request) */
1315 return *(file->next)++;
1318 ret = file_read(buf, 1, file);
1319 return ret < 1 ? -1 : buf[0];
1323 file_gets(char *buf, int len, FILE_T file)
1329 /* check parameters */
1330 if (buf == NULL || len < 1)
1333 /* check that there's no error */
1337 /* process a skip request */
1338 if (file->seek_pending) {
1339 file->seek_pending = FALSE;
1340 if (gz_skip(file, file->skip) == -1)
1344 /* copy output bytes up to new line or len - 1, whichever comes first --
1345 append a terminating zero to the string (we don't check for a zero in
1346 the contents, let the user worry about that) */
1348 left = (unsigned)len - 1;
1350 /* assure that something is in the output buffer */
1351 if (file->have == 0) {
1352 /* We have nothing in the output buffer. */
1354 /* We have an error that may not have
1355 been reported yet; that means we
1356 can't generate any more data into
1357 the output buffer, so return an
1358 error indication. */
1361 if (fill_out_buffer(file) == -1)
1362 return NULL; /* error */
1363 if (file->have == 0) { /* end of file */
1364 if (buf == str) /* got bupkus */
1366 break; /* got something -- return it */
1370 /* look for end-of-line in current output buffer */
1371 n = file->have > left ? left : file->have;
1372 eol = (unsigned char *)memchr(file->next, '\n', n);
1374 n = (unsigned)(eol - file->next) + 1;
1376 /* copy through end-of-line, or remainder if not found */
1377 memcpy(buf, file->next, n);
1383 } while (left && eol == NULL);
1385 /* found end-of-line or out of space -- terminate string and return it */
1391 file_eof(FILE_T file)
1393 /* return end-of-file state */
1394 return (file->eof && file->avail_in == 0 && file->have == 0);
1398 * Routine to return a Wiretap error code (0 for no error, an errno
1399 * for a file error, or a WTAP_ERR_ code for other errors) for an
1400 * I/O stream. Also returns an error string for some errors.
1403 file_error(FILE_T fh, gchar **err_info)
1405 if (fh->err!=0 && err_info) {
1406 /* g_strdup() returns NULL for NULL argument */
1407 *err_info = g_strdup(fh->err_info);
1413 file_clearerr(FILE_T stream)
1415 /* clear error and end-of-file */
1417 stream->err_info = NULL;
1418 stream->eof = FALSE;
1422 file_fdclose(FILE_T file)
1429 file_fdreopen(FILE_T file, const char *path)
1433 if ((fd = ws_open(path, O_RDONLY|O_BINARY, 0000)) == -1)
1440 file_close(FILE_T file)
1444 /* free memory and close file */
1447 inflateEnd(&(file->strm));
1452 g_free(file->fast_seek_cur);
1454 file->err_info = NULL;
1457 * If fd is -1, somebody's done a file_closefd() on us, so
1458 * we don't need to close the FD itself, and shouldn't do
1466 /* internal gzip file state data structure for writing */
1467 struct wtap_writer {
1468 int fd; /* file descriptor */
1469 gint64 pos; /* current position in uncompressed data */
1470 guint size; /* buffer size, zero if not allocated yet */
1471 guint want; /* requested buffer size, default is GZBUFSIZE */
1472 unsigned char *in; /* input buffer */
1473 unsigned char *out; /* output buffer (double-sized when reading) */
1474 unsigned char *next; /* next output data to deliver or write */
1475 int level; /* compression level */
1476 int strategy; /* compression strategy */
1477 int err; /* error code */
1478 /* zlib deflate stream */
1479 z_stream strm; /* stream structure in-place (not a pointer) */
1483 gzwfile_open(const char *path)
1489 fd = ws_open(path, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666);
1492 state = gzwfile_fdopen(fd);
1493 if (state == NULL) {
1502 gzwfile_fdopen(int fd)
1506 /* allocate wtap_writer structure to return */
1507 state = (GZWFILE_T)g_try_malloc(sizeof *state);
1511 state->size = 0; /* no buffers allocated yet */
1512 state->want = GZBUFSIZE; /* requested buffer size */
1514 state->level = Z_DEFAULT_COMPRESSION;
1515 state->strategy = Z_DEFAULT_STRATEGY;
1517 /* initialize stream */
1518 state->err = Z_OK; /* clear error */
1519 state->pos = 0; /* no uncompressed data yet */
1520 state->strm.avail_in = 0; /* no input data yet */
1526 /* Initialize state for writing a gzip file. Mark initialization by setting
1527 state->size to non-zero. Return -1, and set state->err, on failure;
1528 return 0 on success. */
1530 gz_init(GZWFILE_T state)
1533 z_streamp strm = &(state->strm);
1535 /* allocate input and output buffers */
1536 state->in = (unsigned char *)g_try_malloc(state->want);
1537 state->out = (unsigned char *)g_try_malloc(state->want);
1538 if (state->in == NULL || state->out == NULL) {
1541 state->err = ENOMEM;
1545 /* allocate deflate memory, set up for gzip compression */
1546 strm->zalloc = Z_NULL;
1547 strm->zfree = Z_NULL;
1548 strm->opaque = Z_NULL;
1549 ret = deflateInit2(strm, state->level, Z_DEFLATED,
1550 15 + 16, 8, state->strategy);
1554 if (ret == Z_MEM_ERROR) {
1555 /* This means "not enough memory". */
1556 state->err = ENOMEM;
1558 /* This "shouldn't happen". */
1559 state->err = WTAP_ERR_INTERNAL;
1564 /* mark state as initialized */
1565 state->size = state->want;
1567 /* initialize write buffer */
1568 strm->avail_out = state->size;
1569 strm->next_out = state->out;
1570 state->next = strm->next_out;
1574 /* Compress whatever is at avail_in and next_in and write to the output file.
1575 Return -1, and set state->err, if there is an error writing to the output
1576 file; return 0 on success.
1577 flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
1578 then the deflate() state is reset to start a new gzip stream. */
1580 gz_comp(GZWFILE_T state, int flush)
1585 z_streamp strm = &(state->strm);
1587 /* allocate memory if this is the first time through */
1588 if (state->size == 0 && gz_init(state) == -1)
1591 /* run deflate() on provided input until it produces no more output */
1594 /* write out current buffer contents if full, or if flushing, but if
1595 doing Z_FINISH then don't write until we get to Z_STREAM_END */
1596 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
1597 (flush != Z_FINISH || ret == Z_STREAM_END))) {
1598 have = strm->next_out - state->next;
1600 got = ws_write(state->fd, state->next, (unsigned int)have);
1605 if ((ptrdiff_t)got != have) {
1606 state->err = WTAP_ERR_SHORT_WRITE;
1610 if (strm->avail_out == 0) {
1611 strm->avail_out = state->size;
1612 strm->next_out = state->out;
1614 state->next = strm->next_out;
1618 have = strm->avail_out;
1619 ret = deflate(strm, flush);
1620 if (ret == Z_STREAM_ERROR) {
1621 /* This "shouldn't happen". */
1622 state->err = WTAP_ERR_INTERNAL;
1625 have -= strm->avail_out;
1628 /* if that completed a deflate stream, allow another to start */
1629 if (flush == Z_FINISH)
1632 /* all done, no errors */
1636 /* Write out len bytes from buf. Return 0, and set state->err, on
1637 failure or on an attempt to write 0 bytes (in which case state->err
1638 is Z_OK); return the number of bytes written on success. */
1640 gzwfile_write(GZWFILE_T state, const void *buf, guint len)
1646 strm = &(state->strm);
1648 /* check that there's no error */
1649 if (state->err != Z_OK)
1652 /* if len is zero, avoid unnecessary operations */
1656 /* allocate memory if this is the first time through */
1657 if (state->size == 0 && gz_init(state) == -1)
1660 /* for small len, copy to input buffer, otherwise compress directly */
1661 if (len < state->size) {
1662 /* copy to input buffer, compress when full */
1664 if (strm->avail_in == 0)
1665 strm->next_in = state->in;
1666 n = state->size - strm->avail_in;
1671 memcpy((Bytef *)strm->next_in + strm->avail_in, buf, n);
1674 memcpy(strm->next_in + strm->avail_in, buf, n);
1676 strm->avail_in += n;
1678 buf = (const char *)buf + n;
1680 if (len && gz_comp(state, Z_NO_FLUSH) == -1)
1685 /* consume whatever's left in the input buffer */
1686 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
1689 /* directly compress user buffer to file */
1690 strm->avail_in = len;
1692 strm->next_in = (z_const Bytef *)buf;
1695 strm->next_in = (Bytef *)buf;
1699 if (gz_comp(state, Z_NO_FLUSH) == -1)
1703 /* input was all buffered or compressed (put will fit in int) */
1707 /* Flush out what we've written so far. Returns -1, and sets state->err,
1708 on failure; returns 0 on success. */
1710 gzwfile_flush(GZWFILE_T state)
1712 /* check that there's no error */
1713 if (state->err != Z_OK)
1716 /* compress remaining data with Z_SYNC_FLUSH */
1717 gz_comp(state, Z_SYNC_FLUSH);
1718 if (state->err != Z_OK)
1723 /* Flush out all data written, and close the file. Returns a Wiretap
1724 error on failure; returns 0 on success.
1726 If is_stdout is true, do all of that except for closing the file
1727 descriptor, as we don't want to close the standard output file
1728 descriptor out from under the program (even though, if the program
1729 is writing a capture file to the standard output, it shouldn't be
1730 doing anything *else* on the standard output). */
1732 gzwfile_close(GZWFILE_T state, gboolean is_stdout)
1736 /* flush, free memory, and close file */
1737 if (gz_comp(state, Z_FINISH) == -1 && ret == 0)
1739 (void)deflateEnd(&(state->strm));
1744 if (ws_close(state->fd) == -1 && ret == 0)
1752 gzwfile_geterr(GZWFILE_T state)
1759 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1764 * indent-tabs-mode: nil
1767 * vi: set shiftwidth=4 tabstop=8 expandtab:
1768 * :indentSize=4:tabSize=8:noTabs=true: