1381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* gzlib.c -- zlib functions common to reading and writing gzip files 2ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes * Copyright (C) 2004, 2010, 2011 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)); 20381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal gzFile gz_open OF((const char *, 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) 92381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *path; 93381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int fd; 94381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *mode; 95381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 96381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 97381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 98ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes /* check input */ 99ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (path == NULL) 100ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return NULL; 101ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 102381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* allocate gzFile structure to return */ 103381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = malloc(sizeof(gz_state)); 104381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state == NULL) 105381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 106381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->size = 0; /* no buffers allocated yet */ 107381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->want = GZBUFSIZE; /* requested buffer size */ 108381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->msg = NULL; /* no error message yet */ 109381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 110381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* interpret mode */ 111381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_NONE; 112381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->level = Z_DEFAULT_COMPRESSION; 113381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_DEFAULT_STRATEGY; 114ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->direct = 0; 115381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes while (*mode) { 116381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (*mode >= '0' && *mode <= '9') 117381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->level = *mode - '0'; 118381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else 119381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes switch (*mode) { 120381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'r': 121381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_READ; 122381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 123381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifndef NO_GZCOMPRESS 124381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'w': 125381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_WRITE; 126381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 127381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'a': 128381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_APPEND; 129381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 130381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 131381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case '+': /* can't read and write at the same time */ 132381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 133381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 134381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'b': /* ignore -- will request binary anyway */ 135381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 136381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'f': 137381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_FILTERED; 138381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 139381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'h': 140381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_HUFFMAN_ONLY; 141381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 142381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'R': 143381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_RLE; 144381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 145381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case 'F': 146381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strategy = Z_FIXED; 147ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes case 'T': 148ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->direct = 1; 149381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes default: /* could consider as an error, but just ignore */ 150381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ; 151381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 152381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes mode++; 153381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 154381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 155381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* must provide an "r", "w", or "a" */ 156381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_NONE) { 157381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 158381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 159381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 160381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 161ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes /* can't force transparent read */ 162ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->mode == GZ_READ) { 163ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->direct) { 164ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes free(state); 165ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return NULL; 166ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 167ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->direct = 1; /* for empty file */ 168ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 169ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 170381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* save the path name for error messages */ 171381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->path = malloc(strlen(path) + 1); 172381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->path == NULL) { 173381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 174381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 175381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 176381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strcpy(state->path, path); 177381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 178381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* open the file with the appropriate mode (or just use fd) */ 179381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->fd = fd != -1 ? fd : 180381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes open(path, 181381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef O_LARGEFILE 182381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes O_LARGEFILE | 183381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 184381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef O_BINARY 185381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes O_BINARY | 186381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 187381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (state->mode == GZ_READ ? 188381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes O_RDONLY : 189381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (O_WRONLY | O_CREAT | ( 190381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode == GZ_WRITE ? 191381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes O_TRUNC : 192381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes O_APPEND))), 193381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 0666); 194381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->fd == -1) { 195381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->path); 196381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state); 197381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 198381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 199381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_APPEND) 200381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = GZ_WRITE; /* simplify later checks */ 201381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 202381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* save the current position for rewinding (only if reading) */ 203381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_READ) { 204381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->start = LSEEK(state->fd, 0, SEEK_CUR); 205381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->start == -1) state->start = 0; 206381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 207381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 208381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* initialize stream */ 209381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_reset(state); 210381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 211381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* return stream */ 212381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return (gzFile)state; 213381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 214381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 215381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 216381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesgzFile ZEXPORT gzopen(path, mode) 217381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *path; 218381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *mode; 219381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 220381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return gz_open(path, -1, mode); 221381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 222381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 223381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 224381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesgzFile ZEXPORT gzopen64(path, mode) 225381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *path; 226381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *mode; 227381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 228381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return gz_open(path, -1, mode); 229381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 230381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 231381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 232381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesgzFile ZEXPORT gzdopen(fd, mode) 233381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int fd; 234381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *mode; 235381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 236381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes char *path; /* identifier for error messages */ 237381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile gz; 238381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 239381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) 240381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 241381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes sprintf(path, "<fd:%d>", fd); /* for debugging */ 242381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz = gz_open(path, fd, mode); 243381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(path); 244381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return gz; 245381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 246381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 247381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 248381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzbuffer(file, size) 249381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 250381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned size; 251381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 252381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 253381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 254381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 255381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 256381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 257381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 258381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 259381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 260381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 261381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* make sure we haven't already allocated memory */ 262381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->size != 0) 263381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 264381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 265381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check and set requested size */ 266ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (size < 2) 267ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes size = 2; /* need two bytes to check magic header */ 268381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->want = size; 269381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 270381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 271381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 272381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 273381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzrewind(file) 274381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 275381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 276381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 277381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 278381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure */ 279381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 280381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 281381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 282381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 283381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that we're reading and that there's no error */ 284ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->mode != GZ_READ || 285ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes (state->err != Z_OK && state->err != Z_BUF_ERROR)) 286381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 287381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 288381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* back up and start over */ 289381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (LSEEK(state->fd, state->start, SEEK_SET) == -1) 290381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 291381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_reset(state); 292381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 293381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 294381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 295381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 296381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off64_t ZEXPORT gzseek64(file, offset, whence) 297381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 298381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t offset; 299381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int whence; 300381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 301381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned n; 302381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t ret; 303381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 304381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 305381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 306381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 307381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 308381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 309381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 310381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 311381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 312381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check that there's no error */ 313ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->err != Z_OK && state->err != Z_BUF_ERROR) 314381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 315381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 316381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* can only seek from start or relative to current position */ 317381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (whence != SEEK_SET && whence != SEEK_CUR) 318381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 319381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 320381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* normalize offset to a SEEK_CUR specification */ 321381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (whence == SEEK_SET) 322ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes offset -= state->x.pos; 323381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else if (state->seek) 324381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes offset += state->skip; 325381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 326381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 327381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if within raw area while reading, just go there */ 328381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_READ && state->how == COPY && 329ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos + offset >= 0) { 330ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); 331381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (ret == -1) 332381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 333ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.have = 0; 334381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->eof = 0; 335ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->past = 0; 336381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 0; 337381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_OK, NULL); 338381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->strm.avail_in = 0; 339ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos += offset; 340ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return state->x.pos; 341381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 342381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 343381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* calculate skip amount, rewinding if needed for back seek when reading */ 344381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (offset < 0) { 345381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ) /* writing -- can't go backwards */ 346381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 347ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes offset += state->x.pos; 348381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (offset < 0) /* before start of file! */ 349381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 350381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (gzrewind(file) == -1) /* rewind, then skip to offset */ 351381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 352381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 353381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 354381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* if reading, skip what's in output buffer (one less gzgetc() check) */ 355381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_READ) { 356ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? 357ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes (unsigned)offset : state->x.have; 358ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.have -= n; 359ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.next += n; 360ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.pos += n; 361381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes offset -= n; 362381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 363381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 364381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* request skip (if not zero) */ 365381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (offset) { 366381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->seek = 1; 367381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->skip = offset; 368381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 369ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return state->x.pos + offset; 370381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 371381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 372381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 373381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off_t ZEXPORT gzseek(file, offset, whence) 374381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 375381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off_t offset; 376381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int whence; 377381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 378381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t ret; 379381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 380381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = gzseek64(file, (z_off64_t)offset, whence); 381381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret == (z_off_t)ret ? (z_off_t)ret : -1; 382381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 383381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 384381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 385381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off64_t ZEXPORT gztell64(file) 386381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 387381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 388381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 389381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 390381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 391381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 392381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 393381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 394381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 395381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 396381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 397381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* return position */ 398ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return state->x.pos + (state->seek ? state->skip : 0); 399381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 400381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 401381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 402381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off_t ZEXPORT gztell(file) 403381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 404381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 405381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t ret; 406381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 407381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = gztell64(file); 408381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret == (z_off_t)ret ? (z_off_t)ret : -1; 409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 410381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 411381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 412381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off64_t ZEXPORT gzoffset64(file) 413381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 414381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 415381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t offset; 416381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 417381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 418381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 419381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 420381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 421381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 422381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 423381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 424381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 425381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* compute and return effective offset in file */ 426381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes offset = LSEEK(state->fd, 0, SEEK_CUR); 427381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (offset == -1) 428381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return -1; 429381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == GZ_READ) /* reading */ 430381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes offset -= state->strm.avail_in; /* don't count buffered input */ 431381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return offset; 432381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 433381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 434381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 435381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_off_t ZEXPORT gzoffset(file) 436381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 437381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 438381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t ret; 439381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 440381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = gzoffset64(file); 441381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret == (z_off_t)ret ? (z_off_t)ret : -1; 442381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 443381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 444381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 445381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT gzeof(file) 446381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 447381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 448381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 449381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 450381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 451381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 452381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 453381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 454381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 455381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return 0; 456381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 457381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* return end-of-file state */ 458ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return state->mode == GZ_READ ? state->past : 0; 459381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 460381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 461381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 462381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesconst char * ZEXPORT gzerror(file, errnum) 463381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 464381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int *errnum; 465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 466381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 467381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 468381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 469381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 470381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 471381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 472381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 473381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return NULL; 474381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 475381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* return error information */ 476381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (errnum != NULL) 477381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes *errnum = state->err; 478381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return state->msg == NULL ? "" : state->msg; 479381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 480381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 481381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* -- see zlib.h -- */ 482381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesvoid ZEXPORT gzclearerr(file) 483381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gzFile file; 484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 486381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 487381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get internal structure and check integrity */ 488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (file == NULL) 489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 490381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (gz_statep)file; 491381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode != GZ_READ && state->mode != GZ_WRITE) 492381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 493381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* clear error and end-of-file */ 495ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->mode == GZ_READ) { 496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->eof = 0; 497ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->past = 0; 498ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes } 499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_error(state, Z_OK, NULL); 500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 501381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 502381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* Create an error message in allocated memory and set state->err and 503381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->msg accordingly. Free any previous error message already there. Do 504381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes not try to free or allocate space if the error is Z_MEM_ERROR (out of 505381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes memory). Simply save the error message as a static string. If there is an 506381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes allocation failure constructing the error message, then convert the error to 507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes out of memory. */ 508381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesvoid ZLIB_INTERNAL gz_error(state, err, msg) 509381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes gz_statep state; 510381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int err; 511381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes const char *msg; 512381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 513381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* free previously allocated message and clear */ 514381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->msg != NULL) { 515381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->err != Z_MEM_ERROR) 516381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes free(state->msg); 517381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->msg = NULL; 518381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 519381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 520ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ 521ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (err != Z_OK && err != Z_BUF_ERROR) 522ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->x.have = 0; 523ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 524381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* set error code, and if no message, then done */ 525381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->err = err; 526381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (msg == NULL) 527381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 528381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 529381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* for an out of memory error, save as static string */ 530381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (err == Z_MEM_ERROR) { 531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->msg = (char *)msg; 532381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 533381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 534381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 535381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* construct error message with path */ 536381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { 537381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->err = Z_MEM_ERROR; 538381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->msg = (char *)"out of memory"; 539381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 540381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 541381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strcpy(state->msg, state->path); 542381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strcat(state->msg, ": "); 543381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strcat(state->msg, msg); 544381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return; 545381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 546381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifndef INT_MAX 548381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* portably return maximum value for an int (when limits.h presumed not 549381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes available) -- we need to do this to cover cases where 2's complement not 550381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes used, since C standard permits 1's complement and sign-bit representations, 551381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes otherwise we could just use ((unsigned)-1) >> 1 */ 552381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesunsigned ZLIB_INTERNAL gz_intmax() 553381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 554381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unsigned p, q; 555381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 556381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes p = 1; 557381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes do { 558381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes q = p; 559381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes p <<= 1; 560381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes p++; 561381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } while (p > q); 562381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return q >> 1; 563381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 564381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 565