|
|
|
@ -7,6 +7,15 @@ |
|
|
|
|
|
|
|
|
|
/* @(#) $Id$ */ |
|
|
|
|
|
|
|
|
|
#ifdef _LARGEFILE64_SOURCE |
|
|
|
|
# ifndef _LARGEFILE_SOURCE |
|
|
|
|
# define _LARGEFILE_SOURCE |
|
|
|
|
# endif |
|
|
|
|
# ifdef _FILE_OFFSET_BITS |
|
|
|
|
# undef _FILE_OFFSET_BITS |
|
|
|
|
# endif |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include "zutil.h" |
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
|
@ -39,6 +48,14 @@ extern voidp malloc OF((uInt size)); |
|
|
|
|
extern void free OF((voidpf ptr)); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef NO_FSEEKO |
|
|
|
|
# define FSEEK fseek |
|
|
|
|
# define FTELL ftell |
|
|
|
|
#else |
|
|
|
|
# define FSEEK fseeko |
|
|
|
|
# define FTELL ftello |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#define ALLOC(size) malloc(size) |
|
|
|
|
#define TRYFREE(p) {if (p) free(p);} |
|
|
|
|
|
|
|
|
@ -64,15 +81,27 @@ typedef struct gz_stream { |
|
|
|
|
char *path; /* path name for debugging only */ |
|
|
|
|
int transparent; /* 1 if input file is not a .gz file */ |
|
|
|
|
char mode; /* 'w' or 'r' */ |
|
|
|
|
#ifdef _LARGEFILE64_SOURCE |
|
|
|
|
off64_t start; /* start of compressed data in file (header skipped) */ |
|
|
|
|
off64_t in; /* bytes into deflate or inflate */ |
|
|
|
|
off64_t out; /* bytes out of deflate or inflate */ |
|
|
|
|
#else |
|
|
|
|
z_off_t start; /* start of compressed data in file (header skipped) */ |
|
|
|
|
z_off_t in; /* bytes into deflate or inflate */ |
|
|
|
|
z_off_t out; /* bytes out of deflate or inflate */ |
|
|
|
|
#endif |
|
|
|
|
int back; /* one character push-back */ |
|
|
|
|
int last; /* true if push-back is last character */ |
|
|
|
|
} gz_stream; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local gzFile gz_open OF((const char *path, const char *mode, int fd)); |
|
|
|
|
local gzFile gz_open OF((const char *path, const char *mode, int fd, |
|
|
|
|
int use64)); |
|
|
|
|
#ifdef _LARGEFILE64_SOURCE |
|
|
|
|
local off64_t gz_seek OF((gzFile file, off64_t offset, int whence, int use64)); |
|
|
|
|
#else |
|
|
|
|
local z_off_t gz_seek OF((gzFile file, z_off_t offset, int whence, int use64)); |
|
|
|
|
#endif |
|
|
|
|
local int do_flush OF((gzFile file, int flush)); |
|
|
|
|
local int get_byte OF((gz_stream *s)); |
|
|
|
|
local void check_header OF((gz_stream *s)); |
|
|
|
@ -89,10 +118,11 @@ local uLong getLong OF((gz_stream *s)); |
|
|
|
|
can be checked to distinguish the two cases (if errno is zero, the |
|
|
|
|
zlib error is Z_MEM_ERROR). |
|
|
|
|
*/ |
|
|
|
|
local gzFile gz_open (path, mode, fd) |
|
|
|
|
local gzFile gz_open (path, mode, fd, use64) |
|
|
|
|
const char *path; |
|
|
|
|
const char *mode; |
|
|
|
|
int fd; |
|
|
|
|
int use64; |
|
|
|
|
{ |
|
|
|
|
int err; |
|
|
|
|
int level = Z_DEFAULT_COMPRESSION; /* compression level */ |
|
|
|
@ -164,12 +194,7 @@ local gzFile gz_open (path, mode, fd) |
|
|
|
|
s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); |
|
|
|
|
|
|
|
|
|
err = inflateInit2(&(s->stream), -MAX_WBITS); |
|
|
|
|
/* windowBits is passed < 0 to tell that there is no zlib header.
|
|
|
|
|
* Note that in this case inflate *requires* an extra "dummy" byte |
|
|
|
|
* after the compressed stream in order to complete decompression and |
|
|
|
|
* return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are |
|
|
|
|
* present after the compressed stream. |
|
|
|
|
*/ |
|
|
|
|
/* windowBits is passed < 0 to tell that there is no zlib header */ |
|
|
|
|
if (err != Z_OK || s->inbuf == Z_NULL) { |
|
|
|
|
return destroy(s), (gzFile)Z_NULL; |
|
|
|
|
} |
|
|
|
@ -177,7 +202,8 @@ local gzFile gz_open (path, mode, fd) |
|
|
|
|
s->stream.avail_out = Z_BUFSIZE; |
|
|
|
|
|
|
|
|
|
errno = 0; |
|
|
|
|
s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); |
|
|
|
|
s->file = fd < 0 ? (use64 ? F_OPEN64(path, fmode) : F_OPEN(path, fmode)) : |
|
|
|
|
(FILE*)fdopen(fd, fmode); |
|
|
|
|
|
|
|
|
|
if (s->file == NULL) { |
|
|
|
|
return destroy(s), (gzFile)Z_NULL; |
|
|
|
@ -198,7 +224,7 @@ local gzFile gz_open (path, mode, fd) |
|
|
|
|
*/ |
|
|
|
|
} else { |
|
|
|
|
check_header(s); /* skip the .gz header */ |
|
|
|
|
s->start = ftell(s->file) - s->stream.avail_in; |
|
|
|
|
s->start = FTELL(s->file) - s->stream.avail_in; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return (gzFile)s; |
|
|
|
@ -211,7 +237,17 @@ gzFile ZEXPORT gzopen (path, mode) |
|
|
|
|
const char *path; |
|
|
|
|
const char *mode; |
|
|
|
|
{ |
|
|
|
|
return gz_open (path, mode, -1); |
|
|
|
|
return gz_open (path, mode, -1, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
|
Opens a gzip (.gz) file for reading or writing for 64-bit offsets |
|
|
|
|
*/ |
|
|
|
|
gzFile ZEXPORT gzopen64 (path, mode) |
|
|
|
|
const char *path; |
|
|
|
|
const char *mode; |
|
|
|
|
{ |
|
|
|
|
return gz_open (path, mode, -1, 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
@ -227,7 +263,7 @@ gzFile ZEXPORT gzdopen (fd, mode) |
|
|
|
|
if (fd < 0) return (gzFile)Z_NULL; |
|
|
|
|
sprintf(name, "<fd:%d>", fd); /* for debugging */ |
|
|
|
|
|
|
|
|
|
return gz_open (name, mode, fd); |
|
|
|
|
return gz_open (name, mode, fd, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
@ -767,10 +803,17 @@ int ZEXPORT gzflush (file, flush) |
|
|
|
|
SEEK_END is not implemented, returns error. |
|
|
|
|
In this version of the library, gzseek can be extremely slow. |
|
|
|
|
*/ |
|
|
|
|
z_off_t ZEXPORT gzseek (file, offset, whence) |
|
|
|
|
#ifdef _LARGEFILE64_SOURCE |
|
|
|
|
local off64_t gz_seek (file, offset, whence, use64) |
|
|
|
|
gzFile file; |
|
|
|
|
off64_t offset; |
|
|
|
|
#else |
|
|
|
|
local z_off_t gz_seek (file, offset, whence, use64) |
|
|
|
|
gzFile file; |
|
|
|
|
z_off_t offset; |
|
|
|
|
#endif |
|
|
|
|
int whence; |
|
|
|
|
int use64; |
|
|
|
|
{ |
|
|
|
|
gz_stream *s = (gz_stream*)file; |
|
|
|
|
|
|
|
|
@ -819,7 +862,13 @@ z_off_t ZEXPORT gzseek (file, offset, whence) |
|
|
|
|
s->back = EOF; |
|
|
|
|
s->stream.avail_in = 0; |
|
|
|
|
s->stream.next_in = s->inbuf; |
|
|
|
|
if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; |
|
|
|
|
#ifdef _LARGEFILE64_SOURCE |
|
|
|
|
if ((use64 ? fseeko64(s->file, offset, SEEK_SET) : |
|
|
|
|
FSEEK(s->file, offset, SEEK_SET)) < 0) |
|
|
|
|
return -1L; |
|
|
|
|
#else |
|
|
|
|
if (FSEEK(s->file, offset, SEEK_SET) < 0) return -1L; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
s->in = s->out = offset; |
|
|
|
|
return offset; |
|
|
|
@ -854,6 +903,35 @@ z_off_t ZEXPORT gzseek (file, offset, whence) |
|
|
|
|
return s->out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
|
Define external functions gzseek() and gzseek64() using local gz_seek(). |
|
|
|
|
*/ |
|
|
|
|
z_off_t ZEXPORT gzseek (file, offset, whence) |
|
|
|
|
gzFile file; |
|
|
|
|
z_off_t offset; |
|
|
|
|
int whence; |
|
|
|
|
{ |
|
|
|
|
return (z_off_t)gz_seek(file, offset, whence, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef _LARGEFILE64_SOURCE |
|
|
|
|
off64_t ZEXPORT gzseek64 (file, offset, whence) |
|
|
|
|
gzFile file; |
|
|
|
|
off64_t offset; |
|
|
|
|
int whence; |
|
|
|
|
{ |
|
|
|
|
return gz_seek(file, offset, whence, 1); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
z_off_t ZEXPORT gzseek64 (file, offset, whence) |
|
|
|
|
gzFile file; |
|
|
|
|
z_off_t offset; |
|
|
|
|
int whence; |
|
|
|
|
{ |
|
|
|
|
return gz_seek(file, offset, whence, 0); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
|
Rewinds input file. |
|
|
|
|
*/ |
|
|
|
@ -873,7 +951,7 @@ int ZEXPORT gzrewind (file) |
|
|
|
|
if (!s->transparent) (void)inflateReset(&s->stream); |
|
|
|
|
s->in = 0; |
|
|
|
|
s->out = 0; |
|
|
|
|
return fseek(s->file, s->start, SEEK_SET); |
|
|
|
|
return FSEEK(s->file, s->start, SEEK_SET); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
@ -887,6 +965,19 @@ z_off_t ZEXPORT gztell (file) |
|
|
|
|
return gzseek(file, 0L, SEEK_CUR); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
|
64-bit version |
|
|
|
|
*/ |
|
|
|
|
#ifdef _LARGEFILE64_SOURCE |
|
|
|
|
off64_t ZEXPORT gztell64 (file) |
|
|
|
|
#else |
|
|
|
|
z_off_t ZEXPORT gztell64 (file) |
|
|
|
|
#endif |
|
|
|
|
gzFile file; |
|
|
|
|
{ |
|
|
|
|
return gzseek64(file, 0L, SEEK_CUR); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
|
Returns 1 when EOF has previously been detected reading the given |
|
|
|
|
input stream, otherwise zero. |
|
|
|
|