Diff for /embedaddon/sudo/zlib/gzread.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 16:23:02 version 1.1.1.2, 2013/07/22 10:46:14
Line 1 Line 1
 /* gzread.c -- zlib functions for reading gzip files  /* gzread.c -- zlib functions for reading gzip files
 * Copyright (C) 2004, 2005, 2010 Mark Adler * Copyright (C) 2004, 2005, 2010, 2011 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h   * For conditions of distribution and use, see copyright notice in zlib.h
  */   */
   
Line 8 Line 8
 /* Local functions */  /* Local functions */
 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));  local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
 local int gz_avail OF((gz_statep));  local int gz_avail OF((gz_statep));
local int gz_next4 OF((gz_statep, unsigned long *));local int gz_look OF((gz_statep));
local int gz_head OF((gz_statep)); 
 local int gz_decomp OF((gz_statep));  local int gz_decomp OF((gz_statep));
local int gz_make OF((gz_statep));local int gz_fetch OF((gz_statep));
 local int gz_skip OF((gz_statep, z_off64_t));  local int gz_skip OF((gz_statep, z_off64_t));
   
 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from  /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
Line 46  local int gz_load(state, buf, len, have) Line 45  local int gz_load(state, buf, len, have)
    error, 0 otherwise.  Note that the eof flag is set when the end of the input     error, 0 otherwise.  Note that the eof flag is set when the end of the input
    file is reached, even though there may be unused data in the buffer.  Once     file is reached, even though there may be unused data in the buffer.  Once
    that data has been used, no more attempts will be made to read the file.     that data has been used, no more attempts will be made to read the file.
   gz_avail() assumes that strm->avail_in == 0. */   If strm->avail_in != 0, then the current data is moved to the beginning of
    the input buffer, and then the remainder of the buffer is loaded with the
    available data from the input file. */
 local int gz_avail(state)  local int gz_avail(state)
     gz_statep state;      gz_statep state;
 {  {
       unsigned got;
     z_streamp strm = &(state->strm);      z_streamp strm = &(state->strm);
   
    if (state->err != Z_OK)    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
         return -1;          return -1;
     if (state->eof == 0) {      if (state->eof == 0) {
        if (gz_load(state, state->in, state->size,        if (strm->avail_in)
                (unsigned *)&(strm->avail_in)) == -1)            memmove(state->in, strm->next_in, strm->avail_in);
         if (gz_load(state, state->in + strm->avail_in,
                     state->size - strm->avail_in, &got) == -1)
             return -1;              return -1;
           strm->avail_in += got;
         strm->next_in = state->in;          strm->next_in = state->in;
     }      }
     return 0;      return 0;
 }  }
   
/* Get next byte from input, or -1 if end or error. *//* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \ 
                (strm->avail_in == 0 ? -1 : \ 
                 (strm->avail_in--, *(strm->next_in)++))) 
 
/* Get a four-byte little-endian integer and return 0 on success and the value 
   in *ret.  Otherwise -1 is returned and *ret is not modified. */ 
local int gz_next4(state, ret) 
    gz_statep state; 
    unsigned long *ret; 
{ 
    int ch; 
    unsigned long val; 
    z_streamp strm = &(state->strm); 
 
    val = NEXT(); 
    val += (unsigned)NEXT() << 8; 
    val += (unsigned long)NEXT() << 16; 
    ch = NEXT(); 
    if (ch == -1) 
        return -1; 
    val += (unsigned long)ch << 24; 
    *ret = val; 
    return 0; 
} 
 
/* Look for gzip header, set up for inflate or copy.  state->have must be zero. 
    If this is the first time in, allocate required memory.  state->how will be     If this is the first time in, allocate required memory.  state->how will be
    left unchanged if there is no more input data available, will be set to COPY     left unchanged if there is no more input data available, will be set to COPY
    if there is no gzip header and direct copying will be performed, or it will     if there is no gzip header and direct copying will be performed, or it will
   be set to GZIP for decompression, and the gzip header will be skipped so   be set to GZIP for decompression.  If direct copying, then leftover input
   that the next available input data is the raw deflate stream.  If direct   data from the input buffer will be copied to the output buffer.  In that
   copying, then leftover input data from the input buffer will be copied to   case, all further file reads will be directly to either the output buffer or
   the output buffer.  In that case, all further file reads will be directly to   a user buffer.  If decompressing, the inflate state will be initialized.
   either the output buffer or a user buffer.  If decompressing, the inflate   gz_look() will return 0 on success or -1 on failure. */
   state and the check value will be initialized.  gz_head() will return 0 onlocal int gz_look(state)
   success or -1 on failure.  Failures may include read errors or gzip header 
   errors.  */ 
local int gz_head(state) 
     gz_statep state;      gz_statep state;
 {  {
     z_streamp strm = &(state->strm);      z_streamp strm = &(state->strm);
     int flags;  
     unsigned len;  
   
     /* allocate read buffers and inflate memory */      /* allocate read buffers and inflate memory */
     if (state->size == 0) {      if (state->size == 0) {
Line 129  local int gz_head(state) Line 103  local int gz_head(state)
         state->strm.opaque = Z_NULL;          state->strm.opaque = Z_NULL;
         state->strm.avail_in = 0;          state->strm.avail_in = 0;
         state->strm.next_in = Z_NULL;          state->strm.next_in = Z_NULL;
        if (inflateInit2(&(state->strm), -15) != Z_OK) {    /* raw inflate */        if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
             free(state->out);              free(state->out);
             free(state->in);              free(state->in);
             state->size = 0;              state->size = 0;
Line 138  local int gz_head(state) Line 112  local int gz_head(state)
         }          }
     }      }
   
    /* get some data in the input buffer */    /* get at least the magic bytes in the input buffer */
    if (strm->avail_in == 0) {    if (strm->avail_in < 2) {
         if (gz_avail(state) == -1)          if (gz_avail(state) == -1)
             return -1;              return -1;
         if (strm->avail_in == 0)          if (strm->avail_in == 0)
             return 0;              return 0;
     }      }
   
    /* look for the gzip magic header bytes 31 and 139 */    /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
    if (strm->next_in[0] == 31) {       a logical dilemma here when considering the case of a partially written
        strm->avail_in--;       gzip file, to wit, if a single 31 byte is written, then we cannot tell
        strm->next_in++;       whether this is a single-byte file, or just a partially written gzip
        if (strm->avail_in == 0 && gz_avail(state) == -1)       file -- for here we assume that if a gzip file is being written, then
            return -1;       the header will be written in a single operation, so that reading a
        if (strm->avail_in && strm->next_in[0] == 139) {       single byte is sufficient indication that it is not a gzip file) */
            /* we have a gzip header, woo hoo! */    if (strm->avail_in > 1 &&
            strm->avail_in--;            strm->next_in[0] == 31 && strm->next_in[1] == 139) {
            strm->next_in++;        inflateReset(strm);
         state->how = GZIP;
         state->direct = 0;
         return 0;
     }
   
            /* skip rest of header */    /* no gzip header -- if we were decoding gzip before, then this is trailing
            if (NEXT() != 8) {      /* compression method */       garbage.  Ignore the trailing garbage and finish. */
                gz_error(state, Z_DATA_ERROR, "unknown compression method");    if (state->direct == 0) {
                return -1;        strm->avail_in = 0;
            }        state->eof = 1;
            flags = NEXT();        state->x.have = 0;
            if (flags & 0xe0) {     /* reserved flag bits */        return 0;
                gz_error(state, Z_DATA_ERROR, "unknown header flags set"); 
                return -1; 
            } 
            NEXT();                 /* modification time */ 
            NEXT(); 
            NEXT(); 
            NEXT(); 
            NEXT();                 /* extra flags */ 
            NEXT();                 /* operating system */ 
            if (flags & 4) {        /* extra field */ 
                len = (unsigned)NEXT(); 
                len += (unsigned)NEXT() << 8; 
                while (len--) 
                    if (NEXT() < 0) 
                        break; 
            } 
            if (flags & 8)          /* file name */ 
                while (NEXT() > 0) 
                    ; 
            if (flags & 16)         /* comment */ 
                while (NEXT() > 0) 
                    ; 
            if (flags & 2) {        /* header crc */ 
                NEXT(); 
                NEXT(); 
            } 
            /* an unexpected end of file is not checked for here -- it will be 
               noticed on the first request for uncompressed data */ 
 
            /* set up for decompression */ 
            inflateReset(strm); 
            strm->adler = crc32(0L, Z_NULL, 0); 
            state->how = GZIP; 
            state->direct = 0; 
            return 0; 
        } 
        else { 
            /* not a gzip file -- save first byte (31) and fall to raw i/o */ 
            state->out[0] = 31; 
            state->have = 1; 
        } 
     }      }
   
    /* doing raw i/o, save start of raw data for seeking, copy any leftover    /* doing raw i/o, copy any leftover input to output -- this assumes that
       input to output -- this assumes that the output buffer is larger than       the output buffer is larger than the input buffer, which also assures
       the input buffer, which also assures space for gzungetc() */       space for gzungetc() */
    state->raw = state->pos;    state->x.next = state->out;
    state->next = state->out; 
     if (strm->avail_in) {      if (strm->avail_in) {
        memcpy(state->next + state->have, strm->next_in, strm->avail_in);        memcpy(state->x.next, strm->next_in, strm->avail_in);
        state->have += strm->avail_in;        state->x.have = strm->avail_in;
         strm->avail_in = 0;          strm->avail_in = 0;
     }      }
     state->how = COPY;      state->how = COPY;
Line 223  local int gz_head(state) Line 159  local int gz_head(state)
 }  }
   
 /* Decompress from input to the provided next_out and avail_out in the state.  /* Decompress from input to the provided next_out and avail_out in the state.
   If the end of the compressed data is reached, then verify the gzip trailer   On return, state->x.have and state->x.next point to the just decompressed
   check value and length (modulo 2^32).  state->have and state->next are set   data.  If the gzip stream completes, state->how is reset to LOOK to look for
   to point to the just decompressed data, and the crc is updated.  If the   the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
   trailer is verified, state->how is reset to LOOK to look for the next gzip   on success, -1 on failure. */
   stream or raw data, once state->have is depleted.  Returns 0 on success, -1 
   on failure.  Failures may include invalid compressed data or a failed gzip 
   trailer verification. */ 
 local int gz_decomp(state)  local int gz_decomp(state)
     gz_statep state;      gz_statep state;
 {  {
    int ret;    int ret = Z_OK;
     unsigned had;      unsigned had;
     unsigned long crc, len;  
     z_streamp strm = &(state->strm);      z_streamp strm = &(state->strm);
   
     /* fill output buffer up to end of deflate stream */      /* fill output buffer up to end of deflate stream */
Line 245  local int gz_decomp(state) Line 177  local int gz_decomp(state)
         if (strm->avail_in == 0 && gz_avail(state) == -1)          if (strm->avail_in == 0 && gz_avail(state) == -1)
             return -1;              return -1;
         if (strm->avail_in == 0) {          if (strm->avail_in == 0) {
            gz_error(state, Z_DATA_ERROR, "unexpected end of file");            gz_error(state, Z_BUF_ERROR, "unexpected end of file");
            return -1;            break;
         }          }
   
         /* decompress and handle errors */          /* decompress and handle errors */
         ret = inflate(strm, Z_NO_FLUSH);          ret = inflate(strm, Z_NO_FLUSH);
         if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {          if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
             gz_error(state, Z_STREAM_ERROR,              gz_error(state, Z_STREAM_ERROR,
                      "internal error: inflate stream corrupt");                     "internal error: inflate stream corrupt");
             return -1;              return -1;
         }          }
         if (ret == Z_MEM_ERROR) {          if (ret == Z_MEM_ERROR) {
Line 262  local int gz_decomp(state) Line 194  local int gz_decomp(state)
         }          }
         if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */          if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
             gz_error(state, Z_DATA_ERROR,              gz_error(state, Z_DATA_ERROR,
                      strm->msg == NULL ? "compressed data error" : strm->msg);                     strm->msg == NULL ? "compressed data error" : strm->msg);
             return -1;              return -1;
         }          }
     } while (strm->avail_out && ret != Z_STREAM_END);      } while (strm->avail_out && ret != Z_STREAM_END);
   
    /* update available output and crc check value */    /* update available output */
    state->have = had - strm->avail_out;    state->x.have = had - strm->avail_out;
    state->next = strm->next_out - state->have;    state->x.next = strm->next_out - state->x.have;
    strm->adler = crc32(strm->adler, state->next, state->have); 
   
    /* check gzip trailer if at end of deflate stream */    /* if the gzip stream completed successfully, look for another */
    if (ret == Z_STREAM_END) {    if (ret == Z_STREAM_END)
        if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {        state->how = LOOK;
            gz_error(state, Z_DATA_ERROR, "unexpected end of file"); 
            return -1; 
        } 
        if (crc != strm->adler) { 
            gz_error(state, Z_DATA_ERROR, "incorrect data check"); 
            return -1; 
        } 
        if (len != (strm->total_out & 0xffffffffL)) { 
            gz_error(state, Z_DATA_ERROR, "incorrect length check"); 
            return -1; 
        } 
        state->how = LOOK;      /* ready for next stream, once have is 0 (leave 
                                   state->direct unchanged to remember how) */ 
    } 
   
     /* good decompression */      /* good decompression */
     return 0;      return 0;
 }  }
   
/* Make data and put in the output buffer.  Assumes that state->have == 0./* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
    Data is either copied from the input file or decompressed from the input     Data is either copied from the input file or decompressed from the input
    file depending on state->how.  If state->how is LOOK, then a gzip header is     file depending on state->how.  If state->how is LOOK, then a gzip header is
   looked for (and skipped if found) to determine wither to copy or decompress.   looked for to determine whether to copy or decompress.  Returns -1 on error,
   Returns -1 on error, otherwise 0.  gz_make() will leave state->have as COPY   otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
   or GZIP unless the end of the input file has been reached and all data has   end of the input file has been reached and all data has been processed.  */
   been processed.  */local int gz_fetch(state)
local int gz_make(state) 
     gz_statep state;      gz_statep state;
 {  {
     z_streamp strm = &(state->strm);      z_streamp strm = &(state->strm);
   
    if (state->how == LOOK) {           /* look for gzip header */    do {
        if (gz_head(state) == -1)        switch(state->how) {
            return -1;        case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
        if (state->have)                /* got some data from gz_head() */            if (gz_look(state) == -1)
                 return -1;
             if (state->how == LOOK)
                 return 0;
             break;
         case COPY:      /* -> COPY */
             if (gz_load(state, state->out, state->size << 1, &(state->x.have))
                     == -1)
                 return -1;
             state->x.next = state->out;
             return 0;              return 0;
    }        case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
    if (state->how == COPY) {           /* straight copy */            strm->avail_out = state->size << 1;
        if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)            strm->next_out = state->out;
            return -1;            if (gz_decomp(state) == -1)
        state->next = state->out;                return -1;
    }        }
    else if (state->how == GZIP) {      /* decompress */    } while (state->x.have == 0 && (!state->eof || strm->avail_in));
        strm->avail_out = state->size << 1; 
        strm->next_out = state->out; 
        if (gz_decomp(state) == -1) 
            return -1; 
    } 
     return 0;      return 0;
 }  }
   
Line 336  local int gz_skip(state, len) Line 256  local int gz_skip(state, len)
     /* skip over len bytes or reach end-of-file, whichever comes first */      /* skip over len bytes or reach end-of-file, whichever comes first */
     while (len)      while (len)
         /* skip over whatever is in output buffer */          /* skip over whatever is in output buffer */
        if (state->have) {        if (state->x.have) {
            n = GT_OFF(state->have) || (z_off64_t)state->have > len ?            n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
                (unsigned)len : state->have;                (unsigned)len : state->x.have;
            state->have -= n;            state->x.have -= n;
            state->next += n;            state->x.next += n;
            state->pos += n;            state->x.pos += n;
             len -= n;              len -= n;
         }          }
   
Line 352  local int gz_skip(state, len) Line 272  local int gz_skip(state, len)
         /* need more data to skip -- load up output buffer */          /* need more data to skip -- load up output buffer */
         else {          else {
             /* get more output, looking for header if required */              /* get more output, looking for header if required */
            if (gz_make(state) == -1)            if (gz_fetch(state) == -1)
                 return -1;                  return -1;
         }          }
     return 0;      return 0;
Line 374  int ZEXPORT gzread(file, buf, len) Line 294  int ZEXPORT gzread(file, buf, len)
     state = (gz_statep)file;      state = (gz_statep)file;
     strm = &(state->strm);      strm = &(state->strm);
   
    /* check that we're reading and that there's no error */    /* check that we're reading and that there's no (serious) error */
    if (state->mode != GZ_READ || state->err != Z_OK)    if (state->mode != GZ_READ ||
             (state->err != Z_OK && state->err != Z_BUF_ERROR))
         return -1;          return -1;
   
     /* since an int is returned, make sure len fits in one, otherwise return      /* since an int is returned, make sure len fits in one, otherwise return
        with an error (this avoids the flaw in the interface) */         with an error (this avoids the flaw in the interface) */
     if ((int)len < 0) {      if ((int)len < 0) {
        gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");        gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
         return -1;          return -1;
     }      }
   
Line 400  int ZEXPORT gzread(file, buf, len) Line 321  int ZEXPORT gzread(file, buf, len)
     got = 0;      got = 0;
     do {      do {
         /* first just try copying data from the output buffer */          /* first just try copying data from the output buffer */
        if (state->have) {        if (state->x.have) {
            n = state->have > len ? len : state->have;            n = state->x.have > len ? len : state->x.have;
            memcpy(buf, state->next, n);            memcpy(buf, state->x.next, n);
            state->next += n;            state->x.next += n;
            state->have -= n;            state->x.have -= n;
         }          }
   
         /* output buffer empty -- return if we're at the end of the input */          /* output buffer empty -- return if we're at the end of the input */
        else if (state->eof && strm->avail_in == 0)        else if (state->eof && strm->avail_in == 0) {
             state->past = 1;        /* tried to read past end */
             break;              break;
           }
   
         /* need output data -- for small len or new stream load up our output          /* need output data -- for small len or new stream load up our output
            buffer */             buffer */
         else if (state->how == LOOK || len < (state->size << 1)) {          else if (state->how == LOOK || len < (state->size << 1)) {
             /* get more output, looking for header if required */              /* get more output, looking for header if required */
            if (gz_make(state) == -1)            if (gz_fetch(state) == -1)
                 return -1;                  return -1;
             continue;       /* no progress yet -- go back to memcpy() above */              continue;       /* no progress yet -- go back to memcpy() above */
             /* the copy above assures that we will leave with space in the              /* the copy above assures that we will leave with space in the
Line 434  int ZEXPORT gzread(file, buf, len) Line 357  int ZEXPORT gzread(file, buf, len)
             strm->next_out = buf;              strm->next_out = buf;
             if (gz_decomp(state) == -1)              if (gz_decomp(state) == -1)
                 return -1;                  return -1;
            n = state->have;            n = state->x.have;
            state->have = 0;            state->x.have = 0;
         }          }
   
         /* update progress */          /* update progress */
         len -= n;          len -= n;
         buf = (char *)buf + n;          buf = (char *)buf + n;
         got += n;          got += n;
        state->pos += n;        state->x.pos += n;
     } while (len);      } while (len);
   
     /* return number of bytes read into user buffer (will fit in int) */      /* return number of bytes read into user buffer (will fit in int) */
Line 450  int ZEXPORT gzread(file, buf, len) Line 373  int ZEXPORT gzread(file, buf, len)
 }  }
   
 /* -- see zlib.h -- */  /* -- see zlib.h -- */
int ZEXPORT gzgetc(file)int ZEXPORT gzgetc_(file)
     gzFile file;      gzFile file;
 {  {
     int ret;      int ret;
Line 462  int ZEXPORT gzgetc(file) Line 385  int ZEXPORT gzgetc(file)
         return -1;          return -1;
     state = (gz_statep)file;      state = (gz_statep)file;
   
    /* check that we're reading and that there's no error */    /* check that we're reading and that there's no (serious) error */
    if (state->mode != GZ_READ || state->err != Z_OK)    if (state->mode != GZ_READ ||
         (state->err != Z_OK && state->err != Z_BUF_ERROR))
         return -1;          return -1;
   
     /* try output buffer (no need to check for skip request) */      /* try output buffer (no need to check for skip request) */
    if (state->have) {    if (state->x.have) {
        state->have--;        state->x.have--;
        state->pos++;        state->x.pos++;
        return *(state->next)++;        return *(state->x.next)++;
     }      }
   
     /* nothing there -- try gzread() */      /* nothing there -- try gzread() */
Line 478  int ZEXPORT gzgetc(file) Line 402  int ZEXPORT gzgetc(file)
     return ret < 1 ? -1 : buf[0];      return ret < 1 ? -1 : buf[0];
 }  }
   
   #undef gzgetc
   int ZEXPORT gzgetc(file)
   gzFile file;
   {
       return gzgetc_(file);
   }    
   
 /* -- see zlib.h -- */  /* -- see zlib.h -- */
 int ZEXPORT gzungetc(c, file)  int ZEXPORT gzungetc(c, file)
     int c;      int c;
Line 490  int ZEXPORT gzungetc(c, file) Line 421  int ZEXPORT gzungetc(c, file)
         return -1;          return -1;
     state = (gz_statep)file;      state = (gz_statep)file;
   
    /* check that we're reading and that there's no error */    /* check that we're reading and that there's no (serious) error */
    if (state->mode != GZ_READ || state->err != Z_OK)    if (state->mode != GZ_READ ||
         (state->err != Z_OK && state->err != Z_BUF_ERROR))
         return -1;          return -1;
   
     /* process a skip request */      /* process a skip request */
Line 506  int ZEXPORT gzungetc(c, file) Line 438  int ZEXPORT gzungetc(c, file)
         return -1;          return -1;
   
     /* if output buffer empty, put byte at end (allows more pushing) */      /* if output buffer empty, put byte at end (allows more pushing) */
    if (state->have == 0) {    if (state->x.have == 0) {
        state->have = 1;        state->x.have = 1;
        state->next = state->out + (state->size << 1) - 1;        state->x.next = state->out + (state->size << 1) - 1;
        state->next[0] = c;        state->x.next[0] = c;
        state->pos--;        state->x.pos--;
         state->past = 0;
         return c;          return c;
     }      }
   
     /* if no room, give up (must have already done a gzungetc()) */      /* if no room, give up (must have already done a gzungetc()) */
    if (state->have == (state->size << 1)) {    if (state->x.have == (state->size << 1)) {
        gz_error(state, Z_BUF_ERROR, "out of room to push characters");        gz_error(state, Z_DATA_ERROR, "out of room to push characters");
         return -1;          return -1;
     }      }
   
     /* slide output data if needed and insert byte before existing data */      /* slide output data if needed and insert byte before existing data */
    if (state->next == state->out) {    if (state->x.next == state->out) {
        unsigned char *src = state->out + state->have;        unsigned char *src = state->out + state->x.have;
         unsigned char *dest = state->out + (state->size << 1);          unsigned char *dest = state->out + (state->size << 1);
         while (src > state->out)          while (src > state->out)
             *--dest = *--src;              *--dest = *--src;
        state->next = dest;        state->x.next = dest;
     }      }
    state->have++;    state->x.have++;
    state->next--;    state->x.next--;
    state->next[0] = c;    state->x.next[0] = c;
    state->pos--;    state->x.pos--;
     state->past = 0;
     return c;      return c;
 }  }
   
Line 551  char * ZEXPORT gzgets(file, buf, len) Line 485  char * ZEXPORT gzgets(file, buf, len)
         return NULL;          return NULL;
     state = (gz_statep)file;      state = (gz_statep)file;
   
    /* check that we're reading and that there's no error */    /* check that we're reading and that there's no (serious) error */
    if (state->mode != GZ_READ || state->err != Z_OK)    if (state->mode != GZ_READ ||
         (state->err != Z_OK && state->err != Z_BUF_ERROR))
         return NULL;          return NULL;
   
     /* process a skip request */      /* process a skip request */
Line 569  char * ZEXPORT gzgets(file, buf, len) Line 504  char * ZEXPORT gzgets(file, buf, len)
     left = (unsigned)len - 1;      left = (unsigned)len - 1;
     if (left) do {      if (left) do {
         /* assure that something is in the output buffer */          /* assure that something is in the output buffer */
        if (state->have == 0) {        if (state->x.have == 0 && gz_fetch(state) == -1)
            if (gz_make(state) == -1)            return NULL;                /* error */
                return NULL;            /* error */        if (state->x.have == 0) {       /* end of file */
            if (state->have == 0) {     /* end of file */            state->past = 1;            /* read past end */
                if (buf == str)         /* got bupkus */            break;                      /* return what we have */
                    return NULL; 
                break;                  /* got something -- return it */ 
            } 
         }          }
   
         /* look for end-of-line in current output buffer */          /* look for end-of-line in current output buffer */
        n = state->have > left ? left : state->have;        n = state->x.have > left ? left : state->x.have;
        eol = memchr(state->next, '\n', n);        eol = memchr(state->x.next, '\n', n);
         if (eol != NULL)          if (eol != NULL)
            n = (unsigned)(eol - state->next) + 1;            n = (unsigned)(eol - state->x.next) + 1;
   
         /* copy through end-of-line, or remainder if not found */          /* copy through end-of-line, or remainder if not found */
        memcpy(buf, state->next, n);        memcpy(buf, state->x.next, n);
        state->have -= n;        state->x.have -= n;
        state->next += n;        state->x.next += n;
        state->pos += n;        state->x.pos += n;
         left -= n;          left -= n;
         buf += n;          buf += n;
     } while (left && eol == NULL);      } while (left && eol == NULL);
   
    /* found end-of-line or out of space -- terminate string and return it */    /* return terminated string, or if nothing, end of file */
     if (buf == str)
         return NULL;
     buf[0] = 0;      buf[0] = 0;
     return str;      return str;
 }  }
Line 610  int ZEXPORT gzdirect(file) Line 544  int ZEXPORT gzdirect(file)
         return 0;          return 0;
     state = (gz_statep)file;      state = (gz_statep)file;
   
     /* check that we're reading */  
     if (state->mode != GZ_READ)  
         return 0;  
   
     /* if the state is not known, but we can find out, then do so (this is      /* if the state is not known, but we can find out, then do so (this is
        mainly for right after a gzopen() or gzdopen()) */         mainly for right after a gzopen() or gzdopen()) */
    if (state->how == LOOK && state->have == 0)    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
        (void)gz_head(state);        (void)gz_look(state);
   
    /* return 1 if reading direct, 0 if decompressing a gzip stream */    /* return 1 if transparent, 0 if processing a gzip stream */
     return state->direct;      return state->direct;
 }  }
   
Line 627  int ZEXPORT gzdirect(file) Line 557  int ZEXPORT gzdirect(file)
 int ZEXPORT gzclose_r(file)  int ZEXPORT gzclose_r(file)
     gzFile file;      gzFile file;
 {  {
    int ret;    int ret, err;
     gz_statep state;      gz_statep state;
   
     /* get internal structure */      /* get internal structure */
Line 645  int ZEXPORT gzclose_r(file) Line 575  int ZEXPORT gzclose_r(file)
         free(state->out);          free(state->out);
         free(state->in);          free(state->in);
     }      }
       err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
     gz_error(state, Z_OK, NULL);      gz_error(state, Z_OK, NULL);
     free(state->path);      free(state->path);
     ret = close(state->fd);      ret = close(state->fd);
     free(state);      free(state);
    return ret ? Z_ERRNO : Z_OK;    return ret ? Z_ERRNO : err;
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>