diff options
Diffstat (limited to 'extract/src/zip.c')
-rw-r--r-- | extract/src/zip.c | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/extract/src/zip.c b/extract/src/zip.c index 691b743b..baf7bb1b 100644 --- a/extract/src/zip.c +++ b/extract/src/zip.c @@ -30,7 +30,7 @@ typedef struct uint32_t offset; uint16_t attr_internal; uint32_t attr_external; - + } extract_zip_cd_file_t; struct extract_zip_t @@ -38,14 +38,14 @@ struct extract_zip_t extract_buffer_t* buffer; extract_zip_cd_file_t* cd_files; int cd_files_num; - + /* errno_ is set to non-zero if any operation fails; avoids need to check after every small output operation. */ int errno_; int eof; uint16_t compression_method; int compress_level; - + /* Defaults for various values in zip file headers etc. */ uint16_t mtime; uint16_t mdate; @@ -62,9 +62,9 @@ int extract_zip_open(extract_buffer_t* buffer, extract_zip_t** o_zip) int e = -1; extract_zip_t* zip; extract_alloc_t* alloc = extract_buffer_alloc(buffer); - + if (extract_malloc(alloc, &zip, sizeof(*zip))) goto end; - + zip->cd_files = NULL; zip->cd_files_num = 0; zip->buffer = buffer; @@ -72,10 +72,10 @@ int extract_zip_open(extract_buffer_t* buffer, extract_zip_t** o_zip) zip->eof = 0; zip->compression_method = Z_DEFLATED; zip->compress_level = Z_DEFAULT_COMPRESSION; - + /* We could maybe convert current date/time to the ms-dos format required here, but using zeros doesn't seem to make a difference to Word etc. */ - + { time_t t = time(NULL); struct tm* tm; @@ -107,21 +107,21 @@ int extract_zip_open(extract_buffer_t* buffer, extract_zip_t** o_zip) zip->mdate = 0; } } - + /* These are all copied from command-line zip on unix. */ zip->version_creator = (0x3 << 8) + 30; /* 0x3 is unix, 30 means 3.0. */ zip->version_extract = 10; /* 10 means 1.0. */ zip->general_purpose_bit_flag = 0; zip->file_attr_internal = 0; - + /* We follow command-line zip which uses 0x81a40000 which is octal 0100644:0. (0100644 is S_IFREG (regular file) plus rw-r-r. See stat(2) for details.) */ zip->file_attr_external = (0100644 << 16) + 0; if (extract_strdup(alloc, "Artifex", &zip->archive_comment)) goto end; - + e = 0; - + end: if (e) { if (zip) extract_free(alloc, &zip->archive_comment); @@ -184,11 +184,11 @@ static int s_write_compressed( z_stream zstream = {0}; /* Initialise to keep Coverity quiet. */ if (zip->errno_) return -1; if (zip->eof) return +1; - + zstream.zalloc = s_zalloc; zstream.zfree = s_zfree; zstream.opaque = zip; - + /* We need to write raw deflate data, so we use deflateInit2() with -ve windowBits. The values we use are deflateInit()'s defaults. */ ze = deflateInit2( @@ -206,11 +206,11 @@ static int s_write_compressed( outf("deflateInit2() failed ze=%i", ze); return -1; } - + /* Set zstream to read from specified data. */ zstream.next_in = (void*) data; zstream.avail_in = (unsigned) data_length; - + /* We increment *o_compressed_length gradually so that if we return an error, we still indicate how many butes of compressed data have been written. */ @@ -218,7 +218,7 @@ static int s_write_compressed( { *o_compressed_length = 0; } - + for(;;) { /* todo: write an extract_buffer_cache() function so we can write @@ -329,7 +329,7 @@ int extract_zip_write_file( int e = -1; extract_zip_cd_file_t* cd_file = NULL; extract_alloc_t* alloc = extract_buffer_alloc(zip->buffer); - + if (data_length > INT_MAX) { assert(0); errno = EINVAL; @@ -344,7 +344,7 @@ int extract_zip_write_file( )) goto end; cd_file = &zip->cd_files[zip->cd_files_num]; cd_file->name = NULL; - + cd_file->mtime = zip->mtime; cd_file->mdate = zip->mdate; cd_file->crc_sum = (int32_t) crc32(crc32(0, NULL, 0), data, (int) data_length); @@ -358,7 +358,7 @@ int extract_zip_write_file( cd_file->attr_internal = zip->file_attr_internal; cd_file->attr_external = zip->file_attr_external; if (!cd_file->name) goto end; - + /* Write local file header. If we are using compression, we set bit 3 of General purpose bit flag and write zeros for crc-32, compressed size and uncompressed size; then we write the actual values in data descriptor after @@ -390,14 +390,14 @@ int extract_zip_write_file( s_write_string(zip, cd_file->name); /* File name */ s_write(zip, extra_local, sizeof(extra_local)-1); /* Extra field */ } - + if (zip->compression_method) { /* Write compressed data. */ size_t data_length_compressed; s_write_compressed(zip, data, data_length, &data_length_compressed); cd_file->size_compressed = (int) data_length_compressed; - + /* Write data descriptor. */ s_write_uint32(zip, 0x08074b50); /* Data descriptor signature */ s_write_uint32(zip, cd_file->crc_sum); /* CRC-32 of uncompressed data */ @@ -408,14 +408,14 @@ int extract_zip_write_file( { s_write(zip, data, data_length); } - + if (zip->errno_) e = -1; else if (zip->eof) e = +1; else e = 0; - - + + end: - + if (e) { /* Leave zip->cd_files_num unchanged, so calling extract_zip_close() will write out any earlier files. Free cd_file->name to avoid leak. */ @@ -425,7 +425,7 @@ int extract_zip_write_file( /* cd_files[zip->cd_files_num] is valid. */ zip->cd_files_num += 1; } - + return e; } @@ -443,7 +443,7 @@ int extract_zip_close(extract_zip_t** pzip) alloc = extract_buffer_alloc(zip->buffer); pos = extract_buffer_pos(zip->buffer); len = 0; - + /* Write Central directory file headers, freeing data as we go. */ for (i=0; i<zip->cd_files_num; ++i) { const char extra[] = ""; @@ -472,7 +472,7 @@ int extract_zip_close(extract_zip_t** pzip) extract_free(alloc, &cd_file->name); } extract_free(alloc, &zip->cd_files); - + /* Write End of central directory record. */ s_write_uint32(zip, 0x06054b50); s_write_uint16(zip, 0); /* Number of this disk */ @@ -481,16 +481,16 @@ int extract_zip_close(extract_zip_t** pzip) s_write_uint16(zip, (uint16_t) zip->cd_files_num); /* Total number of central directory records */ s_write_uint32(zip, (int) len); /* Size of central directory (bytes) */ s_write_uint32(zip, (int) pos); /* Offset of start of central directory, relative to start of archive */ - + s_write_uint16(zip, (uint16_t) strlen(zip->archive_comment)); /* Comment length (n) */ s_write_string(zip, zip->archive_comment); extract_free(alloc, &zip->archive_comment); - + if (zip->errno_) e = -1; else if (zip->eof) e = +1; else e = 0; - + extract_free(alloc, pzip); - + return e; } |