summaryrefslogtreecommitdiff
path: root/ext/zip/lib/zip_close.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/zip/lib/zip_close.c')
-rw-r--r--ext/zip/lib/zip_close.c492
1 files changed, 0 insertions, 492 deletions
diff --git a/ext/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c
deleted file mode 100644
index b3379cfae5..0000000000
--- a/ext/zip/lib/zip_close.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- zip_close.c -- close zip archive and update changes
- Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
-
- This file is part of libzip, a library to manipulate ZIP archives.
- The authors can be contacted at <libzip@nih.at>
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- 3. The names of the authors may not be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#include "zipint.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef _WIN32
-#include <io.h>
-#include <fcntl.h>
-#endif
-
-
-/* max deflate size increase: size + ceil(size/16k)*5+6 */
-#define MAX_DEFLATE_SIZE_32 4293656963u
-
-static int add_data(zip_t *, zip_source_t *, zip_dirent_t *);
-static int copy_data(zip_t *, zip_uint64_t);
-static int copy_source(zip_t *, zip_source_t *);
-static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
-
-
-ZIP_EXTERN int
-zip_close(zip_t *za)
-{
- zip_uint64_t i, j, survivors;
- zip_int64_t off;
- int error;
- zip_filelist_t *filelist;
- int changed;
-
- if (za == NULL)
- return -1;
-
- changed = _zip_changed(za, &survivors);
-
- /* don't create zip files with no entries */
- if (survivors == 0) {
- if ((za->open_flags & ZIP_TRUNCATE) || changed) {
- if (zip_source_remove(za->src) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
- return -1;
- }
- }
- zip_discard(za);
- return 0;
- }
-
- if (!changed) {
- zip_discard(za);
- return 0;
- }
-
- if (survivors > za->nentry) {
- zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
- return -1;
- }
-
- if ((filelist=(zip_filelist_t *)malloc(sizeof(filelist[0])*(size_t)survivors)) == NULL)
- return -1;
-
- /* create list of files with index into original archive */
- for (i=j=0; i<za->nentry; i++) {
- if (za->entry[i].deleted)
- continue;
-
- if (j >= survivors) {
- free(filelist);
- zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
- return -1;
- }
-
- filelist[j].idx = i;
- j++;
- }
- if (j < survivors) {
- free(filelist);
- zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
- return -1;
- }
-
- if (zip_source_begin_write(za->src) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
- free(filelist);
- return -1;
- }
-
- error = 0;
- for (j=0; j<survivors; j++) {
- int new_data;
- zip_entry_t *entry;
- zip_dirent_t *de;
-
- i = filelist[j].idx;
- entry = za->entry+i;
-
- new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD));
-
- /* create new local directory entry */
- if (entry->changes == NULL) {
- if ((entry->changes=_zip_dirent_clone(entry->orig)) == NULL) {
- zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
- error = 1;
- break;
- }
- }
- de = entry->changes;
-
- if (_zip_read_local_ef(za, i) < 0) {
- error = 1;
- break;
- }
-
- if ((off = zip_source_tell_write(za->src)) < 0) {
- error = 1;
- break;
- }
- de->offset = (zip_uint64_t)off;
-
- if (new_data) {
- zip_source_t *zs;
-
- zs = NULL;
- if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
- if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) {
- error = 1;
- break;
- }
- }
-
- /* add_data writes dirent */
- if (add_data(za, zs ? zs : entry->source, de) < 0) {
- error = 1;
- if (zs)
- zip_source_free(zs);
- break;
- }
- if (zs)
- zip_source_free(zs);
- }
- else {
- zip_uint64_t offset;
-
- /* when copying data, all sizes are known -> no data descriptor needed */
- de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
- if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) {
- error = 1;
- break;
- }
- if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) {
- error = 1;
- break;
- }
- if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
- error = 1;
- break;
- }
- if (copy_data(za, de->comp_size) < 0) {
- error = 1;
- break;
- }
- }
- }
-
- if (!error) {
- if (write_cdir(za, filelist, survivors) < 0)
- error = 1;
- }
-
- free(filelist);
-
- if (!error) {
- if (zip_source_commit_write(za->src) != 0) {
- _zip_error_set_from_source(&za->error, za->src);
- error = 1;
- }
- }
-
- if (error) {
- zip_source_rollback_write(za->src);
- return -1;
- }
-
- zip_discard(za);
-
- return 0;
-}
-
-
-static int
-add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de)
-{
- zip_int64_t offstart, offdata, offend;
- struct zip_stat st;
- zip_source_t *s2;
- int ret;
- int is_zip64;
- zip_flags_t flags;
-
- if (zip_source_stat(src, &st) < 0) {
- _zip_error_set_from_source(&za->error, src);
- return -1;
- }
-
- if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
- st.valid |= ZIP_STAT_COMP_METHOD;
- st.comp_method = ZIP_CM_STORE;
- }
-
- if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE)
- de->comp_method = st.comp_method;
- else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
- st.valid |= ZIP_STAT_COMP_SIZE;
- st.comp_size = st.size;
- }
- else {
- /* we'll recompress */
- st.valid &= ~ZIP_STAT_COMP_SIZE;
- }
-
-
- flags = ZIP_EF_LOCAL;
-
- if ((st.valid & ZIP_STAT_SIZE) == 0)
- flags |= ZIP_FL_FORCE_ZIP64;
- else {
- de->uncomp_size = st.size;
-
- if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) {
- if (( ((de->comp_method == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(de->comp_method)) && st.size > MAX_DEFLATE_SIZE_32)
- || (de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(de->comp_method))))
- flags |= ZIP_FL_FORCE_ZIP64;
- }
- else
- de->comp_size = st.comp_size;
- }
-
- if ((offstart = zip_source_tell_write(za->src)) < 0) {
- return -1;
- }
-
- /* as long as we don't support non-seekable output, clear data descriptor bit */
- de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
- if ((is_zip64=_zip_dirent_write(za, de, flags)) < 0)
- return -1;
-
-
- if (st.comp_method == ZIP_CM_STORE || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != de->comp_method)) {
- zip_source_t *s_store, *s_crc;
- zip_compression_implementation comp_impl;
-
- if (st.comp_method != ZIP_CM_STORE) {
- if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) {
- zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
- return -1;
- }
- if ((s_store=comp_impl(za, src, st.comp_method, ZIP_CODEC_DECODE)) == NULL) {
- /* error set by comp_impl */
- return -1;
- }
- }
- else {
- /* to have the same reference count to src as in the case where it's not stored */
- zip_source_keep(src);
- s_store = src;
- }
-
- s_crc = zip_source_crc(za, s_store, 0);
- zip_source_free(s_store);
- if (s_crc == NULL) {
- return -1;
- }
-
- if (de->comp_method != ZIP_CM_STORE && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
- if ((comp_impl=_zip_get_compression_implementation(de->comp_method)) == NULL) {
- zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
- zip_source_free(s_crc);
- return -1;
- }
- s2 = comp_impl(za, s_crc, de->comp_method, ZIP_CODEC_ENCODE);
- zip_source_free(s_crc);
- if (s2 == NULL) {
- return -1;
- }
- }
- else {
- s2 = s_crc;
- }
- }
- else {
- zip_source_keep(src);
- s2 = src;
- }
-
- if ((offdata = zip_source_tell_write(za->src)) < 0) {
- return -1;
- }
-
- ret = copy_source(za, s2);
-
- if (zip_source_stat(s2, &st) < 0)
- ret = -1;
-
- zip_source_free(s2);
-
- if (ret < 0)
- return -1;
-
- if ((offend = zip_source_tell_write(za->src)) < 0) {
- return -1;
- }
-
- if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
- return -1;
- }
-
- if ((st.valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) {
- zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
- return -1;
- }
-
- if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
- if (st.valid & ZIP_STAT_MTIME)
- de->last_mod = st.mtime;
- else
- time(&de->last_mod);
- }
- de->comp_method = st.comp_method;
- de->crc = st.crc;
- de->uncomp_size = st.size;
- de->comp_size = (zip_uint64_t)(offend - offdata);
-
- if ((ret=_zip_dirent_write(za, de, flags)) < 0)
- return -1;
-
- if (is_zip64 != ret) {
- /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
- zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
- return -1;
- }
-
-
- if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
- return -1;
- }
-
- return 0;
-}
-
-
-static int
-copy_data(zip_t *za, zip_uint64_t len)
-{
- zip_uint8_t buf[BUFSIZE];
- size_t n;
-
- while (len > 0) {
- n = len > sizeof(buf) ? sizeof(buf) : len;
- if (_zip_read(za->src, buf, n, &za->error) < 0) {
- return -1;
- }
-
- if (_zip_write(za, buf, n) < 0) {
- return -1;
- }
-
- len -= n;
- }
-
- return 0;
-}
-
-
-static int
-copy_source(zip_t *za, zip_source_t *src)
-{
- zip_uint8_t buf[BUFSIZE];
- zip_int64_t n;
- int ret;
-
- if (zip_source_open(src) < 0) {
- _zip_error_set_from_source(&za->error, src);
- return -1;
- }
-
- ret = 0;
- while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
- if (_zip_write(za, buf, (zip_uint64_t)n) < 0) {
- ret = -1;
- break;
- }
- }
-
- if (n < 0) {
- _zip_error_set_from_source(&za->error, src);
- ret = -1;
- }
-
- zip_source_close(src);
-
- return ret;
-}
-
-
-static int
-write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
-{
- zip_int64_t cd_start, end, size;
-
- if ((cd_start = zip_source_tell_write(za->src)) < 0) {
- return -1;
- }
-
- if ((size=_zip_cdir_write(za, filelist, survivors)) < 0) {
- return -1;
- }
-
- if ((end = zip_source_tell_write(za->src)) < 0) {
- return -1;
- }
-
- return 0;
-}
-
-
-int
-_zip_changed(const zip_t *za, zip_uint64_t *survivorsp)
-{
- int changed;
- zip_uint64_t i, survivors;
-
- changed = 0;
- survivors = 0;
-
- if (za->comment_changed || za->ch_flags != za->flags)
- changed = 1;
-
- for (i=0; i<za->nentry; i++) {
- if (za->entry[i].deleted || za->entry[i].source || (za->entry[i].changes && za->entry[i].changes->changed != 0))
- changed = 1;
- if (!za->entry[i].deleted)
- survivors++;
- }
-
- if (survivorsp)
- *survivorsp = survivors;
-
- return changed;
-}