s->startpos = (ftell(s->file) - s->stream.avail_in);
local gzFile gz_open (path, mode, fd)    const char *path;    const char *mode;    int  fd;{    int err;    int level = Z_DEFAULT_COMPRESSION; /* compression level */    int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */    char *p = (char*)mode;    gz_stream *s;    char fmode[80]; /* copy of mode, without the compression level */    char *m = fmode;    if (!path || !mode) return Z_NULL;    s = (gz_stream *)ALLOC(sizeof(gz_stream));    if (!s) return Z_NULL;    s->stream.zalloc = (alloc_func)0;    s->stream.zfree = (free_func)0;    s->stream.opaque = (voidpf)0;    s->stream.next_in = s->inbuf = Z_NULL;    s->stream.next_out = s->outbuf = Z_NULL;    s->stream.avail_in = s->stream.avail_out = 0;    s->file = NULL;    s->z_err = Z_OK;    s->z_eof = 0;    s->crc = crc32(0L, Z_NULL, 0);    s->msg = NULL;    s->transparent = 0;    s->path = (char*)ALLOC(strlen(path)+1);    if (s->path == NULL) {        return destroy(s), (gzFile)Z_NULL;    }    strcpy(s->path, path); /* do this early for debugging */    s->mode = '\0';    do {        if (*p == 'r') s->mode = 'r';        if (*p == 'w' || *p == 'a') s->mode = 'w';        if (*p >= '0' && *p <= '9') {	    level = *p - '0';	} else if (*p == 'f') {	  strategy = Z_FILTERED;	} else if (*p == 'h') {	  strategy = Z_HUFFMAN_ONLY;	} else {	    *m++ = *p; /* copy the mode */	}    } while (*p++ && m != fmode + sizeof(fmode));    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;        if (s->mode == 'w') {#ifdef NO_DEFLATE        err = Z_STREAM_ERROR;#else        err = deflateInit2(&(s->stream), level,                           Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);        /* windowBits is passed < 0 to suppress zlib header */        s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);#endif        if (err != Z_OK || s->outbuf == Z_NULL) {            return destroy(s), (gzFile)Z_NULL;        }    } else {        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.         */        if (err != Z_OK || s->inbuf == Z_NULL) {            return destroy(s), (gzFile)Z_NULL;        }    }    s->stream.avail_out = Z_BUFSIZE;    errno = 0;    s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);    if (s->file == NULL) {        return destroy(s), (gzFile)Z_NULL;    }    if (s->mode == 'w') {        /* Write a very simple .gz header:         */        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],             Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);	s->startpos = 10L;	/* We use 10L instead of ftell(s->file) to because ftell causes an         * fflush on some systems. This version of the library doesn't use         * startpos anyway in write mode, so this initialization is not         * necessary.         */    } else {	check_header(s); /* skip the .gz header */	s->startpos = (ftell(s->file) - s->stream.avail_in);    }        return (gzFile)s;}