1ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* gzlib.c -- zlib functions common to reading and writing gzip files 234e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com * Copyright (C) 2004-2017 Mark Adler 3ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis * For conditions of distribution and use, see copyright notice in zlib.h 4ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis */ 5ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 6ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#include "gzguts.h" 7ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 834e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) 9c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes# define LSEEK _lseeki64 10c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#else 11ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 12ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis# define LSEEK lseek64 13ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#else 14ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis# define LSEEK lseek 15ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#endif 16c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 17ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 18ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* Local functions */ 19ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwislocal void gz_reset OF((gz_statep)); 20c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimeslocal gzFile gz_open OF((const void *, int, const char *)); 21ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 22ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#if defined UNDER_CE 23ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 24ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* Map the Windows error number in ERROR to a locale-dependent error message 25ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis string and return a pointer to it. Typically, the values for ERROR come 26ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis from GetLastError. 27ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 28ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis The string pointed to shall not be modified by the application, but may be 29ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis overwritten by a subsequent call to gz_strwinerror 30ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 31ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis The gz_strwinerror function does not change the current setting of 32ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis GetLastError. */ 33ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwischar ZLIB_INTERNAL *gz_strwinerror (error) 34ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis DWORD error; 35ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 36ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis static char buf[1024]; 37ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 38ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis wchar_t *msgbuf; 39ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis DWORD lasterr = GetLastError(); 40ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 41ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis | FORMAT_MESSAGE_ALLOCATE_BUFFER, 42ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis NULL, 43ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis error, 44ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 0, /* Default language */ 45ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis (LPVOID)&msgbuf, 46ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 0, 47ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis NULL); 48ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (chars != 0) { 49ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* If there is an \r\n appended, zap it. */ 50ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (chars >= 2 51ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { 52ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis chars -= 2; 53ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis msgbuf[chars] = 0; 54ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 55ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 56ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (chars > sizeof (buf) - 1) { 57ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis chars = sizeof (buf) - 1; 58ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis msgbuf[chars] = 0; 59ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 60ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 61ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis wcstombs(buf, msgbuf, chars + 1); 62ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis LocalFree(msgbuf); 63ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 64ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis else { 65ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis sprintf(buf, "unknown win32 error (%ld)", error); 66ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 67ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 68ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis SetLastError(lasterr); 69ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return buf; 70ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 71ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 72ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#endif /* UNDER_CE */ 73ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 74ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* Reset gzip file state */ 75ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwislocal void gz_reset(state) 76ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 77ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 78c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->x.have = 0; /* no output data available */ 79ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode == GZ_READ) { /* for reading ... */ 80ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->eof = 0; /* not at end of file */ 81c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->past = 0; /* have not read past end yet */ 82ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->how = LOOK; /* look for gzip header */ 83ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 84ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->seek = 0; /* no seek request pending */ 85ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_error(state, Z_OK, NULL); /* clear error */ 86c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->x.pos = 0; /* no uncompressed data yet */ 87ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->strm.avail_in = 0; /* no input data yet */ 88ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 89ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 90ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* Open a gzip file either by name or file descriptor. */ 91ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwislocal gzFile gz_open(path, fd, mode) 92c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes const void *path; 93ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis int fd; 94ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis const char *mode; 95ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 96ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 9734e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com z_size_t len; 98c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes int oflag; 99c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#ifdef O_CLOEXEC 100c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes int cloexec = 0; 101c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 102c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#ifdef O_EXCL 103c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes int exclusive = 0; 104c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 105c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes 106c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes /* check input */ 107c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (path == NULL) 108c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes return NULL; 109ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 110ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* allocate gzFile structure to return */ 111c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state = (gz_statep)malloc(sizeof(gz_state)); 112ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state == NULL) 113ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return NULL; 114ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->size = 0; /* no buffers allocated yet */ 115ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->want = GZBUFSIZE; /* requested buffer size */ 116ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->msg = NULL; /* no error message yet */ 117ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 118ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* interpret mode */ 119ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->mode = GZ_NONE; 120ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->level = Z_DEFAULT_COMPRESSION; 121ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->strategy = Z_DEFAULT_STRATEGY; 122c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->direct = 0; 123ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis while (*mode) { 124ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (*mode >= '0' && *mode <= '9') 125ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->level = *mode - '0'; 126ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis else 127ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis switch (*mode) { 128ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis case 'r': 129ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->mode = GZ_READ; 130ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis break; 131ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#ifndef NO_GZCOMPRESS 132ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis case 'w': 133ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->mode = GZ_WRITE; 134ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis break; 135ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis case 'a': 136ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->mode = GZ_APPEND; 137ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis break; 138ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#endif 139ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis case '+': /* can't read and write at the same time */ 140ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis free(state); 141ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return NULL; 142ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis case 'b': /* ignore -- will request binary anyway */ 143ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis break; 144c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#ifdef O_CLOEXEC 145c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes case 'e': 146c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes cloexec = 1; 147c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes break; 148c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 149c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#ifdef O_EXCL 150c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes case 'x': 151c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes exclusive = 1; 152c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes break; 153c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 154ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis case 'f': 155ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->strategy = Z_FILTERED; 156ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis break; 157ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis case 'h': 158ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->strategy = Z_HUFFMAN_ONLY; 159ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis break; 160ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis case 'R': 161ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->strategy = Z_RLE; 162ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis break; 163ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis case 'F': 164ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->strategy = Z_FIXED; 165c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes break; 166c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes case 'T': 167c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->direct = 1; 168c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes break; 169ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis default: /* could consider as an error, but just ignore */ 170ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis ; 171ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 172ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis mode++; 173ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 174ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 175ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* must provide an "r", "w", or "a" */ 176ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode == GZ_NONE) { 177ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis free(state); 178ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return NULL; 179ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 180ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 181c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes /* can't force transparent read */ 182c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (state->mode == GZ_READ) { 183c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (state->direct) { 184c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes free(state); 185c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes return NULL; 186c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes } 187c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->direct = 1; /* for empty file */ 188c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes } 189c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes 190ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* save the path name for error messages */ 19134e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com#ifdef WIDECHAR 192c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (fd == -2) { 193c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes len = wcstombs(NULL, path, 0); 19434e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com if (len == (z_size_t)-1) 195c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes len = 0; 196c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes } 197c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes else 198c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 199c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes len = strlen((const char *)path); 200c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->path = (char *)malloc(len + 1); 201ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->path == NULL) { 202ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis free(state); 203ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return NULL; 204ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 20534e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com#ifdef WIDECHAR 206c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (fd == -2) 207c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (len) 208c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes wcstombs(state->path, path, len + 1); 209c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes else 210c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes *(state->path) = 0; 211c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes else 212c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 213c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 21434e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com (void)snprintf(state->path, len + 1, "%s", (const char *)path); 215c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#else 216c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes strcpy(state->path, path); 217c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 218ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 219c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes /* compute the flags for open() */ 220c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes oflag = 221ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#ifdef O_LARGEFILE 222c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes O_LARGEFILE | 223ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#endif 224ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#ifdef O_BINARY 225c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes O_BINARY | 226c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 227c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#ifdef O_CLOEXEC 228c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes (cloexec ? O_CLOEXEC : 0) | 229c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 230c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes (state->mode == GZ_READ ? 231c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes O_RDONLY : 232c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes (O_WRONLY | O_CREAT | 233c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#ifdef O_EXCL 234c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes (exclusive ? O_EXCL : 0) | 235c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 236c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes (state->mode == GZ_WRITE ? 237c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes O_TRUNC : 238c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes O_APPEND))); 239c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes 240c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes /* open the file with the appropriate flags (or just use fd) */ 241c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->fd = fd > -1 ? fd : ( 24234e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com#ifdef WIDECHAR 243c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes fd == -2 ? _wopen(path, oflag, 0666) : 244ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#endif 245c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes open((const char *)path, oflag, 0666)); 246ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->fd == -1) { 247ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis free(state->path); 248ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis free(state); 249ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return NULL; 250ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 25134e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com if (state->mode == GZ_APPEND) { 25234e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ 253ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->mode = GZ_WRITE; /* simplify later checks */ 25434e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com } 255ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 256ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* save the current position for rewinding (only if reading) */ 257ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode == GZ_READ) { 258ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->start = LSEEK(state->fd, 0, SEEK_CUR); 259ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->start == -1) state->start = 0; 260ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 261ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 262ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* initialize stream */ 263ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_reset(state); 264ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 265ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* return stream */ 266ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return (gzFile)state; 267ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 268ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 269ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 270ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. LöwisgzFile ZEXPORT gzopen(path, mode) 271ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis const char *path; 272ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis const char *mode; 273ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 274ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return gz_open(path, -1, mode); 275ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 276ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 277ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 278ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. LöwisgzFile ZEXPORT gzopen64(path, mode) 279ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis const char *path; 280ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis const char *mode; 281ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 282ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return gz_open(path, -1, mode); 283ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 284ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 285ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 286ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. LöwisgzFile ZEXPORT gzdopen(fd, mode) 287ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis int fd; 288ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis const char *mode; 289ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 290ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis char *path; /* identifier for error messages */ 291ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile gz; 292ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 293c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) 294ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return NULL; 295c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 29634e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); 297c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#else 298ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis sprintf(path, "<fd:%d>", fd); /* for debugging */ 299c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 300ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz = gz_open(path, fd, mode); 301ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis free(path); 302ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return gz; 303ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 304ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 305ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 30634e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com#ifdef WIDECHAR 307c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian HeimesgzFile ZEXPORT gzopen_w(path, mode) 308c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes const wchar_t *path; 309c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes const char *mode; 310c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes{ 311c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes return gz_open(path, -2, mode); 312c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes} 313c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 314c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes 315c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes/* -- see zlib.h -- */ 316ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisint ZEXPORT gzbuffer(file, size) 317ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 318ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis unsigned size; 319ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 320ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 321ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 322ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* get internal structure and check integrity */ 323ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (file == NULL) 324ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 325ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state = (gz_statep)file; 326ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode != GZ_READ && state->mode != GZ_WRITE) 327ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 328ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 329ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* make sure we haven't already allocated memory */ 330ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->size != 0) 331ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 332ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 333ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* check and set requested size */ 33434e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com if ((size << 1) < size) 33534e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com return -1; /* need to be able to double it */ 336c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (size < 2) 337c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes size = 2; /* need two bytes to check magic header */ 338ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->want = size; 339ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return 0; 340ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 341ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 342ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 343ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisint ZEXPORT gzrewind(file) 344ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 345ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 346ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 347ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 348ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* get internal structure */ 349ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (file == NULL) 350ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 351ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state = (gz_statep)file; 352ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 353ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* check that we're reading and that there's no error */ 354c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (state->mode != GZ_READ || 355c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes (state->err != Z_OK && state->err != Z_BUF_ERROR)) 356ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 357ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 358ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* back up and start over */ 359ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (LSEEK(state->fd, state->start, SEEK_SET) == -1) 360ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 361ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_reset(state); 362ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return 0; 363ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 364ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 365ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 366ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisz_off64_t ZEXPORT gzseek64(file, offset, whence) 367ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 368ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis z_off64_t offset; 369ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis int whence; 370ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 371ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis unsigned n; 372ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis z_off64_t ret; 373ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 374ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 375ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* get internal structure and check integrity */ 376ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (file == NULL) 377ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 378ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state = (gz_statep)file; 379ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode != GZ_READ && state->mode != GZ_WRITE) 380ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 381ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 382ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* check that there's no error */ 383c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (state->err != Z_OK && state->err != Z_BUF_ERROR) 384ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 385ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 386ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* can only seek from start or relative to current position */ 387ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (whence != SEEK_SET && whence != SEEK_CUR) 388ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 389ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 390ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* normalize offset to a SEEK_CUR specification */ 391ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (whence == SEEK_SET) 392c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes offset -= state->x.pos; 393ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis else if (state->seek) 394ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis offset += state->skip; 395ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->seek = 0; 396ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 397ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* if within raw area while reading, just go there */ 398ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode == GZ_READ && state->how == COPY && 399c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->x.pos + offset >= 0) { 400c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); 401ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (ret == -1) 402ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 403c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->x.have = 0; 404ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->eof = 0; 405c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->past = 0; 406ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->seek = 0; 407ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_error(state, Z_OK, NULL); 408ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->strm.avail_in = 0; 409c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->x.pos += offset; 410c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes return state->x.pos; 411ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 412ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 413ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* calculate skip amount, rewinding if needed for back seek when reading */ 414ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (offset < 0) { 415ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode != GZ_READ) /* writing -- can't go backwards */ 416ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 417c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes offset += state->x.pos; 418ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (offset < 0) /* before start of file! */ 419ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 420ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (gzrewind(file) == -1) /* rewind, then skip to offset */ 421ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 422ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 423ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 424ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* if reading, skip what's in output buffer (one less gzgetc() check) */ 425ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode == GZ_READ) { 426c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? 427c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes (unsigned)offset : state->x.have; 428c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->x.have -= n; 429c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->x.next += n; 430c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->x.pos += n; 431ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis offset -= n; 432ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 433ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 434ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* request skip (if not zero) */ 435ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (offset) { 436ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->seek = 1; 437ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->skip = offset; 438ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 439c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes return state->x.pos + offset; 440ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 441ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 442ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 443ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisz_off_t ZEXPORT gzseek(file, offset, whence) 444ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 445ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis z_off_t offset; 446ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis int whence; 447ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 448ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis z_off64_t ret; 449ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 450ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis ret = gzseek64(file, (z_off64_t)offset, whence); 451ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return ret == (z_off_t)ret ? (z_off_t)ret : -1; 452ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 453ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 454ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 455ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisz_off64_t ZEXPORT gztell64(file) 456ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 457ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 458ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 459ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 460ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* get internal structure and check integrity */ 461ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (file == NULL) 462ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 463ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state = (gz_statep)file; 464ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode != GZ_READ && state->mode != GZ_WRITE) 465ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 466ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 467ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* return position */ 468c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes return state->x.pos + (state->seek ? state->skip : 0); 469ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 470ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 471ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 472ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisz_off_t ZEXPORT gztell(file) 473ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 474ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 475ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis z_off64_t ret; 476ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 477ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis ret = gztell64(file); 478ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return ret == (z_off_t)ret ? (z_off_t)ret : -1; 479ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 480ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 481ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 482ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisz_off64_t ZEXPORT gzoffset64(file) 483ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 484ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 485ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis z_off64_t offset; 486ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 487ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 488ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* get internal structure and check integrity */ 489ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (file == NULL) 490ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 491ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state = (gz_statep)file; 492ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode != GZ_READ && state->mode != GZ_WRITE) 493ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 494ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 495ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* compute and return effective offset in file */ 496ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis offset = LSEEK(state->fd, 0, SEEK_CUR); 497ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (offset == -1) 498ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return -1; 499ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode == GZ_READ) /* reading */ 500ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis offset -= state->strm.avail_in; /* don't count buffered input */ 501ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return offset; 502ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 503ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 504ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 505ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisz_off_t ZEXPORT gzoffset(file) 506ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 507ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 508ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis z_off64_t ret; 509ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 510ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis ret = gzoffset64(file); 511ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return ret == (z_off_t)ret ? (z_off_t)ret : -1; 512ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 513ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 514ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 515ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisint ZEXPORT gzeof(file) 516ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 517ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 518ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 519ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 520ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* get internal structure and check integrity */ 521ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (file == NULL) 522ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return 0; 523ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state = (gz_statep)file; 524ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode != GZ_READ && state->mode != GZ_WRITE) 525ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return 0; 526ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 527ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* return end-of-file state */ 528c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes return state->mode == GZ_READ ? state->past : 0; 529ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 530ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 531ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 532ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisconst char * ZEXPORT gzerror(file, errnum) 533ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 534ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis int *errnum; 535ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 536ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 537ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 538ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* get internal structure and check integrity */ 539ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (file == NULL) 540ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return NULL; 541ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state = (gz_statep)file; 542ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode != GZ_READ && state->mode != GZ_WRITE) 543ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return NULL; 544ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 545ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* return error information */ 546ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (errnum != NULL) 547ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis *errnum = state->err; 548c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes return state->err == Z_MEM_ERROR ? "out of memory" : 549c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes (state->msg == NULL ? "" : state->msg); 550ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 551ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 552ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* -- see zlib.h -- */ 553ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisvoid ZEXPORT gzclearerr(file) 554ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gzFile file; 555ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 556ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 557ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 558ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* get internal structure and check integrity */ 559ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (file == NULL) 560ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return; 561ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state = (gz_statep)file; 562ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->mode != GZ_READ && state->mode != GZ_WRITE) 563ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return; 564ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 565ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* clear error and end-of-file */ 566c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (state->mode == GZ_READ) { 567ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->eof = 0; 568c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->past = 0; 569c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes } 570ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_error(state, Z_OK, NULL); 571ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 572ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 573ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* Create an error message in allocated memory and set state->err and 574ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->msg accordingly. Free any previous error message already there. Do 575ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis not try to free or allocate space if the error is Z_MEM_ERROR (out of 576ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis memory). Simply save the error message as a static string. If there is an 577ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis allocation failure constructing the error message, then convert the error to 578ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis out of memory. */ 579ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisvoid ZLIB_INTERNAL gz_error(state, err, msg) 580ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis gz_statep state; 581ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis int err; 582ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis const char *msg; 583ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 584ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* free previously allocated message and clear */ 585ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->msg != NULL) { 586ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (state->err != Z_MEM_ERROR) 587ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis free(state->msg); 588ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->msg = NULL; 589ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 590ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 591c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ 592c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (err != Z_OK && err != Z_BUF_ERROR) 593c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes state->x.have = 0; 594c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes 595ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* set error code, and if no message, then done */ 596ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->err = err; 597ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis if (msg == NULL) 598ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return; 599ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 600c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes /* for an out of memory error, return literal string when requested */ 601c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if (err == Z_MEM_ERROR) 602ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return; 603ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 604ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis /* construct error message with path */ 605c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == 606c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes NULL) { 607ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis state->err = Z_MEM_ERROR; 608ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return; 609ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } 610c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 61134e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, 61234e7e2ecb1741850190e78f42875480693d3537bdoko@ubuntu.com "%s%s%s", state->path, ": ", msg); 613c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#else 614ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis strcpy(state->msg, state->path); 615ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis strcat(state->msg, ": "); 616ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis strcat(state->msg, msg); 617c20bcde58dc2ed770900ab553ac663f2f1212fc2Christian Heimes#endif 618ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 619ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 620ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#ifndef INT_MAX 621ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis/* portably return maximum value for an int (when limits.h presumed not 622ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis available) -- we need to do this to cover cases where 2's complement not 623ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis used, since C standard permits 1's complement and sign-bit representations, 624ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis otherwise we could just use ((unsigned)-1) >> 1 */ 625ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwisunsigned ZLIB_INTERNAL gz_intmax() 626ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis{ 627ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis unsigned p, q; 628ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis 629ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis p = 1; 630ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis do { 631ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis q = p; 632ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis p <<= 1; 633ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis p++; 634ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis } while (p > q); 635ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis return q >> 1; 636ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis} 637ccbd427d3731aeda2bf553b40d13d2d002984acbMartin v. Löwis#endif 638