Get rid of shared file moved all the code to mzstrm.

Converted miniunz to use new library changes.
This commit is contained in:
Nathan Moinvaziri 2017-10-03 23:19:37 -07:00
parent 4138ca5144
commit 5ef60a2b39
21 changed files with 424 additions and 529 deletions

View File

@ -1,242 +0,0 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include "zlib.h"
#include "mzstrm.h"
#ifdef _WIN32
# include <windows.h>
# include <direct.h>
# include <io.h>
#else
# include <unistd.h>
# include <utime.h>
# include <sys/types.h>
# include <sys/stat.h>
#endif
#include "minishared.h"
uint32_t get_file_date(const char *path, uint32_t *dos_date)
{
int ret = 0;
#ifdef _WIN32
FILETIME ftm_local;
HANDLE find = NULL;
WIN32_FIND_DATAA ff32;
find = FindFirstFileA(path, &ff32);
if (find != INVALID_HANDLE_VALUE)
{
FileTimeToLocalFileTime(&(ff32.ftLastWriteTime), &ftm_local);
FileTimeToDosDateTime(&ftm_local, ((LPWORD)dos_date) + 1, ((LPWORD)dos_date) + 0);
FindClose(find);
ret = 1;
}
#else
struct stat s;
struct tm *filedate = NULL;
time_t tm_t = 0;
memset(&s, 0, sizeof(s));
if (strcmp(path, "-") != 0)
{
size_t len = strlen(path);
char *name = (char *)malloc(len + 1);
strncpy(name, path, len + 1);
name[len] = 0;
if (name[len - 1] == '/')
name[len - 1] = 0;
/* Not all systems allow stat'ing a file with / appended */
if (stat(name, &s) == 0)
{
tm_t = s.st_mtime;
ret = 1;
}
free(name);
}
filedate = localtime(&tm_t);
*dos_date = tm_to_dosdate(filedate);
#endif
return ret;
}
void change_file_date(const char *path, uint32_t dos_date)
{
#ifdef _WIN32
HANDLE handle = NULL;
FILETIME ftm, ftm_local, ftm_create, ftm_access, ftm_modified;
handle = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (handle != INVALID_HANDLE_VALUE)
{
GetFileTime(handle, &ftm_create, &ftm_access, &ftm_modified);
DosDateTimeToFileTime((WORD)(dos_date >> 16), (WORD)dos_date, &ftm_local);
LocalFileTimeToFileTime(&ftm_local, &ftm);
SetFileTime(handle, &ftm, &ftm_access, &ftm);
CloseHandle(handle);
}
#else
struct utimbuf ut;
ut.actime = ut.modtime = dosdate_to_time_t(dos_date);
utime(path, &ut);
#endif
}
int invalid_date(const struct tm *ptm)
{
#define datevalue_in_range(min, max, value) ((min) <= (value) && (value) <= (max))
return (!datevalue_in_range(0, 207, ptm->tm_year) ||
!datevalue_in_range(0, 11, ptm->tm_mon) ||
!datevalue_in_range(1, 31, ptm->tm_mday) ||
!datevalue_in_range(0, 23, ptm->tm_hour) ||
!datevalue_in_range(0, 59, ptm->tm_min) ||
!datevalue_in_range(0, 59, ptm->tm_sec));
#undef datevalue_in_range
}
// Conversion without validation
void dosdate_to_raw_tm(uint64_t dos_date, struct tm *ptm)
{
uint64_t date = (uint64_t)(dos_date >> 16);
ptm->tm_mday = (uint16_t)(date & 0x1f);
ptm->tm_mon = (uint16_t)(((date & 0x1E0) / 0x20) - 1);
ptm->tm_year = (uint16_t)(((date & 0x0FE00) / 0x0200) + 80);
ptm->tm_hour = (uint16_t)((dos_date & 0xF800) / 0x800);
ptm->tm_min = (uint16_t)((dos_date & 0x7E0) / 0x20);
ptm->tm_sec = (uint16_t)(2 * (dos_date & 0x1f));
ptm->tm_isdst = -1;
}
int dosdate_to_tm(uint64_t dos_date, struct tm *ptm)
{
dosdate_to_raw_tm(dos_date, ptm);
if (invalid_date(ptm))
{
// Invalid date stored, so don't return it.
memset(ptm, 0, sizeof(struct tm));
return -1;
}
return 0;
}
time_t dosdate_to_time_t(uint64_t dos_date)
{
struct tm ptm;
dosdate_to_raw_tm(dos_date, &ptm);
return mktime(&ptm);
}
uint32_t tm_to_dosdate(const struct tm *ptm)
{
struct tm fixed_tm = { 0 };
/* Years supported:
* [00, 79] (assumed to be between 2000 and 2079)
* [80, 207] (assumed to be between 1980 and 2107, typical output of old
software that does 'year-1900' to get a double digit year)
* [1980, 2107] (due to the date format limitations, only years between 1980 and 2107 can be stored.)
*/
memcpy(&fixed_tm, ptm, sizeof(struct tm));
if (fixed_tm.tm_year >= 1980) /* range [1980, 2107] */
fixed_tm.tm_year -= 1980;
else if (fixed_tm.tm_year >= 80) /* range [80, 99] */
fixed_tm.tm_year -= 80;
else /* range [00, 79] */
fixed_tm.tm_year += 20;
if (invalid_date(ptm))
return 0;
return (uint32_t)(((fixed_tm.tm_mday) + (32 * (fixed_tm.tm_mon + 1)) + (512 * fixed_tm.tm_year)) << 16) |
((fixed_tm.tm_sec / 2) + (32 * fixed_tm.tm_min) + (2048 * (uint32_t)fixed_tm.tm_hour));
}
int makedir(const char *newdir)
{
char *buffer = NULL;
char *p = NULL;
int len = (int)strlen(newdir);
if (len <= 0)
return 0;
buffer = (char*)malloc(len + 1);
if (buffer == NULL)
{
printf("Error allocating memory\n");
return -1;
}
strcpy(buffer, newdir);
if (buffer[len - 1] == '/')
buffer[len - 1] = 0;
if (MKDIR(buffer) == 0)
{
free(buffer);
return 1;
}
p = buffer + 1;
while (1)
{
char hold;
while (*p && *p != '\\' && *p != '/')
p++;
hold = *p;
*p = 0;
if ((MKDIR(buffer) == -1) && (errno == ENOENT))
{
printf("couldn't create directory %s (%d)\n", buffer, errno);
free(buffer);
return 0;
}
if (hold == 0)
break;
*p++ = hold;
}
free(buffer);
return 1;
}
void display_zpos64(uint64_t n, int size_char)
{
/* To avoid compatibility problem we do here the conversion */
char number[21] = { 0 };
int offset = 19;
int pos_string = 19;
int size_display_string = 19;
while (1)
{
number[offset] = (char)((n % 10) + '0');
if (number[offset] != '0')
pos_string = offset;
n /= 10;
if (offset == 0)
break;
offset--;
}
size_display_string -= pos_string;
while (size_char-- > size_display_string)
printf(" ");
printf("%s", &number[pos_string]);
}

