latest changes from gvollant

This commit is contained in:
Nathan Moinvaziri 2012-01-21 15:12:36 -07:00
parent 6d35b6b884
commit d2368718ee
9 changed files with 474 additions and 399 deletions

28
Makefile.am Normal file
View File

@ -0,0 +1,28 @@
lib_LTLIBRARIES = libminizip.la
libminizip_la_SOURCES = \
ioapi.c \
mztools.c \
unzip.c \
zip.c
libminizip_la_CFLAGS = -I../.. -L../..
libminizip_la_LDFLAGS = -version-info 1:0:0 -lz
minizip_includedir = $(includedir)/minizip
minizip_include_HEADERS = \
crypt.h \
ioapi.h \
mztools.h \
unzip.h \
zip.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = minizip.pc
EXTRA_PROGRAMS = miniunzip minizip
miniunzip_SOURCES = miniunz.c
miniunzip_LDADD = libminizip.la
minizip_SOURCES = minizip.c

12
configure.ac Normal file
View File

@ -0,0 +1,12 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_INIT([minizip], [@ZLIB_VER@], [bugzilla.redhat.com])
AC_CONFIG_SRCDIR([minigzip.c])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_SUBST([HAVE_UNISTD_H], [0])
AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], [])
AC_CONFIG_FILES([Makefile minizip.pc])
AC_OUTPUT

101
miniunz.c
View File

@ -12,7 +12,7 @@
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
*/
#ifndef _WIN32
#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
@ -27,6 +27,18 @@
#endif
#endif
#ifdef __APPLE__
// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
#define FTELLO_FUNC(stream) ftello(stream)
#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
#else
#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
#define FTELLO_FUNC(stream) ftello64(stream)
#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -34,14 +46,15 @@
#include <errno.h>
#include <fcntl.h>
#ifdef unix
# include <unistd.h>
# include <utime.h>
#else
#ifdef _WIN32
# include <direct.h>
# include <io.h>
#else
# include <unistd.h>
# include <utime.h>
#endif
#include "unzip.h"
#define CASESENSITIVITY (0)
@ -84,7 +97,7 @@ void change_file_date(filename,dosdate,tmu_date)
SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
CloseHandle(hFile);
#else
#ifdef unix
#ifdef unix || __APPLE__
struct utimbuf ut;
struct tm newdate;
newdate.tm_sec = tmu_date.tm_sec;
@ -114,10 +127,10 @@ int mymkdir(dirname)
int ret=0;
#ifdef _WIN32
ret = _mkdir(dirname);
#else
#ifdef unix
#elif unix
ret = mkdir (dirname,0775);
#elif __APPLE__
ret = mkdir (dirname,0775);
#endif
#endif
return ret;
}
@ -296,12 +309,11 @@ int do_list(uf)
}
int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password,dirname)
int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
unzFile uf;
const int* popt_extract_without_path;
int* popt_overwrite;
const char* password;
const char* dirname;
{
char filename_inzip[256];
char* filename_withoutpath;
@ -347,18 +359,14 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password,
}
else
{
char write_filename[256];
int skip=0, i;
const char* write_filename;
int skip=0;
strncpy(write_filename,dirname, 256);
if (dirname[strlen(dirname) - 1] != '/' && dirname[strlen(dirname) - 1] != '\\')
strncat(write_filename, "\\", 256);
if ((*popt_extract_without_path)==0)
strncat(write_filename, filename_inzip, 256);
write_filename = filename_inzip;
else
strncat(write_filename, filename_withoutpath, 256);
write_filename = filename_withoutpath;
err = unzOpenCurrentFilePassword(uf,password);
if (err!=UNZ_OK)
{
@ -369,7 +377,7 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password,
{
char rep=0;
FILE* ftestexist;
ftestexist = fopen64(write_filename,"rb");
ftestexist = FOPEN_FUNC(write_filename,"rb");
if (ftestexist!=NULL)
{
fclose(ftestexist);
@ -400,27 +408,16 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password,
if ((skip==0) && (err==UNZ_OK))
{
fout=fopen64(write_filename,"wb");
fout=FOPEN_FUNC(write_filename,"wb");
/* some zipfile don't contain directory alone before file */
if ((fout==NULL) && ((*popt_extract_without_path)==0))
if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
(filename_withoutpath!=(char*)filename_inzip))
{
char write_path[256];
strncpy(write_path, write_filename, 256);
for (i = strlen(write_path) - 1; i >= 0; i -= 1)
{
if (write_path[i] == '/' || write_path[i] == '\\')
{
write_path[i] = 0;
break;
}
}
if ((*write_path) != '\0')
{
printf("creating directory: %s\n",write_path);
makedir(write_path);
fout=fopen64(write_filename,"wb");
}
char c=*(filename_withoutpath-1);
*(filename_withoutpath-1)='\0';
makedir(write_filename);
*(filename_withoutpath-1)=c;
fout=FOPEN_FUNC(write_filename,"wb");
}
if (fout==NULL)
@ -475,12 +472,11 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password,
}
int do_extract(uf,opt_extract_without_path,opt_overwrite,password,dirname)
int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
unzFile uf;
int opt_extract_without_path;
int opt_overwrite;
const char* password;
const char *dirname;
{
uLong i;
unz_global_info64 gi;
@ -495,7 +491,7 @@ int do_extract(uf,opt_extract_without_path,opt_overwrite,password,dirname)
{
if (do_extract_currentfile(uf,&opt_extract_without_path,
&opt_overwrite,
password,dirname) != UNZ_OK)
password) != UNZ_OK)
break;
if ((i+1)<gi.number_entry)
@ -512,13 +508,12 @@ int do_extract(uf,opt_extract_without_path,opt_overwrite,password,dirname)
return 0;
}
int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password,dirname)
int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
unzFile uf;
const char* filename;
int opt_extract_without_path;
int opt_overwrite;
const char* password;
const char *dirname;
{
int err = UNZ_OK;
if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
@ -529,7 +524,7 @@ int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,passwo
if (do_extract_currentfile(uf,&opt_extract_without_path,
&opt_overwrite,
password,dirname) == UNZ_OK)
password) == UNZ_OK)
return 0;
else
return 1;
@ -643,10 +638,20 @@ int main(argc,argv)
ret_value = do_list(uf);
else if (opt_do_extract==1)
{
#ifdef _WIN32
if (opt_extractdir && _chdir(dirname))
#else
if (opt_extractdir && chdir(dirname))
#endif
{
printf("Error changing into %s, aborting\n", dirname);
exit(-1);
}
if (filename_to_extract == NULL)
ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password, dirname);
ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
else
ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password, dirname);
ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
}
unzClose(uf);

