1381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* gzlib.c -- zlib functions common to reading and writing gzip files 204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler 3381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes * For conditions of distribution and use, see copyright notice in zlib.h 4381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes */ 5381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 6381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#include "gzguts.h" 7381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 8ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#if defined(_WIN32) && !defined(__BORLANDC__) 9ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes# define LSEEK _lseeki64 10ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#else 11381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 12381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# define LSEEK lseek64 13381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else 14381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes# define LSEEK lseek 15381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 16ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#endif 17381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 18381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Local functions */ 19381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal void gz_reset OF((gz_statep)); 2009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hugheslocal gzFile gz_open OF((const void *, int, const char *)); 21381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 22381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#if defined UNDER_CE 23381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 24381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Map the Windows error number in ERROR to a locale-dependent error message 25381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes string and return a pointer to it. Typically, the values for ERROR come 26381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes from GetLastError. 27381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 28381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes The string pointed to shall not be modified by the application, but may be 29381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes overwritten by a subsequent call to gz_strwinerror 30381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 31381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes The gz_strwinerror function does not change the current setting of 32381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes GetLastError. */ 33381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheschar ZLIB_INTERNAL *gz_strwinerror (error) 34381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DWORD error; 35381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 36381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes static char buf[1024]; 37381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 38381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes wchar_t *msgbuf; 39381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DWORD lasterr = GetLastError(); 40381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 41381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes | FORMAT_MESSAGE_ALLOCATE_BUFFER, 42381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NULL, 43381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes error, 44381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 0, /* Default language */ 45381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (LPVOID)&msgbuf, 46381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 0, 47381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NULL); 48381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (chars != 0) { 49381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* If there is an \r\n appended, zap it. */ 50381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (chars >= 2 51381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { 52381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes chars -= 2; 53381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes msgbuf[chars] = 0; 54381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 55381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 56381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (chars > sizeof (buf) - 1) { 57381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes chars = sizeof (buf) - 1; 58381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes msgbuf[chars] = 0; 59381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 60381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 61381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes wcstombs(buf, msgbuf, chars + 1); 62381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes LocalFree(msgbuf); 63381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 64381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else { 65381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes sprintf(buf, "unknown win32 error (%ld)", error); 66381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 67381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 68381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes SetLastError(lasterr); 69381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return buf; 70381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 71381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 72381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif /* UNDER_CE */ 73381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 74381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Reset gzip file state */ 75381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal void gz_reset(state) 76381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 77381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 78ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.have = 0; /* no output data available */ 79381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_READ) { /* for reading ... */ 80381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->eof = 0; /* not at end of file */ 81ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->past = 0; /* have not read past end yet */ 82381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->how = LOOK; /* look for gzip header */ 83381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 84381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; /* no seek request pending */ 85381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_OK, NULL); /* clear error */ 86ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos = 0; /* no uncompressed data yet */ 87381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strm.avail_in = 0; /* no input data yet */ 88381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 89381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 90381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Open a gzip file either by name or file descriptor. */ 91381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal gzFile gz_open(path, fd, mode) 9209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes const void *path; 93381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int fd; 94381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *mode; 95381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 96381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 9709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes size_t len; 9809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes int oflag; 9909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef O_CLOEXEC 10009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes int cloexec = 0; 10109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 10209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef O_EXCL 10309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes int exclusive = 0; 10409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 105381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 106ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes /* check input */ 107ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (path == NULL) 108ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return NULL; 109ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 110381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* allocate gzFile structure to return */ 11104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state = (gz_statep)malloc(sizeof(gz_state)); 112381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state == NULL) 113381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 114381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->size = 0; /* no buffers allocated yet */ 115381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->want = GZBUFSIZE; /* requested buffer size */ 116381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->msg = NULL; /* no error message yet */ 117381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 118381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* interpret mode */ 119381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_NONE; 120381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->level = Z_DEFAULT_COMPRESSION; 121381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_DEFAULT_STRATEGY; 122ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->direct = 0; 123381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes while (*mode) { 124381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (*mode >= '0' && *mode <= '9') 125381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->level = *mode - '0'; 126381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else 127381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes switch (*mode) { 128381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'r': 129381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_READ; 130381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 131381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifndef NO_GZCOMPRESS 132381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'w': 133381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_WRITE; 134381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 135381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'a': 136381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_APPEND; 137381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 138381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 139381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case '+': /* can't read and write at the same time */ 140381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 141381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 142381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'b': /* ignore -- will request binary anyway */ 143381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 14409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef O_CLOEXEC 14509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes case 'e': 14609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes cloexec = 1; 14709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes break; 14809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 14909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef O_EXCL 15009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes case 'x': 15109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes exclusive = 1; 15209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes break; 15309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 154381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'f': 155381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_FILTERED; 156381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 157381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'h': 158381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_HUFFMAN_ONLY; 159381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 160381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'R': 161381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_RLE; 162381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 163381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'F': 164381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_FIXED; 16504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes break; 166ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes case 'T': 167ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->direct = 1; 16804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes break; 169381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes default: /* could consider as an error, but just ignore */ 170381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ; 171381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 172381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes mode++; 173381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 174381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 175381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* must provide an "r", "w", or "a" */ 176381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_NONE) { 177381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 178381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 179381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 180381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 181ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes /* can't force transparent read */ 182ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->mode == GZ_READ) { 183ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->direct) { 184ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes free(state); 185ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return NULL; 186ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 187ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->direct = 1; /* for empty file */ 188ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 189ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 190381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* save the path name for error messages */ 19109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef _WIN32 19209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes if (fd == -2) { 19309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes len = wcstombs(NULL, path, 0); 19409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes if (len == (size_t)-1) 19509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes len = 0; 19609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes } 19709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes else 19809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 19904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes len = strlen((const char *)path); 20004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->path = (char *)malloc(len + 1); 201381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->path == NULL) { 202381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 203381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 204381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 20509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef _WIN32 20609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes if (fd == -2) 20709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes if (len) 20809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes wcstombs(state->path, path, len + 1); 20909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes else 21009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes *(state->path) = 0; 21109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes else 21209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 21304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 21404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes snprintf(state->path, len + 1, "%s", (const char *)path); 21504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#else 21609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes strcpy(state->path, path); 21704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#endif 218381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 21909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes /* compute the flags for open() */ 22009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes oflag = 221381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef O_LARGEFILE 22209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes O_LARGEFILE | 223381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 224381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef O_BINARY 22509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes O_BINARY | 226381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 22709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef O_CLOEXEC 22809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes (cloexec ? O_CLOEXEC : 0) | 22909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 23009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes (state->mode == GZ_READ ? 23109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes O_RDONLY : 23209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes (O_WRONLY | O_CREAT | 23309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef O_EXCL 23409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes (exclusive ? O_EXCL : 0) | 23509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 23609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes (state->mode == GZ_WRITE ? 23709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes O_TRUNC : 23809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes O_APPEND))); 23909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes 24009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes /* open the file with the appropriate flags (or just use fd) */ 24109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes state->fd = fd > -1 ? fd : ( 24209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef _WIN32 24309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes fd == -2 ? _wopen(path, oflag, 0666) : 24409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 24504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes open((const char *)path, oflag, 0666)); 246381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->fd == -1) { 247381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->path); 248381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 249381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 250381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 251381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_APPEND) 252381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_WRITE; /* simplify later checks */ 253381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 254381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* save the current position for rewinding (only if reading) */ 255381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_READ) { 256381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->start = LSEEK(state->fd, 0, SEEK_CUR); 257381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->start == -1) state->start = 0; 258381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 259381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 260381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* initialize stream */ 261381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_reset(state); 262381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 263381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* return stream */ 264381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return (gzFile)state; 265381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 266381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 267381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 268381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesgzFile ZEXPORT gzopen(path, mode) 269381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *path; 270381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *mode; 271381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 272381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return gz_open(path, -1, mode); 273381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 274381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 275381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 276381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesgzFile ZEXPORT gzopen64(path, mode) 277381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *path; 278381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *mode; 279381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 280381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return gz_open(path, -1, mode); 281381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 282381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 283381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 284381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesgzFile ZEXPORT gzdopen(fd, mode) 285381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int fd; 286381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *mode; 287381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 288381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes char *path; /* identifier for error messages */ 289381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile gz; 290381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 29104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) 292381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 29304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 29404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */ 29504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#else 296381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes sprintf(path, "<fd:%d>", fd); /* for debugging */ 29704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#endif 298381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz = gz_open(path, fd, mode); 299381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(path); 300381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return gz; 301381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 302381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 303381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 30409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#ifdef _WIN32 30509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott HughesgzFile ZEXPORT gzopen_w(path, mode) 30609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes const wchar_t *path; 30709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes const char *mode; 30809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes{ 30909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes return gz_open(path, -2, mode); 31009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes} 31109eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 31209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes 31309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes/* -- see zlib.h -- */ 314381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzbuffer(file, size) 315381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 316381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned size; 317381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 318381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 319381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 320381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 321381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 322381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 323381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 324381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 325381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 326381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 327381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* make sure we haven't already allocated memory */ 328381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size != 0) 329381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 330381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 331381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check and set requested size */ 332ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (size < 2) 333ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes size = 2; /* need two bytes to check magic header */ 334381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->want = size; 335381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 336381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 337381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 338381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 339381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzrewind(file) 340381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 341381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 342381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 343381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 344381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 345381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 346381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 347381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 348381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 349381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're reading and that there's no error */ 350ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->mode != GZ_READ || 351ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes (state->err != Z_OK && state->err != Z_BUF_ERROR)) 352381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 353381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 354381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* back up and start over */ 355381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (LSEEK(state->fd, state->start, SEEK_SET) == -1) 356381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 357381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_reset(state); 358381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 359381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 360381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 361381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 362381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off64_t ZEXPORT gzseek64(file, offset, whence) 363381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 364381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t offset; 365381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int whence; 366381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 367381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned n; 368381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t ret; 369381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 370381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 371381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 372381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 373381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 374381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 375381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 376381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 377381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 378381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that there's no error */ 379ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->err != Z_OK && state->err != Z_BUF_ERROR) 380381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 381381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 382381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* can only seek from start or relative to current position */ 383381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (whence != SEEK_SET && whence != SEEK_CUR) 384381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 385381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 386381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* normalize offset to a SEEK_CUR specification */ 387381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (whence == SEEK_SET) 388ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes offset -= state->x.pos; 389381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else if (state->seek) 390381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes offset += state->skip; 391381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 392381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 393381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if within raw area while reading, just go there */ 394381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_READ && state->how == COPY && 395ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos + offset >= 0) { 396ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); 397381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (ret == -1) 398381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 399ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.have = 0; 400381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->eof = 0; 401ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->past = 0; 402381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 403381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_OK, NULL); 404381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strm.avail_in = 0; 405ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos += offset; 406ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return state->x.pos; 407381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 408381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* calculate skip amount, rewinding if needed for back seek when reading */ 410381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (offset < 0) { 411381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ) /* writing -- can't go backwards */ 412381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 413ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes offset += state->x.pos; 414381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (offset < 0) /* before start of file! */ 415381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 416381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gzrewind(file) == -1) /* rewind, then skip to offset */ 417381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 418381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 419381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 420381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if reading, skip what's in output buffer (one less gzgetc() check) */ 421381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_READ) { 422ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? 423ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes (unsigned)offset : state->x.have; 424ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.have -= n; 425ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.next += n; 426ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos += n; 427381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes offset -= n; 428381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 429381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 430381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* request skip (if not zero) */ 431381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (offset) { 432381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 1; 433381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->skip = offset; 434381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 435ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return state->x.pos + offset; 436381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 437381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 438381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 439381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off_t ZEXPORT gzseek(file, offset, whence) 440381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 441381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off_t offset; 442381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int whence; 443381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 444381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t ret; 445381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 446381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = gzseek64(file, (z_off64_t)offset, whence); 447381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret == (z_off_t)ret ? (z_off_t)ret : -1; 448381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 449381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 450381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 451381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off64_t ZEXPORT gztell64(file) 452381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 453381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 454381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 455381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 456381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 457381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 458381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 459381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 460381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 461381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 462381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 463381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* return position */ 464ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return state->x.pos + (state->seek ? state->skip : 0); 465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 466381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 467381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 468381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off_t ZEXPORT gztell(file) 469381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 470381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 471381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t ret; 472381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 473381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = gztell64(file); 474381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret == (z_off_t)ret ? (z_off_t)ret : -1; 475381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 476381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 477381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 478381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off64_t ZEXPORT gzoffset64(file) 479381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 480381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 481381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t offset; 482381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 483381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 486381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 487381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 490381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 491381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* compute and return effective offset in file */ 492381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes offset = LSEEK(state->fd, 0, SEEK_CUR); 493381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (offset == -1) 494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_READ) /* reading */ 496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes offset -= state->strm.avail_in; /* don't count buffered input */ 497381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return offset; 498381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 501381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off_t ZEXPORT gzoffset(file) 502381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 503381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 504381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t ret; 505381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 506381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = gzoffset64(file); 507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret == (z_off_t)ret ? (z_off_t)ret : -1; 508381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 509381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 510381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 511381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzeof(file) 512381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 513381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 514381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 515381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 516381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 517381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 518381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 519381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 520381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 521381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 522381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 523381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* return end-of-file state */ 524ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return state->mode == GZ_READ ? state->past : 0; 525381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 526381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 527381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 528381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesconst char * ZEXPORT gzerror(file, errnum) 529381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 530381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int *errnum; 531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 532381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 533381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 534381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 535381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 536381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 537381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 538381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 539381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 540381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 541381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* return error information */ 542381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (errnum != NULL) 543381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes *errnum = state->err; 54404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes return state->err == Z_MEM_ERROR ? "out of memory" : 54504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes (state->msg == NULL ? "" : state->msg); 546381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 548381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 549381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesvoid ZEXPORT gzclearerr(file) 550381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 551381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 552381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 553381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 554381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 555381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 556381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 557381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 558381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 559381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 560381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 561381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* clear error and end-of-file */ 562ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->mode == GZ_READ) { 563381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->eof = 0; 564ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->past = 0; 565ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 566381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_OK, NULL); 567381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 568381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 569381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Create an error message in allocated memory and set state->err and 570381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->msg accordingly. Free any previous error message already there. Do 571381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes not try to free or allocate space if the error is Z_MEM_ERROR (out of 572381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes memory). Simply save the error message as a static string. If there is an 573381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes allocation failure constructing the error message, then convert the error to 574381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes out of memory. */ 575381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesvoid ZLIB_INTERNAL gz_error(state, err, msg) 576381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 577381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int err; 578381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *msg; 579381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 580381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* free previously allocated message and clear */ 581381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->msg != NULL) { 582381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->err != Z_MEM_ERROR) 583381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->msg); 584381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->msg = NULL; 585381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 586381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 587ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ 588ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (err != Z_OK && err != Z_BUF_ERROR) 589ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.have = 0; 590ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 591381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* set error code, and if no message, then done */ 592381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->err = err; 593381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (msg == NULL) 594381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 595381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 59604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes /* for an out of memory error, return literal string when requested */ 59704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (err == Z_MEM_ERROR) 598381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 599381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 600381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* construct error message with path */ 60104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == 60204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes NULL) { 603381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->err = Z_MEM_ERROR; 604381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 605381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 60604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 60704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, 60804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes "%s%s%s", state->path, ": ", msg); 60904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#else 610381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strcpy(state->msg, state->path); 611381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strcat(state->msg, ": "); 612381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strcat(state->msg, msg); 61304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes#endif 614381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 615381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 616381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 617381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifndef INT_MAX 618381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* portably return maximum value for an int (when limits.h presumed not 619381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes available) -- we need to do this to cover cases where 2's complement not 620381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes used, since C standard permits 1's complement and sign-bit representations, 621381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes otherwise we could just use ((unsigned)-1) >> 1 */ 622381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesunsigned ZLIB_INTERNAL gz_intmax() 623381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 624381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned p, q; 625381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 626381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes p = 1; 627381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes do { 628381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes q = p; 629381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes p <<= 1; 630381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes p++; 631381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } while (p > q); 632381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return q >> 1; 633381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 634381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 635