View File

@ -1,45 +0,0 @@
#ifndef _MINISHARED_H
#define _MINISHARED_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
# define MKDIR(d) _mkdir(d)
# define CHDIR(d) _chdir(d)
#else
# define MKDIR(d) mkdir(d, 0775)
# define CHDIR(d) chdir(d)
#endif
/***************************************************************************/
/* Get a file's date and time in dos format */
uint32_t get_file_date(const char *path, uint32_t *dos_date);
/* Sets a file's date and time in dos format */
void change_file_date(const char *path, uint32_t dos_date);
/* Convert dos date/time format to struct tm */
int dosdate_to_tm(uint64_t dos_date, struct tm *ptm);
/* Convert dos date/time format to time_t */
time_t dosdate_to_time_t(uint64_t dos_date);
/* Convert struct tm to dos date/time format */
uint32_t tm_to_dosdate(const struct tm *ptm);
/* Create a directory and all subdirectories */
int makedir(const char *newdir);
/* Print a 64-bit number for compatibility */
void display_zpos64(uint64_t n, int size_char);
/***************************************************************************/
#ifdef __cplusplus
}
#endif
#endif

335
miniunz.c
View File

@ -1,5 +1,5 @@
/* miniunz.c
Version 1.2.0, September 16th, 2017
Version 1.3.0, September 16th, 2017
sample part of the MiniZip project
Copyright (C) 2012-2017 Nathan Moinvaziri
@ -21,27 +21,16 @@
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#ifdef _WIN32
# include <direct.h>
# include <io.h>
#else
# include <sys/stat.h>
# include <unistd.h>
# include <utime.h>
#endif
#include "mzstrm.h"
#include "unzip.h"
#include "mz_compat.h"
#include "mzstrm.h"
#include "minishared.h"
/***************************************************************************/
void miniunz_banner()
{
printf("MiniUnz 1.2.0, demo of zLib + Unz package\n");
printf("MiniUnz 1.3.0, demo of zLib + Unz package\n");
printf("more info at https://github.com/nmoinvaz/minizip\n\n");
}
@ -57,13 +46,25 @@ void miniunz_help()
" -p extract crypted file using password\n\n");
}
int miniunz_list(unzFile uf)
/***************************************************************************/
int miniunz_list(void *handle)
{
int err = unzGoToFirstFile(uf);
if (err != UNZ_OK)
mz_unzip_file *file_info = NULL;
uint32_t ratio = 0;
int16_t level = 0;
int16_t err = MZ_OK;
struct tm tmu_date = { 0 };
const char *string_method = NULL;
char crypt = ' ';
err = mz_unzip_goto_first_entry(handle);
if (err != MZ_OK)
{
printf("error %d with zipfile in unzGoToFirstFile\n", err);
return 1;
printf("Error %d with zip file @ mz_unzip_goto_first_entry\n", err);
return err;
}
printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
@ -71,130 +72,126 @@ int miniunz_list(unzFile uf)
do
{
char filename_inzip[256] = {0};
unz_file_info64 file_info = {0};
uint32_t ratio = 0;
struct tm tmu_date = { 0 };
const char *string_method = NULL;
char char_crypt = ' ';
err = unzGetCurrentFileInfo64(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
if (err != UNZ_OK)
err = mz_unzip_entry_get_info(handle, &file_info);
if (err != MZ_OK)
{
printf("error %d with zipfile in unzGetCurrentFileInfo\n", err);
printf("Error %d with zip file @ mz_unzip_entry_get_info\n", err);
break;
}
if (file_info.uncompressed_size > 0)
ratio = (uint32_t)((file_info.compressed_size * 100) / file_info.uncompressed_size);
if (file_info->uncompressed_size > 0)
ratio = (uint32_t)((file_info->compressed_size * 100) / file_info->uncompressed_size);
/* Display a '*' if the file is encrypted */
if ((file_info.flag & 1) != 0)
char_crypt = '*';
// Display a '*' if the file is encrypted
if ((file_info->flag & 1) != 0)
crypt = '*';
if (file_info.compression_method == 0)
string_method = "Stored";
else if (file_info.compression_method == Z_DEFLATED)
if (file_info->compression_method == 0)
{
uint16_t level = (uint16_t)((file_info.flag & 0x6) / 2);
string_method = "Stored";
}
else if (file_info->compression_method == Z_DEFLATED)
{
level = (int16_t)((file_info->flag & 0x6) / 2);
if (level == 0)
string_method = "Defl:N";
else if (level == 1)
string_method = "Defl:X";
else if ((level == 2) || (level == 3))
string_method = "Defl:F"; /* 2:fast , 3 : extra fast*/
string_method = "Defl:F"; // 2:fast , 3 : extra fast
else
string_method = "Unkn. ";
}
else if (file_info.compression_method == Z_BZIP2ED)
else if (file_info->compression_method == Z_BZIP2ED)
{
string_method = "BZip2 ";
}
else
{
string_method = "Unkn. ";
}
display_zpos64(file_info.uncompressed_size, 7);
printf(" %6s%c", string_method, char_crypt);
display_zpos64(file_info.compressed_size, 7);
mz_dosdate_to_tm(file_info->dos_date, &tmu_date);
dosdate_to_tm(file_info.dos_date, &tmu_date);
printf(" %3u%% %2.2u-%2.2u-%2.2u %2.2u:%2.2u %8.8x %s\n", ratio,
printf(" %7llu %6s%c %7llu %3u%% %2.2u-%2.2u-%2.2u %2.2u:%2.2u %8.8x %s\n",
file_info->uncompressed_size, string_method, crypt, file_info->compressed_size, ratio,
(uint32_t)tmu_date.tm_mon + 1, (uint32_t)tmu_date.tm_mday,
(uint32_t)tmu_date.tm_year % 100,
(uint32_t)tmu_date.tm_hour, (uint32_t)tmu_date.tm_min,
file_info.crc, filename_inzip);
file_info->crc, file_info->filename);
err = unzGoToNextFile(uf);
err = mz_unzip_goto_next_entry(handle);
}
while (err == UNZ_OK);
while (err == MZ_OK);
if (err != UNZ_END_OF_LIST_OF_FILE && err != UNZ_OK)
if (err != MZ_END_OF_LIST && err != MZ_OK)
{
printf("error %d with zipfile in unzGoToNextFile\n", err);
printf("Error %d with zip file @ mz_unzip_goto_next_entry\n", err);
return err;
}
return 0;
return MZ_OK;
}
int miniunz_extract_currentfile(unzFile uf, int opt_extract_without_path, int *popt_overwrite, const char *password)
int miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_path, uint8_t *opt_overwrite, const char *password)
{
unz_file_info64 file_info = {0};
void* buf = NULL;
uint16_t size_buf = 8192;
mz_unzip_file *file_info = NULL;
uint8_t buf[UINT16_MAX];
int32_t read = 0;
int err = UNZ_OK;
int errclose = UNZ_OK;
int skip = 0;
char filename_inzip[256] = {0};
char *filename_withoutpath = NULL;
const char *write_filename = NULL;
char *p = NULL;
int16_t err = MZ_OK;
int16_t err_close = MZ_OK;
uint8_t skip = 0;
void *stream_entry = NULL;
char *match = NULL;
char *filename = NULL;
char *write_filename = NULL;
char directory[512];
err = unzGetCurrentFileInfo64(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
if (err != UNZ_OK)
err = mz_unzip_entry_get_info(handle, &file_info);
if (err != MZ_OK)
{
printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
printf("Error %d with zip file @ mz_unzip_entry_get_info\n", err);
return err;
}
p = filename_withoutpath = filename_inzip;
while (*p != 0)
// Break apart filename and directory from full path
strncpy(directory, file_info->filename, sizeof(directory));
match = filename = directory;
while (*match != 0)
{
if ((*p == '/') || (*p == '\\'))
filename_withoutpath = p+1;
p++;
if ((*match == '/') || (*match == '\\'))
filename = match + 1;
match += 1;
}
if (filename != directory)
*match = 0;
/* If zip entry is a directory then create it on disk */
if (*filename_withoutpath == 0)
// If zip entry is a directory then create it on disk
if (*filename == 0)
{
if (opt_extract_without_path == 0)
{
printf("creating directory: %s\n", filename_inzip);
MKDIR(filename_inzip);
printf("Creating directory: %s\n", file_info->filename);
mz_os_make_dir(directory);
}
return err;
}
buf = (void*)malloc(size_buf);
if (buf == NULL)
{
printf("Error allocating memory\n");
return UNZ_INTERNALERROR;
}
err = mz_unzip_entry_open(handle, 0, password);
err = unzOpenCurrentFilePassword(uf, password);
if (err != UNZ_OK)
printf("error %d with zipfile in unzOpenCurrentFilePassword\n", err);
if (err != MZ_OK)
printf("Error %d with zip file @ mz_unzip_entry_open\n", err);
if (opt_extract_without_path)
write_filename = filename_withoutpath;
write_filename = filename;
else
write_filename = filename_inzip;
write_filename = file_info->filename;
/* Determine if the file should be overwritten or not and ask the user if needed */
if ((err == UNZ_OK) && (*popt_overwrite == 0) && (mz_os_file_exists(write_filename)))
// Determine if the file should be overwritten or not and ask the user if needed
if ((err == MZ_OK) && (*opt_overwrite == 0) && (mz_os_file_exists(write_filename)))
{
char rep = 0;
do
@ -212,41 +209,34 @@ int miniunz_extract_currentfile(unzFile uf, int opt_extract_without_path, int *p
if (rep == 'N')
skip = 1;
if (rep == 'A')
*popt_overwrite = 1;
*opt_overwrite = 1;
}
voidpf stream_entry = NULL;
mz_stream_os_create(&stream_entry);
/* Create the file on disk so we can unzip to it */
if ((skip == 0) && (err == UNZ_OK))
// Create the file on disk so we can unzip to it
if ((skip == 0) && (err == MZ_OK))
{
/* Some zips don't contain directory alone before file */
// Some zips don't contain directory alone before file
if ((mz_stream_os_open(stream_entry, write_filename, MZ_STREAM_MODE_CREATE) != MZ_OK) &&
(opt_extract_without_path == 0) &&
(filename_withoutpath != (char*)filename_inzip))
(opt_extract_without_path == 0) && (filename != file_info->filename))
{
char c = *(filename_withoutpath-1);
*(filename_withoutpath-1) = 0;
makedir(write_filename);
*(filename_withoutpath-1) = c;
mz_os_make_dir(directory);
mz_stream_os_open(stream_entry, write_filename, MZ_STREAM_MODE_CREATE);
}
}
/* Read from the zip, unzip to buffer, and write to disk */
// Read from the zip, unzip to buffer, and write to disk
if (mz_stream_os_is_open(stream_entry) == MZ_OK)
{
printf(" extracting: %s\n", write_filename);
printf(" Extracting: %s\n", write_filename);
while (1)
{
read = unzReadCurrentFile(uf, buf, size_buf);
read = mz_unzip_entry_read(handle, buf, sizeof(buf));
if (read < 0)
{
err = read;
printf("error %d with zipfile in unzReadCurrentFile\n", err);
printf("Error %d with zip file @ mz_unzip_entry_read\n", err);
break;
}
if (read == 0)
@ -254,87 +244,95 @@ int miniunz_extract_currentfile(unzFile uf, int opt_extract_without_path, int *p
if (mz_stream_os_write(stream_entry, buf, read) != read)
{
printf("error %d in writing extracted file\n", err);
printf("Error %d in writing extracted file\n", err);
break;
}
}
mz_stream_os_close(stream_entry);
/* Set the time of the file that has been unzipped */
// Set the time of the file that has been unzipped
if (err == 0)
change_file_date(write_filename, file_info.dos_date);
mz_os_set_file_date(write_filename, file_info->dos_date);
}
else
{
printf("error opening %s\n", write_filename);
printf("Error opening %s\n", write_filename);
}
mz_stream_os_delete(&stream_entry);
errclose = unzCloseCurrentFile(uf);
if (errclose != UNZ_OK)
printf("error %d with zipfile in unzCloseCurrentFile\n", errclose);
err_close = mz_unzip_entry_close(handle);
if (err_close != MZ_OK)
printf("Error %d with zip file @ mz_unzip_entry_close\n", err_close);
free(buf);
return err;
}
int miniunz_extract_all(unzFile uf, int opt_extract_without_path, int opt_overwrite, const char *password)
int miniunz_extract_all(void *handle, uint8_t opt_extract_without_path, uint8_t opt_overwrite, const char *password)
{
int err = unzGoToFirstFile(uf);
if (err != UNZ_OK)
int16_t err = MZ_OK;
err = mz_unzip_goto_first_entry(handle);
if (err != MZ_OK)
{
printf("error %d with zipfile in unzGoToFirstFile\n", err);
printf("Error %d with zip file @ mz_unzip_goto_first_entry\n", err);
return 1;
}
do
{
err = miniunz_extract_currentfile(uf, opt_extract_without_path, &opt_overwrite, password);
if (err != UNZ_OK)
err = miniunz_extract_currentfile(handle, opt_extract_without_path, &opt_overwrite, password);
if (err != MZ_OK)
break;
err = unzGoToNextFile(uf);
}
while (err == UNZ_OK);
if (err != UNZ_END_OF_LIST_OF_FILE)
err = mz_unzip_goto_next_entry(handle);
}
while (err == MZ_OK);
if (err != MZ_END_OF_LIST)
{
printf("error %d with zipfile in unzGoToNextFile\n", err);
printf("Error %d with zip file @ mz_unzip_goto_next_entry\n", err);
return 1;
}
return 0;
}
int miniunz_extract_onefile(unzFile uf, const char *filename, int opt_extract_without_path, int opt_overwrite,
const char *password)
int miniunz_extract_onefile(void *handle, const char *filename, uint8_t opt_extract_without_path,
uint8_t opt_overwrite, const char *password)
{
if (unzLocateFile(uf, filename, NULL) != UNZ_OK)
if (mz_unzip_locate_entry(handle, filename, NULL) != MZ_OK)
{
printf("file %s not found in the zipfile\n", filename);
printf("File %s not found in the zip file\n", filename);
return 2;
}
if (miniunz_extract_currentfile(uf, opt_extract_without_path, &opt_overwrite, password) == UNZ_OK)
if (miniunz_extract_currentfile(handle, opt_extract_without_path, &opt_overwrite, password) == MZ_OK)
return 0;
return 1;
}
#ifndef NOMAIN
int main(int argc, const char *argv[])
{
const char *zipfilename = NULL;
const char *filename_to_extract = NULL;
void *handle = NULL;
void *stream = NULL;
int16_t i = 0;
uint8_t opt_do_list = 0;
uint8_t opt_do_extract = 1;
uint8_t opt_do_extract_withoutpath = 0;
uint8_t opt_overwrite = 0;
uint8_t opt_extractdir = 0;
const char *path = NULL;
const char *password = NULL;
int i = 0;
int ret = 0;
int opt_do_list = 0;
int opt_do_extract = 1;
int opt_do_extract_withoutpath = 0;
int opt_overwrite = 0;
int opt_extractdir = 0;
const char *dirname = NULL;
unzFile uf = NULL;
voidpf stream = NULL;
const char *directory = NULL;
const char *filename_to_extract = NULL;
int err = 0;
miniunz_banner();
if (argc == 1)
@ -343,7 +341,7 @@ int main(int argc, const char *argv[])
return 0;
}
/* Parse command line options */
// Parse command line options
for (i = 1; i < argc; i++)
{
if ((*argv[i]) == '-')
@ -366,64 +364,61 @@ int main(int argc, const char *argv[])
if ((c == 'd') || (c == 'D'))
{
opt_extractdir = 1;
dirname = argv[i+1];
directory = argv[i+1];
}
if (((c == 'p') || (c == 'P')) && (i+1 < argc))
{
password = argv[i+1];
i++;
i += 1;
}
}
continue;
}
else
{
if (zipfilename == NULL)
zipfilename = argv[i];
else if ((filename_to_extract == NULL) && (!opt_extractdir))
filename_to_extract = argv[i];
}
if (path == NULL)
path = argv[i];
else if ((filename_to_extract == NULL) && (!opt_extractdir))
filename_to_extract = argv[i];
}
mz_stream_os_create(&stream);
/* Open zip file */
if (zipfilename != NULL)
{
uf = unzOpen(zipfilename, stream);
}
// Open zip file
if (path != NULL)
handle = mz_unzip_open(path, stream);
if (uf == NULL)
if (handle == NULL)
{
printf("Cannot open %s\n", zipfilename);
printf("Cannot open %s\n", path);
return 1;
}
printf("%s opened\n", zipfilename);
printf("%s opened\n", path);
/* Process command line options */
if (opt_do_list == 1)
// Process command line options
if (opt_do_list)
{
ret = miniunz_list(uf);
err = miniunz_list(handle);
}
else if (opt_do_extract == 1)
else if (opt_do_extract)
{
if (opt_extractdir && CHDIR(dirname))
if (opt_extractdir && mz_os_change_dir(directory))
{
printf("Error changing into %s, aborting\n", dirname);
printf("Error changing into %s, aborting\n", directory);
exit(-1);
}
if (filename_to_extract == NULL)
ret = miniunz_extract_all(uf, opt_do_extract_withoutpath, opt_overwrite, password);
err = miniunz_extract_all(handle, opt_do_extract_withoutpath, opt_overwrite, password);
else
ret = miniunz_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
err = miniunz_extract_onefile(handle, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
}
unzClose(uf);
mz_unzip_close(handle);
mz_stream_os_delete(&stream);
return ret;
return err;
}
#endif