View File

@ -13,7 +13,7 @@
*/
#ifndef _WIN32
#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
@ -28,6 +28,19 @@
#endif
#endif
#ifdef __APPLE__
// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
#define FTELLO_FUNC(stream) ftello(stream)
#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
#else
#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
#define FTELLO_FUNC(stream) ftello64(stream)
#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -35,14 +48,14 @@
#include <errno.h>
#include <fcntl.h>
#ifdef unix
#ifdef _WIN32
# include <direct.h>
# include <io.h>
#else
# include <unistd.h>
# include <utime.h>
# include <sys/types.h>
# include <sys/stat.h>
#else
# include <direct.h>
# include <io.h>
#endif
#include "zip.h"
@ -81,7 +94,7 @@ uLong filetime(f, tmzip, dt)
return ret;
}
#else
#ifdef unix
#ifdef unix || __APPLE__
uLong filetime(f, tmzip, dt)
char *f; /* name of file to get info on */
tm_zip *tmzip; /* return value: access, modific. and creation times */
@ -142,7 +155,7 @@ int check_exist_file(filename)
{
FILE* ftestexist;
int ret = 1;
ftestexist = fopen64(filename,"rb");
ftestexist = FOPEN_FUNC(filename,"rb");
if (ftestexist==NULL)
ret = 0;
else
@ -158,13 +171,12 @@ void do_banner()
void do_help()
{
printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-d bytes] [-j] file.zip [files_to_add]\n\n" \
printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
" -o Overwrite existing file.zip\n" \
" -a Append to existing file.zip\n" \
" -0 Store only\n" \
" -1 Compress faster\n" \
" -9 Compress better\n" \
" -d Disk size\n" \
" -9 Compress better\n\n" \
" -j exclude path. store only the file name.\n\n");
}
@ -174,7 +186,8 @@ int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigne
{
unsigned long calculate_crc=0;
int err=ZIP_OK;
FILE * fin = fopen64(filenameinzip,"rb");
FILE * fin = FOPEN_FUNC(filenameinzip,"rb");
unsigned long size_read = 0;
unsigned long total_read = 0;
if (fin==NULL)
@ -212,20 +225,19 @@ int isLargeFile(const char* filename)
{
int largeFile = 0;
ZPOS64_T pos = 0;
FILE* pFile = fopen64(filename, "rb");
FILE* pFile = FOPEN_FUNC(filename, "rb");
if(pFile != NULL)
{
int n = fseeko64(pFile, 0, SEEK_END);
int n = FSEEKO_FUNC(pFile, 0, SEEK_END);
pos = FTELLO_FUNC(pFile);
pos = ftello64(pFile);
printf("File : %s is %lld bytes\n", filename, pos);
printf("File : %s is %lld bytes\n", filename, pos);
if(pos >= 0xffffffff)
largeFile = 1;
fclose(pFile);
fclose(pFile);
}
return largeFile;
@ -244,7 +256,6 @@ int main(argc,argv)
int zipok;
int err=0;
int size_buf=0;
uLong disk_size = 0;
void* buf=NULL;
const char* password=NULL;
@ -274,11 +285,7 @@ int main(argc,argv)
opt_compress_level = c-'0';
if ((c=='j') || (c=='J'))
opt_exclude_path = 1;
if ((c=='d') && (i+1<argc))
{
disk_size = atoi(argv[i+1]);
i++;
}
if (((c=='p') || (c=='P')) && (i+1<argc))
{
password=argv[i+1];
@ -366,7 +373,7 @@ int main(argc,argv)
# ifdef USEWIN32IOAPI
zlib_filefunc64_def ffunc;
fill_win32_filefunc64A(&ffunc);
zf = zipOpen3_64(filename_try,(opt_overwrite==2) ? 2 : 0,disk_size,NULL,&ffunc);
zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
# else
zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
# endif
@ -453,7 +460,7 @@ int main(argc,argv)
printf("error in opening %s in zipfile\n",filenameinzip);
else
{
fin = fopen64(filenameinzip,"rb");
fin = FOPEN_FUNC(filenameinzip,"rb");
if (fin==NULL)
{
err=ZIP_ERRNO;

12
minizip.pc.in Normal file
View File

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@/minizip
Name: minizip
Description: Minizip zip file manipulation library
Requires:
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lminizip
Libs.private: -lz
Cflags: -I${includedir}

572
mztools.c
View File

@ -1,281 +1,291 @@
/*
Additional tools for Minizip
Code: Xavier Roche '2004
License: Same as ZLIB (www.gzip.org)
*/
/* Code */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zlib.h"
#include "unzip.h"
#define READ_8(adr) ((unsigned char)*(adr))
#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
#define WRITE_8(buff, n) do { \
*((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
} while(0)
#define WRITE_16(buff, n) do { \
WRITE_8((unsigned char*)(buff), n); \
WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
} while(0)
#define WRITE_32(buff, n) do { \
WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
} while(0)
extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
const char* file;
const char* fileOut;
const char* fileOutTmp;
uLong* nRecovered;
uLong* bytesRecovered;
{
int err = Z_OK;
FILE* fpZip = fopen(file, "rb");
FILE* fpOut = fopen(fileOut, "wb");
FILE* fpOutCD = fopen(fileOutTmp, "wb");
if (fpZip != NULL && fpOut != NULL) {
int entries = 0;
uLong totalBytes = 0;
char header[30];
char filename[256];
char extra[1024];
int offset = 0;
int offsetCD = 0;
while ( fread(header, 1, 30, fpZip) == 30 ) {
int currentOffset = offset;
/* File entry */
if (READ_32(header) == 0x04034b50) {
unsigned int version = READ_16(header + 4);
unsigned int gpflag = READ_16(header + 6);
unsigned int method = READ_16(header + 8);
unsigned int filetime = READ_16(header + 10);
unsigned int filedate = READ_16(header + 12);
unsigned int crc = READ_32(header + 14); /* crc */
unsigned int cpsize = READ_32(header + 18); /* compressed size */
unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
unsigned int fnsize = READ_16(header + 26); /* file name length */
unsigned int extsize = READ_16(header + 28); /* extra field length */
filename[0] = extra[0] = '\0';
/* Header */
if (fwrite(header, 1, 30, fpOut) == 30) {
offset += 30;
} else {
err = Z_ERRNO;
break;
}
/* Filename */
if (fnsize > 0) {
if (fread(filename, 1, fnsize, fpZip) == fnsize) {
if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
offset += fnsize;
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_STREAM_ERROR;
break;
}
/* Extra field */
if (extsize > 0) {
if (fread(extra, 1, extsize, fpZip) == extsize) {
if (fwrite(extra, 1, extsize, fpOut) == extsize) {
offset += extsize;
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_ERRNO;
break;
}
}
/* Data */
{
int dataSize = cpsize;
if (dataSize == 0) {
dataSize = uncpsize;
}
if (dataSize > 0) {
char* data = malloc(dataSize);
if (data != NULL) {
if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
offset += dataSize;
totalBytes += dataSize;
} else {
err = Z_ERRNO;
}
} else {
err = Z_ERRNO;
}
free(data);
if (err != Z_OK) {
break;
}
} else {
err = Z_MEM_ERROR;
break;
}
}
}
/* Central directory entry */
{
char header[46];
char* comment = "";
int comsize = (int) strlen(comment);
WRITE_32(header, 0x02014b50);
WRITE_16(header + 4, version);
WRITE_16(header + 6, version);
WRITE_16(header + 8, gpflag);
WRITE_16(header + 10, method);
WRITE_16(header + 12, filetime);
WRITE_16(header + 14, filedate);
WRITE_32(header + 16, crc);
WRITE_32(header + 20, cpsize);
WRITE_32(header + 24, uncpsize);
WRITE_16(header + 28, fnsize);
WRITE_16(header + 30, extsize);
WRITE_16(header + 32, comsize);
WRITE_16(header + 34, 0); /* disk # */
WRITE_16(header + 36, 0); /* int attrb */
WRITE_32(header + 38, 0); /* ext attrb */
WRITE_32(header + 42, currentOffset);
/* Header */
if (fwrite(header, 1, 46, fpOutCD) == 46) {
offsetCD += 46;
/* Filename */
if (fnsize > 0) {
if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
offsetCD += fnsize;
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_STREAM_ERROR;
break;
}
/* Extra field */
if (extsize > 0) {
if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
offsetCD += extsize;
} else {
err = Z_ERRNO;
break;
}
}
/* Comment field */
if (comsize > 0) {
if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
offsetCD += comsize;
} else {
err = Z_ERRNO;
break;
}
}
} else {
err = Z_ERRNO;
break;
}
}
/* Success */
entries++;
} else {
break;
}
}
/* Final central directory */
{
int entriesZip = entries;
char header[22];
char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
int comsize = (int) strlen(comment);
if (entriesZip > 0xffff) {
entriesZip = 0xffff;
}
WRITE_32(header, 0x06054b50);
WRITE_16(header + 4, 0); /* disk # */
WRITE_16(header + 6, 0); /* disk # */
WRITE_16(header + 8, entriesZip); /* hack */
WRITE_16(header + 10, entriesZip); /* hack */
WRITE_32(header + 12, offsetCD); /* size of CD */
WRITE_32(header + 16, offset); /* offset to CD */
WRITE_16(header + 20, comsize); /* comment */
/* Header */
if (fwrite(header, 1, 22, fpOutCD) == 22) {
/* Comment field */
if (comsize > 0) {
if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
err = Z_ERRNO;
}
}
} else {
err = Z_ERRNO;
}
}
/* Final merge (file + central directory) */
fclose(fpOutCD);
if (err == Z_OK) {
fpOutCD = fopen(fileOutTmp, "rb");
if (fpOutCD != NULL) {
int nRead;
char buffer[8192];
while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
err = Z_ERRNO;
break;
}
}
fclose(fpOutCD);
}
}
/* Close */
fclose(fpZip);
fclose(fpOut);
/* Wipe temporary file */
(void)remove(fileOutTmp);
/* Number of recovered entries */
if (err == Z_OK) {
if (nRecovered != NULL) {
*nRecovered = entries;
}
if (bytesRecovered != NULL) {
*bytesRecovered = totalBytes;
}
}
} else {
err = Z_STREAM_ERROR;
}
return err;
}
/*
Additional tools for Minizip
Code: Xavier Roche '2004
License: Same as ZLIB (www.gzip.org)
*/
/* Code */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zlib.h"
#include "unzip.h"
#define READ_8(adr) ((unsigned char)*(adr))
#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
#define WRITE_8(buff, n) do { \
*((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
} while(0)
#define WRITE_16(buff, n) do { \
WRITE_8((unsigned char*)(buff), n); \
WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
} while(0)
#define WRITE_32(buff, n) do { \
WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
} while(0)
extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
const char* file;
const char* fileOut;
const char* fileOutTmp;
uLong* nRecovered;
uLong* bytesRecovered;
{
int err = Z_OK;
FILE* fpZip = fopen(file, "rb");
FILE* fpOut = fopen(fileOut, "wb");
FILE* fpOutCD = fopen(fileOutTmp, "wb");
if (fpZip != NULL && fpOut != NULL) {
int entries = 0;
uLong totalBytes = 0;
char header[30];
char filename[1024];
char extra[1024];
int offset = 0;
int offsetCD = 0;
while ( fread(header, 1, 30, fpZip) == 30 ) {
int currentOffset = offset;
/* File entry */
if (READ_32(header) == 0x04034b50) {
unsigned int version = READ_16(header + 4);
unsigned int gpflag = READ_16(header + 6);
unsigned int method = READ_16(header + 8);
unsigned int filetime = READ_16(header + 10);
unsigned int filedate = READ_16(header + 12);
unsigned int crc = READ_32(header + 14); /* crc */
unsigned int cpsize = READ_32(header + 18); /* compressed size */
unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
unsigned int fnsize = READ_16(header + 26); /* file name length */
unsigned int extsize = READ_16(header + 28); /* extra field length */
filename[0] = extra[0] = '\0';
/* Header */
if (fwrite(header, 1, 30, fpOut) == 30) {
offset += 30;
} else {
err = Z_ERRNO;
break;
}
/* Filename */
if (fnsize > 0) {
if (fnsize < sizeof(filename)) {
if (fread(filename, 1, fnsize, fpZip) == fnsize) {
if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
offset += fnsize;
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_STREAM_ERROR;
break;
}
/* Extra field */
if (extsize > 0) {
if (extsize < sizeof(extra)) {
if (fread(extra, 1, extsize, fpZip) == extsize) {
if (fwrite(extra, 1, extsize, fpOut) == extsize) {
offset += extsize;
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_ERRNO;
break;
}
}
/* Data */
{
int dataSize = cpsize;
if (dataSize == 0) {
dataSize = uncpsize;
}
if (dataSize > 0) {
char* data = malloc(dataSize);
if (data != NULL) {
if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
offset += dataSize;
totalBytes += dataSize;
} else {
err = Z_ERRNO;
}
} else {
err = Z_ERRNO;
}
free(data);
if (err != Z_OK) {
break;
}
} else {
err = Z_MEM_ERROR;
break;
}
}
}
/* Central directory entry */
{
char header[46];
char* comment = "";
int comsize = (int) strlen(comment);
WRITE_32(header, 0x02014b50);
WRITE_16(header + 4, version);
WRITE_16(header + 6, version);
WRITE_16(header + 8, gpflag);
WRITE_16(header + 10, method);
WRITE_16(header + 12, filetime);
WRITE_16(header + 14, filedate);
WRITE_32(header + 16, crc);
WRITE_32(header + 20, cpsize);
WRITE_32(header + 24, uncpsize);
WRITE_16(header + 28, fnsize);
WRITE_16(header + 30, extsize);
WRITE_16(header + 32, comsize);
WRITE_16(header + 34, 0); /* disk # */
WRITE_16(header + 36, 0); /* int attrb */
WRITE_32(header + 38, 0); /* ext attrb */
WRITE_32(header + 42, currentOffset);
/* Header */
if (fwrite(header, 1, 46, fpOutCD) == 46) {
offsetCD += 46;
/* Filename */
if (fnsize > 0) {
if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
offsetCD += fnsize;
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_STREAM_ERROR;
break;
}
/* Extra field */
if (extsize > 0) {
if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
offsetCD += extsize;
} else {
err = Z_ERRNO;
break;
}
}
/* Comment field */
if (comsize > 0) {
if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
offsetCD += comsize;
} else {
err = Z_ERRNO;
break;
}
}
} else {
err = Z_ERRNO;
break;
}
}
/* Success */
entries++;
} else {
break;
}
}
/* Final central directory */
{
int entriesZip = entries;
char header[22];
char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
int comsize = (int) strlen(comment);
if (entriesZip > 0xffff) {
entriesZip = 0xffff;
}
WRITE_32(header, 0x06054b50);
WRITE_16(header + 4, 0); /* disk # */
WRITE_16(header + 6, 0); /* disk # */
WRITE_16(header + 8, entriesZip); /* hack */
WRITE_16(header + 10, entriesZip); /* hack */
WRITE_32(header + 12, offsetCD); /* size of CD */
WRITE_32(header + 16, offset); /* offset to CD */
WRITE_16(header + 20, comsize); /* comment */
/* Header */
if (fwrite(header, 1, 22, fpOutCD) == 22) {
/* Comment field */
if (comsize > 0) {
if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
err = Z_ERRNO;
}
}
} else {
err = Z_ERRNO;
}
}
/* Final merge (file + central directory) */
fclose(fpOutCD);
if (err == Z_OK) {
fpOutCD = fopen(fileOutTmp, "rb");
if (fpOutCD != NULL) {
int nRead;
char buffer[8192];
while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
err = Z_ERRNO;
break;
}
}
fclose(fpOutCD);
}
}
/* Close */
fclose(fpZip);
fclose(fpOut);
/* Wipe temporary file */
(void)remove(fileOutTmp);
/* Number of recovered entries */
if (err == Z_OK) {
if (nRecovered != NULL) {
*nRecovered = entries;
}
if (bytesRecovered != NULL) {
*bytesRecovered = totalBytes;
}
}
} else {
err = Z_STREAM_ERROR;
}
return err;
}

