mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
initial import
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@2 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
2cadbd5e56
commit
cc68a136aa
341 changed files with 180839 additions and 0 deletions
623
unzip/unzip.c
Normal file
623
unzip/unzip.c
Normal file
|
@ -0,0 +1,623 @@
|
|||
#include "unzip.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __SYMBIAN32__
|
||||
#include <ezlib.h>
|
||||
#else
|
||||
#include "zlib/zlib.h"
|
||||
#endif
|
||||
|
||||
/* public globals */
|
||||
//int gUnzipQuiet = 0; /* flag controls error messages */
|
||||
|
||||
#define ERROR_CORRUPT "The zipfile seems to be corrupt, please check it"
|
||||
#define ERROR_FILESYSTEM "Your filesystem seems to be corrupt, please check it"
|
||||
#define ERROR_UNSUPPORTED "The format of this zipfile is not supported, please recompress it"
|
||||
|
||||
#define INFLATE_INPUT_BUFFER_MAX 16384
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
|
||||
// notaz
|
||||
#ifdef __DEBUG_PRINT
|
||||
void dprintf(char *format, ...);
|
||||
#define logerror dprintf
|
||||
void errormsg(const char* extmsg, const char* usermsg, const char* zipname)
|
||||
{
|
||||
dprintf("Error in zipfile %s: %s", zipname, extmsg);
|
||||
}
|
||||
#else
|
||||
#define logerror(x...)
|
||||
#define errormsg(x...)
|
||||
#endif
|
||||
|
||||
/* Print a error message */
|
||||
//void errormsg(const char* extmsg, const char* usermsg, const char* zipname) {
|
||||
/* Output to the user with no internal detail */
|
||||
// if (!gUnzipQuiet)
|
||||
// printf("Error in zipfile %s\n%s\n", zipname, usermsg);
|
||||
/* Output to log file with all informations */
|
||||
// logerror("Error in zipfile %s: %s\n", zipname, extmsg);
|
||||
// printf("Error in zipfile %s: %s\n", zipname, extmsg);
|
||||
//}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Unzip support
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* Use these to avoid structure padding and byte-ordering problems */
|
||||
static UINT16 read_word (char *buf) {
|
||||
unsigned char *ubuf = (unsigned char *) buf;
|
||||
|
||||
return ((UINT16)ubuf[1] << 8) | (UINT16)ubuf[0];
|
||||
}
|
||||
|
||||
/* Use these to avoid structure padding and byte-ordering problems */
|
||||
static UINT32 read_dword (char *buf) {
|
||||
unsigned char *ubuf = (unsigned char *) buf;
|
||||
|
||||
return ((UINT32)ubuf[3] << 24) | ((UINT32)ubuf[2] << 16) | ((UINT32)ubuf[1] << 8) | (UINT32)ubuf[0];
|
||||
}
|
||||
|
||||
/* Locate end-of-central-dir sig in buffer and return offset
|
||||
out:
|
||||
*offset offset of cent dir start in buffer
|
||||
return:
|
||||
==0 not found
|
||||
!=0 found, *offset valid
|
||||
*/
|
||||
static int ecd_find_sig (char *buffer, int buflen, int *offset)
|
||||
{
|
||||
static char ecdsig[] = { 'P', 'K', 0x05, 0x06 };
|
||||
int i;
|
||||
for (i=buflen-22; i>=0; i--) {
|
||||
if (memcmp(buffer+i, ecdsig, 4) == 0) {
|
||||
*offset = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read ecd data in zip structure
|
||||
in:
|
||||
zip->fp, zip->length zip file
|
||||
out:
|
||||
zip->ecd, zip->ecd_length ecd data
|
||||
*/
|
||||
static int ecd_read(ZIP* zip) {
|
||||
char* buf;
|
||||
int buf_length = 1024; /* initial buffer length */
|
||||
|
||||
while (1) {
|
||||
int offset;
|
||||
|
||||
if (buf_length > zip->length)
|
||||
buf_length = zip->length;
|
||||
|
||||
if (fseek(zip->fp, zip->length - buf_length, SEEK_SET) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allocate buffer */
|
||||
buf = (char*)malloc( buf_length );
|
||||
if (!buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread( buf, buf_length, 1, zip->fp ) != 1) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ecd_find_sig(buf, buf_length, &offset)) {
|
||||
zip->ecd_length = buf_length - offset;
|
||||
|
||||
zip->ecd = (char*)malloc( zip->ecd_length );
|
||||
if (!zip->ecd) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(zip->ecd, buf + offset, zip->ecd_length);
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
if (buf_length < zip->length) {
|
||||
/* double buffer */
|
||||
buf_length = 2*buf_length;
|
||||
|
||||
logerror("Retry reading of zip ecd for %d bytes\n",buf_length);
|
||||
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* offsets in end of central directory structure */
|
||||
#define ZIPESIG 0x00
|
||||
#define ZIPEDSK 0x04
|
||||
#define ZIPECEN 0x06
|
||||
#define ZIPENUM 0x08
|
||||
#define ZIPECENN 0x0a
|
||||
#define ZIPECSZ 0x0c
|
||||
#define ZIPEOFST 0x10
|
||||
#define ZIPECOML 0x14
|
||||
#define ZIPECOM 0x16
|
||||
|
||||
/* offsets in central directory entry structure */
|
||||
#define ZIPCENSIG 0x0
|
||||
#define ZIPCVER 0x4
|
||||
#define ZIPCOS 0x5
|
||||
#define ZIPCVXT 0x6
|
||||
#define ZIPCEXOS 0x7
|
||||
#define ZIPCFLG 0x8
|
||||
#define ZIPCMTHD 0xa
|
||||
#define ZIPCTIM 0xc
|
||||
#define ZIPCDAT 0xe
|
||||
#define ZIPCCRC 0x10
|
||||
#define ZIPCSIZ 0x14
|
||||
#define ZIPCUNC 0x18
|
||||
#define ZIPCFNL 0x1c
|
||||
#define ZIPCXTL 0x1e
|
||||
#define ZIPCCML 0x20
|
||||
#define ZIPDSK 0x22
|
||||
#define ZIPINT 0x24
|
||||
#define ZIPEXT 0x26
|
||||
#define ZIPOFST 0x2a
|
||||
#define ZIPCFN 0x2e
|
||||
|
||||
/* offsets in local file header structure */
|
||||
#define ZIPLOCSIG 0x00
|
||||
#define ZIPVER 0x04
|
||||
#define ZIPGENFLG 0x06
|
||||
#define ZIPMTHD 0x08
|
||||
#define ZIPTIME 0x0a
|
||||
#define ZIPDATE 0x0c
|
||||
#define ZIPCRC 0x0e
|
||||
#define ZIPSIZE 0x12
|
||||
#define ZIPUNCMP 0x16
|
||||
#define ZIPFNLN 0x1a
|
||||
#define ZIPXTRALN 0x1c
|
||||
#define ZIPNAME 0x1e
|
||||
|
||||
/* Opens a zip stream for reading
|
||||
return:
|
||||
!=0 success, zip stream
|
||||
==0 error
|
||||
*/
|
||||
ZIP* openzip(const char* zipfile) {
|
||||
/* allocate */
|
||||
ZIP* zip = (ZIP*)malloc( sizeof(ZIP) );
|
||||
if (!zip) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* open */
|
||||
zip->fp = fopen(zipfile, "rb");
|
||||
if (!zip->fp) {
|
||||
errormsg ("Opening for reading", ERROR_FILESYSTEM, zipfile);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* go to end */
|
||||
if (fseek(zip->fp, 0L, SEEK_END) != 0) {
|
||||
errormsg ("Seeking to end", ERROR_FILESYSTEM, zipfile);
|
||||
fclose(zip->fp);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get length */
|
||||
zip->length = ftell(zip->fp);
|
||||
if (zip->length < 0) {
|
||||
errormsg ("Get file size", ERROR_FILESYSTEM, zipfile);
|
||||
fclose(zip->fp);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
if (zip->length == 0) {
|
||||
errormsg ("Empty file", ERROR_CORRUPT, zipfile);
|
||||
fclose(zip->fp);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read ecd data */
|
||||
if (ecd_read(zip)!=0) {
|
||||
errormsg ("Reading ECD (end of central directory)", ERROR_CORRUPT, zipfile);
|
||||
fclose(zip->fp);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* compile ecd info */
|
||||
zip->end_of_cent_dir_sig = read_dword (zip->ecd+ZIPESIG);
|
||||
zip->number_of_this_disk = read_word (zip->ecd+ZIPEDSK);
|
||||
zip->number_of_disk_start_cent_dir = read_word (zip->ecd+ZIPECEN);
|
||||
zip->total_entries_cent_dir_this_disk = read_word (zip->ecd+ZIPENUM);
|
||||
zip->total_entries_cent_dir = read_word (zip->ecd+ZIPECENN);
|
||||
zip->size_of_cent_dir = read_dword (zip->ecd+ZIPECSZ);
|
||||
zip->offset_to_start_of_cent_dir = read_dword (zip->ecd+ZIPEOFST);
|
||||
zip->zipfile_comment_length = read_word (zip->ecd+ZIPECOML);
|
||||
zip->zipfile_comment = zip->ecd+ZIPECOM;
|
||||
|
||||
/* verify that we can work with this zipfile (no disk spanning allowed) */
|
||||
if ((zip->number_of_this_disk != zip->number_of_disk_start_cent_dir) ||
|
||||
(zip->total_entries_cent_dir_this_disk != zip->total_entries_cent_dir) ||
|
||||
(zip->total_entries_cent_dir < 1)) {
|
||||
errormsg("Cannot span disks", ERROR_UNSUPPORTED, zipfile);
|
||||
free(zip->ecd);
|
||||
fclose(zip->fp);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fseek(zip->fp, zip->offset_to_start_of_cent_dir, SEEK_SET)!=0) {
|
||||
errormsg ("Seeking to central directory", ERROR_CORRUPT, zipfile);
|
||||
free(zip->ecd);
|
||||
fclose(zip->fp);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read from start of central directory */
|
||||
zip->cd = (char*)malloc( zip->size_of_cent_dir );
|
||||
if (!zip->cd) {
|
||||
free(zip->ecd);
|
||||
fclose(zip->fp);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fread(zip->cd, zip->size_of_cent_dir, 1, zip->fp)!=1) {
|
||||
errormsg ("Reading central directory", ERROR_CORRUPT, zipfile);
|
||||
free(zip->cd);
|
||||
free(zip->ecd);
|
||||
fclose(zip->fp);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reset ent */
|
||||
zip->ent.name = 0;
|
||||
|
||||
/* rewind */
|
||||
zip->cd_pos = 0;
|
||||
|
||||
/* file name */
|
||||
zip->zip = (char*)malloc(strlen(zipfile)+1);
|
||||
if (!zip->zip) {
|
||||
free(zip->cd);
|
||||
free(zip->ecd);
|
||||
fclose(zip->fp);
|
||||
free(zip);
|
||||
return 0;
|
||||
}
|
||||
strcpy(zip->zip, zipfile);
|
||||
|
||||
return zip;
|
||||
}
|
||||
|
||||
/* Reads the current entry from a zip stream
|
||||
in:
|
||||
zip opened zip
|
||||
return:
|
||||
!=0 success
|
||||
==0 error
|
||||
*/
|
||||
struct zipent* readzip(ZIP* zip) {
|
||||
|
||||
/* end of directory */
|
||||
if (zip->cd_pos >= zip->size_of_cent_dir)
|
||||
return 0;
|
||||
|
||||
/* compile zipent info */
|
||||
zip->ent.cent_file_header_sig = read_dword (zip->cd+zip->cd_pos+ZIPCENSIG);
|
||||
zip->ent.version_made_by = *(zip->cd+zip->cd_pos+ZIPCVER);
|
||||
zip->ent.host_os = *(zip->cd+zip->cd_pos+ZIPCOS);
|
||||
zip->ent.version_needed_to_extract = *(zip->cd+zip->cd_pos+ZIPCVXT);
|
||||
zip->ent.os_needed_to_extract = *(zip->cd+zip->cd_pos+ZIPCEXOS);
|
||||
zip->ent.general_purpose_bit_flag = read_word (zip->cd+zip->cd_pos+ZIPCFLG);
|
||||
zip->ent.compression_method = read_word (zip->cd+zip->cd_pos+ZIPCMTHD);
|
||||
zip->ent.last_mod_file_time = read_word (zip->cd+zip->cd_pos+ZIPCTIM);
|
||||
zip->ent.last_mod_file_date = read_word (zip->cd+zip->cd_pos+ZIPCDAT);
|
||||
zip->ent.crc32 = read_dword (zip->cd+zip->cd_pos+ZIPCCRC);
|
||||
zip->ent.compressed_size = read_dword (zip->cd+zip->cd_pos+ZIPCSIZ);
|
||||
zip->ent.uncompressed_size = read_dword (zip->cd+zip->cd_pos+ZIPCUNC);
|
||||
zip->ent.filename_length = read_word (zip->cd+zip->cd_pos+ZIPCFNL);
|
||||
zip->ent.extra_field_length = read_word (zip->cd+zip->cd_pos+ZIPCXTL);
|
||||
zip->ent.file_comment_length = read_word (zip->cd+zip->cd_pos+ZIPCCML);
|
||||
zip->ent.disk_number_start = read_word (zip->cd+zip->cd_pos+ZIPDSK);
|
||||
zip->ent.internal_file_attrib = read_word (zip->cd+zip->cd_pos+ZIPINT);
|
||||
zip->ent.external_file_attrib = read_dword (zip->cd+zip->cd_pos+ZIPEXT);
|
||||
zip->ent.offset_lcl_hdr_frm_frst_disk = read_dword (zip->cd+zip->cd_pos+ZIPOFST);
|
||||
|
||||
/* check to see if filename length is illegally long (past the size of this directory
|
||||
entry) */
|
||||
if (zip->cd_pos + ZIPCFN + zip->ent.filename_length > zip->size_of_cent_dir)
|
||||
{
|
||||
errormsg("Invalid filename length in directory", ERROR_CORRUPT,zip->zip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy filename */
|
||||
free(zip->ent.name);
|
||||
zip->ent.name = (char*)malloc(zip->ent.filename_length + 1);
|
||||
memcpy(zip->ent.name, zip->cd+zip->cd_pos+ZIPCFN, zip->ent.filename_length);
|
||||
zip->ent.name[zip->ent.filename_length] = 0;
|
||||
|
||||
/* skip to next entry in central dir */
|
||||
zip->cd_pos += ZIPCFN + zip->ent.filename_length + zip->ent.extra_field_length + zip->ent.file_comment_length;
|
||||
|
||||
return &zip->ent;
|
||||
}
|
||||
|
||||
/* Closes a zip stream */
|
||||
void closezip(ZIP* zip) {
|
||||
/* release all */
|
||||
free(zip->ent.name);
|
||||
free(zip->cd);
|
||||
free(zip->ecd);
|
||||
/* only if not suspended */
|
||||
if (zip->fp)
|
||||
fclose(zip->fp);
|
||||
free(zip->zip);
|
||||
free(zip);
|
||||
}
|
||||
|
||||
/* Suspend access to a zip file (release file handler)
|
||||
in:
|
||||
zip opened zip
|
||||
note:
|
||||
A suspended zip is automatically reopened at first call of
|
||||
readuncompressd() or readcompressed() functions
|
||||
*/
|
||||
void suspendzip(ZIP* zip) {
|
||||
if (zip->fp) {
|
||||
fclose(zip->fp);
|
||||
zip->fp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Revive a suspended zip file (reopen file handler)
|
||||
in:
|
||||
zip suspended zip
|
||||
return:
|
||||
zip success
|
||||
==0 error (zip must be closed with closezip)
|
||||
*/
|
||||
static ZIP* revivezip(ZIP* zip) {
|
||||
if (!zip->fp) {
|
||||
zip->fp = fopen(zip->zip, "rb");
|
||||
if (!zip->fp) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return zip;
|
||||
|
||||
}
|
||||
|
||||
/* Reset a zip stream to the first entry
|
||||
in:
|
||||
zip opened zip
|
||||
note:
|
||||
ZIP file must be opened and not suspended
|
||||
*/
|
||||
void rewindzip(ZIP* zip) {
|
||||
zip->cd_pos = 0;
|
||||
}
|
||||
|
||||
/* Seek zip->fp to compressed data
|
||||
return:
|
||||
==0 success
|
||||
<0 error
|
||||
*/
|
||||
int seekcompresszip(ZIP* zip, struct zipent* ent) {
|
||||
char buf[ZIPNAME];
|
||||
long offset;
|
||||
|
||||
if (!zip->fp) {
|
||||
if (!revivezip(zip))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fseek(zip->fp, ent->offset_lcl_hdr_frm_frst_disk, SEEK_SET)!=0) {
|
||||
errormsg ("Seeking to header", ERROR_CORRUPT, zip->zip);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(buf, ZIPNAME, 1, zip->fp)!=1) {
|
||||
errormsg ("Reading header", ERROR_CORRUPT, zip->zip);
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
UINT16 filename_length = read_word (buf+ZIPFNLN);
|
||||
UINT16 extra_field_length = read_word (buf+ZIPXTRALN);
|
||||
|
||||
/* calculate offset to data and fseek() there */
|
||||
offset = ent->offset_lcl_hdr_frm_frst_disk + ZIPNAME + filename_length + extra_field_length;
|
||||
|
||||
if (fseek(zip->fp, offset, SEEK_SET) != 0) {
|
||||
errormsg ("Seeking to compressed data", ERROR_CORRUPT, zip->zip);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Inflate a file
|
||||
in:
|
||||
in_file stream to inflate
|
||||
in_size size of the compressed data to read
|
||||
out_size size of decompressed data
|
||||
out:
|
||||
out_data buffer for decompressed data
|
||||
return:
|
||||
==0 ok
|
||||
|
||||
990525 rewritten for use with zlib MLR
|
||||
*/
|
||||
static int inflate_file(FILE* in_file, unsigned in_size, unsigned char* out_data, unsigned out_size)
|
||||
{
|
||||
int err;
|
||||
unsigned char* in_buffer;
|
||||
z_stream d_stream; /* decompression stream */
|
||||
|
||||
d_stream.zalloc = 0;
|
||||
d_stream.zfree = 0;
|
||||
d_stream.opaque = 0;
|
||||
|
||||
d_stream.next_in = 0;
|
||||
d_stream.avail_in = 0;
|
||||
d_stream.next_out = out_data;
|
||||
d_stream.avail_out = out_size;
|
||||
|
||||
err = inflateInit2(&d_stream, -MAX_WBITS);
|
||||
/* 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.
|
||||
*/
|
||||
if (err != Z_OK)
|
||||
{
|
||||
logerror("inflateInit error: %d\n", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
in_buffer = (unsigned char*)malloc(INFLATE_INPUT_BUFFER_MAX+1);
|
||||
if (!in_buffer)
|
||||
return -1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (in_size <= 0)
|
||||
{
|
||||
logerror("inflate error: compressed size too small\n");
|
||||
free (in_buffer);
|
||||
return -1;
|
||||
}
|
||||
d_stream.next_in = in_buffer;
|
||||
d_stream.avail_in = fread (in_buffer, 1, MIN(in_size, INFLATE_INPUT_BUFFER_MAX), in_file);
|
||||
in_size -= d_stream.avail_in;
|
||||
if (in_size == 0)
|
||||
d_stream.avail_in++; /* add dummy byte at end of compressed data */
|
||||
|
||||
err = inflate(&d_stream, Z_NO_FLUSH);
|
||||
if (err == Z_STREAM_END)
|
||||
break;
|
||||
if (err != Z_OK)
|
||||
{
|
||||
logerror("inflate error: %d\n", err);
|
||||
free (in_buffer);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
err = inflateEnd(&d_stream);
|
||||
if (err != Z_OK)
|
||||
{
|
||||
logerror("inflateEnd error: %d\n", err);
|
||||
free (in_buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free (in_buffer);
|
||||
|
||||
if ((d_stream.avail_out > 0) || (in_size > 0))
|
||||
{
|
||||
logerror("zip size mismatch. %i\n", in_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read compressed data
|
||||
out:
|
||||
data compressed data read
|
||||
return:
|
||||
==0 success
|
||||
<0 error
|
||||
*/
|
||||
int readcompresszip(ZIP* zip, struct zipent* ent, char* data) {
|
||||
int err = seekcompresszip(zip,ent);
|
||||
if (err!=0)
|
||||
return err;
|
||||
|
||||
if (fread(data, ent->compressed_size, 1, zip->fp)!=1) {
|
||||
errormsg ("Reading compressed data", ERROR_CORRUPT, zip->zip);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read UNcompressed data
|
||||
out:
|
||||
data UNcompressed data
|
||||
return:
|
||||
==0 success
|
||||
<0 error
|
||||
*/
|
||||
int readuncompresszip(ZIP* zip, struct zipent* ent, char* data) {
|
||||
if (ent->compression_method == 0x0000) {
|
||||
/* file is not compressed, simply stored */
|
||||
|
||||
/* check if size are equal */
|
||||
if (ent->compressed_size != ent->uncompressed_size) {
|
||||
errormsg("Wrong uncompressed size in store compression", ERROR_CORRUPT,zip->zip);
|
||||
return -3;
|
||||
}
|
||||
|
||||
return readcompresszip(zip,ent,data);
|
||||
} else if (ent->compression_method == 0x0008) {
|
||||
/* file is compressed using "Deflate" method */
|
||||
if (ent->version_needed_to_extract > 0x14) {
|
||||
errormsg("Version too new", ERROR_UNSUPPORTED,zip->zip);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ent->os_needed_to_extract != 0x00) {
|
||||
errormsg("OS not supported", ERROR_UNSUPPORTED,zip->zip);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ent->disk_number_start != zip->number_of_this_disk) {
|
||||
errormsg("Cannot span disks", ERROR_UNSUPPORTED,zip->zip);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* read compressed data */
|
||||
if (seekcompresszip(zip,ent)!=0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* configure inflate */
|
||||
if (inflate_file( zip->fp, ent->compressed_size, (unsigned char*)data, ent->uncompressed_size))
|
||||
{
|
||||
errormsg("Inflating compressed data", ERROR_CORRUPT, zip->zip);
|
||||
return -3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
errormsg("Compression method unsupported", ERROR_UNSUPPORTED, zip->zip);
|
||||
return -2;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue