199767f8919635c4928607450d9e0abb932109ceToomas Soome/* gzlib.c -- zlib functions common to reading and writing gzip files
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler
199767f8919635c4928607450d9e0abb932109ceToomas Soome * For conditions of distribution and use, see copyright notice in zlib.h
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* $FreeBSD$ */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "gzguts.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "zutil.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if defined(_WIN32) && !defined(__BORLANDC__)
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define LSEEK _lseeki64
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define LSEEK lseek64
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define LSEEK lseek
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Local functions */
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal void gz_reset OF((gz_statep));
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal gzFile gz_open OF((const void *, int, const char *));
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if defined UNDER_CE
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Map the Windows error number in ERROR to a locale-dependent error message
199767f8919635c4928607450d9e0abb932109ceToomas Soome string and return a pointer to it. Typically, the values for ERROR come
199767f8919635c4928607450d9e0abb932109ceToomas Soome from GetLastError.
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome The string pointed to shall not be modified by the application, but may be
199767f8919635c4928607450d9e0abb932109ceToomas Soome overwritten by a subsequent call to gz_strwinerror
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome The gz_strwinerror function does not change the current setting of
199767f8919635c4928607450d9e0abb932109ceToomas Soome GetLastError. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomechar ZLIB_INTERNAL *gz_strwinerror (error)
199767f8919635c4928607450d9e0abb932109ceToomas Soome DWORD error;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome static char buf[1024];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome wchar_t *msgbuf;
199767f8919635c4928607450d9e0abb932109ceToomas Soome DWORD lasterr = GetLastError();
199767f8919635c4928607450d9e0abb932109ceToomas Soome DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
199767f8919635c4928607450d9e0abb932109ceToomas Soome | FORMAT_MESSAGE_ALLOCATE_BUFFER,
199767f8919635c4928607450d9e0abb932109ceToomas Soome NULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome error,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0, /* Default language */
199767f8919635c4928607450d9e0abb932109ceToomas Soome (LPVOID)&msgbuf,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0,
199767f8919635c4928607450d9e0abb932109ceToomas Soome NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (chars != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* If there is an \r\n appended, zap it. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (chars >= 2
199767f8919635c4928607450d9e0abb932109ceToomas Soome && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
199767f8919635c4928607450d9e0abb932109ceToomas Soome chars -= 2;
199767f8919635c4928607450d9e0abb932109ceToomas Soome msgbuf[chars] = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (chars > sizeof (buf) - 1) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome chars = sizeof (buf) - 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome msgbuf[chars] = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome wcstombs(buf, msgbuf, chars + 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome LocalFree(msgbuf);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome sprintf(buf, "unknown win32 error (%ld)", error);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome SetLastError(lasterr);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return buf;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif /* UNDER_CE */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Reset gzip file state */
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal void gz_reset(state)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.have = 0; /* no output data available */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode == GZ_READ) { /* for reading ... */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->eof = 0; /* not at end of file */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->past = 0; /* have not read past end yet */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->how = LOOK; /* look for gzip header */
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0; /* no seek request pending */
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_OK, NULL); /* clear error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos = 0; /* no uncompressed data yet */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->strm.avail_in = 0; /* no input data yet */
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Open a gzip file either by name or file descriptor. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomelocal gzFile gz_open(path, fd, mode)
199767f8919635c4928607450d9e0abb932109ceToomas Soome const void *path;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int fd;
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *mode;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome size_t len;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int oflag;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef O_CLOEXEC
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cloexec = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef O_EXCL
199767f8919635c4928607450d9e0abb932109ceToomas Soome int exclusive = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check input */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (path == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* allocate gzFile structure to return */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)malloc(sizeof(gz_state));
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->size = 0; /* no buffers allocated yet */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->want = GZBUFSIZE; /* requested buffer size */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->msg = NULL; /* no error message yet */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* interpret mode */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->mode = GZ_NONE;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->level = Z_DEFAULT_COMPRESSION;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->strategy = Z_DEFAULT_STRATEGY;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->direct = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (*mode) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*mode >= '0' && *mode <= '9')
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->level = *mode - '0';
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome switch (*mode) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'r':
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->mode = GZ_READ;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifndef NO_GZCOMPRESS
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'w':
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->mode = GZ_WRITE;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'a':
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->mode = GZ_APPEND;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome case '+': /* can't read and write at the same time */
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'b': /* ignore -- will request binary anyway */
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef O_CLOEXEC
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'e':
199767f8919635c4928607450d9e0abb932109ceToomas Soome cloexec = 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef O_EXCL
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'x':
199767f8919635c4928607450d9e0abb932109ceToomas Soome exclusive = 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'f':
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->strategy = Z_FILTERED;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'h':
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->strategy = Z_HUFFMAN_ONLY;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'R':
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->strategy = Z_RLE;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'F':
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->strategy = Z_FIXED;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome case 'T':
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->direct = 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome default: /* could consider as an error, but just ignore */
199767f8919635c4928607450d9e0abb932109ceToomas Soome ;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome mode++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* must provide an "r", "w", or "a" */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode == GZ_NONE) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* can't force transparent read */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode == GZ_READ) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->direct) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->direct = 1; /* for empty file */
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* save the path name for error messages */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef _WIN32
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (fd == -2) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = wcstombs(NULL, path, 0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (len == (size_t)-1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = strlen((const char *)path);
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->path = (char *)malloc(len + 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->path == NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef _WIN32
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (fd == -2)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (len)
199767f8919635c4928607450d9e0abb932109ceToomas Soome wcstombs(state->path, path, len + 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome *(state->path) = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
199767f8919635c4928607450d9e0abb932109ceToomas Soome snprintf(state->path, len + 1, "%s", (const char *)path);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome strcpy(state->path, path);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* compute the flags for open() */
199767f8919635c4928607450d9e0abb932109ceToomas Soome oflag =
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef O_LARGEFILE
199767f8919635c4928607450d9e0abb932109ceToomas Soome O_LARGEFILE |
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef O_BINARY
199767f8919635c4928607450d9e0abb932109ceToomas Soome O_BINARY |
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef O_CLOEXEC
199767f8919635c4928607450d9e0abb932109ceToomas Soome (cloexec ? O_CLOEXEC : 0) |
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome (state->mode == GZ_READ ?
199767f8919635c4928607450d9e0abb932109ceToomas Soome O_RDONLY :
199767f8919635c4928607450d9e0abb932109ceToomas Soome (O_WRONLY | O_CREAT |
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef O_EXCL
199767f8919635c4928607450d9e0abb932109ceToomas Soome (exclusive ? O_EXCL : 0) |
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome (state->mode == GZ_WRITE ?
199767f8919635c4928607450d9e0abb932109ceToomas Soome O_TRUNC :
199767f8919635c4928607450d9e0abb932109ceToomas Soome O_APPEND)));
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* open the file with the appropriate flags (or just use fd) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->fd = fd > -1 ? fd : (
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef _WIN32
199767f8919635c4928607450d9e0abb932109ceToomas Soome fd == -2 ? _wopen(path, oflag, 0666) :
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome open((const char *)path, oflag, 0666));
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->fd == -1) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state->path);
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode == GZ_APPEND)
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->mode = GZ_WRITE; /* simplify later checks */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* save the current position for rewinding (only if reading) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode == GZ_READ) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->start = LSEEK(state->fd, 0, SEEK_CUR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->start == -1) state->start = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* initialize stream */
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_reset(state);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* return stream */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (gzFile)state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas SoomegzFile ZEXPORT gzopen(path, mode)
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *path;
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *mode;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome return gz_open(path, -1, mode);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas SoomegzFile ZEXPORT gzopen64(path, mode)
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *path;
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *mode;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome return gz_open(path, -1, mode);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas SoomegzFile ZEXPORT gzdopen(fd, mode)
199767f8919635c4928607450d9e0abb932109ceToomas Soome int fd;
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *mode;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *path; /* identifier for error messages */
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile gz;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
199767f8919635c4928607450d9e0abb932109ceToomas Soome snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome sprintf(path, "<fd:%d>", fd); /* for debugging */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz = gz_open(path, fd, mode);
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(path);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return gz;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef _WIN32
199767f8919635c4928607450d9e0abb932109ceToomas SoomegzFile ZEXPORT gzopen_w(path, mode)
199767f8919635c4928607450d9e0abb932109ceToomas Soome const wchar_t *path;
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *mode;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome return gz_open(path, -2, mode);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORT gzbuffer(file, size)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned size;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure and check integrity */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_READ && state->mode != GZ_WRITE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* make sure we haven't already allocated memory */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->size != 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check and set requested size */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (size < 2)
199767f8919635c4928607450d9e0abb932109ceToomas Soome size = 2; /* need two bytes to check magic header */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->want = size;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORT gzrewind(file)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that we're reading and that there's no error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_READ ||
199767f8919635c4928607450d9e0abb932109ceToomas Soome (state->err != Z_OK && state->err != Z_BUF_ERROR))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* back up and start over */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_reset(state);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomez_off64_t ZEXPORT gzseek64(file, offset, whence)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_off64_t offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int whence;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned n;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_off64_t ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure and check integrity */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_READ && state->mode != GZ_WRITE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check that there's no error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->err != Z_OK && state->err != Z_BUF_ERROR)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* can only seek from start or relative to current position */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (whence != SEEK_SET && whence != SEEK_CUR)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* normalize offset to a SEEK_CUR specification */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (whence == SEEK_SET)
199767f8919635c4928607450d9e0abb932109ceToomas Soome offset -= state->x.pos;
199767f8919635c4928607450d9e0abb932109ceToomas Soome else if (state->seek)
199767f8919635c4928607450d9e0abb932109ceToomas Soome offset += state->skip;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* if within raw area while reading, just go there */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode == GZ_READ && state->how == COPY &&
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos + offset >= 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (ret == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.have = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->eof = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->past = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_OK, NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->strm.avail_in = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos += offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return state->x.pos;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* calculate skip amount, rewinding if needed for back seek when reading */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (offset < 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_READ) /* writing -- can't go backwards */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome offset += state->x.pos;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (offset < 0) /* before start of file! */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (gzrewind(file) == -1) /* rewind, then skip to offset */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* if reading, skip what's in output buffer (one less gzgetc() check) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode == GZ_READ) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
199767f8919635c4928607450d9e0abb932109ceToomas Soome (unsigned)offset : state->x.have;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.have -= n;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.next += n;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.pos += n;
199767f8919635c4928607450d9e0abb932109ceToomas Soome offset -= n;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* request skip (if not zero) */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (offset) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->seek = 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->skip = offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome return state->x.pos + offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomez_off_t ZEXPORT gzseek(file, offset, whence)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_off_t offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int whence;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_off64_t ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = gzseek64(file, (z_off64_t)offset, whence);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return ret == (z_off_t)ret ? (z_off_t)ret : -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomez_off64_t ZEXPORT gztell64(file)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure and check integrity */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_READ && state->mode != GZ_WRITE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* return position */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return state->x.pos + (state->seek ? state->skip : 0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomez_off_t ZEXPORT gztell(file)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_off64_t ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = gztell64(file);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return ret == (z_off_t)ret ? (z_off_t)ret : -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomez_off64_t ZEXPORT gzoffset64(file)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_off64_t offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure and check integrity */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_READ && state->mode != GZ_WRITE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* compute and return effective offset in file */
199767f8919635c4928607450d9e0abb932109ceToomas Soome offset = LSEEK(state->fd, 0, SEEK_CUR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (offset == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode == GZ_READ) /* reading */
199767f8919635c4928607450d9e0abb932109ceToomas Soome offset -= state->strm.avail_in; /* don't count buffered input */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return offset;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomez_off_t ZEXPORT gzoffset(file)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome z_off64_t ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = gzoffset64(file);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return ret == (z_off_t)ret ? (z_off_t)ret : -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint ZEXPORT gzeof(file)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure and check integrity */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_READ && state->mode != GZ_WRITE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* return end-of-file state */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return state->mode == GZ_READ ? state->past : 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeconst char * ZEXPORT gzerror(file, errnum)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int *errnum;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure and check integrity */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_READ && state->mode != GZ_WRITE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* return error information */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (errnum != NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome *errnum = state->err;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return state->err == Z_MEM_ERROR ? "out of memory" :
199767f8919635c4928607450d9e0abb932109ceToomas Soome (state->msg == NULL ? "" : state->msg);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* -- see zlib.h -- */
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid ZEXPORT gzclearerr(file)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gzFile file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* get internal structure and check integrity */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (file == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state = (gz_statep)file;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode != GZ_READ && state->mode != GZ_WRITE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* clear error and end-of-file */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->mode == GZ_READ) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->eof = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->past = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_error(state, Z_OK, NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Create an error message in allocated memory and set state->err and
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->msg accordingly. Free any previous error message already there. Do
199767f8919635c4928607450d9e0abb932109ceToomas Soome not try to free or allocate space if the error is Z_MEM_ERROR (out of
199767f8919635c4928607450d9e0abb932109ceToomas Soome memory). Simply save the error message as a static string. If there is an
199767f8919635c4928607450d9e0abb932109ceToomas Soome allocation failure constructing the error message, then convert the error to
199767f8919635c4928607450d9e0abb932109ceToomas Soome out of memory. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid ZLIB_INTERNAL gz_error(state, err, msg)
199767f8919635c4928607450d9e0abb932109ceToomas Soome gz_statep state;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int err;
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *msg;
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* free previously allocated message and clear */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->msg != NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (state->err != Z_MEM_ERROR)
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(state->msg);
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->msg = NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (err != Z_OK && err != Z_BUF_ERROR)
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->x.have = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* set error code, and if no message, then done */
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->err = err;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (msg == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* for an out of memory error, return literal string when requested */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (err == Z_MEM_ERROR)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* construct error message with path */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
199767f8919635c4928607450d9e0abb932109ceToomas Soome NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome state->err = Z_MEM_ERROR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
199767f8919635c4928607450d9e0abb932109ceToomas Soome snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
199767f8919635c4928607450d9e0abb932109ceToomas Soome "%s%s%s", state->path, ": ", msg);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome strcpy(state->msg, state->path);
199767f8919635c4928607450d9e0abb932109ceToomas Soome strcat(state->msg, ": ");
199767f8919635c4928607450d9e0abb932109ceToomas Soome strcat(state->msg, msg);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifndef INT_MAX
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* portably return maximum value for an int (when limits.h presumed not
199767f8919635c4928607450d9e0abb932109ceToomas Soome available) -- we need to do this to cover cases where 2's complement not
199767f8919635c4928607450d9e0abb932109ceToomas Soome used, since C standard permits 1's complement and sign-bit representations,
199767f8919635c4928607450d9e0abb932109ceToomas Soome otherwise we could just use ((unsigned)-1) >> 1 */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeunsigned ZLIB_INTERNAL gz_intmax()
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned p, q;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome p = 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome do {
199767f8919635c4928607450d9e0abb932109ceToomas Soome q = p;
199767f8919635c4928607450d9e0abb932109ceToomas Soome p <<= 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome p++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } while (p > q);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return q >> 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif