Logo Search packages:      
Sourcecode: tardy version File versions  Download package

int tar_input_filter_gunzip::read_header ( tar_header &   )  [virtual]

The read_header method is used to read file information from the input. Returns 0 at end of input.

Reimplemented from tar_input_filter.

Definition at line 195 of file gunzip.cc.

References buf, buffered_data_pos, buffered_data_size, buffered_getc(), buffered_read(), crc, deflated_file_length, deflated_file_pos, tar_input::fatal(), get_long(), inflated_file_length, inflated_file_pos, pass_through, tar_input_filter::read_header(), tar_input_filter::read_header_padding(), stream, z_eof, and zlib_fatal_error().

{
    if (0 == tar_input_filter::read_header(arg))
      return 0;
    pass_through = (arg.type != tar_header::type_normal_gzipped);
    tar_input_filter::read_header_padding();
    if (pass_through)
      return 1;
    arg.type = tar_header::type_normal;

    /*
     * Check for the magic number.
     * If it isn't present, assume transparent mode.
     */
    deflated_file_pos = 0;
    deflated_file_length = arg.size;
    static unsigned char gz_magic[] = { 0x1F, 0x8B };
    unsigned char magic[sizeof(gz_magic)];
    if
    (
      buffered_read(magic, sizeof(magic)) != sizeof(magic)
    ||
      0 != memcmp(magic, gz_magic, sizeof(magic))
    )
      fatal("gunzip: bad magic number (%02X %02X)", magic[0], magic[1]);

    /*
     * Magic number present, now we require the rest of the header
     * to be present and correctly formed.
     */
    int method = buffered_getc();
    if (method != Z_DEFLATED)
      fatal("gunzip: not deflated encoding");
    int flags = buffered_getc();
    if (flags < 0 || (flags & Z_FLAG_RESERVED) != 0)
      fatal("gunzip: unknown flags");

    /* Discard time, xflags and OS code: */
    for (int oslen = 0; oslen < 6; ++oslen)
      if (buffered_getc() < 0)
          fatal("gunzip: short file");

    if (flags & Z_FLAG_EXTRA_FIELD)
    {
      /* low byte of len must be 4 */
      int len = buffered_getc();
      if (len < 0)
          goto bad_extra;
      if (len != 4)
          goto bad_extra;

      /* high byte of len must be zero */
      int c = buffered_getc();
      if (c < 0)
          goto bad_extra;
      if (c != 0)
          goto bad_extra;

      inflated_file_length = get_long();
    }
    else
    {
      bad_extra:
      fatal("gunzip: extra field required");
    }

    if (flags & Z_FLAG_ORIG_NAME)
    {
      /* skip the original file name */
      for (;;)
      {
          int c = buffered_getc();
          if (c < 0)
                  fatal("gunzip: short file");
          if (c == 0)
                  break;
      }
    }
    if (flags & Z_FLAG_COMMENT)
    {
      /* skip the .gz file comment */
      for (;;)
      {
          int c = buffered_getc();
          if (c < 0)
                  fatal("gunzip: short file");
          if (c == 0)
                  break;
      }
    }
    if (flags & Z_FLAG_HEAD_CRC)
    {
      /* skip the header crc */
      for (int crclen = 0; crclen < 2; ++crclen)
          if (buffered_getc() < 0)
                  fatal("gunzip: short file");
    }

    stream.zalloc = (alloc_func)0;
    stream.zfree = (free_func)0;
    stream.opaque = (voidpf)0;
    stream.next_in = Z_NULL;
    stream.avail_in = 0;
    stream.next_out = Z_NULL;
    stream.avail_out = 0;
    if (!buf)
      buf = new Byte[Z_BUFSIZE];
    crc = crc32(0L, Z_NULL, 0);
    inflated_file_pos = 0;
    z_eof = false;
    buffered_data_pos = 0;
    buffered_data_size = 0;

    /*
     * windowBits is passed < 0 to tell that there is no zlib header.
     * Note that in this case inflate *requires* an extra "dummy" byte
     * after the compressed stream in order to complete decompression
     * and return Z_STREAM_END. Here the gzip CRC32 ensures that 4
     * bytes are present after the compressed stream.
     */
    int err = inflateInit2(&stream, -MAX_WBITS);
    if (err < 0)
      zlib_fatal_error(err);

    /*
     * Re-write the header to reflect the decompressed file data.
     */
    arg.size = inflated_file_length;

    /*
     * Report success.
     */
    return 1;
}


Generated by  Doxygen 1.6.0   Back to index