annotate libzip/lib/zip_close.c @ 56:056ee6b5913e

libzip: update to 1.3.0, closes #654
author David Demelier <markand@malikania.fr>
date Tue, 10 Oct 2017 20:43:12 +0200
parents 2306f4b04790
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 zip_close.c -- close zip archive and update changes
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
3 Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 This file is part of libzip, a library to manipulate ZIP archives.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 The authors can be contacted at <libzip@nih.at>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
7
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 Redistribution and use in source and binary forms, with or without
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 modification, are permitted provided that the following conditions
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 are met:
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 1. Redistributions of source code must retain the above copyright
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 notice, this list of conditions and the following disclaimer.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 2. Redistributions in binary form must reproduce the above copyright
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 notice, this list of conditions and the following disclaimer in
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 the documentation and/or other materials provided with the
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 distribution.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 3. The names of the authors may not be used to endorse or promote
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
18 products derived from this software without specific prior
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 written permission.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
20
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
33
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
34
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 #include "zipint.h"
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
36
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 #include <stdio.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 #include <stdlib.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 #include <string.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 #ifdef HAVE_STRINGS_H
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 #include <strings.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 #endif
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 #ifdef HAVE_UNISTD_H
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 #include <unistd.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 #endif
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 #include <sys/types.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 #include <sys/stat.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 #ifdef _WIN32
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 #include <io.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 #include <fcntl.h>
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 #endif
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
52
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
53
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 static int add_data(zip_t *, zip_source_t *, zip_dirent_t *);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 static int copy_data(zip_t *, zip_uint64_t);
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
56 static int copy_source(zip_t *, zip_source_t *, zip_int64_t);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
58
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 ZIP_EXTERN int
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 zip_close(zip_t *za)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 zip_uint64_t i, j, survivors;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 zip_int64_t off;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 int error;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 zip_filelist_t *filelist;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 int changed;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
67
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 if (za == NULL)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
70
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 changed = _zip_changed(za, &survivors);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
72
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 /* don't create zip files with no entries */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 if (survivors == 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 if ((za->open_flags & ZIP_TRUNCATE) || changed) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 if (zip_source_remove(za->src) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 _zip_error_set_from_source(&za->error, za->src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 zip_discard(za);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
84
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 if (!changed) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 zip_discard(za);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
89
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 if (survivors > za->nentry) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
94
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 if ((filelist=(zip_filelist_t *)malloc(sizeof(filelist[0])*(size_t)survivors)) == NULL)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
97
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 /* create list of files with index into original archive */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 for (i=j=0; i<za->nentry; i++) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 if (za->entry[i].deleted)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 continue;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
102
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 if (j >= survivors) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 free(filelist);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
108
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 filelist[j].idx = i;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 j++;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 if (j < survivors) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 free(filelist);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
117
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 if (zip_source_begin_write(za->src) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 _zip_error_set_from_source(&za->error, za->src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 free(filelist);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 }
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
123
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
124 _zip_progress_start(za->progress);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 error = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 for (j=0; j<survivors; j++) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 int new_data;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 zip_entry_t *entry;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 zip_dirent_t *de;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
130
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
131 _zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j+1) / (double)survivors);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
132
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 i = filelist[j].idx;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 entry = za->entry+i;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
135
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
136 new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD));
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
137
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 /* create new local directory entry */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 if (entry->changes == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 if ((entry->changes=_zip_dirent_clone(entry->orig)) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 de = entry->changes;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
147
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 if (_zip_read_local_ef(za, i) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
152
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 if ((off = zip_source_tell_write(za->src)) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 de->offset = (zip_uint64_t)off;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
158
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 if (new_data) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 zip_source_t *zs;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
161
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 zs = NULL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
169
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 /* add_data writes dirent */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 if (add_data(za, zs ? zs : entry->source, de) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 if (zs)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 zip_source_free(zs);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 if (zs)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 zip_source_free(zs);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 else {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 zip_uint64_t offset;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
182
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 /* when copying data, all sizes are known -> no data descriptor needed */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 _zip_error_set_from_source(&za->error, za->src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 if (copy_data(za, de->comp_size) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
204
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 if (!error) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 if (write_cdir(za, filelist, survivors) < 0)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
209
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 free(filelist);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
211
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 if (!error) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 if (zip_source_commit_write(za->src) != 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 _zip_error_set_from_source(&za->error, za->src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 error = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
218
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 if (error) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 zip_source_rollback_write(za->src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
223
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
224 _zip_progress_end(za->progress);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
225
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 zip_discard(za);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
227
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
230
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
231
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
232 static int
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 {
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
235 zip_int64_t offstart, offdata, offend, data_length;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 struct zip_stat st;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
237 zip_source_t *src_final, *src_tmp;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 int ret;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 int is_zip64;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 zip_flags_t flags;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
241 zip_int8_t compression_flags;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
242 bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
243
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 if (zip_source_stat(src, &st) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 _zip_error_set_from_source(&za->error, src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
247 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
248
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 st.valid |= ZIP_STAT_COMP_METHOD;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 st.comp_method = ZIP_CM_STORE;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
253
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
254 if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
255 de->comp_method = st.comp_method;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 st.valid |= ZIP_STAT_COMP_SIZE;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 st.comp_size = st.size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 else {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 /* we'll recompress */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 st.valid &= ~ZIP_STAT_COMP_SIZE;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
264
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
265 if ((st.valid & ZIP_STAT_ENCRYPTION_METHOD) == 0) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
266 st.valid |= ZIP_STAT_ENCRYPTION_METHOD;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
267 st.encryption_method = ZIP_EM_NONE;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
268 }
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
269
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 flags = ZIP_EF_LOCAL;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
271
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
272 if ((st.valid & ZIP_STAT_SIZE) == 0) {
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 flags |= ZIP_FL_FORCE_ZIP64;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
274 data_length = -1;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
275 }
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
276 else {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 de->uncomp_size = st.size;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
278 /* this is technically incorrect (copy_source counts compressed data), but it's the best we have */
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
279 data_length = (zip_int64_t)st.size;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
280
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) {
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
282 zip_uint64_t max_size;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
283
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
284 switch (ZIP_CM_ACTUAL(de->comp_method)) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
285 case ZIP_CM_BZIP2:
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
286 /* computed by looking at increase of 10 random files of size 1MB when
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
287 * compressed with bzip2, rounded up: 1.006 */
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
288 max_size = 4269351188u;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
289 break;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
290
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
291 case ZIP_CM_DEFLATE:
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
292 /* max deflate size increase: size + ceil(size/16k)*5+6 */
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
293 max_size = 4293656963u;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
294 break;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
295
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
296 case ZIP_CM_STORE:
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
297 max_size = 0xffffffffu;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
298 break;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
299
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
300 default:
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
301 max_size = 0;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
302 }
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
303
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
304 if (st.size > max_size) {
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 flags |= ZIP_FL_FORCE_ZIP64;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
306 }
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
308 else
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 de->comp_size = st.comp_size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
311
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
312 if ((offstart = zip_source_tell_write(za->src)) < 0) {
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
313 _zip_error_set_from_source(&za->error, za->src);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
316
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 /* as long as we don't support non-seekable output, clear data descriptor bit */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
319 if ((is_zip64=_zip_dirent_write(za, de, flags)) < 0) {
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 return -1;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
321 }
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
322
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
323 needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
324 needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
325 needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
326 needs_compress = needs_recompress && (de->comp_method != ZIP_CM_STORE);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
327
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
328 needs_reencrypt = needs_recompress || (de->changed & ZIP_DIRENT_PASSWORD) || (de->encryption_method != st.encryption_method);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
329 needs_decrypt = needs_reencrypt && (st.encryption_method != ZIP_EM_NONE);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
330 needs_encrypt = needs_reencrypt && (de->encryption_method != ZIP_EM_NONE);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
331
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
332 src_final = src;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
333 zip_source_keep(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
334
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
335 if (needs_decrypt) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
336 zip_encryption_implementation impl;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
337
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
338 if ((impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
339 zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
340 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
341 return -1;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
342 }
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
343 if ((src_tmp = impl(za, src_final, st.encryption_method, ZIP_CODEC_DECODE, za->default_password)) == NULL) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
344 /* error set by impl */
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
345 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
346 return -1;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
347 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
348
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
349 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
350 src_final = src_tmp;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
351 }
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
352
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
353 if (needs_decompress) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
354 if ((src_tmp = zip_source_decompress(za, src_final, st.comp_method)) == NULL) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
355 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
356 return -1;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
357 }
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
358
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
359 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
360 src_final = src_tmp;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
361 }
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
362
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
363 if (needs_crc) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
364 if ((src_tmp = zip_source_crc(za, src_final, 0)) == NULL) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
365 zip_source_free(src_final);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
366 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
367 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
368
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
369 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
370 src_final = src_tmp;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
371 }
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
372
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
373 if (needs_compress) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
374 if ((src_tmp = zip_source_compress(za, src_final, de->comp_method, de->compression_level)) == NULL) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
375 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
376 return -1;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
377 }
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
378
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
379 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
380 src_final = src_tmp;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
381 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
382
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
383
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
384 if (needs_encrypt) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
385 zip_encryption_implementation impl;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
386 const char *password = NULL;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
387
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
388 if (de->password) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
389 password = de->password;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
390 } else if (za->default_password) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
391 password = za->default_password;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
392 }
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
393
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
394 if ((impl = _zip_get_encryption_implementation(de->encryption_method, ZIP_CODEC_ENCODE)) == NULL) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
395 zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
396 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
397 return -1;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
398 }
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
399 if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
400 /* error set by impl */
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
401 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
402 return -1;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
403 }
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
404
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
405 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
406 src_final = src_tmp;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
407 }
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
408
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
409
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
410 if ((offdata = zip_source_tell_write(za->src)) < 0) {
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
411 _zip_error_set_from_source(&za->error, za->src);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
412 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
413 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
414
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
415 ret = copy_source(za, src_final, data_length);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
416
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
417 if (zip_source_stat(src_final, &st) < 0) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
418 _zip_error_set_from_source(&za->error, src_final);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
419 ret = -1;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
420 }
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
421
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
422 if ((compression_flags = zip_source_get_compression_flags(src_final)) < 0) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
423 _zip_error_set_from_source(&za->error, src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
424 ret = -1;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
425 }
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
426
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
427 zip_source_free(src_final);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
428
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
429 if (ret < 0) {
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
430 return -1;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
431 }
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
432
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
433 if ((offend = zip_source_tell_write(za->src)) < 0) {
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
434 _zip_error_set_from_source(&za->error, za->src);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
435 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
436 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
437
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
438 if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
439 _zip_error_set_from_source(&za->error, za->src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
440 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
441 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
442
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
443 if ((st.valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
444 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
445 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
446 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
447
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
448 if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
449 if (st.valid & ZIP_STAT_MTIME)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
450 de->last_mod = st.mtime;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
451 else
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
452 time(&de->last_mod);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
453 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
454 de->comp_method = st.comp_method;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
455 de->crc = st.crc;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
456 de->uncomp_size = st.size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
457 de->comp_size = (zip_uint64_t)(offend - offdata);
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
458 de->bitflags = (zip_uint16_t)((de->bitflags & (zip_uint16_t)~6) | ((zip_uint8_t)compression_flags << 1));
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
459 _zip_dirent_set_version_needed(de, (flags & ZIP_FL_FORCE_ZIP64) != 0);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
460
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
461 if ((ret=_zip_dirent_write(za, de, flags)) < 0)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
462 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
463
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
464 if (is_zip64 != ret) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
465 /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
466 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
467 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
468 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
469
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
470 if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
471 _zip_error_set_from_source(&za->error, za->src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
472 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
473 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
474
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
475 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
476 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
477
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
478
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
479 static int
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
480 copy_data(zip_t *za, zip_uint64_t len)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
481 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
482 zip_uint8_t buf[BUFSIZE];
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
483 size_t n;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
484 double total = (double)len;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
485
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
486 while (len > 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
487 n = len > sizeof(buf) ? sizeof(buf) : len;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
488 if (_zip_read(za->src, buf, n, &za->error) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
489 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
490 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
491
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
492 if (_zip_write(za, buf, n) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
493 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
494 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
495
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
496 len -= n;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
497
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
498 _zip_progress_update(za->progress, (total - (double)len) / total);
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
499 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
500
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
501 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
502 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
503
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
504
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
505 static int
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
506 copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length)
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
507 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
508 zip_uint8_t buf[BUFSIZE];
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
509 zip_int64_t n, current;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
510 int ret;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
511
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
512 if (zip_source_open(src) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
513 _zip_error_set_from_source(&za->error, src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
514 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
515 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
516
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
517 ret = 0;
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
518 current = 0;
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
519 while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
520 if (_zip_write(za, buf, (zip_uint64_t)n) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
521 ret = -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
522 break;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
523 }
56
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
524 if (n == sizeof(buf) && za->progress && data_length > 0) {
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
525 current += n;
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
526 _zip_progress_update(za->progress, (double)current/(double)data_length);
056ee6b5913e libzip: update to 1.3.0, closes #654
David Demelier <markand@malikania.fr>
parents: 4
diff changeset
527 }
4
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
528 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
529
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
530 if (n < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
531 _zip_error_set_from_source(&za->error, src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
532 ret = -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
533 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
534
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
535 zip_source_close(src);
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
536
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
537 return ret;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
538 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
539
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
540 static int
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
541 write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
542 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
543 zip_int64_t cd_start, end, size;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
544
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
545 if ((cd_start = zip_source_tell_write(za->src)) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
546 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
547 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
548
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
549 if ((size=_zip_cdir_write(za, filelist, survivors)) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
550 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
551 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
552
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
553 if ((end = zip_source_tell_write(za->src)) < 0) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
554 return -1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
555 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
556
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
557 return 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
558 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
559
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
560
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
561 int
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
562 _zip_changed(const zip_t *za, zip_uint64_t *survivorsp)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
563 {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
564 int changed;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
565 zip_uint64_t i, survivors;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
566
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
567 changed = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
568 survivors = 0;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
569
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
570 if (za->comment_changed || za->ch_flags != za->flags)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
571 changed = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
572
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
573 for (i=0; i<za->nentry; i++) {
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
574 if (za->entry[i].deleted || za->entry[i].source || (za->entry[i].changes && za->entry[i].changes->changed != 0))
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
575 changed = 1;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
576 if (!za->entry[i].deleted)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
577 survivors++;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
578 }
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
579
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
580 if (survivorsp)
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
581 *survivorsp = survivors;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
582
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
583 return changed;
2306f4b04790 libzip: import 1.1.2
David Demelier <markand@malikania.fr>
parents:
diff changeset
584 }