View File

@ -1,5 +1,5 @@
/* minizip.c
Version 1.2.0, September 16th, 2017
Version 1.3.0, September 16th, 2017
sample part of the MiniZip project
Copyright (C) 2012-2017 Nathan Moinvaziri
@ -39,11 +39,9 @@
#include "mzstrm.h"
#include "test.h"
#include "minishared.h"
void minizip_banner()
{
printf("MiniZip 1.2.0, demo of zLib + MiniZip64 package\n");
printf("MiniZip 1.3.0, demo of zLib + MiniZip64 package\n");
printf("more info on MiniZip at https://github.com/nmoinvaz/minizip\n\n");
}
@ -67,8 +65,8 @@ int minizip_addfile(void *zf, const char *path, const char *filenameinzip, int l
char buf[UINT16_MAX];
/* Get information about the file on disk so we can store it in zip */
get_file_date(path, &zi.dos_date);
// Get information about the file on disk so we can store it in zip
mz_os_get_file_date(path, &zi.dos_date);
/* Add to zip file */
err = zipOpenNewFileInZip3_64(zf, filenameinzip, &zi,
@ -81,7 +79,7 @@ int minizip_addfile(void *zf, const char *path, const char *filenameinzip, int l
if (err != ZIP_OK)
{
printf("error in opening %s in zipfile (%d)\n", filenameinzip, err);
printf("error in opening %s in zip file (%d)\n", filenameinzip, err);
}
else
{
@ -109,7 +107,7 @@ int minizip_addfile(void *zf, const char *path, const char *filenameinzip, int l
{
err = zipWriteInFileInZip(zf, buf, size_read);
if (err < 0)
printf("error in writing %s in the zipfile (%d)\n", filenameinzip, err);
printf("error in writing %s in the zip file (%d)\n", filenameinzip, err);
}
}
while ((err == ZIP_OK) && (size_read > 0));
@ -128,7 +126,7 @@ int minizip_addfile(void *zf, const char *path, const char *filenameinzip, int l
{
err = zipCloseFileInZip(zf);
if (err != ZIP_OK)
printf("error in closing %s in the zipfile (%d)\n", filenameinzip, err);
printf("error in closing %s in the zip file (%d)\n", filenameinzip, err);
}
return err;

View File

@ -21,7 +21,7 @@
#ifdef __cplusplus
extern "C" {
#endif
#include "zlib.h"
#ifdef __GNUC__
# define ZIP_UNUSED __attribute__((__unused__))
#else

View File

@ -17,8 +17,12 @@
#include <stdint.h>
#include <string.h>
#include <time.h>
#include "mzstrm.h"
/***************************************************************************/
int32_t mz_stream_open(void *stream, const char *path, int mode)
{
mz_stream *strm = (mz_stream *)stream;
@ -282,12 +286,16 @@ void mz_stream_delete(void **stream)
strm->delete(stream);
}
/***************************************************************************/
typedef struct mz_stream_passthru_s {
mz_stream stream;
int64_t total_in;
int64_t total_out;
} mz_stream_passthru;
/***************************************************************************/
int32_t mz_stream_passthru_open(void *stream, const char *path, int mode)
{
mz_stream_passthru *passthru = (mz_stream_passthru *)stream;
@ -392,6 +400,8 @@ void mz_stream_passthru_delete(void **stream)
free(passthru);
}
/***************************************************************************/
int32_t mz_os_file_exists(const char *path)
{
void *stream = NULL;
@ -410,7 +420,7 @@ int32_t mz_os_file_exists(const char *path)
return opened;
}
int32_t mz_os_file_is_large(const char *path)
int64_t mz_os_file_get_size(const char *path)
{
void *stream = NULL;
int64_t size = 0;
@ -426,5 +436,78 @@ int32_t mz_os_file_is_large(const char *path)
mz_stream_os_delete(&stream);
return (size >= UINT32_MAX);
}
return size;
}
/***************************************************************************/
int mz_invalid_date(const struct tm *ptm)
{
#define datevalue_in_range(min, max, value) ((min) <= (value) && (value) <= (max))
return (!datevalue_in_range(0, 207, ptm->tm_year) ||
!datevalue_in_range(0, 11, ptm->tm_mon) ||
!datevalue_in_range(1, 31, ptm->tm_mday) ||
!datevalue_in_range(0, 23, ptm->tm_hour) ||
!datevalue_in_range(0, 59, ptm->tm_min) ||
!datevalue_in_range(0, 59, ptm->tm_sec));
#undef datevalue_in_range
}
// Conversion without validation
void mz_dosdate_to_raw_tm(uint64_t dos_date, struct tm *ptm)
{
uint64_t date = (uint64_t)(dos_date >> 16);
ptm->tm_mday = (uint16_t)(date & 0x1f);
ptm->tm_mon = (uint16_t)(((date & 0x1E0) / 0x20) - 1);
ptm->tm_year = (uint16_t)(((date & 0x0FE00) / 0x0200) + 80);
ptm->tm_hour = (uint16_t)((dos_date & 0xF800) / 0x800);
ptm->tm_min = (uint16_t)((dos_date & 0x7E0) / 0x20);
ptm->tm_sec = (uint16_t)(2 * (dos_date & 0x1f));
ptm->tm_isdst = -1;
}
int32_t mz_dosdate_to_tm(uint64_t dos_date, struct tm *ptm)
{
mz_dosdate_to_raw_tm(dos_date, ptm);
if (mz_invalid_date(ptm))
{
// Invalid date stored, so don't return it.
memset(ptm, 0, sizeof(struct tm));
return -1;
}
return 0;
}
time_t mz_dosdate_to_time_t(uint64_t dos_date)
{
struct tm ptm;
mz_dosdate_to_raw_tm(dos_date, &ptm);
return mktime(&ptm);
}
uint32_t mz_tm_to_dosdate(const struct tm *ptm)
{
struct tm fixed_tm = { 0 };
// Years supported:
// [00, 79] (assumed to be between 2000 and 2079)
// [80, 207] (assumed to be between 1980 and 2107, typical output of old
// software that does 'year-1900' to get a double digit year)
// [1980, 2107] (due to the date format limitations, only years between 1980 and 2107 can be stored.)
memcpy(&fixed_tm, ptm, sizeof(struct tm));
if (fixed_tm.tm_year >= 1980) // range [1980, 2107]
fixed_tm.tm_year -= 1980;
else if (fixed_tm.tm_year >= 80) // range [80, 99]
fixed_tm.tm_year -= 80;
else // range [00, 79]
fixed_tm.tm_year += 20;
if (mz_invalid_date(ptm))
return 0;
return (uint32_t)(((fixed_tm.tm_mday) + (32 * (fixed_tm.tm_mon + 1)) + (512 * fixed_tm.tm_year)) << 16) |
((fixed_tm.tm_sec / 2) + (32 * fixed_tm.tm_min) + (2048 * (uint32_t)fixed_tm.tm_hour));
}

View File

@ -128,6 +128,10 @@ void mz_stream_passthru_delete(void **stream);
#define mz_stream_os_delete mz_stream_posix_delete
#define mz_os_rand mz_posix_rand
#define mz_os_get_file_date mz_posix_get_file_date
#define mz_os_set_file_date mz_posix_set_file_date
#define mz_os_change_dir mz_posix_change_dir
#define mz_os_make_dir mz_posix_make_dir
#else
#include "mzstrm_win32.h"
@ -144,10 +148,25 @@ void mz_stream_passthru_delete(void **stream);
#define mz_stream_os_delete mz_stream_win32_delete
#define mz_os_rand mz_win32_rand
#define mz_os_get_file_date mz_win32_get_file_date
#define mz_os_set_file_date mz_win32_set_file_date
#define mz_os_change_dir mz_win32_change_dir
#define mz_os_make_dir mz_win32_make_dir
#endif
/***************************************************************************/
int32_t mz_os_file_exists(const char *path);
int32_t mz_os_file_is_large(const char *path);
int64_t mz_os_file_get_size(const char *path);
/***************************************************************************/
int32_t mz_dosdate_to_tm(uint64_t dos_date, struct tm *ptm);
// Convert dos date/time format to struct tm
time_t mz_dosdate_to_time_t(uint64_t dos_date);
// Convert dos date/time format to time_t
uint32_t mz_tm_to_dosdate(const struct tm *ptm);
// Convert struct tm to dos date/time format
/***************************************************************************/

View File

@ -63,7 +63,7 @@ int32_t mz_stream_bzip_open(void *stream, const char *path, int mode)
else if (mode & MZ_STREAM_MODE_WRITE)
{
bzip->bzstream.next_out = bzip->buffer;
bzip->bzstream.avail_out = UINT16_MAX;
bzip->bzstream.avail_out = sizeof(bzip->buffer);
bzip->error = BZ2_bzCompressInit(&bzip->bzstream, bzip->level, 0, 35);
}
@ -102,10 +102,10 @@ int32_t mz_stream_bzip_read(void *stream, void *buf, uint32_t size)
{
if (bzip->bzstream.avail_in == 0)
{
bytes_to_read = UINT16_MAX;
bytes_to_read = sizeof(bzip->buffer);
if (bzip->max_total_in > 0)
{
if ((bzip->max_total_in - bzip->total_in) < UINT16_MAX)
if ((bzip->max_total_in - bzip->total_in) < sizeof(bzip->buffer))
bytes_to_read = (int32_t)(bzip->max_total_in - bzip->total_in);
}
@ -205,7 +205,7 @@ int32_t mz_stream_bzip_write(void *stream, const void *buf, uint32_t size)
return 0;
}
bzip->bzstream.avail_out = UINT32_MAX;
bzip->bzstream.avail_out = sizeof(bzip->buffer);
bzip->bzstream.next_out = bzip->buffer;
bzip->buffer_len = 0;

View File

@ -1,5 +1,5 @@
/* mzstrm_crypt.c -- Code for traditional PKWARE encryption
Version 1.2.0, September 16th, 2017
Version 1.3.0, September 16th, 2017
Copyright (C) 2012-2017 Nathan Moinvaziri
https://github.com/nmoinvaz/minizip

View File

@ -1,5 +1,5 @@
/* mzstrm_crypt.h -- Code for traditional PKWARE encryption
Version 1.2.0, September 16th, 2017
Version 1.3.0, September 16th, 2017
Copyright (C) 2012-2017 Nathan Moinvaziri
https://github.com/nmoinvaz/minizip

View File

@ -322,3 +322,110 @@ int32_t mz_win32_rand(uint8_t *buf, uint32_t size)
return len;
}
int16_t mz_win32_get_file_date(const char *path, uint32_t *dos_date)
{
FILETIME ftm_local;
HANDLE handle = NULL;
WIN32_FIND_DATAW ff32;
wchar_t *path_wide = NULL;
uint32_t path_wide_size = 0;
int16_t err = MZ_INTERNAL_ERROR;
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
path_wide = (wchar_t *)malloc((path_wide_size + 1) * sizeof(wchar_t));
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
handle = FindFirstFileW(path_wide, &ff32);
free(path_wide);
if (handle != INVALID_HANDLE_VALUE)
{
FileTimeToLocalFileTime(&(ff32.ftLastWriteTime), &ftm_local);
FileTimeToDosDateTime(&ftm_local, ((LPWORD)dos_date) + 1, ((LPWORD)dos_date) + 0);
FindClose(handle);
err = MZ_OK;
}
return err;
}
int16_t mz_win32_set_file_date(const char *path, uint32_t dos_date)
{
HANDLE handle = NULL;
FILETIME ftm, ftm_local, ftm_create, ftm_access, ftm_modified;
wchar_t *path_wide = NULL;
uint32_t path_wide_size = 0;
int16_t err = MZ_OK;
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
path_wide = (wchar_t *)malloc((path_wide_size + 1) * sizeof(wchar_t));
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
#ifdef IOWIN32_USING_WINRT_API
handle = CreateFile2W(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
#else
handle = CreateFileW(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
#endif
free(path_wide);
if (handle != INVALID_HANDLE_VALUE)
{
GetFileTime(handle, &ftm_create, &ftm_access, &ftm_modified);
DosDateTimeToFileTime((WORD)(dos_date >> 16), (WORD)dos_date, &ftm_local);
LocalFileTimeToFileTime(&ftm_local, &ftm);
if (SetFileTime(handle, &ftm, &ftm_access, &ftm) == 0)
err = MZ_INTERNAL_ERROR;
CloseHandle(handle);
}
return err;
}
int16_t mz_win32_change_dir(const char *path)
{
wchar_t *path_wide = NULL;
uint32_t path_wide_size = 0;
int16_t err = MZ_OK;
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
path_wide = (wchar_t *)malloc((path_wide_size + 1) * sizeof(wchar_t));
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
if (_wchdir(path_wide) != 0)
err = MZ_INTERNAL_ERROR;
free(path_wide);
return err;
}
int16_t mz_win32_make_dir(const char *path)
{
wchar_t *path_wide = NULL;
uint32_t path_wide_size = 0;
int16_t err = MZ_OK;
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
path_wide = (wchar_t *)malloc((path_wide_size + 1) * sizeof(wchar_t));
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
if (_wmkdir(path_wide) != 0)
err = MZ_INTERNAL_ERROR;
free(path_wide);
return err;
}

View File

@ -37,6 +37,10 @@ void* mz_stream_win32_create(void **stream);
void mz_stream_win32_delete(void **stream);
int32_t mz_win32_rand(uint8_t *buf, uint32_t size);
int16_t mz_win32_get_file_date(const char *path, uint32_t *dos_date);
int16_t mz_win32_set_file_date(const char *path, uint32_t dos_date);
int16_t mz_win32_change_dir(const char *path);
int16_t mz_win32_make_dir(const char *path);
/***************************************************************************/

View File

@ -120,10 +120,10 @@ int32_t mz_stream_zlib_read(void *stream, void *buf, uint32_t size)
{
if (zlib->zstream.avail_in == 0)
{
bytes_to_read = UINT16_MAX;
bytes_to_read = sizeof(zlib->buffer);
if (zlib->max_total_in > 0)
{
if ((zlib->max_total_in - zlib->total_in) < UINT16_MAX)
if ((zlib->max_total_in - zlib->total_in) < sizeof(zlib->buffer))
bytes_to_read = (int32_t)(zlib->max_total_in - zlib->total_in);
}
@ -225,7 +225,7 @@ int32_t mz_stream_zlib_write(void *stream, const void *buf, uint32_t size)
return 0;
}
zlib->zstream.avail_out = UINT32_MAX;
zlib->zstream.avail_out = sizeof(zlib->buffer);
zlib->zstream.next_out = zlib->buffer;
zlib->buffer_len = 0;

16
unzip.c
View File

@ -1,4 +1,4 @@
/* unzip.c -- IO for uncompress .zip files using zlib
/* unzip.c -- Zip manipulation
Version 1.2.0, September 16th, 2017
part of the MiniZip project
@ -59,7 +59,7 @@
/***************************************************************************/
// Contains internal information about the zipfile
// Contains internal information about the zip file
typedef struct mz_unzip_s
{
mz_unzip_global global_info; // public global information
@ -71,8 +71,8 @@ typedef struct mz_unzip_s
void *crypt_stream; // encryption stream
void *file_info_stream; // memory stream for storing file info
uint64_t byte_before_the_zipfile; // byte before the zipfile, (>0 for sfx)
uint64_t num_file; // number of the current file in the zipfile
uint64_t byte_before_the_zipfile; // byte before the zip file, (>0 for sfx)
uint64_t num_file; // number of the current file in the zip file
uint64_t pos_in_central_dir; // pos of the current file in the central dir
uint64_t central_pos; // position of the beginning of the central dir
uint32_t number_disk; // number of the current disk, used for spanning ZIP
@ -80,7 +80,7 @@ typedef struct mz_unzip_s
uint64_t offset_central_dir; // offset of start of central directory with
// respect to the starting disk number
uint64_t pos_in_zipfile; // position in byte on the zipfile, for fseek
uint64_t pos_in_zipfile; // position in byte on the zip file, for fseek
uint8_t stream_initialised; // flag set if stream structure is initialised
uint64_t stream_available; // number of byte to be decompressed
@ -155,7 +155,7 @@ static uint64_t mz_unzip_search_cd(void *stream)
return pos_found;
}
// Locate the central directory 64 of a zipfile (at the end, just before the global comment)
// Locate the central directory 64 of a zip file (at the end, just before the global comment)
static uint64_t mz_unzip_search_zip64_cd(void *stream, const uint64_t endcentraloffset)
{
uint64_t offset = 0;
@ -409,7 +409,7 @@ extern int ZEXPORT mz_unzip_get_global_comment(void *handle, char *comment, uint
return MZ_OK;
}
// Get info about the current file in the zipfile
// Get info about the current file in the zip file
static int mz_unzip_entry_read_header(void *handle)
{
mz_unzip *unzip = NULL;
@ -609,7 +609,7 @@ static int mz_unzip_entry_read_header(void *handle)
return err;
}
// Read the local header of the current zipfile. Check the coherency of the local header and info in the
// Read the local header of the current zip file. Check the coherency of the local header and info in the
// end of central directory about this file store in extrainfo_size the size of extra info in local header
// (filename and size of extra field data)
static int mz_unzip_entry_check_header(mz_unzip *unzip, uint32_t *extrainfo_size, uint64_t *extrafield_local_offset,

View File

@ -1,5 +1,5 @@
/* unzip.h -- IO for uncompress .zip files using zlib
Version 1.2.0, September 16th, 2017
/* unzip.h -- Zip manipulation
Version 1.3.0, September 16th, 2017
part of the MiniZip project
Copyright (C) 2012-2017 Nathan Moinvaziri
@ -54,7 +54,7 @@ typedef struct mz_unzip_global_s
{
uint64_t number_entry; // total number of entries in the central dir on this disk
uint32_t number_disk_with_CD; // number the the disk with central dir, used for spanning ZIP
uint16_t comment_size; // size of the global comment of the zipfile
uint16_t comment_size; // size of the global comment of the zip file
} mz_unzip_global;
// Info about a file in the zip file at the central directory

View File

@ -143,7 +143,6 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\minishared.c" />
<ClCompile Include="..\miniunz.c" />
</ItemGroup>
<ItemGroup>
@ -151,9 +150,6 @@
<Project>{17a4a51f-3e4f-419a-9192-28559785cf66}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\minishared.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -11,16 +11,8 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\minishared.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\miniunz.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\minishared.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -138,12 +138,8 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\minishared.c" />
<ClCompile Include="..\minizip.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\minishared.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="libminizip.vcxproj">
<Project>{17a4a51f-3e4f-419a-9192-28559785cf66}</Project>

View File

@ -11,16 +11,8 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\minishared.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\minizip.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\minishared.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

12
zip.c
View File

@ -1,5 +1,5 @@
/* zip.c -- IO on .zip files using zlib
Version 1.2.0, September 16th, 2017
/* zip.c -- Zip manipulation
Version 1.3.0, September 16th, 2017
part of the MiniZip project
Copyright (C) 2010-2017 Nathan Moinvaziri
@ -86,7 +86,7 @@ typedef struct mz_zip_s
/***************************************************************************/
// Locate the central directory of a zipfile (at the end, just before the global comment)
// Locate the central directory of a zip file (at the end, just before the global comment)
static uint64_t mz_zip_search_cd(void *stream)
{
uint8_t buf[BUFREADCOMMENT + 4];
@ -141,7 +141,7 @@ static uint64_t mz_zip_search_cd(void *stream)
return pos_found;
}
// Locate the central directory 64 of a zipfile (at the end, just before the global comment)
// Locate the central directory 64 of a zip file (at the end, just before the global comment)
static uint64_t mz_zip_search_zip64_cd(void *stream, const uint64_t endcentraloffset)
{
uint64_t offset = 0;
@ -181,7 +181,7 @@ extern void* ZEXPORT mz_zip_open(const char *path, int append, uint64_t disk_siz
{
mz_zip *zip = NULL;
#ifndef NO_ADDFILEINEXISTINGZIP
uint64_t byte_before_the_zipfile = 0; // byte before the zipfile, (>0 for sfx)
uint64_t byte_before_the_zipfile = 0; // byte before the zip file, (>0 for sfx)
uint64_t size_central_dir = 0; // size of the central directory
uint64_t offset_central_dir = 0; // offset of start of central directory
uint64_t number_entry_CD = 0; // total number of entries in the central dir
@ -230,7 +230,7 @@ extern void* ZEXPORT mz_zip_open(const char *path, int append, uint64_t disk_siz
mz_stream_mem_open(zip->cd_stream, NULL, MZ_STREAM_MODE_CREATE);
#ifndef NO_ADDFILEINEXISTINGZIP
// Add file in a zipfile
// Add file in a zip file
if (append == MZ_APPEND_STATUS_ADDINZIP)
{
// Read and cache central directory records

16
zip.h
View File

@ -1,5 +1,5 @@
/* zip.h -- IO on .zip files using zlib
Version 1.2.0, September 16th, 2017
/* zip.h -- Zip manipulation
Version 1.3.0, September 16th, 2017
part of the MiniZip project
Copyright (C) 2012-2017 Nathan Moinvaziri
@ -90,9 +90,9 @@ typedef struct mz_zip_crypt_s
/***************************************************************************/
extern void* ZEXPORT mz_zip_open(const char *path, int append, uint64_t disk_size, void *stream);
// Create a zipfile
// Create a zip file
//
// NOTE: There is no delete function into a zipfile. If you want delete file in a zip file,
// NOTE: There is no delete function into a zip file. If you want delete file in a zip file,
// you must open a zip file, and create another. You can use RAW reading and writing to copy
// the file you did not want delete.
@ -104,16 +104,16 @@ extern int ZEXPORT mz_zip_entry_open(void *handle, const mz_zip_file *file_info,
// Open a file in the ZIP for writing
extern int ZEXPORT mz_zip_entry_write(void *handle, const void *buf, uint32_t len);
// Write data in the zipfile
// Write data in the zip file
extern int ZEXPORT mz_zip_entry_close(void *handle);
// Close the current file in the zipfile
// Close the current file in the zip file
extern int ZEXPORT mz_zip_entry_close_raw(void *handle, uint64_t uncompressed_size, uint32_t crc32);
// Close the current file in the zipfile where raw is compressed data
// Close the current file in the zip file where raw is compressed data
extern int ZEXPORT mz_zip_close(void *handle, const char *global_comment, uint16_t version_madeby);
// Close the zipfile
// Close the zip file
/***************************************************************************/