5128eecc9f 2011-02-23 kinaba: /* gzio.c -- IO on .gz files 5128eecc9f 2011-02-23 kinaba: * Copyright (C) 1995-1998 Jean-loup Gailly. 5128eecc9f 2011-02-23 kinaba: * For conditions of distribution and use, see copyright notice in zlib.h 5128eecc9f 2011-02-23 kinaba: * 5128eecc9f 2011-02-23 kinaba: * Compile this file with -DNO_DEFLATE to avoid the compression code. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* @(#) $Id$ */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #include <stdio.h> 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #include "zutil.h" 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifdef KI_GZ_NO_COMPRESSION 5128eecc9f 2011-02-23 kinaba: #define NO_DEFLATE 5128eecc9f 2011-02-23 kinaba: #endif /* KI_GZ_NO_COMPRESSION */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: struct internal_state {int dummy;}; /* for buggy compilers */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef Z_BUFSIZE 5128eecc9f 2011-02-23 kinaba: # ifdef MAXSEG_64K 5128eecc9f 2011-02-23 kinaba: # define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ 5128eecc9f 2011-02-23 kinaba: # else 5128eecc9f 2011-02-23 kinaba: # define Z_BUFSIZE 16384 5128eecc9f 2011-02-23 kinaba: # endif 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: #ifndef Z_PRINTF_BUFSIZE 5128eecc9f 2011-02-23 kinaba: # define Z_PRINTF_BUFSIZE 4096 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #define ALLOC(size) malloc(size) 5128eecc9f 2011-02-23 kinaba: #define TRYFREE(p) {if (p) free(p);} 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* gzip flag byte */ 5128eecc9f 2011-02-23 kinaba: #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ 5128eecc9f 2011-02-23 kinaba: #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ 5128eecc9f 2011-02-23 kinaba: #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 5128eecc9f 2011-02-23 kinaba: #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 5128eecc9f 2011-02-23 kinaba: #define COMMENT 0x10 /* bit 4 set: file comment present */ 5128eecc9f 2011-02-23 kinaba: #define RESERVED 0xE0 /* bits 5..7: reserved */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: typedef struct gz_stream { 5128eecc9f 2011-02-23 kinaba: z_stream stream; 5128eecc9f 2011-02-23 kinaba: int z_err; /* error code for last stream operation */ 5128eecc9f 2011-02-23 kinaba: int z_eof; /* set if end of input file */ 5128eecc9f 2011-02-23 kinaba: FILE *file; /* .gz file */ 5128eecc9f 2011-02-23 kinaba: Byte *inbuf; /* input buffer */ 5128eecc9f 2011-02-23 kinaba: Byte *outbuf; /* output buffer */ 5128eecc9f 2011-02-23 kinaba: uLong crc; /* crc32 of uncompressed data */ 5128eecc9f 2011-02-23 kinaba: char *msg; /* error message */ 5128eecc9f 2011-02-23 kinaba: char *path; /* path name for debugging only */ 5128eecc9f 2011-02-23 kinaba: int transparent; /* 1 if input file is not a .gz file */ 5128eecc9f 2011-02-23 kinaba: char mode; /* 'w' or 'r' */ 5128eecc9f 2011-02-23 kinaba: long startpos; /* start of compressed data in file (header skipped) */ 5128eecc9f 2011-02-23 kinaba: } gz_stream; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: local gzFile gz_open OF((const char *path, const char *mode, int fd)); 5128eecc9f 2011-02-23 kinaba: local int do_flush OF((gzFile file, int flush)); 5128eecc9f 2011-02-23 kinaba: local int get_byte OF((gz_stream *s)); 5128eecc9f 2011-02-23 kinaba: local void check_header OF((gz_stream *s)); 5128eecc9f 2011-02-23 kinaba: local int destroy OF((gz_stream *s)); 5128eecc9f 2011-02-23 kinaba: local void putLong OF((FILE *file, uLong x)); 5128eecc9f 2011-02-23 kinaba: local uLong getLong OF((gz_stream *s)); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Opens a gzip (.gz) file for reading or writing. The mode parameter 5128eecc9f 2011-02-23 kinaba: is as in fopen ("rb" or "wb"). The file is given either by file descriptor 5128eecc9f 2011-02-23 kinaba: or path name (if fd == -1). 5128eecc9f 2011-02-23 kinaba: gz_open return NULL if the file could not be opened or if there was 5128eecc9f 2011-02-23 kinaba: insufficient memory to allocate the (de)compression state; errno 5128eecc9f 2011-02-23 kinaba: can be checked to distinguish the two cases (if errno is zero, the 5128eecc9f 2011-02-23 kinaba: zlib error is Z_MEM_ERROR). 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: local gzFile gz_open (path, mode, fd) 5128eecc9f 2011-02-23 kinaba: const char *path; 5128eecc9f 2011-02-23 kinaba: const char *mode; 5128eecc9f 2011-02-23 kinaba: int fd; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: int err; 5128eecc9f 2011-02-23 kinaba: int level = Z_DEFAULT_COMPRESSION; /* compression level */ 5128eecc9f 2011-02-23 kinaba: int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ 5128eecc9f 2011-02-23 kinaba: char *p = (char*)mode; 5128eecc9f 2011-02-23 kinaba: gz_stream *s; 5128eecc9f 2011-02-23 kinaba: char fmode[80]; /* copy of mode, without the compression level */ 5128eecc9f 2011-02-23 kinaba: char *m = fmode; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (!path || !mode) return Z_NULL; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s = (gz_stream *)ALLOC(sizeof(gz_stream)); 5128eecc9f 2011-02-23 kinaba: if (!s) return Z_NULL; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->stream.zalloc = (alloc_func)0; 5128eecc9f 2011-02-23 kinaba: s->stream.zfree = (free_func)0; 5128eecc9f 2011-02-23 kinaba: s->stream.opaque = (voidpf)0; 5128eecc9f 2011-02-23 kinaba: s->stream.next_in = s->inbuf = Z_NULL; 5128eecc9f 2011-02-23 kinaba: s->stream.next_out = s->outbuf = Z_NULL; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in = s->stream.avail_out = 0; 5128eecc9f 2011-02-23 kinaba: s->file = NULL; 5128eecc9f 2011-02-23 kinaba: s->z_err = Z_OK; 5128eecc9f 2011-02-23 kinaba: s->z_eof = 0; 5128eecc9f 2011-02-23 kinaba: s->crc = crc32(0L, Z_NULL, 0); 5128eecc9f 2011-02-23 kinaba: s->msg = NULL; 5128eecc9f 2011-02-23 kinaba: s->transparent = 0; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->path = (char*)ALLOC(strlen(path)+1); 5128eecc9f 2011-02-23 kinaba: if (s->path == NULL) { 5128eecc9f 2011-02-23 kinaba: return destroy(s), (gzFile)Z_NULL; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: strcpy(s->path, path); /* do this early for debugging */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->mode = '\0'; 5128eecc9f 2011-02-23 kinaba: do { 5128eecc9f 2011-02-23 kinaba: if (*p == 'r') s->mode = 'r'; 5128eecc9f 2011-02-23 kinaba: if (*p == 'w' || *p == 'a') s->mode = 'w'; 5128eecc9f 2011-02-23 kinaba: if (*p >= '0' && *p <= '9') { 5128eecc9f 2011-02-23 kinaba: level = *p - '0'; 5128eecc9f 2011-02-23 kinaba: } else if (*p == 'f') { 5128eecc9f 2011-02-23 kinaba: strategy = Z_FILTERED; 5128eecc9f 2011-02-23 kinaba: } else if (*p == 'h') { 5128eecc9f 2011-02-23 kinaba: strategy = Z_HUFFMAN_ONLY; 5128eecc9f 2011-02-23 kinaba: } else { 5128eecc9f 2011-02-23 kinaba: *m++ = *p; /* copy the mode */ 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } while (*p++ && m != fmode + sizeof(fmode)); 5128eecc9f 2011-02-23 kinaba: if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->mode == 'w') { 5128eecc9f 2011-02-23 kinaba: #ifdef NO_DEFLATE 5128eecc9f 2011-02-23 kinaba: err = Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: #else 5128eecc9f 2011-02-23 kinaba: err = deflateInit2(&(s->stream), level, 5128eecc9f 2011-02-23 kinaba: Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); 5128eecc9f 2011-02-23 kinaba: /* windowBits is passed < 0 to suppress zlib header */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: if (err != Z_OK || s->outbuf == Z_NULL) { 5128eecc9f 2011-02-23 kinaba: return destroy(s), (gzFile)Z_NULL; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } else { 5128eecc9f 2011-02-23 kinaba: s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: err = inflateInit2(&(s->stream), -MAX_WBITS); 5128eecc9f 2011-02-23 kinaba: /* windowBits is passed < 0 to tell that there is no zlib header. 5128eecc9f 2011-02-23 kinaba: * Note that in this case inflate *requires* an extra "dummy" byte 5128eecc9f 2011-02-23 kinaba: * after the compressed stream in order to complete decompression and 5128eecc9f 2011-02-23 kinaba: * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are 5128eecc9f 2011-02-23 kinaba: * present after the compressed stream. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: if (err != Z_OK || s->inbuf == Z_NULL) { 5128eecc9f 2011-02-23 kinaba: return destroy(s), (gzFile)Z_NULL; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->stream.avail_out = Z_BUFSIZE; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: errno = 0; 5128eecc9f 2011-02-23 kinaba: s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->file == NULL) { 5128eecc9f 2011-02-23 kinaba: return destroy(s), (gzFile)Z_NULL; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if (s->mode == 'w') { 5128eecc9f 2011-02-23 kinaba: /* Write a very simple .gz header: 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], 5128eecc9f 2011-02-23 kinaba: Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); 5128eecc9f 2011-02-23 kinaba: s->startpos = 10L; 5128eecc9f 2011-02-23 kinaba: /* We use 10L instead of ftell(s->file) to because ftell causes an 5128eecc9f 2011-02-23 kinaba: * fflush on some systems. This version of the library doesn't use 5128eecc9f 2011-02-23 kinaba: * startpos anyway in write mode, so this initialization is not 5128eecc9f 2011-02-23 kinaba: * necessary. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: } else { 5128eecc9f 2011-02-23 kinaba: check_header(s); /* skip the .gz header */ 5128eecc9f 2011-02-23 kinaba: s->startpos = (ftell(s->file) - s->stream.avail_in); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return (gzFile)s; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Opens a gzip (.gz) file for reading or writing. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: gzFile ZEXPORT gzopen (path, mode) 5128eecc9f 2011-02-23 kinaba: const char *path; 5128eecc9f 2011-02-23 kinaba: const char *mode; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: return gz_open (path, mode, -1); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Associate a gzFile with the file descriptor fd. fd is not dup'ed here 5128eecc9f 2011-02-23 kinaba: to mimic the behavio(u)r of fdopen. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: gzFile ZEXPORT gzdopen (fd, mode) 5128eecc9f 2011-02-23 kinaba: int fd; 5128eecc9f 2011-02-23 kinaba: const char *mode; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: char name[20]; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (fd < 0) return (gzFile)Z_NULL; 5128eecc9f 2011-02-23 kinaba: sprintf(name, "<fd:%d>", fd); /* for debugging */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return gz_open (name, mode, fd); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: * Update the compression level and strategy 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzsetparams (file, level, strategy) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: int level; 5128eecc9f 2011-02-23 kinaba: int strategy; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: #ifndef KI_GZ_NO_COMPRESSION 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* Make room to allow flushing */ 5128eecc9f 2011-02-23 kinaba: if (s->stream.avail_out == 0) { 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->stream.next_out = s->outbuf; 5128eecc9f 2011-02-23 kinaba: if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { 5128eecc9f 2011-02-23 kinaba: s->z_err = Z_ERRNO; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->stream.avail_out = Z_BUFSIZE; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return deflateParams (&(s->stream), level, strategy); 5128eecc9f 2011-02-23 kinaba: #else 5128eecc9f 2011-02-23 kinaba: return Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: #endif /* KI_GZ_NO_COMPRESSION */ 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Read a byte from a gz_stream; update next_in and avail_in. Return EOF 5128eecc9f 2011-02-23 kinaba: for end of file. 5128eecc9f 2011-02-23 kinaba: IN assertion: the stream s has been sucessfully opened for reading. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: local int get_byte(s) 5128eecc9f 2011-02-23 kinaba: gz_stream *s; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if (s->z_eof) return EOF; 5128eecc9f 2011-02-23 kinaba: if (s->stream.avail_in == 0) { 5128eecc9f 2011-02-23 kinaba: errno = 0; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); 5128eecc9f 2011-02-23 kinaba: if (s->stream.avail_in == 0) { 5128eecc9f 2011-02-23 kinaba: s->z_eof = 1; 5128eecc9f 2011-02-23 kinaba: if (ferror(s->file)) s->z_err = Z_ERRNO; 5128eecc9f 2011-02-23 kinaba: return EOF; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->stream.next_in = s->inbuf; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in--; 5128eecc9f 2011-02-23 kinaba: return *(s->stream.next_in)++; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Check the gzip header of a gz_stream opened for reading. Set the stream 5128eecc9f 2011-02-23 kinaba: mode to transparent if the gzip magic header is not present; set s->err 5128eecc9f 2011-02-23 kinaba: to Z_DATA_ERROR if the magic header is present but the rest of the header 5128eecc9f 2011-02-23 kinaba: is incorrect. 5128eecc9f 2011-02-23 kinaba: IN assertion: the stream s has already been created sucessfully; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in is zero for the first time, but may be non-zero 5128eecc9f 2011-02-23 kinaba: for concatenated .gz files. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: local void check_header(s) 5128eecc9f 2011-02-23 kinaba: gz_stream *s; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: int method; /* method byte */ 5128eecc9f 2011-02-23 kinaba: int flags; /* flags byte */ 5128eecc9f 2011-02-23 kinaba: uInt len; 5128eecc9f 2011-02-23 kinaba: int c; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* Check the gzip magic header */ 5128eecc9f 2011-02-23 kinaba: for (len = 0; len < 2; len++) { 5128eecc9f 2011-02-23 kinaba: c = get_byte(s); 5128eecc9f 2011-02-23 kinaba: if (c != gz_magic[len]) { 5128eecc9f 2011-02-23 kinaba: if (len != 0) s->stream.avail_in++, s->stream.next_in--; 5128eecc9f 2011-02-23 kinaba: if (c != EOF) { 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in++, s->stream.next_in--; 5128eecc9f 2011-02-23 kinaba: s->transparent = 1; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; 5128eecc9f 2011-02-23 kinaba: return; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: method = get_byte(s); 5128eecc9f 2011-02-23 kinaba: flags = get_byte(s); 5128eecc9f 2011-02-23 kinaba: if (method != Z_DEFLATED || (flags & RESERVED) != 0) { 5128eecc9f 2011-02-23 kinaba: s->z_err = Z_DATA_ERROR; 5128eecc9f 2011-02-23 kinaba: return; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* Discard time, xflags and OS code: */ 5128eecc9f 2011-02-23 kinaba: for (len = 0; len < 6; len++) (void)get_byte(s); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ 5128eecc9f 2011-02-23 kinaba: len = (uInt)get_byte(s); 5128eecc9f 2011-02-23 kinaba: len += ((uInt)get_byte(s))<<8; 5128eecc9f 2011-02-23 kinaba: /* len is garbage if EOF but the loop below will quit anyway */ 5128eecc9f 2011-02-23 kinaba: while (len-- != 0 && get_byte(s) != EOF) ; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ 5128eecc9f 2011-02-23 kinaba: while ((c = get_byte(s)) != 0 && c != EOF) ; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ 5128eecc9f 2011-02-23 kinaba: while ((c = get_byte(s)) != 0 && c != EOF) ; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ 5128eecc9f 2011-02-23 kinaba: for (len = 0; len < 2; len++) (void)get_byte(s); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: * Cleanup then free the given gz_stream. Return a zlib error code. 5128eecc9f 2011-02-23 kinaba: Try freeing in the reverse order of allocations. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: local int destroy (s) 5128eecc9f 2011-02-23 kinaba: gz_stream *s; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: int err = Z_OK; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (!s) return Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: TRYFREE(s->msg); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->stream.state != NULL) { 5128eecc9f 2011-02-23 kinaba: if (s->mode == 'w') { 5128eecc9f 2011-02-23 kinaba: #ifdef NO_DEFLATE 5128eecc9f 2011-02-23 kinaba: err = Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: #else 5128eecc9f 2011-02-23 kinaba: err = deflateEnd(&(s->stream)); 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: } else if (s->mode == 'r') { 5128eecc9f 2011-02-23 kinaba: err = inflateEnd(&(s->stream)); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if (s->file != NULL && fclose(s->file)) { 5128eecc9f 2011-02-23 kinaba: #ifdef ESPIPE 5128eecc9f 2011-02-23 kinaba: if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: err = Z_ERRNO; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if (s->z_err < 0) err = s->z_err; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: TRYFREE(s->inbuf); 5128eecc9f 2011-02-23 kinaba: TRYFREE(s->outbuf); 5128eecc9f 2011-02-23 kinaba: TRYFREE(s->path); 5128eecc9f 2011-02-23 kinaba: TRYFREE(s); 5128eecc9f 2011-02-23 kinaba: return err; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Reads the given number of uncompressed bytes from the compressed file. 5128eecc9f 2011-02-23 kinaba: gzread returns the number of bytes actually read (0 for end of file). 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzread (file, buf, len) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: voidp buf; 5128eecc9f 2011-02-23 kinaba: unsigned len; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: Bytef *start = (Bytef*)buf; /* starting point for crc computation */ 5128eecc9f 2011-02-23 kinaba: Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; 5128eecc9f 2011-02-23 kinaba: if (s->z_err == Z_STREAM_END) return 0; /* EOF */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: next_out = (Byte*)buf; 5128eecc9f 2011-02-23 kinaba: s->stream.next_out = (Bytef*)buf; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_out = len; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: while (s->stream.avail_out != 0) { 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->transparent) { 5128eecc9f 2011-02-23 kinaba: /* Copy first the lookahead bytes: */ 5128eecc9f 2011-02-23 kinaba: uInt n = s->stream.avail_in; 5128eecc9f 2011-02-23 kinaba: if (n > s->stream.avail_out) n = s->stream.avail_out; 5128eecc9f 2011-02-23 kinaba: if (n > 0) { 5128eecc9f 2011-02-23 kinaba: zmemcpy(s->stream.next_out, s->stream.next_in, n); 5128eecc9f 2011-02-23 kinaba: next_out += n; 5128eecc9f 2011-02-23 kinaba: s->stream.next_out = next_out; 5128eecc9f 2011-02-23 kinaba: s->stream.next_in += n; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_out -= n; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in -= n; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if (s->stream.avail_out > 0) { 5128eecc9f 2011-02-23 kinaba: s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, 5128eecc9f 2011-02-23 kinaba: s->file); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: len -= s->stream.avail_out; 5128eecc9f 2011-02-23 kinaba: s->stream.total_in += (uLong)len; 5128eecc9f 2011-02-23 kinaba: s->stream.total_out += (uLong)len; 5128eecc9f 2011-02-23 kinaba: if (len == 0) s->z_eof = 1; 5128eecc9f 2011-02-23 kinaba: return (int)len; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if (s->stream.avail_in == 0 && !s->z_eof) { 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: errno = 0; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); 5128eecc9f 2011-02-23 kinaba: if (s->stream.avail_in == 0) { 5128eecc9f 2011-02-23 kinaba: s->z_eof = 1; 5128eecc9f 2011-02-23 kinaba: if (ferror(s->file)) { 5128eecc9f 2011-02-23 kinaba: s->z_err = Z_ERRNO; 5128eecc9f 2011-02-23 kinaba: break; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->stream.next_in = s->inbuf; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->z_err = inflate(&(s->stream), Z_NO_FLUSH); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->z_err == Z_STREAM_END) { 5128eecc9f 2011-02-23 kinaba: /* Check CRC and original size */ 5128eecc9f 2011-02-23 kinaba: s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); 5128eecc9f 2011-02-23 kinaba: start = s->stream.next_out; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (getLong(s) != s->crc) { 5128eecc9f 2011-02-23 kinaba: s->z_err = Z_DATA_ERROR; 5128eecc9f 2011-02-23 kinaba: } else { 5128eecc9f 2011-02-23 kinaba: (void)getLong(s); 5128eecc9f 2011-02-23 kinaba: /* The uncompressed length returned by above getlong() may 5128eecc9f 2011-02-23 kinaba: * be different from s->stream.total_out) in case of 5128eecc9f 2011-02-23 kinaba: * concatenated .gz files. Check for such files: 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: check_header(s); 5128eecc9f 2011-02-23 kinaba: if (s->z_err == Z_OK) { 5128eecc9f 2011-02-23 kinaba: uLong total_in = s->stream.total_in; 5128eecc9f 2011-02-23 kinaba: uLong total_out = s->stream.total_out; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: inflateReset(&(s->stream)); 5128eecc9f 2011-02-23 kinaba: s->stream.total_in = total_in; 5128eecc9f 2011-02-23 kinaba: s->stream.total_out = total_out; 5128eecc9f 2011-02-23 kinaba: s->crc = crc32(0L, Z_NULL, 0); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if (s->z_err != Z_OK || s->z_eof) break; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return (int)(len - s->stream.avail_out); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Reads one byte from the compressed file. gzgetc returns this byte 5128eecc9f 2011-02-23 kinaba: or -1 in case of end of file or error. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzgetc(file) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: unsigned char c; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return gzread(file, &c, 1) == 1 ? c : -1; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Reads bytes from the compressed file until len-1 characters are 5128eecc9f 2011-02-23 kinaba: read, or a newline character is read and transferred to buf, or an 5128eecc9f 2011-02-23 kinaba: end-of-file condition is encountered. The string is then terminated 5128eecc9f 2011-02-23 kinaba: with a null character. 5128eecc9f 2011-02-23 kinaba: gzgets returns buf, or Z_NULL in case of error. 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: The current implementation is not optimized at all. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: char * ZEXPORT gzgets(file, buf, len) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: char *buf; 5128eecc9f 2011-02-23 kinaba: int len; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: char *b = buf; 5128eecc9f 2011-02-23 kinaba: if (buf == Z_NULL || len <= 0) return Z_NULL; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; 5128eecc9f 2011-02-23 kinaba: *buf = '\0'; 5128eecc9f 2011-02-23 kinaba: return b == buf && len > 0 ? Z_NULL : b; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifndef NO_DEFLATE 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Writes the given number of uncompressed bytes into the compressed file. 5128eecc9f 2011-02-23 kinaba: gzwrite returns the number of bytes actually written (0 in case of error). 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzwrite (file, buf, len) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: const voidp buf; 5128eecc9f 2011-02-23 kinaba: unsigned len; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->stream.next_in = (Bytef*)buf; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in = len; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: while (s->stream.avail_in != 0) { 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->stream.avail_out == 0) { 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->stream.next_out = s->outbuf; 5128eecc9f 2011-02-23 kinaba: if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { 5128eecc9f 2011-02-23 kinaba: s->z_err = Z_ERRNO; 5128eecc9f 2011-02-23 kinaba: break; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->stream.avail_out = Z_BUFSIZE; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->z_err = deflate(&(s->stream), Z_NO_FLUSH); 5128eecc9f 2011-02-23 kinaba: if (s->z_err != Z_OK) break; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->crc = crc32(s->crc, (const Bytef *)buf, len); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return (int)(len - s->stream.avail_in); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Converts, formats, and writes the args to the compressed file under 5128eecc9f 2011-02-23 kinaba: control of the format string, as in fprintf. gzprintf returns the number of 5128eecc9f 2011-02-23 kinaba: uncompressed bytes actually written (0 in case of error). 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: #ifdef STDC 5128eecc9f 2011-02-23 kinaba: #include <stdarg.h> 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: char buf[Z_PRINTF_BUFSIZE]; 5128eecc9f 2011-02-23 kinaba: va_list va; 5128eecc9f 2011-02-23 kinaba: int len; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: va_start(va, format); 5128eecc9f 2011-02-23 kinaba: #ifdef HAS_vsnprintf 5128eecc9f 2011-02-23 kinaba: (void)vsnprintf(buf, sizeof(buf), format, va); 5128eecc9f 2011-02-23 kinaba: #else 5128eecc9f 2011-02-23 kinaba: (void)vsprintf(buf, format, va); 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: va_end(va); 5128eecc9f 2011-02-23 kinaba: len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ 5128eecc9f 2011-02-23 kinaba: if (len <= 0) return 0; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return gzwrite(file, buf, (unsigned)len); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: #else /* not ANSI C */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 5128eecc9f 2011-02-23 kinaba: a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: const char *format; 5128eecc9f 2011-02-23 kinaba: int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 5128eecc9f 2011-02-23 kinaba: a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: char buf[Z_PRINTF_BUFSIZE]; 5128eecc9f 2011-02-23 kinaba: int len; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #ifdef HAS_snprintf 5128eecc9f 2011-02-23 kinaba: snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, 5128eecc9f 2011-02-23 kinaba: a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 5128eecc9f 2011-02-23 kinaba: #else 5128eecc9f 2011-02-23 kinaba: sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, 5128eecc9f 2011-02-23 kinaba: a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ 5128eecc9f 2011-02-23 kinaba: if (len <= 0) return 0; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return gzwrite(file, buf, len); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Writes c, converted to an unsigned char, into the compressed file. 5128eecc9f 2011-02-23 kinaba: gzputc returns the value that was written, or -1 in case of error. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzputc(file, c) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: int c; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: unsigned char cc = (unsigned char) c; /* required for big endian systems */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Writes the given null-terminated string to the compressed file, excluding 5128eecc9f 2011-02-23 kinaba: the terminating null character. 5128eecc9f 2011-02-23 kinaba: gzputs returns the number of characters written, or -1 in case of error. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzputs(file, s) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: const char *s; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: return gzwrite(file, (char*)s, (unsigned)strlen(s)); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Flushes all pending output into the compressed file. The parameter 5128eecc9f 2011-02-23 kinaba: flush is as in the deflate() function. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: local int do_flush (file, flush) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: int flush; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: uInt len; 5128eecc9f 2011-02-23 kinaba: int done = 0; 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in = 0; /* should be zero already anyway */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: for (;;) { 5128eecc9f 2011-02-23 kinaba: len = Z_BUFSIZE - s->stream.avail_out; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (len != 0) { 5128eecc9f 2011-02-23 kinaba: if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { 5128eecc9f 2011-02-23 kinaba: s->z_err = Z_ERRNO; 5128eecc9f 2011-02-23 kinaba: return Z_ERRNO; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: s->stream.next_out = s->outbuf; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_out = Z_BUFSIZE; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if (done) break; 5128eecc9f 2011-02-23 kinaba: s->z_err = deflate(&(s->stream), flush); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* Ignore the second of two consecutive flushes: */ 5128eecc9f 2011-02-23 kinaba: if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* deflate has finished flushing only when it hasn't used up 5128eecc9f 2011-02-23 kinaba: * all the available space in the output buffer: 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzflush (file, flush) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: int flush; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: int err = do_flush (file, flush); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (err) return err; 5128eecc9f 2011-02-23 kinaba: fflush(s->file); 5128eecc9f 2011-02-23 kinaba: return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: #endif /* NO_DEFLATE */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Sets the starting position for the next gzread or gzwrite on the given 5128eecc9f 2011-02-23 kinaba: compressed file. The offset represents a number of bytes in the 5128eecc9f 2011-02-23 kinaba: gzseek returns the resulting offset location as measured in bytes from 5128eecc9f 2011-02-23 kinaba: the beginning of the uncompressed stream, or -1 in case of error. 5128eecc9f 2011-02-23 kinaba: SEEK_END is not implemented, returns error. 5128eecc9f 2011-02-23 kinaba: In this version of the library, gzseek can be extremely slow. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: z_off_t ZEXPORT gzseek (file, offset, whence) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: z_off_t offset; 5128eecc9f 2011-02-23 kinaba: int whence; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s == NULL || whence == SEEK_END || 5128eecc9f 2011-02-23 kinaba: s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { 5128eecc9f 2011-02-23 kinaba: return -1L; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->mode == 'w') { 5128eecc9f 2011-02-23 kinaba: #ifdef NO_DEFLATE 5128eecc9f 2011-02-23 kinaba: return -1L; 5128eecc9f 2011-02-23 kinaba: #else 5128eecc9f 2011-02-23 kinaba: if (whence == SEEK_SET) { 5128eecc9f 2011-02-23 kinaba: offset -= s->stream.total_in; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if (offset < 0) return -1L; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* At this point, offset is the number of zero bytes to write. */ 5128eecc9f 2011-02-23 kinaba: if (s->inbuf == Z_NULL) { 5128eecc9f 2011-02-23 kinaba: s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ 5128eecc9f 2011-02-23 kinaba: zmemzero(s->inbuf, Z_BUFSIZE); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: while (offset > 0) { 5128eecc9f 2011-02-23 kinaba: uInt size = Z_BUFSIZE; 5128eecc9f 2011-02-23 kinaba: if (offset < Z_BUFSIZE) size = (uInt)offset; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: size = gzwrite(file, s->inbuf, size); 5128eecc9f 2011-02-23 kinaba: if (size == 0) return -1L; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: offset -= size; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return (z_off_t)s->stream.total_in; 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: /* Rest of function is for reading only */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* compute absolute position */ 5128eecc9f 2011-02-23 kinaba: if (whence == SEEK_CUR) { 5128eecc9f 2011-02-23 kinaba: offset += s->stream.total_out; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: if (offset < 0) return -1L; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->transparent) { 5128eecc9f 2011-02-23 kinaba: /* map to fseek */ 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in = 0; 5128eecc9f 2011-02-23 kinaba: s->stream.next_in = s->inbuf; 5128eecc9f 2011-02-23 kinaba: if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->stream.total_in = s->stream.total_out = (uLong)offset; 5128eecc9f 2011-02-23 kinaba: return offset; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* For a negative seek, rewind and use positive seek */ 5128eecc9f 2011-02-23 kinaba: if ((uLong)offset >= s->stream.total_out) { 5128eecc9f 2011-02-23 kinaba: offset -= s->stream.total_out; 5128eecc9f 2011-02-23 kinaba: } else if (gzrewind(file) < 0) { 5128eecc9f 2011-02-23 kinaba: return -1L; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: /* offset is now the number of bytes to skip. */ 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (offset != 0 && s->outbuf == Z_NULL) { 5128eecc9f 2011-02-23 kinaba: s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: while (offset > 0) { 5128eecc9f 2011-02-23 kinaba: int size = Z_BUFSIZE; 5128eecc9f 2011-02-23 kinaba: if (offset < Z_BUFSIZE) size = (int)offset; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: size = gzread(file, s->outbuf, (uInt)size); 5128eecc9f 2011-02-23 kinaba: if (size <= 0) return -1L; 5128eecc9f 2011-02-23 kinaba: offset -= size; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return (z_off_t)s->stream.total_out; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Rewinds input file. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzrewind (file) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s == NULL || s->mode != 'r') return -1; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: s->z_err = Z_OK; 5128eecc9f 2011-02-23 kinaba: s->z_eof = 0; 5128eecc9f 2011-02-23 kinaba: s->stream.avail_in = 0; 5128eecc9f 2011-02-23 kinaba: s->stream.next_in = s->inbuf; 5128eecc9f 2011-02-23 kinaba: s->crc = crc32(0L, Z_NULL, 0); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->startpos == 0) { /* not a compressed file */ 5128eecc9f 2011-02-23 kinaba: rewind(s->file); 5128eecc9f 2011-02-23 kinaba: return 0; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: (void) inflateReset(&s->stream); 5128eecc9f 2011-02-23 kinaba: return fseek(s->file, s->startpos, SEEK_SET); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Returns the starting position for the next gzread or gzwrite on the 5128eecc9f 2011-02-23 kinaba: given compressed file. This position represents a number of bytes in the 5128eecc9f 2011-02-23 kinaba: uncompressed data stream. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: z_off_t ZEXPORT gztell (file) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: return gzseek(file, 0L, SEEK_CUR); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Returns 1 when EOF has previously been detected reading the given 5128eecc9f 2011-02-23 kinaba: input stream, otherwise zero. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzeof (file) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return (s == NULL || s->mode != 'r') ? 0 : s->z_eof; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Outputs a long in LSB order to the given file 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: local void putLong (file, x) 5128eecc9f 2011-02-23 kinaba: FILE *file; 5128eecc9f 2011-02-23 kinaba: uLong x; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: int n; 5128eecc9f 2011-02-23 kinaba: for (n = 0; n < 4; n++) { 5128eecc9f 2011-02-23 kinaba: fputc((int)(x & 0xff), file); 5128eecc9f 2011-02-23 kinaba: x >>= 8; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Reads a long in LSB order from the given gz_stream. Sets z_err in case 5128eecc9f 2011-02-23 kinaba: of error. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: local uLong getLong (s) 5128eecc9f 2011-02-23 kinaba: gz_stream *s; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: uLong x = (uLong)get_byte(s); 5128eecc9f 2011-02-23 kinaba: int c; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: x += ((uLong)get_byte(s))<<8; 5128eecc9f 2011-02-23 kinaba: x += ((uLong)get_byte(s))<<16; 5128eecc9f 2011-02-23 kinaba: c = get_byte(s); 5128eecc9f 2011-02-23 kinaba: if (c == EOF) s->z_err = Z_DATA_ERROR; 5128eecc9f 2011-02-23 kinaba: x += ((uLong)c)<<24; 5128eecc9f 2011-02-23 kinaba: return x; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Flushes all pending output if necessary, closes the compressed file 5128eecc9f 2011-02-23 kinaba: and deallocates all the (de)compression state. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: int ZEXPORT gzclose (file) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s == NULL) return Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s->mode == 'w') { 5128eecc9f 2011-02-23 kinaba: #ifdef NO_DEFLATE 5128eecc9f 2011-02-23 kinaba: return Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: #else 5128eecc9f 2011-02-23 kinaba: err = do_flush (file, Z_FINISH); 5128eecc9f 2011-02-23 kinaba: if (err != Z_OK) return destroy((gz_stream*)file); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: putLong (s->file, s->crc); 5128eecc9f 2011-02-23 kinaba: putLong (s->file, s->stream.total_in); 5128eecc9f 2011-02-23 kinaba: #endif 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return destroy((gz_stream*)file); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: /* =========================================================================== 5128eecc9f 2011-02-23 kinaba: Returns the error message for the last error which occured on the 5128eecc9f 2011-02-23 kinaba: given compressed file. errnum is set to zlib error number. If an 5128eecc9f 2011-02-23 kinaba: error occured in the file system and not in the compression library, 5128eecc9f 2011-02-23 kinaba: errnum is set to Z_ERRNO and the application may consult errno 5128eecc9f 2011-02-23 kinaba: to get the exact error code. 5128eecc9f 2011-02-23 kinaba: */ 5128eecc9f 2011-02-23 kinaba: const char* ZEXPORT gzerror (file, errnum) 5128eecc9f 2011-02-23 kinaba: gzFile file; 5128eecc9f 2011-02-23 kinaba: int *errnum; 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: char *m; 5128eecc9f 2011-02-23 kinaba: gz_stream *s = (gz_stream*)file; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (s == NULL) { 5128eecc9f 2011-02-23 kinaba: *errnum = Z_STREAM_ERROR; 5128eecc9f 2011-02-23 kinaba: return (const char*)ERR_MSG(Z_STREAM_ERROR); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: *errnum = s->z_err; 5128eecc9f 2011-02-23 kinaba: if (*errnum == Z_OK) return (const char*)""; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: TRYFREE(s->msg); 5128eecc9f 2011-02-23 kinaba: s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); 5128eecc9f 2011-02-23 kinaba: strcpy(s->msg, s->path); 5128eecc9f 2011-02-23 kinaba: strcat(s->msg, ": "); 5128eecc9f 2011-02-23 kinaba: strcat(s->msg, m); 5128eecc9f 2011-02-23 kinaba: return (const char*)s->msg; 5128eecc9f 2011-02-23 kinaba: }