diff --git a/3rdparty/libzip/lib/compat.h b/3rdparty/libzip/lib/compat.h index d8eaab1d49..49d3aa397a 100644 --- a/3rdparty/libzip/lib/compat.h +++ b/3rdparty/libzip/lib/compat.h @@ -123,14 +123,64 @@ typedef char bool; #endif #endif -#ifndef HAVE_FSEEKO -#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) + +#if defined(HAVE__FSEEKI64) && defined(HAVE__FSTAT64) && defined(HAVE__SEEK64) +/* Windows API using int64 */ +typedef zip_int64_t zip_off_t; +typedef struct _stat64 zip_os_stat_t; +#define zip_os_stat _stat64 +#define zip_os_fstat _fstat64 +#define zip_os_seek _fseeki64 +#define ZIP_FSEEK_MAX ZIP_INT64_MAX +#define ZIP_FSEEK_MIN ZIP_INT64_MIN +#else + +/* Normal API */ +#include +typedef struct stat zip_os_stat_t; +#define zip_os_fstat fstat +#define zip_os_stat stat + +#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO) +/* Using off_t */ +typedef off_t zip_off_t; +#if SIZEOF_OFF_T == 8 +#define ZIP_OFF_MAX ZIP_INT64_MAX +#define ZIP_OFF_MIN ZIP_INT64_MIN +#elif SIZEOF_OFF_T == 4 +#define ZIP_OFF_MAX ZIP_INT32_MAX +#define ZIP_OFF_MIN ZIP_INT32_MIN +#elif SIZEOF_OFF_T == 2 +#define ZIP_OFF_MAX ZIP_INT16_MAX +#define ZIP_OFF_MIN ZIP_INT16_MIN +#else +#error unsupported size of off_t +#endif + +#define ZIP_FSEEK_MAX ZIP_OFF_MAX +#define ZIP_FSEEK_MIN ZIP_OFF_MIN + +#define zip_os_fseek fseeko +#define zip_os_ftell ftello +#else + +/* Using long */ +typedef long zip_off_t; +#include +#define ZIP_FSEEK_MAX LONG_MAX +#define ZIP_FSEEK_MIN LONG_MIN + +#define zip_os_fseek fseek +#define zip_os_ftell ftell +#endif + #endif #ifndef HAVE_FTELLO #define ftello(s) ((long)ftell((s))) #endif + #ifdef HAVE_LOCALTIME_S #ifdef _WIN32 /* Windows is incompatible to the C11 standard, hurray! */ @@ -179,27 +229,6 @@ typedef char bool; #endif #endif -#if SIZEOF_OFF_T == 8 -#define ZIP_OFF_MAX ZIP_INT64_MAX -#define ZIP_OFF_MIN ZIP_INT64_MIN -#elif SIZEOF_OFF_T == 4 -#define ZIP_OFF_MAX ZIP_INT32_MAX -#define ZIP_OFF_MIN ZIP_INT32_MIN -#elif SIZEOF_OFF_T == 2 -#define ZIP_OFF_MAX ZIP_INT16_MAX -#define ZIP_OFF_MIN ZIP_INT16_MIN -#else -#error unsupported size of off_t -#endif - -#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO) -#define ZIP_FSEEK_MAX ZIP_OFF_MAX -#define ZIP_FSEEK_MIN ZIP_OFF_MIN -#else -#include -#define ZIP_FSEEK_MAX LONG_MAX -#define ZIP_FSEEK_MIN LONG_MIN -#endif #ifndef SIZE_MAX #if SIZEOF_SIZE_T == 8 diff --git a/3rdparty/libzip/lib/zip_dirent.c b/3rdparty/libzip/lib/zip_dirent.c index 85c4c6dc5e..24bc6abf9c 100644 --- a/3rdparty/libzip/lib/zip_dirent.c +++ b/3rdparty/libzip/lib/zip_dirent.c @@ -39,7 +39,6 @@ #include #include -#include "zip.h" #include "zipint.h" static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str, bool check_consistency); @@ -283,6 +282,7 @@ _zip_dirent_init(zip_dirent_t *de) { de->cloned = 0; de->crc_valid = true; + de->last_mod_mtime_valid = false; de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8); de->version_needed = 10; /* 1.0 */ de->bitflags = 0; @@ -1264,3 +1264,12 @@ zip_dirent_check_consistency(zip_dirent_t *dirent) { } return 0; } + +time_t zip_dirent_get_last_mod_mtime(zip_dirent_t *de) { + if (!de->last_mod_mtime_valid) { + de->last_mod_mtime = _zip_d2u_time(&de->last_mod); + de->last_mod_mtime_valid = true; + } + + return de->last_mod_mtime; +} \ No newline at end of file diff --git a/3rdparty/libzip/lib/zip_file_set_mtime.c b/3rdparty/libzip/lib/zip_file_set_mtime.c index d08d808beb..e60f7a9aaa 100644 --- a/3rdparty/libzip/lib/zip_file_set_mtime.c +++ b/3rdparty/libzip/lib/zip_file_set_mtime.c @@ -33,8 +33,7 @@ #include "zipint.h" -ZIP_EXTERN int -zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) { +static int zip_file_set_time(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags, time_t *mtime) { zip_entry_t *e; if (_zip_get_dirent(za, idx, 0, NULL) == NULL) { @@ -66,18 +65,29 @@ zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16 e->changes->last_mod.time = dtime; e->changes->last_mod.date = ddate; + if (mtime != NULL) { + e->changes->last_mod_mtime = *mtime; + e->changes->last_mod_mtime_valid = true; + } + else { + e->changes->last_mod_mtime_valid = false; + } e->changes->changed |= ZIP_DIRENT_LAST_MOD; return 0; } -ZIP_EXTERN int -zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) { +ZIP_EXTERN int zip_file_set_dostime(zip_t *za, zip_uint64_t idx, zip_uint16_t dtime, zip_uint16_t ddate, zip_flags_t flags) { + return zip_file_set_time(za, idx, dtime, ddate, flags, NULL); +} + + +ZIP_EXTERN int zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags) { zip_dostime_t dostime; if (_zip_u2d_time(mtime, &dostime, &za->error) < 0) { return -1; } - return zip_file_set_dostime(za, idx, dostime.time, dostime.date, flags); + return zip_file_set_time(za, idx, dostime.time, dostime.date, flags, &mtime); } diff --git a/3rdparty/libzip/lib/zip_new.c b/3rdparty/libzip/lib/zip_new.c index fa21086b5f..68e1588fee 100644 --- a/3rdparty/libzip/lib/zip_new.c +++ b/3rdparty/libzip/lib/zip_new.c @@ -68,6 +68,7 @@ _zip_new(zip_error_t *error) { za->nopen_source = za->nopen_source_alloc = 0; za->open_source = NULL; za->progress = NULL; + za->torrent_mtime = 0; return za; } diff --git a/3rdparty/libzip/lib/zip_source_file_stdio.c b/3rdparty/libzip/lib/zip_source_file_stdio.c index f467a87f55..0fb858f122 100644 --- a/3rdparty/libzip/lib/zip_source_file_stdio.c +++ b/3rdparty/libzip/lib/zip_source_file_stdio.c @@ -39,7 +39,6 @@ #include #include #include -#include #ifdef _WIN32 #ifndef S_IWUSR @@ -120,7 +119,7 @@ _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, } #endif - if (fseeko((FILE *)f, (off_t)offset, whence) < 0) { + if (zip_os_fseek((FILE *)f, (zip_off_t)offset, whence) < 0) { zip_error_set(&ctx->error, ZIP_ER_SEEK, errno); return false; } @@ -130,15 +129,15 @@ _zip_stdio_op_seek(zip_source_file_context_t *ctx, void *f, zip_int64_t offset, bool _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) { - struct stat sb; + zip_os_stat_t sb; int ret; if (ctx->fname) { - ret = stat(ctx->fname, &sb); + ret = zip_os_stat(ctx->fname, &sb); } else { - ret = fstat(fileno((FILE *)ctx->f), &sb); + ret = zip_os_fstat(fileno((FILE *)ctx->f), &sb); } if (ret < 0) { @@ -168,7 +167,7 @@ _zip_stdio_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t *st) { zip_int64_t _zip_stdio_op_tell(zip_source_file_context_t *ctx, void *f) { - off_t offset = ftello((FILE *)f); + zip_off_t offset = zip_os_ftell((FILE *)f); if (offset < 0) { zip_error_set(&ctx->error, ZIP_ER_SEEK, errno); diff --git a/3rdparty/libzip/lib/zip_source_file_stdio_named.c b/3rdparty/libzip/lib/zip_source_file_stdio_named.c index 4a9e5f02ce..1a5ca22603 100644 --- a/3rdparty/libzip/lib/zip_source_file_stdio_named.c +++ b/3rdparty/libzip/lib/zip_source_file_stdio_named.c @@ -178,9 +178,9 @@ _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uin { int fd; struct file_clone_range range; - struct stat st; + zip_os_stat_t st; - if (fstat(fileno(ctx->f), &st) < 0) { + if (zip_os_fstat(fileno(ctx->f), &st) < 0) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); return -1; } @@ -223,7 +223,7 @@ _zip_stdio_op_create_temp_output_cloning(zip_source_file_context_t *ctx, zip_uin ctx->tmpname = NULL; return -1; } - if (fseeko(tfp, (off_t)offset, SEEK_SET) < 0) { + if (zip_os_fseek(tfp, (zip_off_t)offset, SEEK_SET) < 0) { zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno); (void)fclose(tfp); (void)remove(ctx->tmpname); @@ -290,11 +290,11 @@ _zip_stdio_op_write(zip_source_file_context_t *ctx, const void *data, zip_uint64 static int create_temp_file(zip_source_file_context_t *ctx, bool create_file) { char *temp; int mode; - struct stat st; + zip_os_stat_t st; int fd = 0; char *start, *end; - if (stat(ctx->fname, &st) == 0) { + if (zip_os_stat(ctx->fname, &st) == 0) { mode = st.st_mode; } else { @@ -344,7 +344,7 @@ static int create_temp_file(zip_source_file_context_t *ctx, bool create_file) { } } else { - if (stat(temp, &st) < 0) { + if (zip_os_stat(temp, &st) < 0) { if (errno == ENOENT) { break; } diff --git a/3rdparty/libzip/lib/zip_stat_index.c b/3rdparty/libzip/lib/zip_stat_index.c index 5130eb6ac4..af9f0e5fc8 100644 --- a/3rdparty/libzip/lib/zip_stat_index.c +++ b/3rdparty/libzip/lib/zip_stat_index.c @@ -77,7 +77,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) } if (entry->changes != NULL && entry->changes->changed & ZIP_DIRENT_LAST_MOD) { - st->mtime = _zip_d2u_time(&de->last_mod); + st->mtime = zip_dirent_get_last_mod_mtime(de); st->valid |= ZIP_STAT_MTIME; } } @@ -86,7 +86,7 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) st->crc = de->crc; st->size = de->uncomp_size; - st->mtime = _zip_d2u_time(&de->last_mod); + st->mtime = zip_dirent_get_last_mod_mtime(de); st->comp_size = de->comp_size; st->comp_method = (zip_uint16_t)de->comp_method; st->encryption_method = de->encryption_method; @@ -97,9 +97,12 @@ zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags, zip_stat_t *st) } if ((za->ch_flags & ZIP_AFL_WANT_TORRENTZIP) && (flags & ZIP_FL_UNCHANGED) == 0) { - zip_dostime_t dostime = {0xbc00, 0x2198}; + if (za->torrent_mtime == 0) { + zip_dostime_t dostime = {0xbc00, 0x2198}; + za->torrent_mtime = _zip_d2u_time(&dostime); + } st->comp_method = ZIP_CM_DEFLATE; - st->mtime = _zip_d2u_time(&dostime); + st->mtime = za->torrent_mtime; st->valid |= ZIP_STAT_MTIME | ZIP_STAT_COMP_METHOD; st->valid &= ~ZIP_STAT_COMP_SIZE; } diff --git a/3rdparty/libzip/lib/zipint.h b/3rdparty/libzip/lib/zipint.h index 5b931dcee7..e22d74c21d 100644 --- a/3rdparty/libzip/lib/zipint.h +++ b/3rdparty/libzip/lib/zipint.h @@ -314,6 +314,7 @@ struct zip { zip_progress_t *progress; /* progress callback for zip_close() */ zip_uint32_t* write_crc; /* have _zip_write() compute CRC */ + time_t torrent_mtime; }; /* file in zip archive, part of API */ @@ -346,6 +347,7 @@ struct zip_dirent { bool cloned; /* whether this instance is cloned, and thus shares non-changed strings */ bool crc_valid; /* if CRC is valid (sometimes not for encrypted archives) */ + bool last_mod_mtime_valid; zip_uint16_t version_madeby; /* (c) version of creator */ zip_uint16_t version_needed; /* (cl) version needed to extract */ @@ -366,6 +368,8 @@ struct zip_dirent { zip_uint32_t compression_level; /* level of compression to use (never valid in orig) */ zip_uint16_t encryption_method; /* encryption method, computed from other fields */ char *password; /* file specific encryption password */ + + time_t last_mod_mtime; /* cached last_mod in Unix time format */ }; /* zip archive central directory */ @@ -553,6 +557,7 @@ int zip_dirent_check_consistency(zip_dirent_t *dirent); zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *); void _zip_dirent_free(zip_dirent_t *); void _zip_dirent_finalize(zip_dirent_t *); +time_t zip_dirent_get_last_mod_mtime(zip_dirent_t *de); void _zip_dirent_init(zip_dirent_t *); bool _zip_dirent_needs_zip64(const zip_dirent_t *, zip_flags_t); zip_dirent_t *_zip_dirent_new(void);