View File

@ -1,31 +1,37 @@
/*
Additional tools for Minizip
Code: Xavier Roche '2004
License: Same as ZLIB (www.gzip.org)
*/
#ifndef _zip_tools_H
#define _zip_tools_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ZLIB_H
#include "zlib.h"
#endif
#include "unzip.h"
/* Repair a ZIP file (missing central directory)
file: file to recover
fileOut: output file after recovery
fileOutTmp: temporary file name used for recovery
*/
extern int ZEXPORT unzRepair(const char* file,
const char* fileOut,
const char* fileOutTmp,
uLong* nRecovered,
uLong* bytesRecovered);
#endif
/*
Additional tools for Minizip
Code: Xavier Roche '2004
License: Same as ZLIB (www.gzip.org)
*/
#ifndef _zip_tools_H
#define _zip_tools_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ZLIB_H
#include "zlib.h"
#endif
#include "unzip.h"
/* Repair a ZIP file (missing central directory)
file: file to recover
fileOut: output file after recovery
fileOutTmp: temporary file name used for recovery
*/
extern int ZEXPORT unzRepair(const char* file,
const char* fileOut,
const char* fileOutTmp,
uLong* nRecovered,
uLong* bytesRecovered);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -86,9 +86,6 @@
#else
# include <errno.h>
#endif
#ifdef _WINDOWS
# define snprintf _snprintf
#endif
#ifndef local
# define local static
@ -104,7 +101,7 @@
#ifndef UNZ_BUFSIZE
#define UNZ_BUFSIZE (64 * 1024)
#define UNZ_BUFSIZE (16384)
#endif
#ifndef UNZ_MAXFILENAMEINZIP
@ -1154,7 +1151,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
szFileName,fileNameBufferSize,
extraField,extraFieldBufferSize,
szComment,commentBufferSize);
if (err==UNZ_OK)
if ((err==UNZ_OK) && (pfile_info != NULL))
{
pfile_info->version = file_info64.version;
pfile_info->version_needed = file_info64.version_needed;

16
zip.c
View File

@ -39,9 +39,7 @@
#else
# include <errno.h>
#endif
#ifdef _WINDOWS
# define snprintf _snprintf
#endif
#ifndef local
# define local static
@ -53,7 +51,7 @@
#endif
#ifndef Z_BUFSIZE
#define Z_BUFSIZE (64 * 1024)
#define Z_BUFSIZE (64*1024) //(16384)
#endif
#ifndef Z_MAXFILENAMEINZIP
@ -481,7 +479,6 @@ local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def
#ifndef BUFREADCOMMENT
#define BUFREADCOMMENT (0x400)
#endif
local int zipGetDiskSizeAvailable(zipFile file, ZPOS64_T *size_available)
{
zip64_internal* zi;
@ -1214,10 +1211,11 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
uInt i;
int err = ZIP_OK;
# ifdef NOCRYPT
#ifdef NOCRYPT
(crcForCrypting);
if (password != NULL)
return ZIP_PARAMERROR;
# endif
#endif
if (file == NULL)
return ZIP_PARAMERROR;
@ -1334,7 +1332,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
zi->ci.totalCompressedData = 0;
zi->ci.totalUncompressedData = 0;
zi->ci.pos_zip64extrainfo = 0;
err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
#ifdef HAVE_BZIP2
@ -1918,7 +1916,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
if (err==ZIP_OK) /* uncompressed size, unknown */
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
}
else
else
err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
}
else