summaryrefslogtreecommitdiff
path: root/utils/rbutilqt/quazip
diff options
context:
space:
mode:
Diffstat (limited to 'utils/rbutilqt/quazip')
-rw-r--r--utils/rbutilqt/quazip/LICENSE.LGPL458
-rw-r--r--utils/rbutilqt/quazip/README.ROCKBOX9
-rw-r--r--utils/rbutilqt/quazip/ioapi.h207
-rw-r--r--utils/rbutilqt/quazip/minizip_crypt.h135
-rw-r--r--utils/rbutilqt/quazip/qioapi.cpp363
-rw-r--r--utils/rbutilqt/quazip/quazip.cpp846
-rw-r--r--utils/rbutilqt/quazip/quazip.h611
-rw-r--r--utils/rbutilqt/quazip/quazip.pri25
-rw-r--r--utils/rbutilqt/quazip/quazip_global.h63
-rw-r--r--utils/rbutilqt/quazip/quazipfile.cpp570
-rw-r--r--utils/rbutilqt/quazip/quazipfile.h508
-rw-r--r--utils/rbutilqt/quazip/quazipfileinfo.cpp196
-rw-r--r--utils/rbutilqt/quazip/quazipfileinfo.h226
-rw-r--r--utils/rbutilqt/quazip/quazipnewinfo.cpp290
-rw-r--r--utils/rbutilqt/quazip/quazipnewinfo.h208
-rw-r--r--utils/rbutilqt/quazip/unzip.c2163
-rw-r--r--utils/rbutilqt/quazip/unzip.h461
-rw-r--r--utils/rbutilqt/quazip/zip.c2111
-rw-r--r--utils/rbutilqt/quazip/zip.h391
19 files changed, 9841 insertions, 0 deletions
diff --git a/utils/rbutilqt/quazip/LICENSE.LGPL b/utils/rbutilqt/quazip/LICENSE.LGPL
new file mode 100644
index 0000000000..2cba2ac74c
--- /dev/null
+++ b/utils/rbutilqt/quazip/LICENSE.LGPL
@@ -0,0 +1,458 @@
1 GNU LESSER GENERAL PUBLIC LICENSE
2 Version 2.1, February 1999
3
4 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9[This is the first released version of the Lesser GPL. It also counts
10 as the successor of the GNU Library Public License, version 2, hence
11 the version number 2.1.]
12
13 Preamble
14
15 The licenses for most software are designed to take away your
16freedom to share and change it. By contrast, the GNU General Public
17Licenses are intended to guarantee your freedom to share and change
18free software--to make sure the software is free for all its users.
19
20 This license, the Lesser General Public License, applies to some
21specially designated software packages--typically libraries--of the
22Free Software Foundation and other authors who decide to use it. You
23can use it too, but we suggest you first think carefully about whether
24this license or the ordinary General Public License is the better
25strategy to use in any particular case, based on the explanations below.
26
27 When we speak of free software, we are referring to freedom of use,
28not price. Our General Public Licenses are designed to make sure that
29you have the freedom to distribute copies of free software (and charge
30for this service if you wish); that you receive source code or can get
31it if you want it; that you can change the software and use pieces of
32it in new free programs; and that you are informed that you can do
33these things.
34
35 To protect your rights, we need to make restrictions that forbid
36distributors to deny you these rights or to ask you to surrender these
37rights. These restrictions translate to certain responsibilities for
38you if you distribute copies of the library or if you modify it.
39
40 For example, if you distribute copies of the library, whether gratis
41or for a fee, you must give the recipients all the rights that we gave
42you. You must make sure that they, too, receive or can get the source
43code. If you link other code with the library, you must provide
44complete object files to the recipients, so that they can relink them
45with the library after making changes to the library and recompiling
46it. And you must show them these terms so they know their rights.
47
48 We protect your rights with a two-step method: (1) we copyright the
49library, and (2) we offer you this license, which gives you legal
50permission to copy, distribute and/or modify the library.
51
52 To protect each distributor, we want to make it very clear that
53there is no warranty for the free library. Also, if the library is
54modified by someone else and passed on, the recipients should know
55that what they have is not the original version, so that the original
56author's reputation will not be affected by problems that might be
57introduced by others.
58
59 Finally, software patents pose a constant threat to the existence of
60any free program. We wish to make sure that a company cannot
61effectively restrict the users of a free program by obtaining a
62restrictive license from a patent holder. Therefore, we insist that
63any patent license obtained for a version of the library must be
64consistent with the full freedom of use specified in this license.
65
66 Most GNU software, including some libraries, is covered by the
67ordinary GNU General Public License. This license, the GNU Lesser
68General Public License, applies to certain designated libraries, and
69is quite different from the ordinary General Public License. We use
70this license for certain libraries in order to permit linking those
71libraries into non-free programs.
72
73 When a program is linked with a library, whether statically or using
74a shared library, the combination of the two is legally speaking a
75combined work, a derivative of the original library. The ordinary
76General Public License therefore permits such linking only if the
77entire combination fits its criteria of freedom. The Lesser General
78Public License permits more lax criteria for linking other code with
79the library.
80
81 We call this license the "Lesser" General Public License because it
82does Less to protect the user's freedom than the ordinary General
83Public License. It also provides other free software developers Less
84of an advantage over competing non-free programs. These disadvantages
85are the reason we use the ordinary General Public License for many
86libraries. However, the Lesser license provides advantages in certain
87special circumstances.
88
89 For example, on rare occasions, there may be a special need to
90encourage the widest possible use of a certain library, so that it becomes
91a de-facto standard. To achieve this, non-free programs must be
92allowed to use the library. A more frequent case is that a free
93library does the same job as widely used non-free libraries. In this
94case, there is little to gain by limiting the free library to free
95software only, so we use the Lesser General Public License.
96
97 In other cases, permission to use a particular library in non-free
98programs enables a greater number of people to use a large body of
99free software. For example, permission to use the GNU C Library in
100non-free programs enables many more people to use the whole GNU
101operating system, as well as its variant, the GNU/Linux operating
102system.
103
104 Although the Lesser General Public License is Less protective of the
105users' freedom, it does ensure that the user of a program that is
106linked with the Library has the freedom and the wherewithal to run
107that program using a modified version of the Library.
108
109 The precise terms and conditions for copying, distribution and
110modification follow. Pay close attention to the difference between a
111"work based on the library" and a "work that uses the library". The
112former contains code derived from the library, whereas the latter must
113be combined with the library in order to run.
114
115 GNU LESSER GENERAL PUBLIC LICENSE
116 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
118 0. This License Agreement applies to any software library or other
119program which contains a notice placed by the copyright holder or
120other authorized party saying it may be distributed under the terms of
121this Lesser General Public License (also called "this License").
122Each licensee is addressed as "you".
123
124 A "library" means a collection of software functions and/or data
125prepared so as to be conveniently linked with application programs
126(which use some of those functions and data) to form executables.
127
128 The "Library", below, refers to any such software library or work
129which has been distributed under these terms. A "work based on the
130Library" means either the Library or any derivative work under
131copyright law: that is to say, a work containing the Library or a
132portion of it, either verbatim or with modifications and/or translated
133straightforwardly into another language. (Hereinafter, translation is
134included without limitation in the term "modification".)
135
136 "Source code" for a work means the preferred form of the work for
137making modifications to it. For a library, complete source code means
138all the source code for all modules it contains, plus any associated
139interface definition files, plus the scripts used to control compilation
140and installation of the library.
141
142 Activities other than copying, distribution and modification are not
143covered by this License; they are outside its scope. The act of
144running a program using the Library is not restricted, and output from
145such a program is covered only if its contents constitute a work based
146on the Library (independent of the use of the Library in a tool for
147writing it). Whether that is true depends on what the Library does
148and what the program that uses the Library does.
149
150 1. You may copy and distribute verbatim copies of the Library's
151complete source code as you receive it, in any medium, provided that
152you conspicuously and appropriately publish on each copy an
153appropriate copyright notice and disclaimer of warranty; keep intact
154all the notices that refer to this License and to the absence of any
155warranty; and distribute a copy of this License along with the
156Library.
157
158 You may charge a fee for the physical act of transferring a copy,
159and you may at your option offer warranty protection in exchange for a
160fee.
161
162 2. You may modify your copy or copies of the Library or any portion
163of it, thus forming a work based on the Library, and copy and
164distribute such modifications or work under the terms of Section 1
165above, provided that you also meet all of these conditions:
166
167 a) The modified work must itself be a software library.
168
169 b) You must cause the files modified to carry prominent notices
170 stating that you changed the files and the date of any change.
171
172 c) You must cause the whole of the work to be licensed at no
173 charge to all third parties under the terms of this License.
174
175 d) If a facility in the modified Library refers to a function or a
176 table of data to be supplied by an application program that uses
177 the facility, other than as an argument passed when the facility
178 is invoked, then you must make a good faith effort to ensure that,
179 in the event an application does not supply such function or
180 table, the facility still operates, and performs whatever part of
181 its purpose remains meaningful.
182
183 (For example, a function in a library to compute square roots has
184 a purpose that is entirely well-defined independent of the
185 application. Therefore, Subsection 2d requires that any
186 application-supplied function or table used by this function must
187 be optional: if the application does not supply it, the square
188 root function must still compute square roots.)
189
190These requirements apply to the modified work as a whole. If
191identifiable sections of that work are not derived from the Library,
192and can be reasonably considered independent and separate works in
193themselves, then this License, and its terms, do not apply to those
194sections when you distribute them as separate works. But when you
195distribute the same sections as part of a whole which is a work based
196on the Library, the distribution of the whole must be on the terms of
197this License, whose permissions for other licensees extend to the
198entire whole, and thus to each and every part regardless of who wrote
199it.
200
201Thus, it is not the intent of this section to claim rights or contest
202your rights to work written entirely by you; rather, the intent is to
203exercise the right to control the distribution of derivative or
204collective works based on the Library.
205
206In addition, mere aggregation of another work not based on the Library
207with the Library (or with a work based on the Library) on a volume of
208a storage or distribution medium does not bring the other work under
209the scope of this License.
210
211 3. You may opt to apply the terms of the ordinary GNU General Public
212License instead of this License to a given copy of the Library. To do
213this, you must alter all the notices that refer to this License, so
214that they refer to the ordinary GNU General Public License, version 2,
215instead of to this License. (If a newer version than version 2 of the
216ordinary GNU General Public License has appeared, then you can specify
217that version instead if you wish.) Do not make any other change in
218these notices.
219
220 Once this change is made in a given copy, it is irreversible for
221that copy, so the ordinary GNU General Public License applies to all
222subsequent copies and derivative works made from that copy.
223
224 This option is useful when you wish to copy part of the code of
225the Library into a program that is not a library.
226
227 4. You may copy and distribute the Library (or a portion or
228derivative of it, under Section 2) in object code or executable form
229under the terms of Sections 1 and 2 above provided that you accompany
230it with the complete corresponding machine-readable source code, which
231must be distributed under the terms of Sections 1 and 2 above on a
232medium customarily used for software interchange.
233
234 If distribution of object code is made by offering access to copy
235from a designated place, then offering equivalent access to copy the
236source code from the same place satisfies the requirement to
237distribute the source code, even though third parties are not
238compelled to copy the source along with the object code.
239
240 5. A program that contains no derivative of any portion of the
241Library, but is designed to work with the Library by being compiled or
242linked with it, is called a "work that uses the Library". Such a
243work, in isolation, is not a derivative work of the Library, and
244therefore falls outside the scope of this License.
245
246 However, linking a "work that uses the Library" with the Library
247creates an executable that is a derivative of the Library (because it
248contains portions of the Library), rather than a "work that uses the
249library". The executable is therefore covered by this License.
250Section 6 states terms for distribution of such executables.
251
252 When a "work that uses the Library" uses material from a header file
253that is part of the Library, the object code for the work may be a
254derivative work of the Library even though the source code is not.
255Whether this is true is especially significant if the work can be
256linked without the Library, or if the work is itself a library. The
257threshold for this to be true is not precisely defined by law.
258
259 If such an object file uses only numerical parameters, data
260structure layouts and accessors, and small macros and small inline
261functions (ten lines or less in length), then the use of the object
262file is unrestricted, regardless of whether it is legally a derivative
263work. (Executables containing this object code plus portions of the
264Library will still fall under Section 6.)
265
266 Otherwise, if the work is a derivative of the Library, you may
267distribute the object code for the work under the terms of Section 6.
268Any executables containing that work also fall under Section 6,
269whether or not they are linked directly with the Library itself.
270
271 6. As an exception to the Sections above, you may also combine or
272link a "work that uses the Library" with the Library to produce a
273work containing portions of the Library, and distribute that work
274under terms of your choice, provided that the terms permit
275modification of the work for the customer's own use and reverse
276engineering for debugging such modifications.
277
278 You must give prominent notice with each copy of the work that the
279Library is used in it and that the Library and its use are covered by
280this License. You must supply a copy of this License. If the work
281during execution displays copyright notices, you must include the
282copyright notice for the Library among them, as well as a reference
283directing the user to the copy of this License. Also, you must do one
284of these things:
285
286 a) Accompany the work with the complete corresponding
287 machine-readable source code for the Library including whatever
288 changes were used in the work (which must be distributed under
289 Sections 1 and 2 above); and, if the work is an executable linked
290 with the Library, with the complete machine-readable "work that
291 uses the Library", as object code and/or source code, so that the
292 user can modify the Library and then relink to produce a modified
293 executable containing the modified Library. (It is understood
294 that the user who changes the contents of definitions files in the
295 Library will not necessarily be able to recompile the application
296 to use the modified definitions.)
297
298 b) Use a suitable shared library mechanism for linking with the
299 Library. A suitable mechanism is one that (1) uses at run time a
300 copy of the library already present on the user's computer system,
301 rather than copying library functions into the executable, and (2)
302 will operate properly with a modified version of the library, if
303 the user installs one, as long as the modified version is
304 interface-compatible with the version that the work was made with.
305
306 c) Accompany the work with a written offer, valid for at
307 least three years, to give the same user the materials
308 specified in Subsection 6a, above, for a charge no more
309 than the cost of performing this distribution.
310
311 d) If distribution of the work is made by offering access to copy
312 from a designated place, offer equivalent access to copy the above
313 specified materials from the same place.
314
315 e) Verify that the user has already received a copy of these
316 materials or that you have already sent this user a copy.
317
318 For an executable, the required form of the "work that uses the
319Library" must include any data and utility programs needed for
320reproducing the executable from it. However, as a special exception,
321the materials to be distributed need not include anything that is
322normally distributed (in either source or binary form) with the major
323components (compiler, kernel, and so on) of the operating system on
324which the executable runs, unless that component itself accompanies
325the executable.
326
327 It may happen that this requirement contradicts the license
328restrictions of other proprietary libraries that do not normally
329accompany the operating system. Such a contradiction means you cannot
330use both them and the Library together in an executable that you
331distribute.
332
333 7. You may place library facilities that are a work based on the
334Library side-by-side in a single library together with other library
335facilities not covered by this License, and distribute such a combined
336library, provided that the separate distribution of the work based on
337the Library and of the other library facilities is otherwise
338permitted, and provided that you do these two things:
339
340 a) Accompany the combined library with a copy of the same work
341 based on the Library, uncombined with any other library
342 facilities. This must be distributed under the terms of the
343 Sections above.
344
345 b) Give prominent notice with the combined library of the fact
346 that part of it is a work based on the Library, and explaining
347 where to find the accompanying uncombined form of the same work.
348
349 8. You may not copy, modify, sublicense, link with, or distribute
350the Library except as expressly provided under this License. Any
351attempt otherwise to copy, modify, sublicense, link with, or
352distribute the Library is void, and will automatically terminate your
353rights under this License. However, parties who have received copies,
354or rights, from you under this License will not have their licenses
355terminated so long as such parties remain in full compliance.
356
357 9. You are not required to accept this License, since you have not
358signed it. However, nothing else grants you permission to modify or
359distribute the Library or its derivative works. These actions are
360prohibited by law if you do not accept this License. Therefore, by
361modifying or distributing the Library (or any work based on the
362Library), you indicate your acceptance of this License to do so, and
363all its terms and conditions for copying, distributing or modifying
364the Library or works based on it.
365
366 10. Each time you redistribute the Library (or any work based on the
367Library), the recipient automatically receives a license from the
368original licensor to copy, distribute, link with or modify the Library
369subject to these terms and conditions. You may not impose any further
370restrictions on the recipients' exercise of the rights granted herein.
371You are not responsible for enforcing compliance by third parties with
372this License.
373
374 11. If, as a consequence of a court judgment or allegation of patent
375infringement or for any other reason (not limited to patent issues),
376conditions are imposed on you (whether by court order, agreement or
377otherwise) that contradict the conditions of this License, they do not
378excuse you from the conditions of this License. If you cannot
379distribute so as to satisfy simultaneously your obligations under this
380License and any other pertinent obligations, then as a consequence you
381may not distribute the Library at all. For example, if a patent
382license would not permit royalty-free redistribution of the Library by
383all those who receive copies directly or indirectly through you, then
384the only way you could satisfy both it and this License would be to
385refrain entirely from distribution of the Library.
386
387If any portion of this section is held invalid or unenforceable under any
388particular circumstance, the balance of the section is intended to apply,
389and the section as a whole is intended to apply in other circumstances.
390
391It is not the purpose of this section to induce you to infringe any
392patents or other property right claims or to contest validity of any
393such claims; this section has the sole purpose of protecting the
394integrity of the free software distribution system which is
395implemented by public license practices. Many people have made
396generous contributions to the wide range of software distributed
397through that system in reliance on consistent application of that
398system; it is up to the author/donor to decide if he or she is willing
399to distribute software through any other system and a licensee cannot
400impose that choice.
401
402This section is intended to make thoroughly clear what is believed to
403be a consequence of the rest of this License.
404
405 12. If the distribution and/or use of the Library is restricted in
406certain countries either by patents or by copyrighted interfaces, the
407original copyright holder who places the Library under this License may add
408an explicit geographical distribution limitation excluding those countries,
409so that distribution is permitted only in or among countries not thus
410excluded. In such case, this License incorporates the limitation as if
411written in the body of this License.
412
413 13. The Free Software Foundation may publish revised and/or new
414versions of the Lesser General Public License from time to time.
415Such new versions will be similar in spirit to the present version,
416but may differ in detail to address new problems or concerns.
417
418Each version is given a distinguishing version number. If the Library
419specifies a version number of this License which applies to it and
420"any later version", you have the option of following the terms and
421conditions either of that version or of any later version published by
422the Free Software Foundation. If the Library does not specify a
423license version number, you may choose any version ever published by
424the Free Software Foundation.
425
426 14. If you wish to incorporate parts of the Library into other free
427programs whose distribution conditions are incompatible with these,
428write to the author to ask for permission. For software which is
429copyrighted by the Free Software Foundation, write to the Free
430Software Foundation; we sometimes make exceptions for this. Our
431decision will be guided by the two goals of preserving the free status
432of all derivatives of our free software and of promoting the sharing
433and reuse of software generally.
434
435 NO WARRANTY
436
437 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
447 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456DAMAGES.
457
458 END OF TERMS AND CONDITIONS
diff --git a/utils/rbutilqt/quazip/README.ROCKBOX b/utils/rbutilqt/quazip/README.ROCKBOX
new file mode 100644
index 0000000000..a168b2a079
--- /dev/null
+++ b/utils/rbutilqt/quazip/README.ROCKBOX
@@ -0,0 +1,9 @@
1This folder contains the quazip project for ZIP file compression/decompression.
2These files are distributed under the LGPL v2.1 or later. Only source files
3actually used in Rockbox Utility are included, further sources have been left
4out. Check the quazip source distribution for those.
5
6The source files have been last synced with the projects release 0.9.1 at
7https://github.com/stachenov/quazip/ on June 8, 2020.
8
9
diff --git a/utils/rbutilqt/quazip/ioapi.h b/utils/rbutilqt/quazip/ioapi.h
new file mode 100644
index 0000000000..75d0aa6933
--- /dev/null
+++ b/utils/rbutilqt/quazip/ioapi.h
@@ -0,0 +1,207 @@
1/* ioapi.h -- IO base function header for compress/uncompress .zip
2 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
3
4 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
5
6 Modifications for Zip64 support
7 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
8
9 Modified by Sergey A. Tachenov to allow QIODevice API usage.
10
11 For more info read MiniZip_info.txt
12
13 Changes
14
15 Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
16 Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
17 More if/def section may be needed to support other platforms
18 Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
19 (but you should use iowin32.c for windows instead)
20
21*/
22
23#ifndef _ZLIBIOAPI64_H
24#define _ZLIBIOAPI64_H
25
26#if (!defined(_WIN32)) && (!defined(WIN32))
27
28 // Linux needs this to support file operation on files larger then 4+GB
29 // But might need better if/def to select just the platforms that needs them.
30
31 #ifndef __USE_FILE_OFFSET64
32 #define __USE_FILE_OFFSET64
33 #endif
34 #ifndef __USE_LARGEFILE64
35 #define __USE_LARGEFILE64
36 #endif
37 #ifndef _LARGEFILE64_SOURCE
38 #define _LARGEFILE64_SOURCE
39 #endif
40 #ifndef _FILE_OFFSET_BIT
41 #define _FILE_OFFSET_BIT 64
42 #endif
43#endif
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <zlib.h>
48
49#if defined(USE_FILE32API)
50#define fopen64 fopen
51#define ftello64 ftell
52#define fseeko64 fseek
53#else
54#ifdef _MSC_VER
55 #define fopen64 fopen
56 #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
57 #define ftello64 _ftelli64
58 #define fseeko64 _fseeki64
59 #else // old MSC
60 #define ftello64 ftell
61 #define fseeko64 fseek
62 #endif
63#endif
64#endif
65
66/*
67#ifndef ZPOS64_T
68 #ifdef _WIN32
69 #define ZPOS64_T fpos_t
70 #else
71 #include <stdint.h>
72 #define ZPOS64_T uint64_t
73 #endif
74#endif
75*/
76
77#ifdef HAVE_MINIZIP64_CONF_H
78#include "mz64conf.h"
79#endif
80
81/* a type choosen by DEFINE */
82#ifdef HAVE_64BIT_INT_CUSTOM
83typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
84#else
85#ifdef HAS_STDINT_H
86#include "stdint.h"
87typedef uint64_t ZPOS64_T;
88#else
89
90
91#if defined(_MSC_VER) || defined(__BORLANDC__)
92typedef unsigned __int64 ZPOS64_T;
93#else
94typedef unsigned long long int ZPOS64_T;
95#endif
96#endif
97#endif
98
99
100
101#ifdef __cplusplus
102extern "C" {
103#endif
104
105#ifndef OF
106#define OF _Z_OF
107#endif
108
109#define ZLIB_FILEFUNC_SEEK_CUR (1)
110#define ZLIB_FILEFUNC_SEEK_END (2)
111#define ZLIB_FILEFUNC_SEEK_SET (0)
112
113#define ZLIB_FILEFUNC_MODE_READ (1)
114#define ZLIB_FILEFUNC_MODE_WRITE (2)
115#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
116
117#define ZLIB_FILEFUNC_MODE_EXISTING (4)
118#define ZLIB_FILEFUNC_MODE_CREATE (8)
119
120
121#ifndef ZCALLBACK
122 #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
123 #define ZCALLBACK CALLBACK
124 #else
125 #define ZCALLBACK
126 #endif
127#endif
128
129
130
131
132typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, voidpf file, int mode));
133typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
134typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
135typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
136typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
137
138typedef uLong (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
139typedef int (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
140
141
142/* here is the "old" 32 bits structure structure */
143typedef struct zlib_filefunc_def_s
144{
145 open_file_func zopen_file;
146 read_file_func zread_file;
147 write_file_func zwrite_file;
148 tell_file_func ztell_file;
149 seek_file_func zseek_file;
150 close_file_func zclose_file;
151 testerror_file_func zerror_file;
152 voidpf opaque;
153} zlib_filefunc_def;
154
155typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
156typedef int (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
157typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, voidpf file, int mode));
158
159typedef struct zlib_filefunc64_def_s
160{
161 open64_file_func zopen64_file;
162 read_file_func zread_file;
163 write_file_func zwrite_file;
164 tell64_file_func ztell64_file;
165 seek64_file_func zseek64_file;
166 close_file_func zclose_file;
167 testerror_file_func zerror_file;
168 voidpf opaque;
169 close_file_func zfakeclose_file; // for no-auto-close flag
170} zlib_filefunc64_def;
171
172void fill_qiodevice64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
173void fill_qiodevice_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
174
175/* now internal definition, only for zip.c and unzip.h */
176typedef struct zlib_filefunc64_32_def_s
177{
178 zlib_filefunc64_def zfile_func64;
179 open_file_func zopen32_file;
180 tell_file_func ztell32_file;
181 seek_file_func zseek32_file;
182} zlib_filefunc64_32_def;
183
184
185#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
186#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
187//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
188//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
189#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
190#define ZFAKECLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zfakeclose_file)) ((filefunc).zfile_func64.opaque,filestream))
191#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
192
193voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode));
194int call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
195ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
196
197void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
198
199#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
200#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
201#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
202
203#ifdef __cplusplus
204}
205#endif
206
207#endif
diff --git a/utils/rbutilqt/quazip/minizip_crypt.h b/utils/rbutilqt/quazip/minizip_crypt.h
new file mode 100644
index 0000000000..2e833f7f3c
--- /dev/null
+++ b/utils/rbutilqt/quazip/minizip_crypt.h
@@ -0,0 +1,135 @@
1/* crypt.h -- base code for crypt/uncrypt ZIPfile
2
3
4 Version 1.01e, February 12th, 2005
5
6 Copyright (C) 1998-2005 Gilles Vollant
7
8 This code is a modified version of crypting code in Infozip distribution
9
10 The encryption/decryption parts of this source code (as opposed to the
11 non-echoing password parts) were originally written in Europe. The
12 whole source package can be freely distributed, including from the USA.
13 (Prior to January 2000, re-export from the US was a violation of US law.)
14
15 This encryption code is a direct transcription of the algorithm from
16 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
17 file (appnote.txt) is distributed with the PKZIP program (even in the
18 version without encryption capabilities).
19
20 If you don't need crypting in your application, just define symbols
21 NOCRYPT and NOUNCRYPT.
22
23 This code support the "Traditional PKWARE Encryption".
24
25 The new AES encryption added on Zip format by Winzip (see the page
26 http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
27 Encryption is not supported.
28*/
29
30#include "quazip_global.h"
31
32#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
33
34/***********************************************************************
35 * Return the next byte in the pseudo-random sequence
36 */
37static int decrypt_byte(unsigned long* pkeys, const z_crc_t FAR * pcrc_32_tab QUAZIP_UNUSED)
38{
39 //(void) pcrc_32_tab; /* avoid "unused parameter" warning */
40 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
41 * unpredictable manner on 16-bit systems; not a problem
42 * with any known compiler so far, though */
43
44 temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
45 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
46}
47
48/***********************************************************************
49 * Update the encryption keys with the next byte of plain text
50 */
51static int update_keys(unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab,int c)
52{
53 (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
54 (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
55 (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
56 {
57 register int keyshift = (int)((*(pkeys+1)) >> 24);
58 (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
59 }
60 return c;
61}
62
63
64/***********************************************************************
65 * Initialize the encryption keys and the random header according to
66 * the given password.
67 */
68static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab)
69{
70 *(pkeys+0) = 305419896L;
71 *(pkeys+1) = 591751049L;
72 *(pkeys+2) = 878082192L;
73 while (*passwd != '\0') {
74 update_keys(pkeys,pcrc_32_tab,(int)*passwd);
75 passwd++;
76 }
77}
78
79#define zdecode(pkeys,pcrc_32_tab,c) \
80 (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
81
82#define zencode(pkeys,pcrc_32_tab,c,t) \
83 (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
84
85#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
86
87#define RAND_HEAD_LEN 12
88 /* "last resort" source for second part of crypt seed pattern */
89# ifndef ZCR_SEED2
90# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
91# endif
92
93static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
94 const char *passwd; /* password string */
95 unsigned char *buf; /* where to write header */
96 int bufSize;
97 unsigned long* pkeys;
98 const z_crc_t FAR * pcrc_32_tab;
99 unsigned long crcForCrypting;
100{
101 int n; /* index in random header */
102 int t; /* temporary */
103 int c; /* random byte */
104 unsigned char header[RAND_HEAD_LEN-2]; /* random header */
105 static unsigned calls = 0; /* ensure different random header each time */
106
107 if (bufSize<RAND_HEAD_LEN)
108 return 0;
109
110 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
111 * output of rand() to get less predictability, since rand() is
112 * often poorly implemented.
113 */
114 if (++calls == 1)
115 {
116 srand((unsigned)(time(NULL) ^ ZCR_SEED2));
117 }
118 init_keys(passwd, pkeys, pcrc_32_tab);
119 for (n = 0; n < RAND_HEAD_LEN-2; n++)
120 {
121 c = (rand() >> 7) & 0xff;
122 header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
123 }
124 /* Encrypt random header (last two bytes is high word of crc) */
125 init_keys(passwd, pkeys, pcrc_32_tab);
126 for (n = 0; n < RAND_HEAD_LEN-2; n++)
127 {
128 buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
129 }
130 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
131 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
132 return n;
133}
134
135#endif
diff --git a/utils/rbutilqt/quazip/qioapi.cpp b/utils/rbutilqt/quazip/qioapi.cpp
new file mode 100644
index 0000000000..3932ebeef0
--- /dev/null
+++ b/utils/rbutilqt/quazip/qioapi.cpp
@@ -0,0 +1,363 @@
1/* ioapi.c -- IO base function header for compress/uncompress .zip
2 files using zlib + zip or unzip API
3
4 Version 1.01e, February 12th, 2005
5
6 Copyright (C) 1998-2005 Gilles Vollant
7
8 Modified by Sergey A. Tachenov to integrate with Qt.
9*/
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <zlib.h>
15
16#include "ioapi.h"
17#include "quazip_global.h"
18#include <QtCore/QIODevice>
19#if (QT_VERSION >= 0x050100)
20#define QUAZIP_QSAVEFILE_BUG_WORKAROUND
21#endif
22#ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND
23#include <QtCore/QSaveFile>
24#endif
25
26/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
27
28#ifndef SEEK_CUR
29#define SEEK_CUR 1
30#endif
31
32#ifndef SEEK_END
33#define SEEK_END 2
34#endif
35
36#ifndef SEEK_SET
37#define SEEK_SET 0
38#endif
39
40voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode)
41{
42 if (pfilefunc->zfile_func64.zopen64_file != NULL)
43 return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,file,mode);
44 else
45 {
46 return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,file,mode);
47 }
48}
49
50int call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
51{
52 if (pfilefunc->zfile_func64.zseek64_file != NULL)
53 return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
54 else
55 {
56 uLong offsetTruncated = (uLong)offset;
57 if (offsetTruncated != offset)
58 return -1;
59 else
60 return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
61 }
62}
63
64ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
65{
66 if (pfilefunc->zfile_func64.zseek64_file != NULL)
67 return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
68 else
69 {
70 uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
71 if ((tell_uLong) == ((uLong)-1))
72 return (ZPOS64_T)-1;
73 else
74 return tell_uLong;
75 }
76}
77
78/// @cond internal
79struct QIODevice_descriptor {
80 // Position only used for writing to sequential devices.
81 qint64 pos;
82 inline QIODevice_descriptor():
83 pos(0)
84 {}
85};
86/// @endcond
87
88voidpf ZCALLBACK qiodevice_open_file_func (
89 voidpf opaque,
90 voidpf file,
91 int mode)
92{
93 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
94 QIODevice *iodevice = reinterpret_cast<QIODevice*>(file);
95 QIODevice::OpenMode desiredMode;
96 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
97 desiredMode = QIODevice::ReadOnly;
98 else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
99 desiredMode = QIODevice::ReadWrite;
100 else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
101 desiredMode = QIODevice::WriteOnly;
102 if (iodevice->isOpen()) {
103 if ((iodevice->openMode() & desiredMode) == desiredMode) {
104 if (desiredMode != QIODevice::WriteOnly
105 && iodevice->isSequential()) {
106 // We can use sequential devices only for writing.
107 delete d;
108 return NULL;
109 } else {
110 if ((desiredMode & QIODevice::WriteOnly) != 0) {
111 // open for writing, need to seek existing device
112 if (!iodevice->isSequential()) {
113 iodevice->seek(0);
114 } else {
115 d->pos = iodevice->pos();
116 }
117 }
118 }
119 return iodevice;
120 } else {
121 delete d;
122 return NULL;
123 }
124 }
125 iodevice->open(desiredMode);
126 if (iodevice->isOpen()) {
127 if (desiredMode != QIODevice::WriteOnly && iodevice->isSequential()) {
128 // We can use sequential devices only for writing.
129 iodevice->close();
130 delete d;
131 return NULL;
132 } else {
133 return iodevice;
134 }
135 } else {
136 delete d;
137 return NULL;
138 }
139}
140
141
142uLong ZCALLBACK qiodevice_read_file_func (
143 voidpf opaque,
144 voidpf stream,
145 void* buf,
146 uLong size)
147{
148 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
149 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
150 qint64 ret64 = iodevice->read((char*)buf,size);
151 uLong ret;
152 ret = (uLong) ret64;
153 if (ret64 != -1) {
154 d->pos += ret64;
155 }
156 return ret;
157}
158
159
160uLong ZCALLBACK qiodevice_write_file_func (
161 voidpf opaque,
162 voidpf stream,
163 const void* buf,
164 uLong size)
165{
166 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
167 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
168 uLong ret;
169 qint64 ret64 = iodevice->write((char*)buf,size);
170 if (ret64 != -1) {
171 d->pos += ret64;
172 }
173 ret = (uLong) ret64;
174 return ret;
175}
176
177uLong ZCALLBACK qiodevice_tell_file_func (
178 voidpf opaque,
179 voidpf stream)
180{
181 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
182 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
183 uLong ret;
184 qint64 ret64;
185 if (iodevice->isSequential()) {
186 ret64 = d->pos;
187 } else {
188 ret64 = iodevice->pos();
189 }
190 ret = static_cast<uLong>(ret64);
191 return ret;
192}
193
194ZPOS64_T ZCALLBACK qiodevice64_tell_file_func (
195 voidpf opaque,
196 voidpf stream)
197{
198 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
199 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
200 qint64 ret;
201 if (iodevice->isSequential()) {
202 ret = d->pos;
203 } else {
204 ret = iodevice->pos();
205 }
206 return static_cast<ZPOS64_T>(ret);
207}
208
209int ZCALLBACK qiodevice_seek_file_func (
210 voidpf /*opaque UNUSED*/,
211 voidpf stream,
212 uLong offset,
213 int origin)
214{
215 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
216 if (iodevice->isSequential()) {
217 if (origin == ZLIB_FILEFUNC_SEEK_END
218 && offset == 0) {
219 // sequential devices are always at end (needed in mdAppend)
220 return 0;
221 } else {
222 qWarning("qiodevice_seek_file_func() called for sequential device");
223 return -1;
224 }
225 }
226 uLong qiodevice_seek_result=0;
227 int ret;
228 switch (origin)
229 {
230 case ZLIB_FILEFUNC_SEEK_CUR :
231 qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
232 break;
233 case ZLIB_FILEFUNC_SEEK_END :
234 qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
235 break;
236 case ZLIB_FILEFUNC_SEEK_SET :
237 qiodevice_seek_result = offset;
238 break;
239 default:
240 return -1;
241 }
242 ret = !iodevice->seek(qiodevice_seek_result);
243 return ret;
244}
245
246int ZCALLBACK qiodevice64_seek_file_func (
247 voidpf /*opaque UNUSED*/,
248 voidpf stream,
249 ZPOS64_T offset,
250 int origin)
251{
252 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
253 if (iodevice->isSequential()) {
254 if (origin == ZLIB_FILEFUNC_SEEK_END
255 && offset == 0) {
256 // sequential devices are always at end (needed in mdAppend)
257 return 0;
258 } else {
259 qWarning("qiodevice_seek_file_func() called for sequential device");
260 return -1;
261 }
262 }
263 qint64 qiodevice_seek_result=0;
264 int ret;
265 switch (origin)
266 {
267 case ZLIB_FILEFUNC_SEEK_CUR :
268 qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
269 break;
270 case ZLIB_FILEFUNC_SEEK_END :
271 qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
272 break;
273 case ZLIB_FILEFUNC_SEEK_SET :
274 qiodevice_seek_result = offset;
275 break;
276 default:
277 return -1;
278 }
279 ret = !iodevice->seek(qiodevice_seek_result);
280 return ret;
281}
282
283int ZCALLBACK qiodevice_close_file_func (
284 voidpf opaque,
285 voidpf stream)
286{
287 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
288 delete d;
289 QIODevice *device = reinterpret_cast<QIODevice*>(stream);
290#ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND
291 // QSaveFile terribly breaks the is-a idiom:
292 // it IS a QIODevice, but it is NOT compatible with it: close() is private
293 QSaveFile *file = qobject_cast<QSaveFile*>(device);
294 if (file != NULL) {
295 // We have to call the ugly commit() instead:
296 return file->commit() ? 0 : -1;
297 }
298#endif
299 device->close();
300 return 0;
301}
302
303int ZCALLBACK qiodevice_fakeclose_file_func (
304 voidpf opaque,
305 voidpf /*stream*/)
306{
307 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
308 delete d;
309 return 0;
310}
311
312int ZCALLBACK qiodevice_error_file_func (
313 voidpf /*opaque UNUSED*/,
314 voidpf /*stream UNUSED*/)
315{
316 // can't check for error due to the QIODevice API limitation
317 return 0;
318}
319
320void fill_qiodevice_filefunc (
321 zlib_filefunc_def* pzlib_filefunc_def)
322{
323 pzlib_filefunc_def->zopen_file = qiodevice_open_file_func;
324 pzlib_filefunc_def->zread_file = qiodevice_read_file_func;
325 pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func;
326 pzlib_filefunc_def->ztell_file = qiodevice_tell_file_func;
327 pzlib_filefunc_def->zseek_file = qiodevice_seek_file_func;
328 pzlib_filefunc_def->zclose_file = qiodevice_close_file_func;
329 pzlib_filefunc_def->zerror_file = qiodevice_error_file_func;
330 pzlib_filefunc_def->opaque = new QIODevice_descriptor;
331}
332
333void fill_qiodevice64_filefunc (
334 zlib_filefunc64_def* pzlib_filefunc_def)
335{
336 // Open functions are the same for Qt.
337 pzlib_filefunc_def->zopen64_file = qiodevice_open_file_func;
338 pzlib_filefunc_def->zread_file = qiodevice_read_file_func;
339 pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func;
340 pzlib_filefunc_def->ztell64_file = qiodevice64_tell_file_func;
341 pzlib_filefunc_def->zseek64_file = qiodevice64_seek_file_func;
342 pzlib_filefunc_def->zclose_file = qiodevice_close_file_func;
343 pzlib_filefunc_def->zerror_file = qiodevice_error_file_func;
344 pzlib_filefunc_def->opaque = new QIODevice_descriptor;
345 pzlib_filefunc_def->zfakeclose_file = qiodevice_fakeclose_file_func;
346}
347
348void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
349{
350 p_filefunc64_32->zfile_func64.zopen64_file = NULL;
351 p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
352 p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
353 p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
354 p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
355 p_filefunc64_32->zfile_func64.ztell64_file = NULL;
356 p_filefunc64_32->zfile_func64.zseek64_file = NULL;
357 p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
358 p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
359 p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
360 p_filefunc64_32->zfile_func64.zfakeclose_file = NULL;
361 p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
362 p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
363}
diff --git a/utils/rbutilqt/quazip/quazip.cpp b/utils/rbutilqt/quazip/quazip.cpp
new file mode 100644
index 0000000000..61c2ea87eb
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazip.cpp
@@ -0,0 +1,846 @@
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant, see
22quazip/(un)zip.h files for details, basically it's zlib license.
23 **/
24
25#include <QtCore/QFile>
26#include <QtCore/QFlags>
27#include <QtCore/QHash>
28
29#include "quazip.h"
30
31#define QUAZIP_OS_UNIX 3u
32
33/// All the internal stuff for the QuaZip class.
34/**
35 \internal
36
37 This class keeps all the private stuff for the QuaZip class so it can
38 be changed without breaking binary compatibility, according to the
39 Pimpl idiom.
40 */
41class QuaZipPrivate {
42 friend class QuaZip;
43 private:
44 Q_DISABLE_COPY(QuaZipPrivate)
45 /// The pointer to the corresponding QuaZip instance.
46 QuaZip *q;
47 /// The codec for file names (used when UTF-8 is not enabled).
48 QTextCodec *fileNameCodec;
49 /// The codec for comments (used when UTF-8 is not enabled).
50 QTextCodec *commentCodec;
51 /// The archive file name.
52 QString zipName;
53 /// The device to access the archive.
54 QIODevice *ioDevice;
55 /// The global comment.
56 QString comment;
57 /// The open mode.
58 QuaZip::Mode mode;
59 union {
60 /// The internal handle for UNZIP modes.
61 unzFile unzFile_f;
62 /// The internal handle for ZIP modes.
63 zipFile zipFile_f;
64 };
65 /// Whether a current file is set.
66 bool hasCurrentFile_f;
67 /// The last error.
68 int zipError;
69 /// Whether \ref QuaZip::setDataDescriptorWritingEnabled() "the data descriptor writing mode" is enabled.
70 bool dataDescriptorWritingEnabled;
71 /// The zip64 mode.
72 bool zip64;
73 /// The auto-close flag.
74 bool autoClose;
75 /// The UTF-8 flag.
76 bool utf8;
77 /// The OS code.
78 uint osCode;
79 inline QTextCodec *getDefaultFileNameCodec()
80 {
81 if (defaultFileNameCodec == NULL) {
82 return QTextCodec::codecForLocale();
83 } else {
84 return defaultFileNameCodec;
85 }
86 }
87 /// The constructor for the corresponding QuaZip constructor.
88 inline QuaZipPrivate(QuaZip *q):
89 q(q),
90 fileNameCodec(getDefaultFileNameCodec()),
91 commentCodec(QTextCodec::codecForLocale()),
92 ioDevice(NULL),
93 mode(QuaZip::mdNotOpen),
94 hasCurrentFile_f(false),
95 zipError(UNZ_OK),
96 dataDescriptorWritingEnabled(true),
97 zip64(false),
98 autoClose(true),
99 utf8(false),
100 osCode(defaultOsCode)
101 {
102 unzFile_f = NULL;
103 zipFile_f = NULL;
104 lastMappedDirectoryEntry.num_of_file = 0;
105 lastMappedDirectoryEntry.pos_in_zip_directory = 0;
106 }
107 /// The constructor for the corresponding QuaZip constructor.
108 inline QuaZipPrivate(QuaZip *q, const QString &zipName):
109 q(q),
110 fileNameCodec(getDefaultFileNameCodec()),
111 commentCodec(QTextCodec::codecForLocale()),
112 zipName(zipName),
113 ioDevice(NULL),
114 mode(QuaZip::mdNotOpen),
115 hasCurrentFile_f(false),
116 zipError(UNZ_OK),
117 dataDescriptorWritingEnabled(true),
118 zip64(false),
119 autoClose(true),
120 utf8(false),
121 osCode(defaultOsCode)
122 {
123 unzFile_f = NULL;
124 zipFile_f = NULL;
125 lastMappedDirectoryEntry.num_of_file = 0;
126 lastMappedDirectoryEntry.pos_in_zip_directory = 0;
127 }
128 /// The constructor for the corresponding QuaZip constructor.
129 inline QuaZipPrivate(QuaZip *q, QIODevice *ioDevice):
130 q(q),
131 fileNameCodec(getDefaultFileNameCodec()),
132 commentCodec(QTextCodec::codecForLocale()),
133 ioDevice(ioDevice),
134 mode(QuaZip::mdNotOpen),
135 hasCurrentFile_f(false),
136 zipError(UNZ_OK),
137 dataDescriptorWritingEnabled(true),
138 zip64(false),
139 autoClose(true),
140 utf8(false),
141 osCode(defaultOsCode)
142 {
143 unzFile_f = NULL;
144 zipFile_f = NULL;
145 lastMappedDirectoryEntry.num_of_file = 0;
146 lastMappedDirectoryEntry.pos_in_zip_directory = 0;
147 }
148 /// Returns either a list of file names or a list of QuaZipFileInfo.
149 template<typename TFileInfo>
150 bool getFileInfoList(QList<TFileInfo> *result) const;
151
152 /// Stores map of filenames and file locations for unzipping
153 inline void clearDirectoryMap();
154 inline void addCurrentFileToDirectoryMap(const QString &fileName);
155 bool goToFirstUnmappedFile();
156 QHash<QString, unz64_file_pos> directoryCaseSensitive;
157 QHash<QString, unz64_file_pos> directoryCaseInsensitive;
158 unz64_file_pos lastMappedDirectoryEntry;
159 static QTextCodec *defaultFileNameCodec;
160 static uint defaultOsCode;
161};
162
163QTextCodec *QuaZipPrivate::defaultFileNameCodec = NULL;
164uint QuaZipPrivate::defaultOsCode = QUAZIP_OS_UNIX;
165
166void QuaZipPrivate::clearDirectoryMap()
167{
168 directoryCaseInsensitive.clear();
169 directoryCaseSensitive.clear();
170 lastMappedDirectoryEntry.num_of_file = 0;
171 lastMappedDirectoryEntry.pos_in_zip_directory = 0;
172}
173
174void QuaZipPrivate::addCurrentFileToDirectoryMap(const QString &fileName)
175{
176 if (!hasCurrentFile_f || fileName.isEmpty()) {
177 return;
178 }
179 // Adds current file to filename map as fileName
180 unz64_file_pos fileDirectoryPos;
181 unzGetFilePos64(unzFile_f, &fileDirectoryPos);
182 directoryCaseSensitive.insert(fileName, fileDirectoryPos);
183 // Only add lowercase to directory map if not already there
184 // ensures only map the first one seen
185 QString lower = fileName.toLower();
186 if (!directoryCaseInsensitive.contains(lower))
187 directoryCaseInsensitive.insert(lower, fileDirectoryPos);
188 // Mark last one
189 if (fileDirectoryPos.pos_in_zip_directory > lastMappedDirectoryEntry.pos_in_zip_directory)
190 lastMappedDirectoryEntry = fileDirectoryPos;
191}
192
193bool QuaZipPrivate::goToFirstUnmappedFile()
194{
195 zipError = UNZ_OK;
196 if (mode != QuaZip::mdUnzip) {
197 qWarning("QuaZipPrivate::goToNextUnmappedFile(): ZIP is not open in mdUnzip mode");
198 return false;
199 }
200 // If not mapped anything, go to beginning
201 if (lastMappedDirectoryEntry.pos_in_zip_directory == 0) {
202 unzGoToFirstFile(unzFile_f);
203 } else {
204 // Goto the last one mapped, plus one
205 unzGoToFilePos64(unzFile_f, &lastMappedDirectoryEntry);
206 unzGoToNextFile(unzFile_f);
207 }
208 hasCurrentFile_f=zipError==UNZ_OK;
209 if(zipError==UNZ_END_OF_LIST_OF_FILE)
210 zipError=UNZ_OK;
211 return hasCurrentFile_f;
212}
213
214QuaZip::QuaZip():
215 p(new QuaZipPrivate(this))
216{
217}
218
219QuaZip::QuaZip(const QString& zipName):
220 p(new QuaZipPrivate(this, zipName))
221{
222}
223
224QuaZip::QuaZip(QIODevice *ioDevice):
225 p(new QuaZipPrivate(this, ioDevice))
226{
227}
228
229QuaZip::~QuaZip()
230{
231 if(isOpen())
232 close();
233 delete p;
234}
235
236bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi)
237{
238 p->zipError=UNZ_OK;
239 if(isOpen()) {
240 qWarning("QuaZip::open(): ZIP already opened");
241 return false;
242 }
243 QIODevice *ioDevice = p->ioDevice;
244 if (ioDevice == NULL) {
245 if (p->zipName.isEmpty()) {
246 qWarning("QuaZip::open(): set either ZIP file name or IO device first");
247 return false;
248 } else {
249 ioDevice = new QFile(p->zipName);
250 }
251 }
252 unsigned flags = 0;
253 switch(mode) {
254 case mdUnzip:
255 if (ioApi == NULL) {
256 if (p->autoClose)
257 flags |= UNZ_AUTO_CLOSE;
258 p->unzFile_f=unzOpenInternal(ioDevice, NULL, 1, flags);
259 } else {
260 // QuaZIP pre-zip64 compatibility mode
261 p->unzFile_f=unzOpen2(ioDevice, ioApi);
262 if (p->unzFile_f != NULL) {
263 if (p->autoClose) {
264 unzSetFlags(p->unzFile_f, UNZ_AUTO_CLOSE);
265 } else {
266 unzClearFlags(p->unzFile_f, UNZ_AUTO_CLOSE);
267 }
268 }
269 }
270 if(p->unzFile_f!=NULL) {
271 if (ioDevice->isSequential()) {
272 unzClose(p->unzFile_f);
273 if (!p->zipName.isEmpty())
274 delete ioDevice;
275 qWarning("QuaZip::open(): "
276 "only mdCreate can be used with "
277 "sequential devices");
278 return false;
279 }
280 p->mode=mode;
281 p->ioDevice = ioDevice;
282 return true;
283 } else {
284 p->zipError=UNZ_OPENERROR;
285 if (!p->zipName.isEmpty())
286 delete ioDevice;
287 return false;
288 }
289 case mdCreate:
290 case mdAppend:
291 case mdAdd:
292 if (ioApi == NULL) {
293 if (p->autoClose)
294 flags |= ZIP_AUTO_CLOSE;
295 if (p->dataDescriptorWritingEnabled)
296 flags |= ZIP_WRITE_DATA_DESCRIPTOR;
297 if (p->utf8)
298 flags |= ZIP_ENCODING_UTF8;
299 p->zipFile_f=zipOpen3(ioDevice,
300 mode==mdCreate?APPEND_STATUS_CREATE:
301 mode==mdAppend?APPEND_STATUS_CREATEAFTER:
302 APPEND_STATUS_ADDINZIP,
303 NULL, NULL, flags);
304 } else {
305 // QuaZIP pre-zip64 compatibility mode
306 p->zipFile_f=zipOpen2(ioDevice,
307 mode==mdCreate?APPEND_STATUS_CREATE:
308 mode==mdAppend?APPEND_STATUS_CREATEAFTER:
309 APPEND_STATUS_ADDINZIP,
310 NULL,
311 ioApi);
312 if (p->zipFile_f != NULL) {
313 zipSetFlags(p->zipFile_f, flags);
314 }
315 }
316 if(p->zipFile_f!=NULL) {
317 if (ioDevice->isSequential()) {
318 if (mode != mdCreate) {
319 zipClose(p->zipFile_f, NULL);
320 qWarning("QuaZip::open(): "
321 "only mdCreate can be used with "
322 "sequential devices");
323 if (!p->zipName.isEmpty())
324 delete ioDevice;
325 return false;
326 }
327 zipSetFlags(p->zipFile_f, ZIP_SEQUENTIAL);
328 }
329 p->mode=mode;
330 p->ioDevice = ioDevice;
331 return true;
332 } else {
333 p->zipError=UNZ_OPENERROR;
334 if (!p->zipName.isEmpty())
335 delete ioDevice;
336 return false;
337 }
338 default:
339 qWarning("QuaZip::open(): unknown mode: %d", (int)mode);
340 if (!p->zipName.isEmpty())
341 delete ioDevice;
342 return false;
343 break;
344 }
345}
346
347void QuaZip::close()
348{
349 p->zipError=UNZ_OK;
350 switch(p->mode) {
351 case mdNotOpen:
352 qWarning("QuaZip::close(): ZIP is not open");
353 return;
354 case mdUnzip:
355 p->zipError=unzClose(p->unzFile_f);
356 break;
357 case mdCreate:
358 case mdAppend:
359 case mdAdd:
360 p->zipError=zipClose(p->zipFile_f, p->comment.isNull() ? NULL : isUtf8Enabled()
361 ? p->comment.toUtf8().constData()
362 : p->commentCodec->fromUnicode(p->comment).constData());
363 break;
364 default:
365 qWarning("QuaZip::close(): unknown mode: %d", (int)p->mode);
366 return;
367 }
368 // opened by name, need to delete the internal IO device
369 if (!p->zipName.isEmpty()) {
370 delete p->ioDevice;
371 p->ioDevice = NULL;
372 }
373 p->clearDirectoryMap();
374 if(p->zipError==UNZ_OK)
375 p->mode=mdNotOpen;
376}
377
378void QuaZip::setZipName(const QString& zipName)
379{
380 if(isOpen()) {
381 qWarning("QuaZip::setZipName(): ZIP is already open!");
382 return;
383 }
384 p->zipName=zipName;
385 p->ioDevice = NULL;
386}
387
388void QuaZip::setIoDevice(QIODevice *ioDevice)
389{
390 if(isOpen()) {
391 qWarning("QuaZip::setIoDevice(): ZIP is already open!");
392 return;
393 }
394 p->ioDevice = ioDevice;
395 p->zipName = QString();
396}
397
398int QuaZip::getEntriesCount()const
399{
400 QuaZip *fakeThis=(QuaZip*)this; // non-const
401 fakeThis->p->zipError=UNZ_OK;
402 if(p->mode!=mdUnzip) {
403 qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode");
404 return -1;
405 }
406 unz_global_info64 globalInfo;
407 if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK)
408 return p->zipError;
409 return (int)globalInfo.number_entry;
410}
411
412QString QuaZip::getComment()const
413{
414 QuaZip *fakeThis=(QuaZip*)this; // non-const
415 fakeThis->p->zipError=UNZ_OK;
416 if(p->mode!=mdUnzip) {
417 qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode");
418 return QString();
419 }
420 unz_global_info64 globalInfo;
421 QByteArray comment;
422 if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK)
423 return QString();
424 comment.resize(globalInfo.size_comment);
425 if((fakeThis->p->zipError=unzGetGlobalComment(p->unzFile_f, comment.data(), comment.size())) < 0)
426 return QString();
427 fakeThis->p->zipError = UNZ_OK;
428 unsigned flags = 0;
429 return (unzGetFileFlags(p->unzFile_f, &flags) == UNZ_OK) && (flags & UNZ_ENCODING_UTF8)
430 ? QString::fromUtf8(comment) : p->commentCodec->toUnicode(comment);
431}
432
433bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs)
434{
435 p->zipError=UNZ_OK;
436 if(p->mode!=mdUnzip) {
437 qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode");
438 return false;
439 }
440 if(fileName.isEmpty()) {
441 p->hasCurrentFile_f=false;
442 return true;
443 }
444 // Unicode-aware reimplementation of the unzLocateFile function
445 if(p->unzFile_f==NULL) {
446 p->zipError=UNZ_PARAMERROR;
447 return false;
448 }
449 if(fileName.length()>MAX_FILE_NAME_LENGTH) {
450 p->zipError=UNZ_PARAMERROR;
451 return false;
452 }
453 // Find the file by name
454 bool sens = convertCaseSensitivity(cs) == Qt::CaseSensitive;
455 QString lower, current;
456 if(!sens) lower=fileName.toLower();
457 p->hasCurrentFile_f=false;
458
459 // Check the appropriate Map
460 unz64_file_pos fileDirPos;
461 fileDirPos.pos_in_zip_directory = 0;
462 if (sens) {
463 if (p->directoryCaseSensitive.contains(fileName))
464 fileDirPos = p->directoryCaseSensitive.value(fileName);
465 } else {
466 if (p->directoryCaseInsensitive.contains(lower))
467 fileDirPos = p->directoryCaseInsensitive.value(lower);
468 }
469
470 if (fileDirPos.pos_in_zip_directory != 0) {
471 p->zipError = unzGoToFilePos64(p->unzFile_f, &fileDirPos);
472 p->hasCurrentFile_f = p->zipError == UNZ_OK;
473 }
474
475 if (p->hasCurrentFile_f)
476 return p->hasCurrentFile_f;
477
478 // Not mapped yet, start from where we have got to so far
479 for(bool more=p->goToFirstUnmappedFile(); more; more=goToNextFile()) {
480 current=getCurrentFileName();
481 if(current.isEmpty()) return false;
482 if(sens) {
483 if(current==fileName) break;
484 } else {
485 if(current.toLower()==lower) break;
486 }
487 }
488 return p->hasCurrentFile_f;
489}
490
491bool QuaZip::goToFirstFile()
492{
493 p->zipError=UNZ_OK;
494 if(p->mode!=mdUnzip) {
495 qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
496 return false;
497 }
498 p->zipError=unzGoToFirstFile(p->unzFile_f);
499 p->hasCurrentFile_f=p->zipError==UNZ_OK;
500 return p->hasCurrentFile_f;
501}
502
503bool QuaZip::goToNextFile()
504{
505 p->zipError=UNZ_OK;
506 if(p->mode!=mdUnzip) {
507 qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
508 return false;
509 }
510 p->zipError=unzGoToNextFile(p->unzFile_f);
511 p->hasCurrentFile_f=p->zipError==UNZ_OK;
512 if(p->zipError==UNZ_END_OF_LIST_OF_FILE)
513 p->zipError=UNZ_OK;
514 return p->hasCurrentFile_f;
515}
516
517bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const
518{
519 QuaZipFileInfo64 info64;
520 if (info == NULL) { // Very unlikely because of the overloads
521 return false;
522 }
523 if (getCurrentFileInfo(&info64)) {
524 info64.toQuaZipFileInfo(*info);
525 return true;
526 } else {
527 return false;
528 }
529}
530
531bool QuaZip::getCurrentFileInfo(QuaZipFileInfo64 *info)const
532{
533 QuaZip *fakeThis=(QuaZip*)this; // non-const
534 fakeThis->p->zipError=UNZ_OK;
535 if(p->mode!=mdUnzip) {
536 qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode");
537 return false;
538 }
539 unz_file_info64 info_z;
540 QByteArray fileName;
541 QByteArray extra;
542 QByteArray comment;
543 if(info==NULL) return false;
544 if(!isOpen()||!hasCurrentFile()) return false;
545 if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &info_z, NULL, 0, NULL, 0, NULL, 0))!=UNZ_OK)
546 return false;
547 fileName.resize(info_z.size_filename);
548 extra.resize(info_z.size_file_extra);
549 comment.resize(info_z.size_file_comment);
550 if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, NULL,
551 fileName.data(), fileName.size(),
552 extra.data(), extra.size(),
553 comment.data(), comment.size()))!=UNZ_OK)
554 return false;
555 info->versionCreated=info_z.version;
556 info->versionNeeded=info_z.version_needed;
557 info->flags=info_z.flag;
558 info->method=info_z.compression_method;
559 info->crc=info_z.crc;
560 info->compressedSize=info_z.compressed_size;
561 info->uncompressedSize=info_z.uncompressed_size;
562 info->diskNumberStart=info_z.disk_num_start;
563 info->internalAttr=info_z.internal_fa;
564 info->externalAttr=info_z.external_fa;
565 info->name=(info->flags & UNZ_ENCODING_UTF8) ? QString::fromUtf8(fileName) : p->fileNameCodec->toUnicode(fileName);
566 info->comment=(info->flags & UNZ_ENCODING_UTF8) ? QString::fromUtf8(comment) : p->commentCodec->toUnicode(comment);
567 info->extra=extra;
568 info->dateTime=QDateTime(
569 QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday),
570 QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec));
571 // Add to directory map
572 p->addCurrentFileToDirectoryMap(info->name);
573 return true;
574}
575
576QString QuaZip::getCurrentFileName()const
577{
578 QuaZip *fakeThis=(QuaZip*)this; // non-const
579 fakeThis->p->zipError=UNZ_OK;
580 if(p->mode!=mdUnzip) {
581 qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode");
582 return QString();
583 }
584 if(!isOpen()||!hasCurrentFile()) return QString();
585 QByteArray fileName(MAX_FILE_NAME_LENGTH, 0);
586 unz_file_info64 file_info;
587 if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &file_info, fileName.data(), fileName.size(),
588 NULL, 0, NULL, 0))!=UNZ_OK)
589 return QString();
590 fileName.resize(file_info.size_filename);
591 QString result = (file_info.flag & UNZ_ENCODING_UTF8)
592 ? QString::fromUtf8(fileName) : p->fileNameCodec->toUnicode(fileName);
593 if (result.isEmpty())
594 return result;
595 // Add to directory map
596 p->addCurrentFileToDirectoryMap(result);
597 return result;
598}
599
600void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec)
601{
602 p->fileNameCodec=fileNameCodec;
603}
604
605void QuaZip::setFileNameCodec(const char *fileNameCodecName)
606{
607 p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName);
608}
609
610void QuaZip::setOsCode(uint osCode)
611{
612 p->osCode = osCode;
613}
614
615uint QuaZip::getOsCode() const
616{
617 return p->osCode;
618}
619
620QTextCodec *QuaZip::getFileNameCodec()const
621{
622 return p->fileNameCodec;
623}
624
625void QuaZip::setCommentCodec(QTextCodec *commentCodec)
626{
627 p->commentCodec=commentCodec;
628}
629
630void QuaZip::setCommentCodec(const char *commentCodecName)
631{
632 p->commentCodec=QTextCodec::codecForName(commentCodecName);
633}
634
635QTextCodec *QuaZip::getCommentCodec()const
636{
637 return p->commentCodec;
638}
639
640QString QuaZip::getZipName() const
641{
642 return p->zipName;
643}
644
645QIODevice *QuaZip::getIoDevice() const
646{
647 if (!p->zipName.isEmpty()) // opened by name, using an internal QIODevice
648 return NULL;
649 return p->ioDevice;
650}
651
652QuaZip::Mode QuaZip::getMode()const
653{
654 return p->mode;
655}
656
657bool QuaZip::isOpen()const
658{
659 return p->mode!=mdNotOpen;
660}
661
662int QuaZip::getZipError() const
663{
664 return p->zipError;
665}
666
667void QuaZip::setComment(const QString& comment)
668{
669 p->comment=comment;
670}
671
672bool QuaZip::hasCurrentFile()const
673{
674 return p->hasCurrentFile_f;
675}
676
677unzFile QuaZip::getUnzFile()
678{
679 return p->unzFile_f;
680}
681
682zipFile QuaZip::getZipFile()
683{
684 return p->zipFile_f;
685}
686
687void QuaZip::setDataDescriptorWritingEnabled(bool enabled)
688{
689 p->dataDescriptorWritingEnabled = enabled;
690}
691
692bool QuaZip::isDataDescriptorWritingEnabled() const
693{
694 return p->dataDescriptorWritingEnabled;
695}
696
697template<typename TFileInfo>
698TFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok);
699
700template<>
701QuaZipFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok)
702{
703 QuaZipFileInfo info;
704 *ok = zip->getCurrentFileInfo(&info);
705 return info;
706}
707
708template<>
709QuaZipFileInfo64 QuaZip_getFileInfo(QuaZip *zip, bool *ok)
710{
711 QuaZipFileInfo64 info;
712 *ok = zip->getCurrentFileInfo(&info);
713 return info;
714}
715
716template<>
717QString QuaZip_getFileInfo(QuaZip *zip, bool *ok)
718{
719 QString name = zip->getCurrentFileName();
720 *ok = !name.isEmpty();
721 return name;
722}
723
724template<typename TFileInfo>
725bool QuaZipPrivate::getFileInfoList(QList<TFileInfo> *result) const
726{
727 QuaZipPrivate *fakeThis=const_cast<QuaZipPrivate*>(this);
728 fakeThis->zipError=UNZ_OK;
729 if (mode!=QuaZip::mdUnzip) {
730 qWarning("QuaZip::getFileNameList/getFileInfoList(): "
731 "ZIP is not open in mdUnzip mode");
732 return false;
733 }
734 QString currentFile;
735 if (q->hasCurrentFile()) {
736 currentFile = q->getCurrentFileName();
737 }
738 if (q->goToFirstFile()) {
739 do {
740 bool ok;
741 result->append(QuaZip_getFileInfo<TFileInfo>(q, &ok));
742 if (!ok)
743 return false;
744 } while (q->goToNextFile());
745 }
746 if (zipError != UNZ_OK)
747 return false;
748 if (currentFile.isEmpty()) {
749 if (!q->goToFirstFile())
750 return false;
751 } else {
752 if (!q->setCurrentFile(currentFile))
753 return false;
754 }
755 return true;
756}
757
758QStringList QuaZip::getFileNameList() const
759{
760 QStringList list;
761 if (p->getFileInfoList(&list))
762 return list;
763 else
764 return QStringList();
765}
766
767QList<QuaZipFileInfo> QuaZip::getFileInfoList() const
768{
769 QList<QuaZipFileInfo> list;
770 if (p->getFileInfoList(&list))
771 return list;
772 else
773 return QList<QuaZipFileInfo>();
774}
775
776QList<QuaZipFileInfo64> QuaZip::getFileInfoList64() const
777{
778 QList<QuaZipFileInfo64> list;
779 if (p->getFileInfoList(&list))
780 return list;
781 else
782 return QList<QuaZipFileInfo64>();
783}
784
785Qt::CaseSensitivity QuaZip::convertCaseSensitivity(QuaZip::CaseSensitivity cs)
786{
787 if (cs == csDefault) {
788#ifdef Q_OS_WIN
789 return Qt::CaseInsensitive;
790#else
791 return Qt::CaseSensitive;
792#endif
793 } else {
794 return cs == csSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
795 }
796}
797
798void QuaZip::setDefaultFileNameCodec(QTextCodec *codec)
799{
800 QuaZipPrivate::defaultFileNameCodec = codec;
801}
802
803void QuaZip::setDefaultFileNameCodec(const char *codecName)
804{
805 setDefaultFileNameCodec(QTextCodec::codecForName(codecName));
806}
807
808void QuaZip::setDefaultOsCode(uint osCode)
809{
810 QuaZipPrivate::defaultOsCode = osCode;
811}
812
813uint QuaZip::getDefaultOsCode()
814{
815 return QuaZipPrivate::defaultOsCode;
816}
817
818void QuaZip::setZip64Enabled(bool zip64)
819{
820 p->zip64 = zip64;
821}
822
823bool QuaZip::isZip64Enabled() const
824{
825 return p->zip64;
826}
827
828void QuaZip::setUtf8Enabled(bool utf8)
829{
830 p->utf8 = utf8;
831}
832
833bool QuaZip::isUtf8Enabled() const
834{
835 return p->utf8;
836}
837
838bool QuaZip::isAutoClose() const
839{
840 return p->autoClose;
841}
842
843void QuaZip::setAutoClose(bool autoClose) const
844{
845 p->autoClose = autoClose;
846}
diff --git a/utils/rbutilqt/quazip/quazip.h b/utils/rbutilqt/quazip/quazip.h
new file mode 100644
index 0000000000..8ff0756254
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazip.h
@@ -0,0 +1,611 @@
1#ifndef QUA_ZIP_H
2#define QUA_ZIP_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant, see
25quazip/(un)zip.h files for details, basically it's zlib license.
26 **/
27
28#include <QtCore/QString>
29#include <QtCore/QStringList>
30#include <QTextCodec>
31
32#include "zip.h"
33#include "unzip.h"
34
35#include "quazip_global.h"
36#include "quazipfileinfo.h"
37
38// just in case it will be defined in the later versions of the ZIP/UNZIP
39#ifndef UNZ_OPENERROR
40// define additional error code
41#define UNZ_OPENERROR -1000
42#endif
43
44class QuaZipPrivate;
45
46/// ZIP archive.
47/** \class QuaZip quazip.h <quazip/quazip.h>
48 * This class implements basic interface to the ZIP archive. It can be
49 * used to read table contents of the ZIP archive and retreiving
50 * information about the files inside it.
51 *
52 * You can also use this class to open files inside archive by passing
53 * pointer to the instance of this class to the constructor of the
54 * QuaZipFile class. But see QuaZipFile::QuaZipFile(QuaZip*, QObject*)
55 * for the possible pitfalls.
56 *
57 * This class is indended to provide interface to the ZIP subpackage of
58 * the ZIP/UNZIP package as well as to the UNZIP subpackage. But
59 * currently it supports only UNZIP.
60 *
61 * The use of this class is simple - just create instance using
62 * constructor, then set ZIP archive file name using setFile() function
63 * (if you did not passed the name to the constructor), then open() and
64 * then use different functions to work with it! Well, if you are
65 * paranoid, you may also wish to call close before destructing the
66 * instance, to check for errors on close.
67 *
68 * You may also use getUnzFile() and getZipFile() functions to get the
69 * ZIP archive handle and use it with ZIP/UNZIP package API directly.
70 *
71 * This class supports localized file names inside ZIP archive, but you
72 * have to set up proper codec with setCodec() function. By default,
73 * locale codec will be used, which is probably ok for UNIX systems, but
74 * will almost certainly fail with ZIP archives created in Windows. This
75 * is because Windows ZIP programs have strange habit of using DOS
76 * encoding for file names in ZIP archives. For example, ZIP archive
77 * with cyrillic names created in Windows will have file names in \c
78 * IBM866 encoding instead of \c WINDOWS-1251. I think that calling one
79 * function is not much trouble, but for true platform independency it
80 * would be nice to have some mechanism for file name encoding auto
81 * detection using locale information. Does anyone know a good way to do
82 * it?
83 **/
84class QUAZIP_EXPORT QuaZip {
85 friend class QuaZipPrivate;
86 public:
87 /// Useful constants.
88 enum Constants {
89 MAX_FILE_NAME_LENGTH=256 /**< Maximum file name length. Taken from
90 \c UNZ_MAXFILENAMEINZIP constant in
91 unzip.c. */
92 };
93 /// Open mode of the ZIP file.
94 enum Mode {
95 mdNotOpen, ///< ZIP file is not open. This is the initial mode.
96 mdUnzip, ///< ZIP file is open for reading files inside it.
97 mdCreate, ///< ZIP file was created with open() call.
98 mdAppend, /**< ZIP file was opened in append mode. This refers to
99 * \c APPEND_STATUS_CREATEAFTER mode in ZIP/UNZIP package
100 * and means that zip is appended to some existing file
101 * what is useful when that file contains
102 * self-extractor code. This is obviously \em not what
103 * you whant to use to add files to the existing ZIP
104 * archive.
105 **/
106 mdAdd ///< ZIP file was opened for adding files in the archive.
107 };
108 /// Case sensitivity for the file names.
109 /** This is what you specify when accessing files in the archive.
110 * Works perfectly fine with any characters thanks to Qt's great
111 * unicode support. This is different from ZIP/UNZIP API, where
112 * only US-ASCII characters was supported.
113 **/
114 enum CaseSensitivity {
115 csDefault=0, ///< Default for platform. Case sensitive for UNIX, not for Windows.
116 csSensitive=1, ///< Case sensitive.
117 csInsensitive=2 ///< Case insensitive.
118 };
119 /// Returns the actual case sensitivity for the specified QuaZIP one.
120 /**
121 \param cs The value to convert.
122 \returns If CaseSensitivity::csDefault, then returns the default
123 file name case sensitivity for the platform. Otherwise, just
124 returns the appropriate value from the Qt::CaseSensitivity enum.
125 */
126 static Qt::CaseSensitivity convertCaseSensitivity(
127 CaseSensitivity cs);
128 private:
129 QuaZipPrivate *p;
130 // not (and will not be) implemented
131 QuaZip(const QuaZip& that);
132 // not (and will not be) implemented
133 QuaZip& operator=(const QuaZip& that);
134 public:
135 /// Constructs QuaZip object.
136 /** Call setName() before opening constructed object. */
137 QuaZip();
138 /// Constructs QuaZip object associated with ZIP file \a zipName.
139 QuaZip(const QString& zipName);
140 /// Constructs QuaZip object associated with ZIP file represented by \a ioDevice.
141 /** The IO device must be seekable, otherwise an error will occur when opening. */
142 QuaZip(QIODevice *ioDevice);
143 /// Destroys QuaZip object.
144 /** Calls close() if necessary. */
145 ~QuaZip();
146 /// Opens ZIP file.
147 /**
148 * Argument \a mode specifies open mode of the ZIP archive. See Mode
149 * for details. Note that there is zipOpen2() function in the
150 * ZIP/UNZIP API which accepts \a globalcomment argument, but it
151 * does not use it anywhere, so this open() function does not have this
152 * argument. See setComment() if you need to set global comment.
153 *
154 * If the ZIP file is accessed via explicitly set QIODevice, then
155 * this device is opened in the necessary mode. If the device was
156 * already opened by some other means, then QuaZIP checks if the
157 * open mode is compatible to the mode needed for the requested operation.
158 * If necessary, seeking is performed to position the device properly.
159 *
160 * \return \c true if successful, \c false otherwise.
161 *
162 * \note ZIP/UNZIP API open calls do not return error code - they
163 * just return \c NULL indicating an error. But to make things
164 * easier, quazip.h header defines additional error code \c
165 * UNZ_ERROROPEN and getZipError() will return it if the open call
166 * of the ZIP/UNZIP API returns \c NULL.
167 *
168 * Argument \a ioApi specifies IO function set for ZIP/UNZIP
169 * package to use. See unzip.h, zip.h and ioapi.h for details. Note
170 * that IO API for QuaZip is different from the original package.
171 * The file path argument was changed to be of type \c voidpf, and
172 * QuaZip passes a QIODevice pointer there. This QIODevice is either
173 * set explicitly via setIoDevice() or the QuaZip(QIODevice*)
174 * constructor, or it is created internally when opening the archive
175 * by its file name. The default API (qioapi.cpp) just delegates
176 * everything to the QIODevice API. Not only this allows to use a
177 * QIODevice instead of file name, but also has a nice side effect
178 * of raising the file size limit from 2G to 4G (in non-zip64 archives).
179 *
180 * \note If the zip64 support is needed, the ioApi argument \em must be NULL
181 * because due to the backwards compatibility issues it can be used to
182 * provide a 32-bit API only.
183 *
184 * \note If the \ref QuaZip::setAutoClose() "no-auto-close" feature is used,
185 * then the \a ioApi argument \em should be NULL because the old API
186 * doesn't support the 'fake close' operation, causing slight memory leaks
187 * and other possible troubles (like closing the output device in case
188 * when an error occurs during opening).
189 *
190 * In short: just forget about the \a ioApi argument and you'll be
191 * fine.
192 **/
193 bool open(Mode mode, zlib_filefunc_def *ioApi =NULL);
194 /// Closes ZIP file.
195 /** Call getZipError() to determine if the close was successful.
196 *
197 * If the file was opened by name, then the underlying QIODevice is closed
198 * and deleted.
199 *
200 * If the underlying QIODevice was set explicitly using setIoDevice() or
201 * the appropriate constructor, then it is closed if the auto-close flag
202 * is set (which it is by default). Call setAutoClose() to clear the
203 * auto-close flag if this behavior is undesirable.
204 *
205 * Since Qt 5.1, the QSaveFile was introduced. It breaks the QIODevice API
206 * by making close() private and crashing the application if it is called
207 * from the base class where it is public. It is an excellent example
208 * of poor design that illustrates why you should never ever break
209 * an is-a relationship between the base class and a subclass. QuaZIP
210 * works around this bug by checking if the QIODevice is an instance
211 * of QSaveFile, using qobject_cast<>, and if it is, calls
212 * QSaveFile::commit() instead of close(). It is a really ugly hack,
213 * but at least it makes your programs work instead of crashing. Note that
214 * if the auto-close flag is cleared, then this is a non-issue, and
215 * commit() isn't called.
216 */
217 void close();
218 /// Sets the codec used to encode/decode file names inside archive.
219 /** This is necessary to access files in the ZIP archive created
220 * under Windows with non-latin characters in file names. For
221 * example, file names with cyrillic letters will be in \c IBM866
222 * encoding.
223 **/
224 void setFileNameCodec(QTextCodec *fileNameCodec);
225 /// Sets the codec used to encode/decode file names inside archive.
226 /** \overload
227 * Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName));
228 **/
229 void setFileNameCodec(const char *fileNameCodecName);
230 /// Sets the OS code (highest 8 bits of the “version made by” field) for new files.
231 /** There is currently no way to specify this for each file individually,
232 except by calling this function before opening each file. If this function is not called,
233 then the default OS code will be used. The default code is set by calling
234 setDefaultOsCode(). The default value at the moment of QuaZip creation will be used. */
235 void setOsCode(uint osCode);
236 /// Returns the OS code for new files.
237 uint getOsCode() const;
238 /// Returns the codec used to encode/decode comments inside archive.
239 QTextCodec* getFileNameCodec() const;
240 /// Sets the codec used to encode/decode comments inside archive.
241 /** This codec defaults to locale codec, which is probably ok.
242 **/
243 void setCommentCodec(QTextCodec *commentCodec);
244 /// Sets the codec used to encode/decode comments inside archive.
245 /** \overload
246 * Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName));
247 **/
248 void setCommentCodec(const char *commentCodecName);
249 /// Returns the codec used to encode/decode comments inside archive.
250 QTextCodec* getCommentCodec() const;
251 /// Returns the name of the ZIP file.
252 /** Returns null string if no ZIP file name has been set, for
253 * example when the QuaZip instance is set up to use a QIODevice
254 * instead.
255 * \sa setZipName(), setIoDevice(), getIoDevice()
256 **/
257 QString getZipName() const;
258 /// Sets the name of the ZIP file.
259 /** Does nothing if the ZIP file is open.
260 *
261 * Does not reset error code returned by getZipError().
262 * \sa setIoDevice(), getIoDevice(), getZipName()
263 **/
264 void setZipName(const QString& zipName);
265 /// Returns the device representing this ZIP file.
266 /** Returns null string if no device has been set explicitly, for
267 * example when opening a ZIP file by name.
268 * \sa setIoDevice(), getZipName(), setZipName()
269 **/
270 QIODevice *getIoDevice() const;
271 /// Sets the device representing the ZIP file.
272 /** Does nothing if the ZIP file is open.
273 *
274 * Does not reset error code returned by getZipError().
275 * \sa getIoDevice(), getZipName(), setZipName()
276 **/
277 void setIoDevice(QIODevice *ioDevice);
278 /// Returns the mode in which ZIP file was opened.
279 Mode getMode() const;
280 /// Returns \c true if ZIP file is open, \c false otherwise.
281 bool isOpen() const;
282 /// Returns the error code of the last operation.
283 /** Returns \c UNZ_OK if the last operation was successful.
284 *
285 * Error code resets to \c UNZ_OK every time you call any function
286 * that accesses something inside ZIP archive, even if it is \c
287 * const (like getEntriesCount()). open() and close() calls reset
288 * error code too. See documentation for the specific functions for
289 * details on error detection.
290 **/
291 int getZipError() const;
292 /// Returns number of the entries in the ZIP central directory.
293 /** Returns negative error code in the case of error. The same error
294 * code will be returned by subsequent getZipError() call.
295 **/
296 int getEntriesCount() const;
297 /// Returns global comment in the ZIP file.
298 QString getComment() const;
299 /// Sets the global comment in the ZIP file.
300 /** The comment will be written to the archive on close operation.
301 * QuaZip makes a distinction between a null QByteArray() comment
302 * and an empty &quot;&quot; comment in the QuaZip::mdAdd mode.
303 * A null comment is the default and it means &quot;don't change
304 * the comment&quot;. An empty comment removes the original comment.
305 *
306 * \sa open()
307 **/
308 void setComment(const QString& comment);
309 /// Sets the current file to the first file in the archive.
310 /** Returns \c true on success, \c false otherwise. Call
311 * getZipError() to get the error code.
312 **/
313 bool goToFirstFile();
314 /// Sets the current file to the next file in the archive.
315 /** Returns \c true on success, \c false otherwise. Call
316 * getZipError() to determine if there was an error.
317 *
318 * Should be used only in QuaZip::mdUnzip mode.
319 *
320 * \note If the end of file was reached, getZipError() will return
321 * \c UNZ_OK instead of \c UNZ_END_OF_LIST_OF_FILE. This is to make
322 * things like this easier:
323 * \code
324 * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
325 * // do something
326 * }
327 * if(zip.getZipError()==UNZ_OK) {
328 * // ok, there was no error
329 * }
330 * \endcode
331 **/
332 bool goToNextFile();
333 /// Sets current file by its name.
334 /** Returns \c true if successful, \c false otherwise. Argument \a
335 * cs specifies case sensitivity of the file name. Call
336 * getZipError() in the case of a failure to get error code.
337 *
338 * This is not a wrapper to unzLocateFile() function. That is
339 * because I had to implement locale-specific case-insensitive
340 * comparison.
341 *
342 * Here are the differences from the original implementation:
343 *
344 * - If the file was not found, error code is \c UNZ_OK, not \c
345 * UNZ_END_OF_LIST_OF_FILE (see also goToNextFile()).
346 * - If this function fails, it unsets the current file rather than
347 * resetting it back to what it was before the call.
348 *
349 * If \a fileName is null string then this function unsets the
350 * current file and return \c true. Note that you should close the
351 * file first if it is open! See
352 * QuaZipFile::QuaZipFile(QuaZip*,QObject*) for the details.
353 *
354 * Should be used only in QuaZip::mdUnzip mode.
355 *
356 * \sa setFileNameCodec(), CaseSensitivity
357 **/
358 bool setCurrentFile(const QString& fileName, CaseSensitivity cs =csDefault);
359 /// Returns \c true if the current file has been set.
360 bool hasCurrentFile() const;
361 /// Retrieves information about the current file.
362 /** Fills the structure pointed by \a info. Returns \c true on
363 * success, \c false otherwise. In the latter case structure pointed
364 * by \a info remains untouched. If there was an error,
365 * getZipError() returns error code.
366 *
367 * Should be used only in QuaZip::mdUnzip mode.
368 *
369 * Does nothing and returns \c false in any of the following cases.
370 * - ZIP is not open;
371 * - ZIP does not have current file.
372 *
373 * In both cases getZipError() returns \c UNZ_OK since there
374 * is no ZIP/UNZIP API call.
375 *
376 * This overload doesn't support zip64, but will work OK on zip64 archives
377 * except that if one of the sizes (compressed or uncompressed) is greater
378 * than 0xFFFFFFFFu, it will be set to exactly 0xFFFFFFFFu.
379 *
380 * \sa getCurrentFileInfo(QuaZipFileInfo64* info)const
381 * \sa QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo&)const
382 **/
383 bool getCurrentFileInfo(QuaZipFileInfo* info)const;
384 /// Retrieves information about the current file.
385 /** \overload
386 *
387 * This function supports zip64. If the archive doesn't use zip64, it is
388 * completely equivalent to getCurrentFileInfo(QuaZipFileInfo* info)
389 * except for the argument type.
390 *
391 * \sa
392 **/
393 bool getCurrentFileInfo(QuaZipFileInfo64* info)const;
394 /// Returns the current file name.
395 /** Equivalent to calling getCurrentFileInfo() and then getting \c
396 * name field of the QuaZipFileInfo structure, but faster and more
397 * convenient.
398 *
399 * Should be used only in QuaZip::mdUnzip mode.
400 **/
401 QString getCurrentFileName()const;
402 /// Returns \c unzFile handle.
403 /** You can use this handle to directly call UNZIP part of the
404 * ZIP/UNZIP package functions (see unzip.h).
405 *
406 * \warning When using the handle returned by this function, please
407 * keep in mind that QuaZip class is unable to detect any changes
408 * you make in the ZIP file state (e. g. changing current file, or
409 * closing the handle). So please do not do anything with this
410 * handle that is possible to do with the functions of this class.
411 * Or at least return the handle in the original state before
412 * calling some another function of this class (including implicit
413 * destructor calls and calls from the QuaZipFile objects that refer
414 * to this QuaZip instance!). So if you have changed the current
415 * file in the ZIP archive - then change it back or you may
416 * experience some strange behavior or even crashes.
417 **/
418 unzFile getUnzFile();
419 /// Returns \c zipFile handle.
420 /** You can use this handle to directly call ZIP part of the
421 * ZIP/UNZIP package functions (see zip.h). Warnings about the
422 * getUnzFile() function also apply to this function.
423 **/
424 zipFile getZipFile();
425 /// Changes the data descriptor writing mode.
426 /**
427 According to the ZIP format specification, a file inside archive
428 may have a data descriptor immediately following the file
429 data. This is reflected by a special flag in the local file header
430 and in the central directory. By default, QuaZIP sets this flag
431 and writes the data descriptor unless both method and level were
432 set to 0, in which case it operates in 1.0-compatible mode and
433 never writes data descriptors.
434
435 By setting this flag to false, it is possible to disable data
436 descriptor writing, thus increasing compatibility with archive
437 readers that don't understand this feature of the ZIP file format.
438
439 Setting this flag affects all the QuaZipFile instances that are
440 opened after this flag is set.
441
442 The data descriptor writing mode is enabled by default.
443
444 Note that if the ZIP archive is written into a QIODevice for which
445 QIODevice::isSequential() returns \c true, then the data descriptor
446 is mandatory and will be written even if this flag is set to false.
447
448 \param enabled If \c true, enable local descriptor writing,
449 disable it otherwise.
450
451 \sa QuaZipFile::isDataDescriptorWritingEnabled()
452 */
453 void setDataDescriptorWritingEnabled(bool enabled);
454 /// Returns the data descriptor default writing mode.
455 /**
456 \sa setDataDescriptorWritingEnabled()
457 */
458 bool isDataDescriptorWritingEnabled() const;
459 /// Returns a list of files inside the archive.
460 /**
461 \return A list of file names or an empty list if there
462 was an error or if the archive is empty (call getZipError() to
463 figure out which).
464 \sa getFileInfoList()
465 */
466 QStringList getFileNameList() const;
467 /// Returns information list about all files inside the archive.
468 /**
469 \return A list of QuaZipFileInfo objects or an empty list if there
470 was an error or if the archive is empty (call getZipError() to
471 figure out which).
472
473 This function doesn't support zip64, but will still work with zip64
474 archives, converting results using QuaZipFileInfo64::toQuaZipFileInfo().
475 If all file sizes are below 4 GB, it will work just fine.
476
477 \sa getFileNameList()
478 \sa getFileInfoList64()
479 */
480 QList<QuaZipFileInfo> getFileInfoList() const;
481 /// Returns information list about all files inside the archive.
482 /**
483 \overload
484
485 This function supports zip64.
486
487 \sa getFileNameList()
488 \sa getFileInfoList()
489 */
490 QList<QuaZipFileInfo64> getFileInfoList64() const;
491 /// Enables the zip64 mode.
492 /**
493 * @param zip64 If \c true, the zip64 mode is enabled, disabled otherwise.
494 *
495 * Once this is enabled, all new files (until the mode is disabled again)
496 * will be created in the zip64 mode, thus enabling the ability to write
497 * files larger than 4 GB. By default, the zip64 mode is off due to
498 * compatibility reasons.
499 *
500 * Note that this does not affect the ability to read zip64 archives in any
501 * way.
502 *
503 * \sa isZip64Enabled()
504 */
505 void setZip64Enabled(bool zip64);
506 /// Returns whether the zip64 mode is enabled.
507 /**
508 * @return \c true if and only if the zip64 mode is enabled.
509 *
510 * \sa setZip64Enabled()
511 */
512 bool isZip64Enabled() const;
513 /// Enables the use of UTF-8 encoding for file names and comments text.
514 /**
515 * @param utf8 If \c true, the UTF-8 mode is enabled, disabled otherwise.
516 *
517 * Once this is enabled, the names of all new files and comments text (until
518 * the mode is disabled again) will be encoded in UTF-8 encoding, and the
519 * version to extract will be set to 6.3 (63) in ZIP header. By default,
520 * the UTF-8 mode is off due to compatibility reasons.
521 *
522 * Note that when extracting ZIP archives, the UTF-8 mode is determined from
523 * ZIP file header, not from this flag.
524 *
525 * \sa isUtf8Enabled()
526 */
527 void setUtf8Enabled(bool utf8);
528 /// Returns whether the UTF-8 encoding mode is enabled.
529 /**
530 * @return \c true if and only if the UTF-8 mode is enabled.
531 *
532 * \sa setUtf8Enabled()
533 */
534 bool isUtf8Enabled() const;
535 /// Returns the auto-close flag.
536 /**
537 @sa setAutoClose()
538 */
539 bool isAutoClose() const;
540 /// Sets or unsets the auto-close flag.
541 /**
542 By default, QuaZIP opens the underlying QIODevice when open() is called,
543 and closes it when close() is called. In some cases, when the device
544 is set explicitly using setIoDevice(), it may be desirable to
545 leave the device open. If the auto-close flag is unset using this method,
546 then the device isn't closed automatically if it was set explicitly.
547
548 If it is needed to clear this flag, it is recommended to do so before
549 opening the archive because otherwise QuaZIP may close the device
550 during the open() call if an error is encountered after the device
551 is opened.
552
553 If the device was not set explicitly, but rather the setZipName() or
554 the appropriate constructor was used to set the ZIP file name instead,
555 then the auto-close flag has no effect, and the internal device
556 is closed nevertheless because there is no other way to close it.
557
558 @sa isAutoClose()
559 @sa setIoDevice()
560 */
561 void setAutoClose(bool autoClose) const;
562 /// Sets the default file name codec to use.
563 /**
564 * The default codec is used by the constructors, so calling this function
565 * won't affect the QuaZip instances already created at that moment.
566 *
567 * The codec specified here can be overriden by calling setFileNameCodec().
568 * If neither function is called, QTextCodec::codecForLocale() will be used
569 * to decode or encode file names. Use this function with caution if
570 * the application uses other libraries that depend on QuaZIP. Those
571 * libraries can either call this function by themselves, thus overriding
572 * your setting or can rely on the default encoding, thus failing
573 * mysteriously if you change it. For these reasons, it isn't recommended
574 * to use this function if you are developing a library, not an application.
575 * Instead, ask your library users to call it in case they need specific
576 * encoding.
577 *
578 * In most cases, using setFileNameCodec() instead is the right choice.
579 * However, if you depend on third-party code that uses QuaZIP, then the
580 * reasons stated above can actually become a reason to use this function
581 * in case the third-party code in question fails because it doesn't
582 * understand the encoding you need and doesn't provide a way to specify it.
583 * This applies to the JlCompress class as well, as it was contributed and
584 * doesn't support explicit encoding parameters.
585 *
586 * In short: use setFileNameCodec() when you can, resort to
587 * setDefaultFileNameCodec() when you don't have access to the QuaZip
588 * instance.
589 *
590 * @param codec The codec to use by default. If NULL, resets to default.
591 */
592 static void setDefaultFileNameCodec(QTextCodec *codec);
593 /**
594 * @overload
595 * Equivalent to calling
596 * setDefaultFileNameCodec(QTextCodec::codecForName(codecName)).
597 */
598 static void setDefaultFileNameCodec(const char *codecName);
599 /// Sets default OS code.
600 /**
601 * @sa setOsCode()
602 */
603 static void setDefaultOsCode(uint osCode);
604 /// Returns default OS code.
605 /**
606 * @sa getOsCode()
607 */
608 static uint getDefaultOsCode();
609};
610
611#endif
diff --git a/utils/rbutilqt/quazip/quazip.pri b/utils/rbutilqt/quazip/quazip.pri
new file mode 100644
index 0000000000..3a82bd0275
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazip.pri
@@ -0,0 +1,25 @@
1
2SOURCES += \
3 $$PWD/quazip.cpp \
4 $$PWD/quazipfile.cpp \
5 $$PWD/quazipnewinfo.cpp \
6 $$PWD/quazipfileinfo.cpp \
7 $$PWD/qioapi.cpp \
8 $$PWD/unzip.c \
9 $$PWD/zip.c \
10
11HEADERS += \
12 $$PWD/minizip_crypt.h \
13 $$PWD/ioapi.h \
14 $$PWD/quazipfile.h \
15 $$PWD/quazipfileinfo.h \
16 $$PWD/quazipnewinfo.h \
17 $$PWD/quazip.h \
18 $$PWD/quazipnewinfo.h \
19 $$PWD/quazip_global.h \
20 $$PWD/unzip.h \
21 $$PWD/zip.h \
22
23DEFINES += \
24 QUAZIP_STATIC
25
diff --git a/utils/rbutilqt/quazip/quazip_global.h b/utils/rbutilqt/quazip/quazip_global.h
new file mode 100644
index 0000000000..de581bd7c4
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazip_global.h
@@ -0,0 +1,63 @@
1#ifndef QUAZIP_GLOBAL_H
2#define QUAZIP_GLOBAL_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant and contributors,
25see quazip/(un)zip.h files for details. Basically it's the zlib license.
26*/
27
28#include <QtCore/qglobal.h>
29
30/**
31 This is automatically defined when building a static library, but when
32 including QuaZip sources directly into a project, QUAZIP_STATIC should
33 be defined explicitly to avoid possible troubles with unnecessary
34 importing/exporting.
35 */
36#ifdef QUAZIP_STATIC
37#define QUAZIP_EXPORT
38#else
39/**
40 * When building a DLL with MSVC, QUAZIP_BUILD must be defined.
41 * qglobal.h takes care of defining Q_DECL_* correctly for msvc/gcc.
42 */
43#if defined(QUAZIP_BUILD)
44 #define QUAZIP_EXPORT Q_DECL_EXPORT
45#else
46 #define QUAZIP_EXPORT Q_DECL_IMPORT
47#endif
48#endif // QUAZIP_STATIC
49
50#ifdef __GNUC__
51#define QUAZIP_UNUSED __attribute__((__unused__))
52#else
53#define QUAZIP_UNUSED
54#endif
55
56#define QUAZIP_EXTRA_NTFS_MAGIC 0x000Au
57#define QUAZIP_EXTRA_NTFS_TIME_MAGIC 0x0001u
58#define QUAZIP_EXTRA_EXT_TIME_MAGIC 0x5455u
59#define QUAZIP_EXTRA_EXT_MOD_TIME_FLAG 1
60#define QUAZIP_EXTRA_EXT_AC_TIME_FLAG 2
61#define QUAZIP_EXTRA_EXT_CR_TIME_FLAG 4
62
63#endif // QUAZIP_GLOBAL_H
diff --git a/utils/rbutilqt/quazip/quazipfile.cpp b/utils/rbutilqt/quazip/quazipfile.cpp
new file mode 100644
index 0000000000..b984de7279
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipfile.cpp
@@ -0,0 +1,570 @@
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant, see
22quazip/(un)zip.h files for details, basically it's zlib license.
23 **/
24
25#include "quazipfile.h"
26
27#include "quazipfileinfo.h"
28
29using namespace std;
30
31#define QUAZIP_VERSION_MADE_BY 0x1Eu
32
33/// The implementation class for QuaZip.
34/**
35\internal
36
37This class contains all the private stuff for the QuaZipFile class, thus
38allowing to preserve binary compatibility between releases, the
39technique known as the Pimpl (private implementation) idiom.
40*/
41class QuaZipFilePrivate {
42 friend class QuaZipFile;
43 private:
44 Q_DISABLE_COPY(QuaZipFilePrivate)
45 /// The pointer to the associated QuaZipFile instance.
46 QuaZipFile *q;
47 /// The QuaZip object to work with.
48 QuaZip *zip;
49 /// The file name.
50 QString fileName;
51 /// Case sensitivity mode.
52 QuaZip::CaseSensitivity caseSensitivity;
53 /// Whether this file is opened in the raw mode.
54 bool raw;
55 /// Write position to keep track of.
56 /**
57 QIODevice::pos() is broken for non-seekable devices, so we need
58 our own position.
59 */
60 qint64 writePos;
61 /// Uncompressed size to write along with a raw file.
62 quint64 uncompressedSize;
63 /// CRC to write along with a raw file.
64 quint32 crc;
65 /// Whether \ref zip points to an internal QuaZip instance.
66 /**
67 This is true if the archive was opened by name, rather than by
68 supplying an existing QuaZip instance.
69 */
70 bool internal;
71 /// The last error.
72 int zipError;
73 /// Resets \ref zipError.
74 inline void resetZipError() const {setZipError(UNZ_OK);}
75 /// Sets the zip error.
76 /**
77 This function is marked as const although it changes one field.
78 This allows to call it from const functions that don't change
79 anything by themselves.
80 */
81 void setZipError(int zipError) const;
82 /// The constructor for the corresponding QuaZipFile constructor.
83 inline QuaZipFilePrivate(QuaZipFile *q):
84 q(q),
85 zip(NULL),
86 caseSensitivity(QuaZip::csDefault),
87 raw(false),
88 writePos(0),
89 uncompressedSize(0),
90 crc(0),
91 internal(true),
92 zipError(UNZ_OK) {}
93 /// The constructor for the corresponding QuaZipFile constructor.
94 inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName):
95 q(q),
96 caseSensitivity(QuaZip::csDefault),
97 raw(false),
98 writePos(0),
99 uncompressedSize(0),
100 crc(0),
101 internal(true),
102 zipError(UNZ_OK)
103 {
104 zip=new QuaZip(zipName);
105 }
106 /// The constructor for the corresponding QuaZipFile constructor.
107 inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName,
108 QuaZip::CaseSensitivity cs):
109 q(q),
110 raw(false),
111 writePos(0),
112 uncompressedSize(0),
113 crc(0),
114 internal(true),
115 zipError(UNZ_OK)
116 {
117 zip=new QuaZip(zipName);
118 this->fileName=fileName;
119 if (this->fileName.startsWith(QLatin1String("/")))
120 this->fileName = this->fileName.mid(1);
121 this->caseSensitivity=cs;
122 }
123 /// The constructor for the QuaZipFile constructor accepting a file name.
124 inline QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip):
125 q(q),
126 zip(zip),
127 raw(false),
128 writePos(0),
129 uncompressedSize(0),
130 crc(0),
131 internal(false),
132 zipError(UNZ_OK) {}
133 /// The destructor.
134 inline ~QuaZipFilePrivate()
135 {
136 if (internal)
137 delete zip;
138 }
139};
140
141QuaZipFile::QuaZipFile():
142 p(new QuaZipFilePrivate(this))
143{
144}
145
146QuaZipFile::QuaZipFile(QObject *parent):
147 QIODevice(parent),
148 p(new QuaZipFilePrivate(this))
149{
150}
151
152QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent):
153 QIODevice(parent),
154 p(new QuaZipFilePrivate(this, zipName))
155{
156}
157
158QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName,
159 QuaZip::CaseSensitivity cs, QObject *parent):
160 QIODevice(parent),
161 p(new QuaZipFilePrivate(this, zipName, fileName, cs))
162{
163}
164
165QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent):
166 QIODevice(parent),
167 p(new QuaZipFilePrivate(this, zip))
168{
169}
170
171QuaZipFile::~QuaZipFile()
172{
173 if (isOpen())
174 close();
175 delete p;
176}
177
178QString QuaZipFile::getZipName() const
179{
180 return p->zip==NULL ? QString() : p->zip->getZipName();
181}
182
183QuaZip *QuaZipFile::getZip() const
184{
185 return p->internal ? NULL : p->zip;
186}
187
188QString QuaZipFile::getActualFileName()const
189{
190 p->setZipError(UNZ_OK);
191 if (p->zip == NULL || (openMode() & WriteOnly))
192 return QString();
193 QString name=p->zip->getCurrentFileName();
194 if(name.isNull())
195 p->setZipError(p->zip->getZipError());
196 return name;
197}
198
199void QuaZipFile::setZipName(const QString& zipName)
200{
201 if(isOpen()) {
202 qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name");
203 return;
204 }
205 if(p->zip!=NULL && p->internal)
206 delete p->zip;
207 p->zip=new QuaZip(zipName);
208 p->internal=true;
209}
210
211void QuaZipFile::setZip(QuaZip *zip)
212{
213 if(isOpen()) {
214 qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP");
215 return;
216 }
217 if(p->zip!=NULL && p->internal)
218 delete p->zip;
219 p->zip=zip;
220 p->fileName=QString();
221 p->internal=false;
222}
223
224void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs)
225{
226 if(p->zip==NULL) {
227 qWarning("QuaZipFile::setFileName(): call setZipName() first");
228 return;
229 }
230 if(!p->internal) {
231 qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip");
232 return;
233 }
234 if(isOpen()) {
235 qWarning("QuaZipFile::setFileName(): can not set file name for already opened file");
236 return;
237 }
238 p->fileName=fileName;
239 if (p->fileName.startsWith(QLatin1String("/")))
240 p->fileName = p->fileName.mid(1);
241 p->caseSensitivity=cs;
242}
243
244void QuaZipFilePrivate::setZipError(int zipError) const
245{
246 QuaZipFilePrivate *fakeThis = const_cast<QuaZipFilePrivate*>(this); // non-const
247 fakeThis->zipError=zipError;
248 if(zipError==UNZ_OK)
249 q->setErrorString(QString());
250 else
251 q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(zipError));
252}
253
254bool QuaZipFile::open(OpenMode mode)
255{
256 return open(mode, NULL);
257}
258
259bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password)
260{
261 p->resetZipError();
262 if(isOpen()) {
263 qWarning("QuaZipFile::open(): already opened");
264 return false;
265 }
266 if(mode&Unbuffered) {
267 qWarning("QuaZipFile::open(): Unbuffered mode is not supported");
268 return false;
269 }
270 if((mode&ReadOnly)&&!(mode&WriteOnly)) {
271 if(p->internal) {
272 if(!p->zip->open(QuaZip::mdUnzip)) {
273 p->setZipError(p->zip->getZipError());
274 return false;
275 }
276 if(!p->zip->setCurrentFile(p->fileName, p->caseSensitivity)) {
277 p->setZipError(p->zip->getZipError());
278 p->zip->close();
279 return false;
280 }
281 } else {
282 if(p->zip==NULL) {
283 qWarning("QuaZipFile::open(): zip is NULL");
284 return false;
285 }
286 if(p->zip->getMode()!=QuaZip::mdUnzip) {
287 qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
288 (int)mode, (int)p->zip->getMode());
289 return false;
290 }
291 if(!p->zip->hasCurrentFile()) {
292 qWarning("QuaZipFile::open(): zip does not have current file");
293 return false;
294 }
295 }
296 p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password));
297 if(p->zipError==UNZ_OK) {
298 setOpenMode(mode);
299 p->raw=raw;
300 return true;
301 } else
302 return false;
303 }
304 qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
305 return false;
306}
307
308bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info,
309 const char *password, quint32 crc,
310 int method, int level, bool raw,
311 int windowBits, int memLevel, int strategy)
312{
313 zip_fileinfo info_z;
314 p->resetZipError();
315 if(isOpen()) {
316 qWarning("QuaZipFile::open(): already opened");
317 return false;
318 }
319 if((mode&WriteOnly)&&!(mode&ReadOnly)) {
320 if(p->internal) {
321 qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach");
322 return false;
323 }
324 if(p->zip==NULL) {
325 qWarning("QuaZipFile::open(): zip is NULL");
326 return false;
327 }
328 if(p->zip->getMode()!=QuaZip::mdCreate&&p->zip->getMode()!=QuaZip::mdAppend&&p->zip->getMode()!=QuaZip::mdAdd) {
329 qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
330 (int)mode, (int)p->zip->getMode());
331 return false;
332 }
333 info_z.tmz_date.tm_year=info.dateTime.date().year();
334 info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1;
335 info_z.tmz_date.tm_mday=info.dateTime.date().day();
336 info_z.tmz_date.tm_hour=info.dateTime.time().hour();
337 info_z.tmz_date.tm_min=info.dateTime.time().minute();
338 info_z.tmz_date.tm_sec=info.dateTime.time().second();
339 info_z.dosDate = 0;
340 info_z.internal_fa=(uLong)info.internalAttr;
341 info_z.external_fa=(uLong)info.externalAttr;
342 if (p->zip->isDataDescriptorWritingEnabled())
343 zipSetFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR);
344 else
345 zipClearFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR);
346 p->setZipError(zipOpenNewFileInZip4_64(p->zip->getZipFile(),
347 p->zip->isUtf8Enabled()
348 ? info.name.toUtf8().constData()
349 : p->zip->getFileNameCodec()->fromUnicode(info.name).constData(),
350 &info_z,
351 info.extraLocal.constData(), info.extraLocal.length(),
352 info.extraGlobal.constData(), info.extraGlobal.length(),
353 p->zip->isUtf8Enabled()
354 ? info.comment.toUtf8().constData()
355 : p->zip->getCommentCodec()->fromUnicode(info.comment).constData(),
356 method, level, (int)raw,
357 windowBits, memLevel, strategy,
358 password, (uLong)crc,
359 (p->zip->getOsCode() << 8) | QUAZIP_VERSION_MADE_BY,
360 0,
361 p->zip->isZip64Enabled()));
362 if(p->zipError==UNZ_OK) {
363 p->writePos=0;
364 setOpenMode(mode);
365 p->raw=raw;
366 if(raw) {
367 p->crc=crc;
368 p->uncompressedSize=info.uncompressedSize;
369 }
370 return true;
371 } else
372 return false;
373 }
374 qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
375 return false;
376}
377
378bool QuaZipFile::isSequential()const
379{
380 return true;
381}
382
383qint64 QuaZipFile::pos()const
384{
385 if(p->zip==NULL) {
386 qWarning("QuaZipFile::pos(): call setZipName() or setZip() first");
387 return -1;
388 }
389 if(!isOpen()) {
390 qWarning("QuaZipFile::pos(): file is not open");
391 return -1;
392 }
393 if(openMode()&ReadOnly)
394 // QIODevice::pos() is broken for sequential devices,
395 // but thankfully bytesAvailable() returns the number of
396 // bytes buffered, so we know how far ahead we are.
397 return unztell64(p->zip->getUnzFile()) - QIODevice::bytesAvailable();
398 else
399 return p->writePos;
400}
401
402bool QuaZipFile::atEnd()const
403{
404 if(p->zip==NULL) {
405 qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first");
406 return false;
407 }
408 if(!isOpen()) {
409 qWarning("QuaZipFile::atEnd(): file is not open");
410 return false;
411 }
412 if(openMode()&ReadOnly)
413 // the same problem as with pos()
414 return QIODevice::bytesAvailable() == 0
415 && unzeof(p->zip->getUnzFile())==1;
416 else
417 return true;
418}
419
420qint64 QuaZipFile::size()const
421{
422 if(!isOpen()) {
423 qWarning("QuaZipFile::atEnd(): file is not open");
424 return -1;
425 }
426 if(openMode()&ReadOnly)
427 return p->raw?csize():usize();
428 else
429 return p->writePos;
430}
431
432qint64 QuaZipFile::csize()const
433{
434 unz_file_info64 info_z;
435 p->setZipError(UNZ_OK);
436 if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
437 p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
438 if(p->zipError!=UNZ_OK)
439 return -1;
440 return info_z.compressed_size;
441}
442
443qint64 QuaZipFile::usize()const
444{
445 unz_file_info64 info_z;
446 p->setZipError(UNZ_OK);
447 if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
448 p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
449 if(p->zipError!=UNZ_OK)
450 return -1;
451 return info_z.uncompressed_size;
452}
453
454bool QuaZipFile::getFileInfo(QuaZipFileInfo *info)
455{
456 QuaZipFileInfo64 info64;
457 if (getFileInfo(&info64)) {
458 info64.toQuaZipFileInfo(*info);
459 return true;
460 } else {
461 return false;
462 }
463}
464
465bool QuaZipFile::getFileInfo(QuaZipFileInfo64 *info)
466{
467 if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return false;
468 p->zip->getCurrentFileInfo(info);
469 p->setZipError(p->zip->getZipError());
470 return p->zipError==UNZ_OK;
471}
472
473void QuaZipFile::close()
474{
475 p->resetZipError();
476 if(p->zip==NULL||!p->zip->isOpen()) return;
477 if(!isOpen()) {
478 qWarning("QuaZipFile::close(): file isn't open");
479 return;
480 }
481 if(openMode()&ReadOnly)
482 p->setZipError(unzCloseCurrentFile(p->zip->getUnzFile()));
483 else if(openMode()&WriteOnly)
484 if(isRaw()) p->setZipError(zipCloseFileInZipRaw64(p->zip->getZipFile(), p->uncompressedSize, p->crc));
485 else p->setZipError(zipCloseFileInZip(p->zip->getZipFile()));
486 else {
487 qWarning("Wrong open mode: %d", (int)openMode());
488 return;
489 }
490 if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen);
491 else return;
492 if(p->internal) {
493 p->zip->close();
494 p->setZipError(p->zip->getZipError());
495 }
496}
497
498qint64 QuaZipFile::readData(char *data, qint64 maxSize)
499{
500 p->setZipError(UNZ_OK);
501 qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize);
502 if (bytesRead < 0) {
503 p->setZipError((int) bytesRead);
504 return -1;
505 }
506 return bytesRead;
507}
508
509qint64 QuaZipFile::writeData(const char* data, qint64 maxSize)
510{
511 p->setZipError(ZIP_OK);
512 p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize));
513 if(p->zipError!=ZIP_OK) return -1;
514 else {
515 p->writePos+=maxSize;
516 return maxSize;
517 }
518}
519
520QString QuaZipFile::getFileName() const
521{
522 return p->fileName;
523}
524
525QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity() const
526{
527 return p->caseSensitivity;
528}
529
530bool QuaZipFile::isRaw() const
531{
532 return p->raw;
533}
534
535int QuaZipFile::getZipError() const
536{
537 return p->zipError;
538}
539
540qint64 QuaZipFile::bytesAvailable() const
541{
542 return size() - pos();
543}
544
545QByteArray QuaZipFile::getLocalExtraField()
546{
547 int size = unzGetLocalExtrafield(p->zip->getUnzFile(), NULL, 0);
548 QByteArray extra(size, '\0');
549 int err = unzGetLocalExtrafield(p->zip->getUnzFile(), extra.data(), static_cast<uint>(extra.size()));
550 if (err < 0) {
551 p->setZipError(err);
552 return QByteArray();
553 }
554 return extra;
555}
556
557QDateTime QuaZipFile::getExtModTime()
558{
559 return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_MOD_TIME_FLAG);
560}
561
562QDateTime QuaZipFile::getExtAcTime()
563{
564 return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_AC_TIME_FLAG);
565}
566
567QDateTime QuaZipFile::getExtCrTime()
568{
569 return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_CR_TIME_FLAG);
570}
diff --git a/utils/rbutilqt/quazip/quazipfile.h b/utils/rbutilqt/quazip/quazipfile.h
new file mode 100644
index 0000000000..0fd6829f36
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipfile.h
@@ -0,0 +1,508 @@
1#ifndef QUA_ZIPFILE_H
2#define QUA_ZIPFILE_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant, see
25quazip/(un)zip.h files for details, basically it's zlib license.
26 **/
27
28#include <QtCore/QIODevice>
29
30#include "quazip_global.h"
31#include "quazip.h"
32#include "quazipnewinfo.h"
33
34class QuaZipFilePrivate;
35
36/// A file inside ZIP archive.
37/** \class QuaZipFile quazipfile.h <quazip/quazipfile.h>
38 * This is the most interesting class. Not only it provides C++
39 * interface to the ZIP/UNZIP package, but also integrates it with Qt by
40 * subclassing QIODevice. This makes possible to access files inside ZIP
41 * archive using QTextStream or QDataStream, for example. Actually, this
42 * is the main purpose of the whole QuaZIP library.
43 *
44 * You can either use existing QuaZip instance to create instance of
45 * this class or pass ZIP archive file name to this class, in which case
46 * it will create internal QuaZip object. See constructors' descriptions
47 * for details. Writing is only possible with the existing instance.
48 *
49 * Note that due to the underlying library's limitation it is not
50 * possible to use multiple QuaZipFile instances to open several files
51 * in the same archive at the same time. If you need to write to
52 * multiple files in parallel, then you should write to temporary files
53 * first, then pack them all at once when you have finished writing. If
54 * you need to read multiple files inside the same archive in parallel,
55 * you should extract them all into a temporary directory first.
56 *
57 * \section quazipfile-sequential Sequential or random-access?
58 *
59 * At the first thought, QuaZipFile has fixed size, the start and the
60 * end and should be therefore considered random-access device. But
61 * there is one major obstacle to making it random-access: ZIP/UNZIP API
62 * does not support seek() operation and the only way to implement it is
63 * through reopening the file and re-reading to the required position,
64 * but this is prohibitively slow.
65 *
66 * Therefore, QuaZipFile is considered to be a sequential device. This
67 * has advantage of availability of the ungetChar() operation (QIODevice
68 * does not implement it properly for non-sequential devices unless they
69 * support seek()). Disadvantage is a somewhat strange behaviour of the
70 * size() and pos() functions. This should be kept in mind while using
71 * this class.
72 *
73 **/
74class QUAZIP_EXPORT QuaZipFile: public QIODevice {
75 friend class QuaZipFilePrivate;
76 Q_OBJECT
77 private:
78 QuaZipFilePrivate *p;
79 // these are not supported nor implemented
80 QuaZipFile(const QuaZipFile& that);
81 QuaZipFile& operator=(const QuaZipFile& that);
82 protected:
83 /// Implementation of the QIODevice::readData().
84 qint64 readData(char *data, qint64 maxSize);
85 /// Implementation of the QIODevice::writeData().
86 qint64 writeData(const char *data, qint64 maxSize);
87 public:
88 /// Constructs a QuaZipFile instance.
89 /** You should use setZipName() and setFileName() or setZip() before
90 * trying to call open() on the constructed object.
91 **/
92 QuaZipFile();
93 /// Constructs a QuaZipFile instance.
94 /** \a parent argument specifies this object's parent object.
95 *
96 * You should use setZipName() and setFileName() or setZip() before
97 * trying to call open() on the constructed object.
98 **/
99 QuaZipFile(QObject *parent);
100 /// Constructs a QuaZipFile instance.
101 /** \a parent argument specifies this object's parent object and \a
102 * zipName specifies ZIP archive file name.
103 *
104 * You should use setFileName() before trying to call open() on the
105 * constructed object.
106 *
107 * QuaZipFile constructed by this constructor can be used for read
108 * only access. Use QuaZipFile(QuaZip*,QObject*) for writing.
109 **/
110 QuaZipFile(const QString& zipName, QObject *parent =NULL);
111 /// Constructs a QuaZipFile instance.
112 /** \a parent argument specifies this object's parent object, \a
113 * zipName specifies ZIP archive file name and \a fileName and \a cs
114 * specify a name of the file to open inside archive.
115 *
116 * QuaZipFile constructed by this constructor can be used for read
117 * only access. Use QuaZipFile(QuaZip*,QObject*) for writing.
118 *
119 * \sa QuaZip::setCurrentFile()
120 **/
121 QuaZipFile(const QString& zipName, const QString& fileName,
122 QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL);
123 /// Constructs a QuaZipFile instance.
124 /** \a parent argument specifies this object's parent object.
125 *
126 * \a zip is the pointer to the existing QuaZip object. This
127 * QuaZipFile object then can be used to read current file in the
128 * \a zip or to write to the file inside it.
129 *
130 * \warning Using this constructor for reading current file can be
131 * tricky. Let's take the following example:
132 * \code
133 * QuaZip zip("archive.zip");
134 * zip.open(QuaZip::mdUnzip);
135 * zip.setCurrentFile("file-in-archive");
136 * QuaZipFile file(&zip);
137 * file.open(QIODevice::ReadOnly);
138 * // ok, now we can read from the file
139 * file.read(somewhere, some);
140 * zip.setCurrentFile("another-file-in-archive"); // oops...
141 * QuaZipFile anotherFile(&zip);
142 * anotherFile.open(QIODevice::ReadOnly);
143 * anotherFile.read(somewhere, some); // this is still ok...
144 * file.read(somewhere, some); // and this is NOT
145 * \endcode
146 * So, what exactly happens here? When we change current file in the
147 * \c zip archive, \c file that references it becomes invalid
148 * (actually, as far as I understand ZIP/UNZIP sources, it becomes
149 * closed, but QuaZipFile has no means to detect it).
150 *
151 * Summary: do not close \c zip object or change its current file as
152 * long as QuaZipFile is open. Even better - use another constructors
153 * which create internal QuaZip instances, one per object, and
154 * therefore do not cause unnecessary trouble. This constructor may
155 * be useful, though, if you already have a QuaZip instance and do
156 * not want to access several files at once. Good example:
157 * \code
158 * QuaZip zip("archive.zip");
159 * zip.open(QuaZip::mdUnzip);
160 * // first, we need some information about archive itself
161 * QByteArray comment=zip.getComment();
162 * // and now we are going to access files inside it
163 * QuaZipFile file(&zip);
164 * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
165 * file.open(QIODevice::ReadOnly);
166 * // do something cool with file here
167 * file.close(); // do not forget to close!
168 * }
169 * zip.close();
170 * \endcode
171 **/
172 QuaZipFile(QuaZip *zip, QObject *parent =NULL);
173 /// Destroys a QuaZipFile instance.
174 /** Closes file if open, destructs internal QuaZip object (if it
175 * exists and \em is internal, of course).
176 **/
177 virtual ~QuaZipFile();
178 /// Returns the ZIP archive file name.
179 /** If this object was created by passing QuaZip pointer to the
180 * constructor, this function will return that QuaZip's file name
181 * (or null string if that object does not have file name yet).
182 *
183 * Otherwise, returns associated ZIP archive file name or null
184 * string if there are no name set yet.
185 *
186 * \sa setZipName() getFileName()
187 **/
188 QString getZipName()const;
189 /// Returns a pointer to the associated QuaZip object.
190 /** Returns \c NULL if there is no associated QuaZip or it is
191 * internal (so you will not mess with it).
192 **/
193 QuaZip* getZip()const;
194 /// Returns file name.
195 /** This function returns file name you passed to this object either
196 * by using
197 * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*)
198 * or by calling setFileName(). Real name of the file may differ in
199 * case if you used case-insensitivity.
200 *
201 * Returns null string if there is no file name set yet. This is the
202 * case when this QuaZipFile operates on the existing QuaZip object
203 * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used).
204 *
205 * \sa getActualFileName
206 **/
207 QString getFileName() const;
208 /// Returns case sensitivity of the file name.
209 /** This function returns case sensitivity argument you passed to
210 * this object either by using
211 * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*)
212 * or by calling setFileName().
213 *
214 * Returns unpredictable value if getFileName() returns null string
215 * (this is the case when you did not used setFileName() or
216 * constructor above).
217 *
218 * \sa getFileName
219 **/
220 QuaZip::CaseSensitivity getCaseSensitivity() const;
221 /// Returns the actual file name in the archive.
222 /** This is \em not a ZIP archive file name, but a name of file inside
223 * archive. It is not necessary the same name that you have passed
224 * to the
225 * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*),
226 * setFileName() or QuaZip::setCurrentFile() - this is the real file
227 * name inside archive, so it may differ in case if the file name
228 * search was case-insensitive.
229 *
230 * Equivalent to calling getCurrentFileName() on the associated
231 * QuaZip object. Returns null string if there is no associated
232 * QuaZip object or if it does not have a current file yet. And this
233 * is the case if you called setFileName() but did not open the
234 * file yet. So this is perfectly fine:
235 * \code
236 * QuaZipFile file("somezip.zip");
237 * file.setFileName("somefile");
238 * QString name=file.getName(); // name=="somefile"
239 * QString actual=file.getActualFileName(); // actual is null string
240 * file.open(QIODevice::ReadOnly);
241 * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows
242 * \endcode
243 *
244 * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity
245 **/
246 QString getActualFileName()const;
247 /// Sets the ZIP archive file name.
248 /** Automatically creates internal QuaZip object and destroys
249 * previously created internal QuaZip object, if any.
250 *
251 * Will do nothing if this file is already open. You must close() it
252 * first.
253 **/
254 void setZipName(const QString& zipName);
255 /// Returns \c true if the file was opened in raw mode.
256 /** If the file is not open, the returned value is undefined.
257 *
258 * \sa open(OpenMode,int*,int*,bool,const char*)
259 **/
260 bool isRaw() const;
261 /// Binds to the existing QuaZip instance.
262 /** This function destroys internal QuaZip object, if any, and makes
263 * this QuaZipFile to use current file in the \a zip object for any
264 * further operations. See QuaZipFile(QuaZip*,QObject*) for the
265 * possible pitfalls.
266 *
267 * Will do nothing if the file is currently open. You must close()
268 * it first.
269 **/
270 void setZip(QuaZip *zip);
271 /// Sets the file name.
272 /** Will do nothing if at least one of the following conditions is
273 * met:
274 * - ZIP name has not been set yet (getZipName() returns null
275 * string).
276 * - This QuaZipFile is associated with external QuaZip. In this
277 * case you should call that QuaZip's setCurrentFile() function
278 * instead!
279 * - File is already open so setting the name is meaningless.
280 *
281 * \sa QuaZip::setCurrentFile
282 **/
283 void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault);
284 /// Opens a file for reading.
285 /** Returns \c true on success, \c false otherwise.
286 * Call getZipError() to get error code.
287 *
288 * \note Since ZIP/UNZIP API provides buffered reading only,
289 * QuaZipFile does not support unbuffered reading. So do not pass
290 * QIODevice::Unbuffered flag in \a mode, or open will fail.
291 **/
292 virtual bool open(OpenMode mode);
293 /// Opens a file for reading.
294 /** \overload
295 * Argument \a password specifies a password to decrypt the file. If
296 * it is NULL then this function behaves just like open(OpenMode).
297 **/
298 inline bool open(OpenMode mode, const char *password)
299 {return open(mode, NULL, NULL, false, password);}
300 /// Opens a file for reading.
301 /** \overload
302 * Argument \a password specifies a password to decrypt the file.
303 *
304 * An integers pointed by \a method and \a level will receive codes
305 * of the compression method and level used. See unzip.h.
306 *
307 * If raw is \c true then no decompression is performed.
308 *
309 * \a method should not be \c NULL. \a level can be \c NULL if you
310 * don't want to know the compression level.
311 **/
312 bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL);
313 /// Opens a file for writing.
314 /** \a info argument specifies information about file. It should at
315 * least specify a correct file name. Also, it is a good idea to
316 * specify correct timestamp (by default, current time will be
317 * used). See QuaZipNewInfo.
318 *
319 * The \a password argument specifies the password for crypting. Pass NULL
320 * if you don't need any crypting. The \a crc argument was supposed
321 * to be used for crypting too, but then it turned out that it's
322 * false information, so you need to set it to 0 unless you want to
323 * use the raw mode (see below).
324 *
325 * Arguments \a method and \a level specify compression method and
326 * level. The only method supported is Z_DEFLATED, but you may also
327 * specify 0 for no compression. If all of the files in the archive
328 * use both method 0 and either level 0 is explicitly specified or
329 * data descriptor writing is disabled with
330 * QuaZip::setDataDescriptorWritingEnabled(), then the
331 * resulting archive is supposed to be compatible with the 1.0 ZIP
332 * format version, should you need that. Except for this, \a level
333 * has no other effects with method 0.
334 *
335 * If \a raw is \c true, no compression is performed. In this case,
336 * \a crc and uncompressedSize field of the \a info are required.
337 *
338 * Arguments \a windowBits, \a memLevel, \a strategy provide zlib
339 * algorithms tuning. See deflateInit2() in zlib.
340 **/
341 bool open(OpenMode mode, const QuaZipNewInfo& info,
342 const char *password =NULL, quint32 crc =0,
343 int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false,
344 int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY);
345 /// Returns \c true, but \ref quazipfile-sequential "beware"!
346 virtual bool isSequential()const;
347 /// Returns current position in the file.
348 /** Implementation of the QIODevice::pos(). When reading, this
349 * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is
350 * unable to keep track of the ungetChar() calls (which is
351 * non-virtual and therefore is dangerous to reimplement). So if you
352 * are using ungetChar() feature of the QIODevice, this function
353 * reports incorrect value until you get back characters which you
354 * ungot.
355 *
356 * When writing, pos() returns number of bytes already written
357 * (uncompressed unless you use raw mode).
358 *
359 * \note Although
360 * \ref quazipfile-sequential "QuaZipFile is a sequential device"
361 * and therefore pos() should always return zero, it does not,
362 * because it would be misguiding. Keep this in mind.
363 *
364 * This function returns -1 if the file or archive is not open.
365 *
366 * Error code returned by getZipError() is not affected by this
367 * function call.
368 **/
369 virtual qint64 pos()const;
370 /// Returns \c true if the end of file was reached.
371 /** This function returns \c false in the case of error. This means
372 * that you called this function on either not open file, or a file
373 * in the not open archive or even on a QuaZipFile instance that
374 * does not even have QuaZip instance associated. Do not do that
375 * because there is no means to determine whether \c false is
376 * returned because of error or because end of file was reached.
377 * Well, on the other side you may interpret \c false return value
378 * as "there is no file open to check for end of file and there is
379 * no end of file therefore".
380 *
381 * When writing, this function always returns \c true (because you
382 * are always writing to the end of file).
383 *
384 * Error code returned by getZipError() is not affected by this
385 * function call.
386 **/
387 virtual bool atEnd()const;
388 /// Returns file size.
389 /** This function returns csize() if the file is open for reading in
390 * raw mode, usize() if it is open for reading in normal mode and
391 * pos() if it is open for writing.
392 *
393 * Returns -1 on error, call getZipError() to get error code.
394 *
395 * \note This function returns file size despite that
396 * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device",
397 * for which size() should return bytesAvailable() instead. But its
398 * name would be very misguiding otherwise, so just keep in mind
399 * this inconsistence.
400 **/
401 virtual qint64 size()const;
402 /// Returns compressed file size.
403 /** Equivalent to calling getFileInfo() and then getting
404 * compressedSize field, but more convenient and faster.
405 *
406 * File must be open for reading before calling this function.
407 *
408 * Returns -1 on error, call getZipError() to get error code.
409 **/
410 qint64 csize()const;
411 /// Returns uncompressed file size.
412 /** Equivalent to calling getFileInfo() and then getting
413 * uncompressedSize field, but more convenient and faster. See
414 * getFileInfo() for a warning.
415 *
416 * File must be open for reading before calling this function.
417 *
418 * Returns -1 on error, call getZipError() to get error code.
419 **/
420 qint64 usize()const;
421 /// Gets information about current file.
422 /** This function does the same thing as calling
423 * QuaZip::getCurrentFileInfo() on the associated QuaZip object,
424 * but you can not call getCurrentFileInfo() if the associated
425 * QuaZip is internal (because you do not have access to it), while
426 * you still can call this function in that case.
427 *
428 * File must be open for reading before calling this function.
429 *
430 * \return \c false in the case of an error.
431 *
432 * This function doesn't support zip64, but will still work fine on zip64
433 * archives if file sizes are below 4 GB, otherwise the values will be set
434 * as if converted using QuaZipFileInfo64::toQuaZipFileInfo().
435 *
436 * \sa getFileInfo(QuaZipFileInfo64*)
437 **/
438 bool getFileInfo(QuaZipFileInfo *info);
439 /// Gets information about current file with zip64 support.
440 /**
441 * @overload
442 *
443 * \sa getFileInfo(QuaZipFileInfo*)
444 */
445 bool getFileInfo(QuaZipFileInfo64 *info);
446 /// Closes the file.
447 /** Call getZipError() to determine if the close was successful.
448 **/
449 virtual void close();
450 /// Returns the error code returned by the last ZIP/UNZIP API call.
451 int getZipError() const;
452 /// Returns the number of bytes available for reading.
453 virtual qint64 bytesAvailable() const;
454 /// Returns the local extra field
455 /**
456 There are two (optional) local extra fields associated with a file.
457 One is located in the central header and is available along
458 with the rest of the file information in @ref QuaZipFileInfo64::extra.
459 Another is located before the file itself,
460 and is returned by this function. The file must be open first.
461
462 @return the local extra field, or an empty array if there is none
463 (or file is not open)
464 */
465 QByteArray getLocalExtraField();
466 /// Returns the extended modification timestamp
467 /**
468 * The getExt*Time() functions only work if there is an extended timestamp
469 * extra field (ID 0x5455) present. Otherwise, they all return invalid null
470 * timestamps.
471 *
472 * Modification time, but not other times, can also be accessed through
473 * @ref QuaZipFileInfo64 without the need to open the file first.
474 *
475 * @sa dateTime
476 * @sa QuaZipFileInfo64::getExtModTime()
477 * @sa getExtAcTime()
478 * @sa getExtCrTime()
479 * @return The extended modification time, UTC
480 */
481 QDateTime getExtModTime();
482 /// Returns the extended access timestamp
483 /**
484 * The getExt*Time() functions only work if there is an extended timestamp
485 * extra field (ID 0x5455) present. Otherwise, they all return invalid null
486 * timestamps.
487 * @sa dateTime
488 * @sa QuaZipFileInfo64::getExtModTime()
489 * @sa getExtModTime()
490 * @sa getExtCrTime()
491 * @return The extended access time, UTC
492 */
493 QDateTime getExtAcTime();
494 /// Returns the extended creation timestamp
495 /**
496 * The getExt*Time() functions only work if there is an extended timestamp
497 * extra field (ID 0x5455) present. Otherwise, they all return invalid null
498 * timestamps.
499 * @sa dateTime
500 * @sa QuaZipFileInfo64::getExtModTime()
501 * @sa getExtModTime()
502 * @sa getExtAcTime()
503 * @return The extended creation time, UTC
504 */
505 QDateTime getExtCrTime();
506};
507
508#endif
diff --git a/utils/rbutilqt/quazip/quazipfileinfo.cpp b/utils/rbutilqt/quazip/quazipfileinfo.cpp
new file mode 100644
index 0000000000..d5798ea771
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipfileinfo.cpp
@@ -0,0 +1,196 @@
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant and contributors,
22see quazip/(un)zip.h files for details. Basically it's the zlib license.
23*/
24
25#include "quazipfileinfo.h"
26
27#include <QtCore/QDataStream>
28
29static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) {
30 quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16;
31 QFile::Permissions perm = QFile::Permissions();
32 if ((uPerm & 0400) != 0)
33 perm |= QFile::ReadOwner;
34 if ((uPerm & 0200) != 0)
35 perm |= QFile::WriteOwner;
36 if ((uPerm & 0100) != 0)
37 perm |= QFile::ExeOwner;
38 if ((uPerm & 0040) != 0)
39 perm |= QFile::ReadGroup;
40 if ((uPerm & 0020) != 0)
41 perm |= QFile::WriteGroup;
42 if ((uPerm & 0010) != 0)
43 perm |= QFile::ExeGroup;
44 if ((uPerm & 0004) != 0)
45 perm |= QFile::ReadOther;
46 if ((uPerm & 0002) != 0)
47 perm |= QFile::WriteOther;
48 if ((uPerm & 0001) != 0)
49 perm |= QFile::ExeOther;
50 return perm;
51
52}
53
54QFile::Permissions QuaZipFileInfo::getPermissions() const
55{
56 return permissionsFromExternalAttr(externalAttr);
57}
58
59QFile::Permissions QuaZipFileInfo64::getPermissions() const
60{
61 return permissionsFromExternalAttr(externalAttr);
62}
63
64bool QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo &info) const
65{
66 bool noOverflow = true;
67 info.name = name;
68 info.versionCreated = versionCreated;
69 info.versionNeeded = versionNeeded;
70 info.flags = flags;
71 info.method = method;
72 info.dateTime = dateTime;
73 info.crc = crc;
74 if (compressedSize > 0xFFFFFFFFu) {
75 info.compressedSize = 0xFFFFFFFFu;
76 noOverflow = false;
77 } else {
78 info.compressedSize = compressedSize;
79 }
80 if (uncompressedSize > 0xFFFFFFFFu) {
81 info.uncompressedSize = 0xFFFFFFFFu;
82 noOverflow = false;
83 } else {
84 info.uncompressedSize = uncompressedSize;
85 }
86 info.diskNumberStart = diskNumberStart;
87 info.internalAttr = internalAttr;
88 info.externalAttr = externalAttr;
89 info.comment = comment;
90 info.extra = extra;
91 return noOverflow;
92}
93
94static QDateTime getNTFSTime(const QByteArray &extra, int position,
95 int *fineTicks)
96{
97 QDateTime dateTime;
98 QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra);
99 QList<QByteArray> ntfsExtraFields = extraHash[QUAZIP_EXTRA_NTFS_MAGIC];
100 if (ntfsExtraFields.isEmpty())
101 return dateTime;
102 QByteArray ntfsExtraField = ntfsExtraFields.at(0);
103 if (ntfsExtraField.length() <= 4)
104 return dateTime;
105 QByteArray ntfsAttributes = ntfsExtraField.mid(4);
106 QuaExtraFieldHash ntfsHash = QuaZipFileInfo64::parseExtraField(ntfsAttributes);
107 QList<QByteArray> ntfsTimeAttributes = ntfsHash[QUAZIP_EXTRA_NTFS_TIME_MAGIC];
108 if (ntfsTimeAttributes.isEmpty())
109 return dateTime;
110 QByteArray ntfsTimes = ntfsTimeAttributes.at(0);
111 if (ntfsTimes.size() < 24)
112 return dateTime;
113 QDataStream timeReader(ntfsTimes);
114 timeReader.setByteOrder(QDataStream::LittleEndian);
115 timeReader.device()->seek(position);
116 quint64 time;
117 timeReader >> time;
118 QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
119 dateTime = base.addMSecs(time / 10000);
120 if (fineTicks != NULL) {
121 *fineTicks = static_cast<int>(time % 10000);
122 }
123 return dateTime;
124}
125
126QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const
127{
128 return getNTFSTime(extra, 0, fineTicks);
129}
130
131QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const
132{
133 return getNTFSTime(extra, 8, fineTicks);
134}
135
136QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const
137{
138 return getNTFSTime(extra, 16, fineTicks);
139}
140
141QDateTime QuaZipFileInfo64::getExtTime(const QByteArray &extra, int flag)
142{
143 QDateTime dateTime;
144 QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra);
145 QList<QByteArray> extTimeFields = extraHash[QUAZIP_EXTRA_EXT_TIME_MAGIC];
146 if (extTimeFields.isEmpty())
147 return dateTime;
148 QByteArray extTimeField = extTimeFields.at(0);
149 if (extTimeField.length() < 1)
150 return dateTime;
151 QDataStream input(extTimeField);
152 input.setByteOrder(QDataStream::LittleEndian);
153 quint8 flags;
154 input >> flags;
155 int flagsRemaining = flags;
156 while (!input.atEnd()) {
157 int nextFlag = flagsRemaining & -flagsRemaining;
158 flagsRemaining &= flagsRemaining - 1;
159 qint32 time;
160 input >> time;
161 if (nextFlag == flag) {
162 QDateTime base(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC);
163 dateTime = base.addSecs(time);
164 return dateTime;
165 }
166 }
167 return dateTime;
168}
169
170QDateTime QuaZipFileInfo64::getExtModTime() const
171{
172 return getExtTime(extra, 1);
173}
174
175QuaExtraFieldHash QuaZipFileInfo64::parseExtraField(const QByteArray &extraField)
176{
177 QDataStream input(extraField);
178 input.setByteOrder(QDataStream::LittleEndian);
179 QHash<quint16, QList<QByteArray> > result;
180 while (!input.atEnd()) {
181 quint16 id, size;
182 input >> id;
183 if (input.status() == QDataStream::ReadPastEnd)
184 return result;
185 input >> size;
186 if (input.status() == QDataStream::ReadPastEnd)
187 return result;
188 QByteArray data;
189 data.resize(size);
190 int read = input.readRawData(data.data(), data.size());
191 if (read < data.size())
192 return result;
193 result[id] << data;
194 }
195 return result;
196}
diff --git a/utils/rbutilqt/quazip/quazipfileinfo.h b/utils/rbutilqt/quazip/quazipfileinfo.h
new file mode 100644
index 0000000000..43665b4ac2
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipfileinfo.h
@@ -0,0 +1,226 @@
1#ifndef QUA_ZIPFILEINFO_H
2#define QUA_ZIPFILEINFO_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant and contributors,
25see quazip/(un)zip.h files for details. Basically it's the zlib license.
26*/
27
28#include <QtCore/QByteArray>
29#include <QtCore/QDateTime>
30#include <QtCore/QFile>
31#include <QtCore/QHash>
32
33#include "quazip_global.h"
34
35/// The typedef to store extra field parse results
36typedef QHash<quint16, QList<QByteArray> > QuaExtraFieldHash;
37
38/// Information about a file inside archive.
39/**
40 * \deprecated Use QuaZipFileInfo64 instead. Not only it supports large files,
41 * but also more convenience methods as well.
42 *
43 * Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to
44 * fill this structure. */
45struct QUAZIP_EXPORT QuaZipFileInfo {
46 /// File name.
47 QString name;
48 /// Version created by.
49 quint16 versionCreated;
50 /// Version needed to extract.
51 quint16 versionNeeded;
52 /// General purpose flags.
53 quint16 flags;
54 /// Compression method.
55 quint16 method;
56 /// Last modification date and time.
57 QDateTime dateTime;
58 /// CRC.
59 quint32 crc;
60 /// Compressed file size.
61 quint32 compressedSize;
62 /// Uncompressed file size.
63 quint32 uncompressedSize;
64 /// Disk number start.
65 quint16 diskNumberStart;
66 /// Internal file attributes.
67 quint16 internalAttr;
68 /// External file attributes.
69 quint32 externalAttr;
70 /// Comment.
71 QString comment;
72 /// Extra field.
73 QByteArray extra;
74 /// Get the file permissions.
75 /**
76 Returns the high 16 bits of external attributes converted to
77 QFile::Permissions.
78 */
79 QFile::Permissions getPermissions() const;
80};
81
82/// Information about a file inside archive (with zip64 support).
83/** Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to
84 * fill this structure. */
85struct QUAZIP_EXPORT QuaZipFileInfo64 {
86 /// File name.
87 QString name;
88 /// Version created by.
89 quint16 versionCreated;
90 /// Version needed to extract.
91 quint16 versionNeeded;
92 /// General purpose flags.
93 quint16 flags;
94 /// Compression method.
95 quint16 method;
96 /// Last modification date and time.
97 /**
98 * This is the time stored in the standard ZIP header. This format only allows
99 * to store time with 2-second precision, so the seconds will always be even
100 * and the milliseconds will always be zero. If you need more precise
101 * date and time, you can try to call the getNTFSmTime() function or
102 * its siblings, provided that the archive itself contains these NTFS times.
103 */
104 QDateTime dateTime;
105 /// CRC.
106 quint32 crc;
107 /// Compressed file size.
108 quint64 compressedSize;
109 /// Uncompressed file size.
110 quint64 uncompressedSize;
111 /// Disk number start.
112 quint16 diskNumberStart;
113 /// Internal file attributes.
114 quint16 internalAttr;
115 /// External file attributes.
116 quint32 externalAttr;
117 /// Comment.
118 QString comment;
119 /// Extra field.
120 QByteArray extra;
121 /// Get the file permissions.
122 /**
123 Returns the high 16 bits of external attributes converted to
124 QFile::Permissions.
125 */
126 QFile::Permissions getPermissions() const;
127 /// Converts to QuaZipFileInfo
128 /**
129 If any of the fields are greater than 0xFFFFFFFFu, they are set to
130 0xFFFFFFFFu exactly, not just truncated. This function should be mainly used
131 for compatibility with the old code expecting QuaZipFileInfo, in the cases
132 when it's impossible or otherwise unadvisable (due to ABI compatibility
133 reasons, for example) to modify that old code to use QuaZipFileInfo64.
134
135 \return \c true if all fields converted correctly, \c false if an overflow
136 occured.
137 */
138 bool toQuaZipFileInfo(QuaZipFileInfo &info) const;
139 /// Returns the NTFS modification time
140 /**
141 * The getNTFS*Time() functions only work if there is an NTFS extra field
142 * present. Otherwise, they all return invalid null timestamps.
143 * @param fineTicks If not NULL, the fractional part of milliseconds returned
144 * there, measured in 100-nanosecond ticks. Will be set to
145 * zero if there is no NTFS extra field.
146 * @sa dateTime
147 * @sa getNTFSaTime()
148 * @sa getNTFScTime()
149 * @return The NTFS modification time, UTC
150 */
151 QDateTime getNTFSmTime(int *fineTicks = NULL) const;
152 /// Returns the NTFS access time
153 /**
154 * The getNTFS*Time() functions only work if there is an NTFS extra field
155 * present. Otherwise, they all return invalid null timestamps.
156 * @param fineTicks If not NULL, the fractional part of milliseconds returned
157 * there, measured in 100-nanosecond ticks. Will be set to
158 * zero if there is no NTFS extra field.
159 * @sa dateTime
160 * @sa getNTFSmTime()
161 * @sa getNTFScTime()
162 * @return The NTFS access time, UTC
163 */
164 QDateTime getNTFSaTime(int *fineTicks = NULL) const;
165 /// Returns the NTFS creation time
166 /**
167 * The getNTFS*Time() functions only work if there is an NTFS extra field
168 * present. Otherwise, they all return invalid null timestamps.
169 * @param fineTicks If not NULL, the fractional part of milliseconds returned
170 * there, measured in 100-nanosecond ticks. Will be set to
171 * zero if there is no NTFS extra field.
172 * @sa dateTime
173 * @sa getNTFSmTime()
174 * @sa getNTFSaTime()
175 * @return The NTFS creation time, UTC
176 */
177 QDateTime getNTFScTime(int *fineTicks = NULL) const;
178 /// Returns the extended modification timestamp
179 /**
180 * The getExt*Time() functions only work if there is an extended timestamp
181 * extra field (ID 0x5455) present. Otherwise, they all return invalid null
182 * timestamps.
183 *
184 * QuaZipFileInfo64 only contains the modification time because it's extracted
185 * from @ref extra, which contains the global extra field, and access and
186 * creation time are in the local header which can be accessed through
187 * @ref QuaZipFile.
188 *
189 * @sa dateTime
190 * @sa QuaZipFile::getExtModTime()
191 * @sa QuaZipFile::getExtAcTime()
192 * @sa QuaZipFile::getExtCrTime()
193 * @return The extended modification time, UTC
194 */
195 QDateTime getExtModTime() const;
196 /// Checks whether the file is encrypted.
197 bool isEncrypted() const {return (flags & 1) != 0;}
198 /// Parses extra field
199 /**
200 * The returned hash table contains a list of data blocks for every header ID
201 * in the provided extra field. The number of data blocks in a hash table value
202 * equals to the number of occurrences of the appropriate header id. In most cases,
203 * a block with a specific header ID only occurs once, and therefore the returned
204 * hash table will contain a list consisting of a single element for that header ID.
205 *
206 * @param extraField extra field to parse
207 * @return header id to list of data block hash
208 */
209 static QuaExtraFieldHash parseExtraField(const QByteArray &extraField);
210 /// Extracts extended time from the extra field
211 /**
212 * Utility function used by various getExt*Time() functions, but can be used directly
213 * if the extra field is obtained elsewhere (from a third party library, for example).
214 *
215 * @param extra the extra field for a file
216 * @param flag 1 - modification time, 2 - access time, 4 - creation time
217 * @return the extracted time or null QDateTime if not present
218 * @sa getExtModTime()
219 * @sa QuaZipFile::getExtModTime()
220 * @sa QuaZipFile::getExtAcTime()
221 * @sa QuaZipFile::getExtCrTime()
222 */
223 static QDateTime getExtTime(const QByteArray &extra, int flag);
224};
225
226#endif
diff --git a/utils/rbutilqt/quazip/quazipnewinfo.cpp b/utils/rbutilqt/quazip/quazipnewinfo.cpp
new file mode 100644
index 0000000000..98630e086a
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipnewinfo.cpp
@@ -0,0 +1,290 @@
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant and contributors,
22see quazip/(un)zip.h files for details. Basically it's the zlib license.
23*/
24
25#include <QtCore/QFileInfo>
26
27#include "quazipnewinfo.h"
28
29#include <string.h>
30
31static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info,
32 QFile::Permissions perm, bool isDir, bool isSymLink = false)
33{
34 quint32 uPerm = isDir ? 0040000 : 0100000;
35
36 if ( isSymLink ) {
37#ifdef Q_OS_WIN
38 uPerm = 0200000;
39#else
40 uPerm = 0120000;
41#endif
42 }
43
44 if ((perm & QFile::ReadOwner) != 0)
45 uPerm |= 0400;
46 if ((perm & QFile::WriteOwner) != 0)
47 uPerm |= 0200;
48 if ((perm & QFile::ExeOwner) != 0)
49 uPerm |= 0100;
50 if ((perm & QFile::ReadGroup) != 0)
51 uPerm |= 0040;
52 if ((perm & QFile::WriteGroup) != 0)
53 uPerm |= 0020;
54 if ((perm & QFile::ExeGroup) != 0)
55 uPerm |= 0010;
56 if ((perm & QFile::ReadOther) != 0)
57 uPerm |= 0004;
58 if ((perm & QFile::WriteOther) != 0)
59 uPerm |= 0002;
60 if ((perm & QFile::ExeOther) != 0)
61 uPerm |= 0001;
62 info->externalAttr = (info->externalAttr & ~0xFFFF0000u) | (uPerm << 16);
63}
64
65template<typename FileInfo>
66void QuaZipNewInfo_init(QuaZipNewInfo &self, const FileInfo &existing)
67{
68 self.name = existing.name;
69 self.dateTime = existing.dateTime;
70 self.internalAttr = existing.internalAttr;
71 self.externalAttr = existing.externalAttr;
72 self.comment = existing.comment;
73 self.extraLocal = existing.extra;
74 self.extraGlobal = existing.extra;
75 self.uncompressedSize = existing.uncompressedSize;
76}
77
78QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo &existing)
79{
80 QuaZipNewInfo_init(*this, existing);
81}
82
83QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo64 &existing)
84{
85 QuaZipNewInfo_init(*this, existing);
86}
87
88QuaZipNewInfo::QuaZipNewInfo(const QString& name):
89 name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0),
90 uncompressedSize(0)
91{
92}
93
94QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file):
95 name(name), internalAttr(0), externalAttr(0), uncompressedSize(0)
96{
97 QFileInfo info(file);
98 QDateTime lm = info.lastModified();
99 if (!info.exists()) {
100 dateTime = QDateTime::currentDateTime();
101 } else {
102 dateTime = lm;
103 QuaZipNewInfo_setPermissions(this, info.permissions(), info.isDir(), info.isSymLink());
104 }
105}
106
107void QuaZipNewInfo::setFileDateTime(const QString& file)
108{
109 QFileInfo info(file);
110 QDateTime lm = info.lastModified();
111 if (info.exists())
112 dateTime = lm;
113}
114
115void QuaZipNewInfo::setFilePermissions(const QString &file)
116{
117 QFileInfo info = QFileInfo(file);
118 QFile::Permissions perm = info.permissions();
119 QuaZipNewInfo_setPermissions(this, perm, info.isDir(), info.isSymLink());
120}
121
122void QuaZipNewInfo::setPermissions(QFile::Permissions permissions)
123{
124 QuaZipNewInfo_setPermissions(this, permissions, name.endsWith(QLatin1String("/")));
125}
126
127void QuaZipNewInfo::setFileNTFSTimes(const QString &fileName)
128{
129 QFileInfo fi(fileName);
130 if (!fi.exists()) {
131 qWarning("QuaZipNewInfo::setFileNTFSTimes(): '%s' doesn't exist",
132 fileName.toUtf8().constData());
133 return;
134 }
135 setFileNTFSmTime(fi.lastModified());
136 setFileNTFSaTime(fi.lastRead());
137#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
138 setFileNTFScTime(fi.birthTime());
139#else
140 setFileNTFScTime(fi.created());
141#endif
142}
143
144static void setNTFSTime(QByteArray &extra, const QDateTime &time, int position,
145 int fineTicks) {
146 int ntfsPos = -1, timesPos = -1;
147 unsigned ntfsLength = 0, ntfsTimesLength = 0;
148 for (int i = 0; i <= extra.size() - 4; ) {
149 unsigned type = static_cast<unsigned>(static_cast<unsigned char>(
150 extra.at(i)))
151 | (static_cast<unsigned>(static_cast<unsigned char>(
152 extra.at(i + 1))) << 8);
153 i += 2;
154 unsigned length = static_cast<unsigned>(static_cast<unsigned char>(
155 extra.at(i)))
156 | (static_cast<unsigned>(static_cast<unsigned char>(
157 extra.at(i + 1))) << 8);
158 i += 2;
159 if (type == QUAZIP_EXTRA_NTFS_MAGIC) {
160 ntfsPos = i - 4; // the beginning of the NTFS record
161 ntfsLength = length;
162 if (length <= 4) {
163 break; // no times in the NTFS record
164 }
165 i += 4; // reserved
166 while (i <= extra.size() - 4) {
167 unsigned tag = static_cast<unsigned>(
168 static_cast<unsigned char>(extra.at(i)))
169 | (static_cast<unsigned>(
170 static_cast<unsigned char>(extra.at(i + 1)))
171 << 8);
172 i += 2;
173 unsigned tagsize = static_cast<unsigned>(
174 static_cast<unsigned char>(extra.at(i)))
175 | (static_cast<unsigned>(
176 static_cast<unsigned char>(extra.at(i + 1)))
177 << 8);
178 i += 2;
179 if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC) {
180 timesPos = i - 4; // the beginning of the NTFS times tag
181 ntfsTimesLength = tagsize;
182 break;
183 } else {
184 i += tagsize;
185 }
186 }
187 break; // I ain't going to search for yet another NTFS record!
188 } else {
189 i += length;
190 }
191 }
192 if (ntfsPos == -1) {
193 // No NTFS record, need to create one.
194 ntfsPos = extra.size();
195 ntfsLength = 32;
196 extra.resize(extra.size() + 4 + ntfsLength);
197 // the NTFS record header
198 extra[ntfsPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC);
199 extra[ntfsPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC >> 8);
200 extra[ntfsPos + 2] = 32; // the 2-byte size in LittleEndian
201 extra[ntfsPos + 3] = 0;
202 // zero the record
203 memset(extra.data() + ntfsPos + 4, 0, 32);
204 timesPos = ntfsPos + 8;
205 // now set the tag data
206 extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
207 extra[timesPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC
208 >> 8);
209 // the size:
210 extra[timesPos + 2] = 24;
211 extra[timesPos + 3] = 0;
212 ntfsTimesLength = 24;
213 }
214 if (timesPos == -1) {
215 // No time tag in the NTFS record, need to add one.
216 timesPos = ntfsPos + 4 + ntfsLength;
217 extra.resize(extra.size() + 28);
218 // Now we need to move the rest of the field
219 // (possibly zero bytes, but memmove() is OK with that).
220 // 0 ......... ntfsPos .. ntfsPos + 4 ... timesPos
221 // <some data> <header> <NTFS record> <need-to-move data> <end>
222 memmove(extra.data() + timesPos + 28, extra.data() + timesPos,
223 extra.size() - 28 - timesPos);
224 ntfsLength += 28;
225 // now set the tag data
226 extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
227 extra[timesPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC
228 >> 8);
229 // the size:
230 extra[timesPos + 2] = 24;
231 extra[timesPos + 3] = 0;
232 // zero the record
233 memset(extra.data() + timesPos + 4, 0, 24);
234 ntfsTimesLength = 24;
235 }
236 if (ntfsTimesLength < 24) {
237 // Broken times field. OK, this is really unlikely, but just in case...
238 size_t timesEnd = timesPos + 4 + ntfsTimesLength;
239 extra.resize(extra.size() + (24 - ntfsTimesLength));
240 // Move it!
241 // 0 ......... timesPos .... timesPos + 4 .. timesEnd
242 // <some data> <time header> <broken times> <need-to-move data> <end>
243 memmove(extra.data() + timesEnd + (24 - ntfsTimesLength),
244 extra.data() + timesEnd,
245 extra.size() - (24 - ntfsTimesLength) - timesEnd);
246 // Now we have to increase the NTFS record and time tag lengths.
247 ntfsLength += (24 - ntfsTimesLength);
248 ntfsTimesLength = 24;
249 extra[ntfsPos + 2] = static_cast<char>(ntfsLength);
250 extra[ntfsPos + 3] = static_cast<char>(ntfsLength >> 8);
251 extra[timesPos + 2] = static_cast<char>(ntfsTimesLength);
252 extra[timesPos + 3] = static_cast<char>(ntfsTimesLength >> 8);
253 }
254 QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
255#if (QT_VERSION >= 0x040700)
256 quint64 ticks = base.msecsTo(time) * 10000 + fineTicks;
257#else
258 QDateTime utc = time.toUTC();
259 quint64 ticks = (static_cast<qint64>(base.date().daysTo(utc.date()))
260 * Q_INT64_C(86400000)
261 + static_cast<qint64>(base.time().msecsTo(utc.time())))
262 * Q_INT64_C(10000) + fineTicks;
263#endif
264 extra[timesPos + 4 + position] = static_cast<char>(ticks);
265 extra[timesPos + 5 + position] = static_cast<char>(ticks >> 8);
266 extra[timesPos + 6 + position] = static_cast<char>(ticks >> 16);
267 extra[timesPos + 7 + position] = static_cast<char>(ticks >> 24);
268 extra[timesPos + 8 + position] = static_cast<char>(ticks >> 32);
269 extra[timesPos + 9 + position] = static_cast<char>(ticks >> 40);
270 extra[timesPos + 10 + position] = static_cast<char>(ticks >> 48);
271 extra[timesPos + 11 + position] = static_cast<char>(ticks >> 56);
272}
273
274void QuaZipNewInfo::setFileNTFSmTime(const QDateTime &mTime, int fineTicks)
275{
276 setNTFSTime(extraLocal, mTime, 0, fineTicks);
277 setNTFSTime(extraGlobal, mTime, 0, fineTicks);
278}
279
280void QuaZipNewInfo::setFileNTFSaTime(const QDateTime &aTime, int fineTicks)
281{
282 setNTFSTime(extraLocal, aTime, 8, fineTicks);
283 setNTFSTime(extraGlobal, aTime, 8, fineTicks);
284}
285
286void QuaZipNewInfo::setFileNTFScTime(const QDateTime &cTime, int fineTicks)
287{
288 setNTFSTime(extraLocal, cTime, 16, fineTicks);
289 setNTFSTime(extraGlobal, cTime, 16, fineTicks);
290}
diff --git a/utils/rbutilqt/quazip/quazipnewinfo.h b/utils/rbutilqt/quazip/quazipnewinfo.h
new file mode 100644
index 0000000000..43a1e6fd08
--- /dev/null
+++ b/utils/rbutilqt/quazip/quazipnewinfo.h
@@ -0,0 +1,208 @@
1#ifndef QUA_ZIPNEWINFO_H
2#define QUA_ZIPNEWINFO_H
3
4/*
5Copyright (C) 2005-2014 Sergey A. Tachenov
6
7This file is part of QuaZIP.
8
9QuaZIP is free software: you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation, either version 2.1 of the License, or
12(at your option) any later version.
13
14QuaZIP is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
21
22See COPYING file for the full LGPL text.
23
24Original ZIP package is copyrighted by Gilles Vollant, see
25quazip/(un)zip.h files for details, basically it's zlib license.
26 **/
27
28#include <QtCore/QDateTime>
29#include <QtCore/QFile>
30#include <QtCore/QString>
31
32#include "quazip_global.h"
33
34#include "quazipfileinfo.h"
35
36/// Information about a file to be created.
37/** This structure holds information about a file to be created inside
38 * ZIP archive. At least name should be set to something correct before
39 * passing this structure to
40 * QuaZipFile::open(OpenMode,const QuaZipNewInfo&,int,int,bool).
41 *
42 * Zip64 support of this structure is slightly limited: in the raw mode (when
43 * a pre-compressed file is written into a ZIP file as-is), it is necessary
44 * to specify the uncompressed file size and the appropriate field is 32 bit.
45 * Since the raw mode is used extremely rare, there is no real need to have
46 * a separate QuaZipNewInfo64 structure like QuaZipFileInfo64. It may be added
47 * in the future though, if there is a demand for the raw mode with zip64
48 * archives.
49 **/
50struct QUAZIP_EXPORT QuaZipNewInfo {
51 /// File name.
52 /** This field holds file name inside archive, including path relative
53 * to archive root.
54 **/
55 QString name;
56 /// File timestamp.
57 /** This is the last file modification date and time. Will be stored
58 * in the archive central directory. It is a good practice to set it
59 * to the source file timestamp instead of archive creating time. Use
60 * setFileDateTime() or QuaZipNewInfo(const QString&, const QString&).
61 **/
62 QDateTime dateTime;
63 /// File internal attributes.
64 quint16 internalAttr;
65 /// File external attributes.
66 /**
67 The highest 16 bits contain Unix file permissions and type (dir or
68 file). The constructor QuaZipNewInfo(const QString&, const QString&)
69 takes permissions from the provided file.
70 */
71 quint32 externalAttr;
72 /// File comment.
73 /** Will be encoded in UTF-8 encoding.
74 **/
75 QString comment;
76 /// File local extra field.
77 QByteArray extraLocal;
78 /// File global extra field.
79 QByteArray extraGlobal;
80 /// Uncompressed file size.
81 /** This is only needed if you are using raw file zipping mode, i. e.
82 * adding precompressed file in the zip archive.
83 **/
84 ulong uncompressedSize;
85 /// Constructs QuaZipNewInfo instance.
86 /** Initializes name with \a name, dateTime with current date and
87 * time. Attributes are initialized with zeros, comment and extra
88 * field with null values.
89 **/
90 QuaZipNewInfo(const QString& name);
91 /// Constructs QuaZipNewInfo instance.
92 /** Initializes name with \a name. Timestamp and permissions are taken
93 * from the specified file. If the \a file does not exists or its timestamp
94 * is inaccessible (e. g. you do not have read permission for the
95 * directory file in), uses current time and zero permissions. Other attributes are
96 * initialized with zeros, comment and extra field with null values.
97 *
98 * \sa setFileDateTime()
99 **/
100 QuaZipNewInfo(const QString& name, const QString& file);
101 /// Initializes the new instance from existing file info.
102 /** Mainly used when copying files between archives.
103 *
104 * Both extra fields are initialized to existing.extra.
105 * @brief QuaZipNewInfo
106 * @param existing
107 */
108 QuaZipNewInfo(const QuaZipFileInfo &existing);
109 /// Initializes the new instance from existing file info.
110 /** Mainly used when copying files between archives.
111 *
112 * Both extra fields are initialized to existing.extra.
113 * @brief QuaZipNewInfo
114 * @param existing
115 */
116 QuaZipNewInfo(const QuaZipFileInfo64 &existing);
117 /// Sets the file timestamp from the existing file.
118 /** Use this function to set the file timestamp from the existing
119 * file. Use it like this:
120 * \code
121 * QuaZipFile zipFile(&zip);
122 * QFile file("file-to-add");
123 * file.open(QIODevice::ReadOnly);
124 * QuaZipNewInfo info("file-name-in-archive");
125 * info.setFileDateTime("file-to-add"); // take the timestamp from file
126 * zipFile.open(QIODevice::WriteOnly, info);
127 * \endcode
128 *
129 * This function does not change dateTime if some error occured (e. g.
130 * file is inaccessible).
131 **/
132 void setFileDateTime(const QString& file);
133 /// Sets the file permissions from the existing file.
134 /**
135 Takes permissions from the file and sets the high 16 bits of
136 external attributes. Uses QFileInfo to get permissions on all
137 platforms.
138 */
139 void setFilePermissions(const QString &file);
140 /// Sets the file permissions.
141 /**
142 Modifies the highest 16 bits of external attributes. The type part
143 is set to dir if the name ends with a slash, and to regular file
144 otherwise.
145 */
146 void setPermissions(QFile::Permissions permissions);
147 /// Sets the NTFS times from an existing file.
148 /**
149 * If the file doesn't exist, a warning is printed to the stderr and nothing
150 * is done. Otherwise, all three times, as reported by
151 * QFileInfo::lastModified(), QFileInfo::lastRead() and
152 * QFileInfo::birthTime() (>=Qt5.10) or QFileInfo::created(), are written to
153 * the NTFS extra field record.
154 *
155 * The NTFS record is written to
156 * both the local and the global extra fields, updating the existing record
157 * if there is one, or creating a new one and appending it to the end
158 * of each extra field.
159 *
160 * The microseconds will be zero, as they aren't reported by QFileInfo.
161 * @param fileName
162 */
163 void setFileNTFSTimes(const QString &fileName);
164 /// Sets the NTFS modification time.
165 /**
166 * The time is written into the NTFS record in
167 * both the local and the global extra fields, updating the existing record
168 * if there is one, or creating a new one and appending it to the end
169 * of each extra field. When updating an existing record, all other fields
170 * are left intact.
171 * @param mTime The new modification time.
172 * @param fineTicks The fractional part of milliseconds, in 100-nanosecond
173 * ticks (i. e. 9999 ticks = 999.9 microsecond). Values greater than
174 * 9999 will add milliseconds or even seconds, but this can be
175 * confusing and therefore is discouraged.
176 */
177 void setFileNTFSmTime(const QDateTime &mTime, int fineTicks = 0);
178 /// Sets the NTFS access time.
179 /**
180 * The time is written into the NTFS record in
181 * both the local and the global extra fields, updating the existing record
182 * if there is one, or creating a new one and appending it to the end
183 * of each extra field. When updating an existing record, all other fields
184 * are left intact.
185 * @param aTime The new access time.
186 * @param fineTicks The fractional part of milliseconds, in 100-nanosecond
187 * ticks (i. e. 9999 ticks = 999.9 microsecond). Values greater than
188 * 9999 will add milliseconds or even seconds, but this can be
189 * confusing and therefore is discouraged.
190 */
191 void setFileNTFSaTime(const QDateTime &aTime, int fineTicks = 0);
192 /// Sets the NTFS creation time.
193 /**
194 * The time is written into the NTFS record in
195 * both the local and the global extra fields, updating the existing record
196 * if there is one, or creating a new one and appending it to the end
197 * of each extra field. When updating an existing record, all other fields
198 * are left intact.
199 * @param cTime The new creation time.
200 * @param fineTicks The fractional part of milliseconds, in 100-nanosecond
201 * ticks (i. e. 9999 ticks = 999.9 microsecond). Values greater than
202 * 9999 will add milliseconds or even seconds, but this can be
203 * confusing and therefore is discouraged.
204 */
205 void setFileNTFScTime(const QDateTime &cTime, int fineTicks = 0);
206};
207
208#endif
diff --git a/utils/rbutilqt/quazip/unzip.c b/utils/rbutilqt/quazip/unzip.c
new file mode 100644
index 0000000000..6aaeba6930
--- /dev/null
+++ b/utils/rbutilqt/quazip/unzip.c
@@ -0,0 +1,2163 @@
1/* unzip.c -- IO for uncompress .zip files using zlib
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
4
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
6
7 Modifications of Unzip for Zip64
8 Copyright (C) 2007-2008 Even Rouault
9
10 Modifications for Zip64 support on both zip and unzip
11 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
12
13 Modifications for QIODevice support and other QuaZIP fixes
14 Copyright (C) 2005-2014 Sergey A. Tachenov
15
16 For more info read MiniZip_info.txt
17
18 Modifications for static code analysis report
19 Copyright (C) 2016 Intel Deutschland GmbH
20
21 ------------------------------------------------------------------------------------
22 Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
23 compatibility with older software. The following is from the original crypt.c.
24 Code woven in by Terry Thorsen 1/2003.
25
26 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
27
28 See the accompanying file LICENSE, version 2000-Apr-09 or later
29 (the contents of which are also included in zip.h) for terms of use.
30 If, for some reason, all these files are missing, the Info-ZIP license
31 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
32
33 crypt.c (full version) by Info-ZIP. Last revised: [see minizip_crypt.h]
34
35 The encryption/decryption parts of this source code (as opposed to the
36 non-echoing password parts) were originally written in Europe. The
37 whole source package can be freely distributed, including from the USA.
38 (Prior to January 2000, re-export from the US was a violation of US law.)
39
40 This encryption code is a direct transcription of the algorithm from
41 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
42 file (appnote.txt) is distributed with the PKZIP program (even in the
43 version without encryption capabilities).
44
45 ------------------------------------------------------------------------------------
46
47 Changes in unzip.c
48
49 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
50 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
51 2007-2008 - Even Rouault - Remove old C style function prototypes
52 2007-2008 - Even Rouault - Add unzip support for ZIP64
53
54 Copyright (C) 2007-2008 Even Rouault
55
56
57 Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
58 Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
59 should only read the compressed/uncompressed size from the Zip64 format if
60 the size from normal header was 0xFFFFFFFF
61 Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
62 Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
63 Patch created by Daniel Borca
64
65 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
66
67 Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
68
69*/
70
71
72#include <stdio.h>
73#include <stdlib.h>
74#include <string.h>
75
76#include <zlib.h>
77#if (ZLIB_VERNUM < 0x1270)
78typedef uLongf z_crc_t;
79#endif
80#include "unzip.h"
81
82#ifdef STDC
83# include <stddef.h>
84# include <string.h>
85# include <stdlib.h>
86#endif
87#ifdef NO_ERRNO_H
88 extern int errno;
89#else
90# include <errno.h>
91#endif
92
93
94#ifndef local
95# define local static
96#endif
97/* compile with -Dlocal if your debugger can't find static symbols */
98
99
100#ifndef CASESENSITIVITYDEFAULT_NO
101# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
102# define CASESENSITIVITYDEFAULT_NO
103# endif
104#endif
105
106
107#ifndef UNZ_BUFSIZE
108#define UNZ_BUFSIZE (16384)
109#endif
110
111#ifndef UNZ_MAXFILENAMEINZIP
112#define UNZ_MAXFILENAMEINZIP (256)
113#endif
114
115#ifndef ALLOC
116# define ALLOC(size) (malloc(size))
117#endif
118#ifndef TRYFREE
119# define TRYFREE(p) {if (p) free(p);}
120#endif
121
122#define SIZECENTRALDIRITEM (0x2e)
123#define SIZEZIPLOCALHEADER (0x1e)
124
125
126const char unz_copyright[] =
127 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
128
129/* unz_file_info_interntal contain internal info about a file in zipfile*/
130typedef struct unz_file_info64_internal_s
131{
132 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
133} unz_file_info64_internal;
134
135
136/* file_in_zip_read_info_s contain internal information about a file in zipfile,
137 when reading and decompress it */
138typedef struct
139{
140 char *read_buffer; /* internal buffer for compressed data */
141 z_stream stream; /* zLib stream structure for inflate */
142
143#ifdef HAVE_BZIP2
144 bz_stream bstream; /* bzLib stream structure for bziped */
145#endif
146
147 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
148 uLong stream_initialised; /* flag set if stream structure is initialised*/
149
150 ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
151 uInt size_local_extrafield;/* size of the local extra field */
152 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
153 ZPOS64_T total_out_64;
154
155 uLong crc32; /* crc32 of all data uncompressed */
156 uLong crc32_wait; /* crc32 we must obtain after decompress all */
157 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
158 ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
159 zlib_filefunc64_32_def z_filefunc;
160 voidpf filestream; /* io structore of the zipfile */
161 uLong compression_method; /* compression method (0==store) */
162 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
163 int raw;
164} file_in_zip64_read_info_s;
165
166
167/* unz64_s contain internal information about the zipfile
168*/
169typedef struct
170{
171 zlib_filefunc64_32_def z_filefunc;
172 int is64bitOpenFunction;
173 voidpf filestream; /* io structore of the zipfile */
174 unz_global_info64 gi; /* public global information */
175 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
176 ZPOS64_T num_file; /* number of the current file in the zipfile*/
177 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
178 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
179 ZPOS64_T central_pos; /* position of the beginning of the central dir*/
180
181 ZPOS64_T size_central_dir; /* size of the central directory */
182 ZPOS64_T offset_central_dir; /* offset of start of central directory with
183 respect to the starting disk number */
184
185 unz_file_info64 cur_file_info; /* public info about the current file in zip*/
186 unz_file_info64_internal cur_file_info_internal; /* private info about it*/
187 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
188 file if we are decompressing it */
189 int encrypted;
190
191 int isZip64;
192 unsigned flags;
193
194# ifndef NOUNCRYPT
195 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
196 const z_crc_t FAR * pcrc_32_tab;
197# endif
198} unz64_s;
199
200
201#ifndef NOUNCRYPT
202#include "minizip_crypt.h"
203#endif
204
205/* ===========================================================================
206 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
207 for end of file.
208 IN assertion: the stream s has been sucessfully opened for reading.
209*/
210
211
212local int unz64local_getByte OF((
213 const zlib_filefunc64_32_def* pzlib_filefunc_def,
214 voidpf filestream,
215 int *pi));
216
217local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
218{
219 unsigned char c;
220 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
221 if (err==1)
222 {
223 *pi = (int)c;
224 return UNZ_OK;
225 }
226 else
227 {
228 if (ZERROR64(*pzlib_filefunc_def,filestream))
229 return UNZ_ERRNO;
230 else
231 return UNZ_EOF;
232 }
233}
234
235
236/* ===========================================================================
237 Reads a long in LSB order from the given gz_stream. Sets
238*/
239local int unz64local_getShort OF((
240 const zlib_filefunc64_32_def* pzlib_filefunc_def,
241 voidpf filestream,
242 uLong *pX));
243
244local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
245 voidpf filestream,
246 uLong *pX)
247{
248 uLong x ;
249 int i = 0;
250 int err;
251
252 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
253 x = (uLong)i;
254
255 if (err==UNZ_OK)
256 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
257 x |= ((uLong)i)<<8;
258
259 if (err==UNZ_OK)
260 *pX = x;
261 else
262 *pX = 0;
263 return err;
264}
265
266local int unz64local_getLong OF((
267 const zlib_filefunc64_32_def* pzlib_filefunc_def,
268 voidpf filestream,
269 uLong *pX));
270
271local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
272 voidpf filestream,
273 uLong *pX)
274{
275 uLong x ;
276 int i = 0;
277 int err;
278
279 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
280 x = (uLong)i;
281
282 if (err==UNZ_OK)
283 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
284 x |= ((uLong)i)<<8;
285
286 if (err==UNZ_OK)
287 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
288 x |= ((uLong)i)<<16;
289
290 if (err==UNZ_OK)
291 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
292 x += ((uLong)i)<<24;
293
294 if (err==UNZ_OK)
295 *pX = x;
296 else
297 *pX = 0;
298 return err;
299}
300
301local int unz64local_getLong64 OF((
302 const zlib_filefunc64_32_def* pzlib_filefunc_def,
303 voidpf filestream,
304 ZPOS64_T *pX));
305
306
307local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
308 voidpf filestream,
309 ZPOS64_T *pX)
310{
311 ZPOS64_T x ;
312 int i = 0;
313 int err;
314
315 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
316 x = (ZPOS64_T)i;
317
318 if (err==UNZ_OK)
319 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
320 x |= ((ZPOS64_T)i)<<8;
321
322 if (err==UNZ_OK)
323 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
324 x |= ((ZPOS64_T)i)<<16;
325
326 if (err==UNZ_OK)
327 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
328 x |= ((ZPOS64_T)i)<<24;
329
330 if (err==UNZ_OK)
331 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
332 x |= ((ZPOS64_T)i)<<32;
333
334 if (err==UNZ_OK)
335 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
336 x |= ((ZPOS64_T)i)<<40;
337
338 if (err==UNZ_OK)
339 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
340 x |= ((ZPOS64_T)i)<<48;
341
342 if (err==UNZ_OK)
343 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
344 x |= ((ZPOS64_T)i)<<56;
345
346 if (err==UNZ_OK)
347 *pX = x;
348 else
349 *pX = 0;
350 return err;
351}
352
353/* My own strcmpi / strcasecmp */
354local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
355{
356 for (;;)
357 {
358 char c1=*(fileName1++);
359 char c2=*(fileName2++);
360 if ((c1>='a') && (c1<='z'))
361 c1 -= 0x20;
362 if ((c2>='a') && (c2<='z'))
363 c2 -= 0x20;
364 if (c1=='\0')
365 return ((c2=='\0') ? 0 : -1);
366 if (c2=='\0')
367 return 1;
368 if (c1<c2)
369 return -1;
370 if (c1>c2)
371 return 1;
372 }
373}
374
375
376#ifdef CASESENSITIVITYDEFAULT_NO
377#define CASESENSITIVITYDEFAULTVALUE 2
378#else
379#define CASESENSITIVITYDEFAULTVALUE 1
380#endif
381
382#ifndef STRCMPCASENOSENTIVEFUNCTION
383#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
384#endif
385
386/*
387 Compare two filename (fileName1,fileName2).
388 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
389 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
390 or strcasecmp)
391 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
392 (like 1 on Unix, 2 on Windows)
393
394*/
395extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
396 const char* fileName2,
397 int iCaseSensitivity)
398
399{
400 if (iCaseSensitivity==0)
401 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
402
403 if (iCaseSensitivity==1)
404 return strcmp(fileName1,fileName2);
405
406 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
407}
408
409#ifndef BUFREADCOMMENT
410#define BUFREADCOMMENT (0x400)
411#endif
412
413/*
414 Locate the Central directory of a zipfile (at the end, just before
415 the global comment)
416*/
417local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
418local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
419{
420 unsigned char* buf;
421 ZPOS64_T uSizeFile;
422 ZPOS64_T uBackRead;
423 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
424 ZPOS64_T uPosFound=0;
425
426 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
427 return 0;
428
429
430 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
431
432 if (uMaxBack>uSizeFile)
433 uMaxBack = uSizeFile;
434
435 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
436 if (buf==NULL)
437 return 0;
438
439 uBackRead = 4;
440 while (uBackRead<uMaxBack)
441 {
442 uLong uReadSize;
443 ZPOS64_T uReadPos ;
444 int i;
445 if (uBackRead+BUFREADCOMMENT>uMaxBack)
446 uBackRead = uMaxBack;
447 else
448 uBackRead+=BUFREADCOMMENT;
449 uReadPos = uSizeFile-uBackRead ;
450
451 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
452 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
453 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
454 break;
455
456 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
457 break;
458
459 for (i=(int)uReadSize-3; (i--)>0;)
460 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
461 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
462 {
463 uPosFound = uReadPos+i;
464 break;
465 }
466
467 if (uPosFound!=0)
468 break;
469 }
470 TRYFREE(buf);
471 return uPosFound;
472}
473
474
475/*
476 Locate the Central directory 64 of a zipfile (at the end, just before
477 the global comment)
478*/
479local ZPOS64_T unz64local_SearchCentralDir64 OF((
480 const zlib_filefunc64_32_def* pzlib_filefunc_def,
481 voidpf filestream));
482
483local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
484 voidpf filestream)
485{
486 unsigned char* buf;
487 ZPOS64_T uSizeFile;
488 ZPOS64_T uBackRead;
489 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
490 ZPOS64_T uPosFound=0;
491 uLong uL;
492 ZPOS64_T relativeOffset;
493
494 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
495 return 0;
496
497
498 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
499
500 if (uMaxBack>uSizeFile)
501 uMaxBack = uSizeFile;
502
503 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
504 if (buf==NULL)
505 return 0;
506
507 uBackRead = 4;
508 while (uBackRead<uMaxBack)
509 {
510 uLong uReadSize;
511 ZPOS64_T uReadPos;
512 int i;
513 if (uBackRead+BUFREADCOMMENT>uMaxBack)
514 uBackRead = uMaxBack;
515 else
516 uBackRead+=BUFREADCOMMENT;
517 uReadPos = uSizeFile-uBackRead ;
518
519 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
520 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
521 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
522 break;
523
524 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
525 break;
526
527 for (i=(int)uReadSize-3; (i--)>0;)
528 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
529 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
530 {
531 uPosFound = uReadPos+i;
532 break;
533 }
534
535 if (uPosFound!=0)
536 break;
537 }
538 TRYFREE(buf);
539 if (uPosFound == 0)
540 return 0;
541
542 /* Zip64 end of central directory locator */
543 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
544 return 0;
545
546 /* the signature, already checked */
547 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
548 return 0;
549
550 /* number of the disk with the start of the zip64 end of central directory */
551 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
552 return 0;
553 if (uL != 0)
554 return 0;
555
556 /* relative offset of the zip64 end of central directory record */
557 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
558 return 0;
559
560 /* total number of disks */
561 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
562 return 0;
563 if (uL != 1)
564 return 0;
565
566 /* Goto end of central directory record */
567 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
568 return 0;
569
570 /* the signature */
571 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
572 return 0;
573
574 if (uL != 0x06064b50)
575 return 0;
576
577 return relativeOffset;
578}
579
580/*
581 Open a Zip file. path contain the full pathname (by example,
582 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
583 "zlib/zlib114.zip".
584 If the zipfile cannot be opened (file doesn't exist or in not valid), the
585 return value is NULL.
586 Else, the return value is a unzFile Handle, usable with other function
587 of this unzip package.
588*/
589extern unzFile unzOpenInternal (voidpf file,
590 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
591 int is64bitOpenFunction, unsigned flags)
592{
593 unz64_s us;
594 unz64_s *s;
595 ZPOS64_T central_pos;
596 uLong uL;
597
598 uLong number_disk; /* number of the current dist, used for
599 spaning ZIP, unsupported, always 0*/
600 uLong number_disk_with_CD; /* number the the disk with central dir, used
601 for spaning ZIP, unsupported, always 0*/
602 ZPOS64_T number_entry_CD; /* total number of entries in
603 the central dir
604 (same than number_entry on nospan) */
605
606 int err=UNZ_OK;
607
608 if (unz_copyright[0]!=' ')
609 return NULL;
610
611 us.flags = flags;
612 us.z_filefunc.zseek32_file = NULL;
613 us.z_filefunc.ztell32_file = NULL;
614 if (pzlib_filefunc64_32_def==NULL)
615 fill_qiodevice64_filefunc(&us.z_filefunc.zfile_func64);
616 else
617 us.z_filefunc = *pzlib_filefunc64_32_def;
618 us.is64bitOpenFunction = is64bitOpenFunction;
619
620
621
622 us.filestream = ZOPEN64(us.z_filefunc,
623 file,
624 ZLIB_FILEFUNC_MODE_READ |
625 ZLIB_FILEFUNC_MODE_EXISTING);
626 if (us.filestream==NULL)
627 return NULL;
628
629 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
630 if (central_pos)
631 {
632 uLong uS;
633 ZPOS64_T uL64;
634
635 us.isZip64 = 1;
636
637 if (ZSEEK64(us.z_filefunc, us.filestream,
638 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
639 err=UNZ_ERRNO;
640
641 /* the signature, already checked */
642 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
643 err=UNZ_ERRNO;
644
645 /* size of zip64 end of central directory record */
646 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
647 err=UNZ_ERRNO;
648
649 /* version made by */
650 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
651 err=UNZ_ERRNO;
652
653 /* version needed to extract */
654 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
655 err=UNZ_ERRNO;
656
657 /* number of this disk */
658 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
659 err=UNZ_ERRNO;
660
661 /* number of the disk with the start of the central directory */
662 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
663 err=UNZ_ERRNO;
664
665 /* total number of entries in the central directory on this disk */
666 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
667 err=UNZ_ERRNO;
668
669 /* total number of entries in the central directory */
670 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
671 err=UNZ_ERRNO;
672
673 if ((number_entry_CD!=us.gi.number_entry) ||
674 (number_disk_with_CD!=0) ||
675 (number_disk!=0))
676 err=UNZ_BADZIPFILE;
677
678 /* size of the central directory */
679 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
680 err=UNZ_ERRNO;
681
682 /* offset of start of central directory with respect to the
683 starting disk number */
684 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
685 err=UNZ_ERRNO;
686
687 us.gi.size_comment = 0;
688 }
689 else
690 {
691 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
692 if (central_pos==0)
693 err=UNZ_ERRNO;
694
695 us.isZip64 = 0;
696
697 if (ZSEEK64(us.z_filefunc, us.filestream,
698 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
699 err=UNZ_ERRNO;
700
701 /* the signature, already checked */
702 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
703 err=UNZ_ERRNO;
704
705 /* number of this disk */
706 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
707 err=UNZ_ERRNO;
708
709 /* number of the disk with the start of the central directory */
710 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
711 err=UNZ_ERRNO;
712
713 /* total number of entries in the central dir on this disk */
714 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
715 err=UNZ_ERRNO;
716 us.gi.number_entry = uL;
717
718 /* total number of entries in the central dir */
719 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
720 err=UNZ_ERRNO;
721 number_entry_CD = uL;
722
723 if ((number_entry_CD!=us.gi.number_entry) ||
724 (number_disk_with_CD!=0) ||
725 (number_disk!=0))
726 err=UNZ_BADZIPFILE;
727
728 /* size of the central directory */
729 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
730 err=UNZ_ERRNO;
731 us.size_central_dir = uL;
732
733 /* offset of start of central directory with respect to the
734 starting disk number */
735 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
736 err=UNZ_ERRNO;
737 us.offset_central_dir = uL;
738
739 /* zipfile comment length */
740 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
741 err=UNZ_ERRNO;
742 }
743
744 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
745 (err==UNZ_OK))
746 err=UNZ_BADZIPFILE;
747
748 if (err!=UNZ_OK)
749 {
750 if ((us.flags & UNZ_AUTO_CLOSE) != 0)
751 ZCLOSE64(us.z_filefunc, us.filestream);
752 else
753 ZFAKECLOSE64(us.z_filefunc, us.filestream);
754 return NULL;
755 }
756
757 us.byte_before_the_zipfile = central_pos -
758 (us.offset_central_dir+us.size_central_dir);
759 us.central_pos = central_pos;
760 us.pfile_in_zip_read = NULL;
761 us.encrypted = 0;
762
763
764 s=(unz64_s*)ALLOC(sizeof(unz64_s));
765 if( s != NULL)
766 {
767 *s=us;
768 unzGoToFirstFile((unzFile)s);
769 }
770 return (unzFile)s;
771}
772
773
774extern unzFile ZEXPORT unzOpen2 (voidpf file,
775 zlib_filefunc_def* pzlib_filefunc32_def)
776{
777 if (pzlib_filefunc32_def != NULL)
778 {
779 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
780 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
781 return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 0, UNZ_DEFAULT_FLAGS);
782 }
783 else
784 return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS);
785}
786
787extern unzFile ZEXPORT unzOpen2_64 (voidpf file,
788 zlib_filefunc64_def* pzlib_filefunc_def)
789{
790 if (pzlib_filefunc_def != NULL)
791 {
792 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
793 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
794 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
795 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
796 return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 1, UNZ_DEFAULT_FLAGS);
797 }
798 else
799 return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS);
800}
801
802extern unzFile ZEXPORT unzOpen (voidpf file)
803{
804 return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS);
805}
806
807extern unzFile ZEXPORT unzOpen64 (voidpf file)
808{
809 return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS);
810}
811
812/*
813 Close a ZipFile opened with unzipOpen.
814 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
815 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
816 return UNZ_OK if there is no problem. */
817extern int ZEXPORT unzClose (unzFile file)
818{
819 unz64_s* s;
820 if (file==NULL)
821 return UNZ_PARAMERROR;
822 s=(unz64_s*)file;
823
824 if (s->pfile_in_zip_read!=NULL)
825 unzCloseCurrentFile(file);
826
827 if ((s->flags & UNZ_AUTO_CLOSE) != 0)
828 ZCLOSE64(s->z_filefunc, s->filestream);
829 else
830 ZFAKECLOSE64(s->z_filefunc, s->filestream);
831 TRYFREE(s);
832 return UNZ_OK;
833}
834
835
836/*
837 Write info about the ZipFile in the *pglobal_info structure.
838 No preparation of the structure is needed
839 return UNZ_OK if there is no problem. */
840extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
841{
842 unz64_s* s;
843 if (file==NULL)
844 return UNZ_PARAMERROR;
845 s=(unz64_s*)file;
846 *pglobal_info=s->gi;
847 return UNZ_OK;
848}
849
850extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
851{
852 unz64_s* s;
853 if (file==NULL)
854 return UNZ_PARAMERROR;
855 s=(unz64_s*)file;
856 /* to do : check if number_entry is not truncated */
857 pglobal_info32->number_entry = (uLong)s->gi.number_entry;
858 pglobal_info32->size_comment = s->gi.size_comment;
859 return UNZ_OK;
860}
861
862extern int ZEXPORT unzGetFileFlags (unzFile file, unsigned* pflags)
863{
864 unz64_s* s;
865 if (file==NULL)
866 return UNZ_PARAMERROR;
867 s=(unz64_s*)file;
868 *pflags = s->flags;
869 return UNZ_OK;
870}
871
872/*
873 Translate date/time from Dos format to tm_unz (readable more easilty)
874*/
875local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
876{
877 ZPOS64_T uDate;
878 uDate = (ZPOS64_T)(ulDosDate>>16);
879 ptm->tm_mday = (uInt)(uDate&0x1f) ;
880 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
881 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
882
883 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
884 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
885 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
886}
887
888/*
889 Get Info about the current file in the zipfile, with internal only info
890*/
891local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
892 unz_file_info64 *pfile_info,
893 unz_file_info64_internal
894 *pfile_info_internal,
895 char *szFileName,
896 uLong fileNameBufferSize,
897 void *extraField,
898 uLong extraFieldBufferSize,
899 char *szComment,
900 uLong commentBufferSize));
901
902local int unz64local_GetCurrentFileInfoInternal (unzFile file,
903 unz_file_info64 *pfile_info,
904 unz_file_info64_internal
905 *pfile_info_internal,
906 char *szFileName,
907 uLong fileNameBufferSize,
908 void *extraField,
909 uLong extraFieldBufferSize,
910 char *szComment,
911 uLong commentBufferSize)
912{
913 unz64_s* s;
914 unz_file_info64 file_info;
915 unz_file_info64_internal file_info_internal;
916 int err=UNZ_OK;
917 uLong uMagic;
918 ZPOS64_T llSeek=0;
919 uLong uL;
920
921 if (file==NULL)
922 return UNZ_PARAMERROR;
923 s=(unz64_s*)file;
924 if (ZSEEK64(s->z_filefunc, s->filestream,
925 s->pos_in_central_dir+s->byte_before_the_zipfile,
926 ZLIB_FILEFUNC_SEEK_SET)!=0)
927 err=UNZ_ERRNO;
928
929
930 /* we check the magic */
931 if (err==UNZ_OK)
932 {
933 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
934 err=UNZ_ERRNO;
935 else if (uMagic!=0x02014b50)
936 err=UNZ_BADZIPFILE;
937 }
938
939 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
940 err=UNZ_ERRNO;
941
942 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
943 err=UNZ_ERRNO;
944
945 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
946 err=UNZ_ERRNO;
947
948 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
949 err=UNZ_ERRNO;
950
951 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
952 err=UNZ_ERRNO;
953
954 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
955
956 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
957 err=UNZ_ERRNO;
958
959 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
960 err=UNZ_ERRNO;
961 file_info.compressed_size = uL;
962
963 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
964 err=UNZ_ERRNO;
965 file_info.uncompressed_size = uL;
966
967 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
968 err=UNZ_ERRNO;
969
970 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
971 err=UNZ_ERRNO;
972
973 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
974 err=UNZ_ERRNO;
975
976 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
977 err=UNZ_ERRNO;
978
979 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
980 err=UNZ_ERRNO;
981
982 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
983 err=UNZ_ERRNO;
984
985 /* relative offset of local header */
986 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
987 err=UNZ_ERRNO;
988 file_info_internal.offset_curfile = uL;
989
990 llSeek+=file_info.size_filename;
991 if ((err==UNZ_OK) && (szFileName!=NULL))
992 {
993 uLong uSizeRead ;
994 if (file_info.size_filename<fileNameBufferSize)
995 {
996 *(szFileName+file_info.size_filename)='\0';
997 uSizeRead = file_info.size_filename;
998 }
999 else
1000 uSizeRead = fileNameBufferSize;
1001
1002 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
1003 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
1004 err=UNZ_ERRNO;
1005 llSeek -= uSizeRead;
1006 }
1007
1008 /* Read extrafield */
1009 if ((err==UNZ_OK) && (extraField!=NULL))
1010 {
1011 ZPOS64_T uSizeRead ;
1012 if (file_info.size_file_extra<extraFieldBufferSize)
1013 uSizeRead = file_info.size_file_extra;
1014 else
1015 uSizeRead = extraFieldBufferSize;
1016
1017 if (llSeek!=0)
1018 {
1019 if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1020 llSeek=0;
1021 else
1022 err=UNZ_ERRNO;
1023 }
1024
1025 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
1026 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
1027 err=UNZ_ERRNO;
1028
1029 llSeek += file_info.size_file_extra - (uLong)uSizeRead;
1030 }
1031 else
1032 llSeek += file_info.size_file_extra;
1033
1034
1035 if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
1036 {
1037 uLong acc = 0;
1038
1039 /* since lSeek now points to after the extra field we need to move back */
1040 llSeek -= file_info.size_file_extra;
1041
1042 if (llSeek!=0)
1043 {
1044 if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1045 llSeek=0;
1046 else
1047 err=UNZ_ERRNO;
1048 }
1049
1050 while(acc < file_info.size_file_extra)
1051 {
1052 uLong headerId;
1053 uLong dataSize;
1054
1055 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
1056 err=UNZ_ERRNO;
1057
1058 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
1059 err=UNZ_ERRNO;
1060
1061 /* ZIP64 extra fields */
1062 if (headerId == 0x0001)
1063 {
1064 uLong uL;
1065
1066 if(file_info.uncompressed_size == (ZPOS64_T)0xFFFFFFFFu)
1067 {
1068 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
1069 err=UNZ_ERRNO;
1070 }
1071
1072 if(file_info.compressed_size == (ZPOS64_T)0xFFFFFFFFu)
1073 {
1074 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
1075 err=UNZ_ERRNO;
1076 }
1077
1078 if(file_info_internal.offset_curfile == (ZPOS64_T)0xFFFFFFFFu)
1079 {
1080 /* Relative Header offset */
1081 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
1082 err=UNZ_ERRNO;
1083 }
1084
1085 if(file_info.disk_num_start == 0xFFFFFFFFu)
1086 {
1087 /* Disk Start Number */
1088 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1089 err=UNZ_ERRNO;
1090 }
1091
1092 }
1093 else
1094 {
1095 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
1096 err=UNZ_ERRNO;
1097 }
1098
1099 acc += 2 + 2 + dataSize;
1100 }
1101 }
1102
1103 if ((err==UNZ_OK) && (szComment!=NULL))
1104 {
1105 uLong uSizeRead ;
1106 if (file_info.size_file_comment<commentBufferSize)
1107 {
1108 *(szComment+file_info.size_file_comment)='\0';
1109 uSizeRead = file_info.size_file_comment;
1110 }
1111 else
1112 uSizeRead = commentBufferSize;
1113
1114 if (llSeek!=0)
1115 {
1116 if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1117 llSeek=0;
1118 else
1119 err=UNZ_ERRNO;
1120 }
1121
1122 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
1123 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
1124 err=UNZ_ERRNO;
1125 llSeek+=file_info.size_file_comment - uSizeRead;
1126 }
1127 else
1128 llSeek+=file_info.size_file_comment;
1129
1130
1131 if ((err==UNZ_OK) && (pfile_info!=NULL))
1132 *pfile_info=file_info;
1133
1134 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1135 *pfile_info_internal=file_info_internal;
1136
1137 return err;
1138}
1139
1140
1141
1142/*
1143 Write info about the ZipFile in the *pglobal_info structure.
1144 No preparation of the structure is needed
1145 return UNZ_OK if there is no problem.
1146*/
1147extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
1148 unz_file_info64 * pfile_info,
1149 char * szFileName, uLong fileNameBufferSize,
1150 void *extraField, uLong extraFieldBufferSize,
1151 char* szComment, uLong commentBufferSize)
1152{
1153 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1154 szFileName,fileNameBufferSize,
1155 extraField,extraFieldBufferSize,
1156 szComment,commentBufferSize);
1157}
1158
1159extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
1160 unz_file_info * pfile_info,
1161 char * szFileName, uLong fileNameBufferSize,
1162 void *extraField, uLong extraFieldBufferSize,
1163 char* szComment, uLong commentBufferSize)
1164{
1165 int err;
1166 unz_file_info64 file_info64;
1167 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1168 szFileName,fileNameBufferSize,
1169 extraField,extraFieldBufferSize,
1170 szComment,commentBufferSize);
1171 if (err==UNZ_OK && pfile_info != NULL)
1172 {
1173 pfile_info->version = file_info64.version;
1174 pfile_info->version_needed = file_info64.version_needed;
1175 pfile_info->flag = file_info64.flag;
1176 pfile_info->compression_method = file_info64.compression_method;
1177 pfile_info->dosDate = file_info64.dosDate;
1178 pfile_info->crc = file_info64.crc;
1179
1180 pfile_info->size_filename = file_info64.size_filename;
1181 pfile_info->size_file_extra = file_info64.size_file_extra;
1182 pfile_info->size_file_comment = file_info64.size_file_comment;
1183
1184 pfile_info->disk_num_start = file_info64.disk_num_start;
1185 pfile_info->internal_fa = file_info64.internal_fa;
1186 pfile_info->external_fa = file_info64.external_fa;
1187
1188 pfile_info->tmu_date = file_info64.tmu_date,
1189
1190
1191 pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1192 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1193
1194 }
1195 return err;
1196}
1197/*
1198 Set the current file of the zipfile to the first file.
1199 return UNZ_OK if there is no problem
1200*/
1201extern int ZEXPORT unzGoToFirstFile (unzFile file)
1202{
1203 int err=UNZ_OK;
1204 unz64_s* s;
1205 if (file==NULL)
1206 return UNZ_PARAMERROR;
1207 s=(unz64_s*)file;
1208 s->pos_in_central_dir=s->offset_central_dir;
1209 s->num_file=0;
1210 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1211 &s->cur_file_info_internal,
1212 NULL,0,NULL,0,NULL,0);
1213 s->current_file_ok = (err == UNZ_OK);
1214 if (s->cur_file_info.flag & UNZ_ENCODING_UTF8)
1215 unzSetFlags(file, UNZ_ENCODING_UTF8);
1216 return err;
1217}
1218
1219/*
1220 Set the current file of the zipfile to the next file.
1221 return UNZ_OK if there is no problem
1222 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1223*/
1224extern int ZEXPORT unzGoToNextFile (unzFile file)
1225{
1226 unz64_s* s;
1227 int err;
1228
1229 if (file==NULL)
1230 return UNZ_PARAMERROR;
1231 s=(unz64_s*)file;
1232 if (!s->current_file_ok)
1233 return UNZ_END_OF_LIST_OF_FILE;
1234 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1235 if (s->num_file+1==s->gi.number_entry)
1236 return UNZ_END_OF_LIST_OF_FILE;
1237
1238 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1239 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1240 s->num_file++;
1241 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1242 &s->cur_file_info_internal,
1243 NULL,0,NULL,0,NULL,0);
1244 s->current_file_ok = (err == UNZ_OK);
1245 return err;
1246}
1247
1248
1249/*
1250 Try locate the file szFileName in the zipfile.
1251 For the iCaseSensitivity signification, see unzipStringFileNameCompare
1252
1253 return value :
1254 UNZ_OK if the file is found. It becomes the current file.
1255 UNZ_END_OF_LIST_OF_FILE if the file is not found
1256*/
1257extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
1258{
1259 unz64_s* s;
1260 int err;
1261
1262 /* We remember the 'current' position in the file so that we can jump
1263 * back there if we fail.
1264 */
1265 unz_file_info64 cur_file_infoSaved;
1266 unz_file_info64_internal cur_file_info_internalSaved;
1267 ZPOS64_T num_fileSaved;
1268 ZPOS64_T pos_in_central_dirSaved;
1269
1270
1271 if (file==NULL)
1272 return UNZ_PARAMERROR;
1273
1274 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1275 return UNZ_PARAMERROR;
1276
1277 s=(unz64_s*)file;
1278 if (!s->current_file_ok)
1279 return UNZ_END_OF_LIST_OF_FILE;
1280
1281 /* Save the current state */
1282 num_fileSaved = s->num_file;
1283 pos_in_central_dirSaved = s->pos_in_central_dir;
1284 cur_file_infoSaved = s->cur_file_info;
1285 cur_file_info_internalSaved = s->cur_file_info_internal;
1286
1287 err = unzGoToFirstFile(file);
1288
1289 while (err == UNZ_OK)
1290 {
1291 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1292 err = unzGetCurrentFileInfo64(file,NULL,
1293 szCurrentFileName,sizeof(szCurrentFileName)-1,
1294 NULL,0,NULL,0);
1295 if (err == UNZ_OK)
1296 {
1297 if (unzStringFileNameCompare(szCurrentFileName,
1298 szFileName,iCaseSensitivity)==0)
1299 return UNZ_OK;
1300 err = unzGoToNextFile(file);
1301 }
1302 }
1303
1304 /* We failed, so restore the state of the 'current file' to where we
1305 * were.
1306 */
1307 s->num_file = num_fileSaved ;
1308 s->pos_in_central_dir = pos_in_central_dirSaved ;
1309 s->cur_file_info = cur_file_infoSaved;
1310 s->cur_file_info_internal = cur_file_info_internalSaved;
1311 return err;
1312}
1313
1314
1315/*
1316///////////////////////////////////////////
1317// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1318// I need random access
1319//
1320// Further optimization could be realized by adding an ability
1321// to cache the directory in memory. The goal being a single
1322// comprehensive file read to put the file I need in a memory.
1323*/
1324
1325/*
1326typedef struct unz_file_pos_s
1327{
1328 ZPOS64_T pos_in_zip_directory; // offset in file
1329 ZPOS64_T num_of_file; // # of file
1330} unz_file_pos;
1331*/
1332
1333extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
1334{
1335 unz64_s* s;
1336
1337 if (file==NULL || file_pos==NULL)
1338 return UNZ_PARAMERROR;
1339 s=(unz64_s*)file;
1340 if (!s->current_file_ok)
1341 return UNZ_END_OF_LIST_OF_FILE;
1342
1343 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1344 file_pos->num_of_file = s->num_file;
1345
1346 return UNZ_OK;
1347}
1348
1349extern int ZEXPORT unzGetFilePos(
1350 unzFile file,
1351 unz_file_pos* file_pos)
1352{
1353 unz64_file_pos file_pos64;
1354 int err = unzGetFilePos64(file,&file_pos64);
1355 if (err==UNZ_OK)
1356 {
1357 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1358 file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1359 }
1360 return err;
1361}
1362
1363extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
1364{
1365 unz64_s* s;
1366 int err;
1367
1368 if (file==NULL || file_pos==NULL)
1369 return UNZ_PARAMERROR;
1370 s=(unz64_s*)file;
1371
1372 /* jump to the right spot */
1373 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1374 s->num_file = file_pos->num_of_file;
1375
1376 /* set the current file */
1377 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1378 &s->cur_file_info_internal,
1379 NULL,0,NULL,0,NULL,0);
1380 /* return results */
1381 s->current_file_ok = (err == UNZ_OK);
1382 return err;
1383}
1384
1385extern int ZEXPORT unzGoToFilePos(
1386 unzFile file,
1387 unz_file_pos* file_pos)
1388{
1389 unz64_file_pos file_pos64;
1390 if (file_pos == NULL)
1391 return UNZ_PARAMERROR;
1392
1393 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1394 file_pos64.num_of_file = file_pos->num_of_file;
1395 return unzGoToFilePos64(file,&file_pos64);
1396}
1397
1398/* Unzip Helper Functions - should be here? */
1399/*///////////////////////////////////////// */
1400
1401/*
1402 Read the local header of the current zipfile
1403 Check the coherency of the local header and info in the end of central
1404 directory about this file
1405 store in *piSizeVar the size of extra info in local header
1406 (filename and size of extra field data)
1407*/
1408local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
1409 ZPOS64_T * poffset_local_extrafield,
1410 uInt * psize_local_extrafield)
1411{
1412 uLong uMagic,uData,uFlags;
1413 uLong size_filename;
1414 uLong size_extra_field;
1415 int err=UNZ_OK;
1416
1417 *piSizeVar = 0;
1418 *poffset_local_extrafield = 0;
1419 *psize_local_extrafield = 0;
1420
1421 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1422 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1423 return UNZ_ERRNO;
1424
1425
1426 if (err==UNZ_OK)
1427 {
1428 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1429 err=UNZ_ERRNO;
1430 else if (uMagic!=0x04034b50)
1431 err=UNZ_BADZIPFILE;
1432 }
1433
1434 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1435 err=UNZ_ERRNO;
1436/*
1437 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1438 err=UNZ_BADZIPFILE;
1439*/
1440 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1441 err=UNZ_ERRNO;
1442
1443 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1444 err=UNZ_ERRNO;
1445 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1446 err=UNZ_BADZIPFILE;
1447
1448 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1449/* #ifdef HAVE_BZIP2 */
1450 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1451/* #endif */
1452 (s->cur_file_info.compression_method!=Z_DEFLATED))
1453 err=UNZ_BADZIPFILE;
1454
1455 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1456 err=UNZ_ERRNO;
1457
1458 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1459 err=UNZ_ERRNO;
1460 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
1461 err=UNZ_BADZIPFILE;
1462
1463 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1464 err=UNZ_ERRNO;
1465 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
1466 err=UNZ_BADZIPFILE;
1467
1468 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1469 err=UNZ_ERRNO;
1470 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
1471 err=UNZ_BADZIPFILE;
1472
1473 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1474 err=UNZ_ERRNO;
1475 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1476 err=UNZ_BADZIPFILE;
1477
1478 *piSizeVar += (uInt)size_filename;
1479
1480 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1481 err=UNZ_ERRNO;
1482 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1483 SIZEZIPLOCALHEADER + size_filename;
1484 *psize_local_extrafield = (uInt)size_extra_field;
1485
1486 *piSizeVar += (uInt)size_extra_field;
1487
1488 return err;
1489}
1490
1491/*
1492 Open for reading data the current file in the zipfile.
1493 If there is no error and the file is opened, the return value is UNZ_OK.
1494*/
1495extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
1496 int* level, int raw, const char* password)
1497{
1498 int err=UNZ_OK;
1499 uInt iSizeVar;
1500 unz64_s* s;
1501 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1502 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
1503 uInt size_local_extrafield; /* size of the local extra field */
1504# ifndef NOUNCRYPT
1505 char source[12];
1506# else
1507 if (password != NULL)
1508 return UNZ_PARAMERROR;
1509# endif
1510
1511 if (file==NULL)
1512 return UNZ_PARAMERROR;
1513 s=(unz64_s*)file;
1514 if (!s->current_file_ok)
1515 return UNZ_PARAMERROR;
1516
1517 if (s->pfile_in_zip_read != NULL)
1518 unzCloseCurrentFile(file);
1519
1520 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1521 return UNZ_BADZIPFILE;
1522
1523 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
1524 if (pfile_in_zip_read_info==NULL)
1525 return UNZ_INTERNALERROR;
1526
1527 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1528 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1529 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1530 pfile_in_zip_read_info->pos_local_extrafield=0;
1531 pfile_in_zip_read_info->raw=raw;
1532
1533 if (pfile_in_zip_read_info->read_buffer==NULL)
1534 {
1535 TRYFREE(pfile_in_zip_read_info);
1536 return UNZ_INTERNALERROR;
1537 }
1538
1539 pfile_in_zip_read_info->stream_initialised=0;
1540
1541 if (method!=NULL)
1542 *method = (int)s->cur_file_info.compression_method;
1543
1544 if (level!=NULL)
1545 {
1546 *level = 6;
1547 switch (s->cur_file_info.flag & 0x06)
1548 {
1549 case 6 : *level = 1; break;
1550 case 4 : *level = 2; break;
1551 case 2 : *level = 9; break;
1552 }
1553 }
1554
1555 if ((s->cur_file_info.compression_method!=0) &&
1556/* #ifdef HAVE_BZIP2 */
1557 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1558/* #endif */
1559 (s->cur_file_info.compression_method!=Z_DEFLATED))
1560
1561 err=UNZ_BADZIPFILE;
1562
1563 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1564 pfile_in_zip_read_info->crc32=0;
1565 pfile_in_zip_read_info->total_out_64=0;
1566 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1567 pfile_in_zip_read_info->filestream=s->filestream;
1568 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1569 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1570
1571 pfile_in_zip_read_info->stream.total_out = 0;
1572
1573 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
1574 {
1575#ifdef HAVE_BZIP2
1576 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1577 pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1578 pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1579 pfile_in_zip_read_info->bstream.state = (voidpf)0;
1580
1581 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1582 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1583 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1584 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1585 pfile_in_zip_read_info->stream.avail_in = 0;
1586
1587 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1588 if (err == Z_OK)
1589 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1590 else
1591 {
1592 TRYFREE(pfile_in_zip_read_info);
1593 return err;
1594 }
1595#else
1596 pfile_in_zip_read_info->raw=1;
1597#endif
1598 }
1599 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1600 {
1601 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1602 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1603 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1604 pfile_in_zip_read_info->stream.next_in = 0;
1605 pfile_in_zip_read_info->stream.avail_in = 0;
1606
1607 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1608 if (err == Z_OK)
1609 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
1610 else
1611 {
1612 TRYFREE(pfile_in_zip_read_info->read_buffer);
1613 TRYFREE(pfile_in_zip_read_info);
1614 return err;
1615 }
1616 /* windowBits is passed < 0 to tell that there is no zlib header.
1617 * Note that in this case inflate *requires* an extra "dummy" byte
1618 * after the compressed stream in order to complete decompression and
1619 * return Z_STREAM_END.
1620 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1621 * size of both compressed and uncompressed data
1622 */
1623 }
1624 pfile_in_zip_read_info->rest_read_compressed =
1625 s->cur_file_info.compressed_size ;
1626 pfile_in_zip_read_info->rest_read_uncompressed =
1627 s->cur_file_info.uncompressed_size ;
1628
1629
1630 pfile_in_zip_read_info->pos_in_zipfile =
1631 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1632 iSizeVar;
1633
1634 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1635
1636 s->pfile_in_zip_read = pfile_in_zip_read_info;
1637 s->encrypted = 0;
1638
1639# ifndef NOUNCRYPT
1640 if (password != NULL)
1641 {
1642 int i;
1643 s->pcrc_32_tab = get_crc_table();
1644 init_keys(password,s->keys,s->pcrc_32_tab);
1645 if (ZSEEK64(s->z_filefunc, s->filestream,
1646 s->pfile_in_zip_read->pos_in_zipfile +
1647 s->pfile_in_zip_read->byte_before_the_zipfile,
1648 SEEK_SET)!=0)
1649 return UNZ_INTERNALERROR;
1650 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
1651 return UNZ_INTERNALERROR;
1652
1653 for (i = 0; i<12; i++)
1654 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1655
1656 s->pfile_in_zip_read->pos_in_zipfile+=12;
1657 s->encrypted=1;
1658 }
1659# endif
1660
1661
1662 return UNZ_OK;
1663}
1664
1665extern int ZEXPORT unzOpenCurrentFile (unzFile file)
1666{
1667 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1668}
1669
1670extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
1671{
1672 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1673}
1674
1675extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
1676{
1677 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1678}
1679
1680/** Addition for GDAL : START */
1681
1682extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
1683{
1684 unz64_s* s;
1685 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1686 s=(unz64_s*)file;
1687 if (file==NULL)
1688 return 0; /*UNZ_PARAMERROR; */
1689 pfile_in_zip_read_info=s->pfile_in_zip_read;
1690 if (pfile_in_zip_read_info==NULL)
1691 return 0; /*UNZ_PARAMERROR; */
1692 return pfile_in_zip_read_info->pos_in_zipfile +
1693 pfile_in_zip_read_info->byte_before_the_zipfile;
1694}
1695
1696/** Addition for GDAL : END */
1697
1698/*
1699 Read bytes from the current file.
1700 buf contain buffer where data must be copied
1701 len the size of buf.
1702
1703 return the number of byte copied if somes bytes are copied
1704 return 0 if the end of file was reached
1705 return <0 with error code if there is an error
1706 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1707*/
1708extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
1709{
1710 int err=UNZ_OK;
1711 uInt iRead = 0;
1712 unz64_s* s;
1713 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1714 if (file==NULL)
1715 return UNZ_PARAMERROR;
1716 s=(unz64_s*)file;
1717 pfile_in_zip_read_info=s->pfile_in_zip_read;
1718
1719 if (pfile_in_zip_read_info==NULL)
1720 return UNZ_PARAMERROR;
1721
1722
1723 if (pfile_in_zip_read_info->read_buffer == NULL)
1724 return UNZ_END_OF_LIST_OF_FILE;
1725 if (len==0)
1726 return 0;
1727
1728 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1729
1730 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1731
1732 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1733 (!(pfile_in_zip_read_info->raw)))
1734 pfile_in_zip_read_info->stream.avail_out =
1735 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1736
1737 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1738 pfile_in_zip_read_info->stream.avail_in) &&
1739 (pfile_in_zip_read_info->raw))
1740 pfile_in_zip_read_info->stream.avail_out =
1741 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1742 pfile_in_zip_read_info->stream.avail_in;
1743
1744 while (pfile_in_zip_read_info->stream.avail_out>0)
1745 {
1746 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1747 (pfile_in_zip_read_info->rest_read_compressed>0))
1748 {
1749 uInt uReadThis = UNZ_BUFSIZE;
1750 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1751 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1752 if (uReadThis == 0)
1753 return UNZ_EOF;
1754 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1755 pfile_in_zip_read_info->filestream,
1756 pfile_in_zip_read_info->pos_in_zipfile +
1757 pfile_in_zip_read_info->byte_before_the_zipfile,
1758 ZLIB_FILEFUNC_SEEK_SET)!=0)
1759 return UNZ_ERRNO;
1760 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1761 pfile_in_zip_read_info->filestream,
1762 pfile_in_zip_read_info->read_buffer,
1763 uReadThis)!=uReadThis)
1764 return UNZ_ERRNO;
1765
1766
1767# ifndef NOUNCRYPT
1768 if(s->encrypted)
1769 {
1770 uInt i;
1771 for(i=0;i<uReadThis;i++)
1772 pfile_in_zip_read_info->read_buffer[i] =
1773 zdecode(s->keys,s->pcrc_32_tab,
1774 pfile_in_zip_read_info->read_buffer[i]);
1775 }
1776# endif
1777
1778
1779 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1780
1781 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1782
1783 pfile_in_zip_read_info->stream.next_in =
1784 (Bytef*)pfile_in_zip_read_info->read_buffer;
1785 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1786 }
1787
1788 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1789 {
1790 uInt uDoCopy,i ;
1791
1792 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1793 (pfile_in_zip_read_info->rest_read_compressed == 0))
1794 return (iRead==0) ? UNZ_EOF : iRead;
1795
1796 if (pfile_in_zip_read_info->stream.avail_out <
1797 pfile_in_zip_read_info->stream.avail_in)
1798 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1799 else
1800 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1801
1802 for (i=0;i<uDoCopy;i++)
1803 *(pfile_in_zip_read_info->stream.next_out+i) =
1804 *(pfile_in_zip_read_info->stream.next_in+i);
1805
1806 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
1807
1808 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1809 pfile_in_zip_read_info->stream.next_out,
1810 uDoCopy);
1811 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1812 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1813 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1814 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1815 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1816 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1817 iRead += uDoCopy;
1818 }
1819 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
1820 {
1821#ifdef HAVE_BZIP2
1822 uLong uTotalOutBefore,uTotalOutAfter;
1823 const Bytef *bufBefore;
1824 uLong uOutThis;
1825
1826 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
1827 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
1828 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
1829 pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
1830 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
1831 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
1832 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1833 pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1834
1835 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1836 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
1837
1838 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1839
1840 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1841 uOutThis = uTotalOutAfter-uTotalOutBefore;
1842
1843 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1844
1845 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
1846 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1847 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1848
1849 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
1850 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
1851 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
1852 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
1853 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1854 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1855
1856 if (err==BZ_STREAM_END)
1857 return (iRead==0) ? UNZ_EOF : iRead;
1858 if (err!=BZ_OK)
1859 break;
1860#endif
1861 } /* end Z_BZIP2ED */
1862 else
1863 {
1864 uInt uAvailOutBefore,uAvailOutAfter;
1865 const Bytef *bufBefore;
1866 uInt uOutThis;
1867 int flush=Z_SYNC_FLUSH;
1868
1869 uAvailOutBefore = pfile_in_zip_read_info->stream.avail_out;
1870 bufBefore = pfile_in_zip_read_info->stream.next_out;
1871
1872 err=inflate(&pfile_in_zip_read_info->stream,flush);
1873
1874 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1875 err = Z_DATA_ERROR;
1876
1877 uAvailOutAfter = pfile_in_zip_read_info->stream.avail_out;
1878 uOutThis = uAvailOutBefore - uAvailOutAfter;
1879
1880 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1881
1882 pfile_in_zip_read_info->crc32
1883 = crc32(pfile_in_zip_read_info->crc32,bufBefore, uOutThis);
1884
1885 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1886
1887 iRead += uAvailOutBefore - uAvailOutAfter;
1888
1889 if (err==Z_STREAM_END)
1890 return (iRead==0) ? UNZ_EOF : iRead;
1891 if (err!=Z_OK)
1892 break;
1893 }
1894 }
1895
1896 if (err==Z_OK)
1897 return iRead;
1898 return err;
1899}
1900
1901
1902/*
1903 Give the current position in uncompressed data
1904*/
1905extern z_off_t ZEXPORT unztell (unzFile file)
1906{
1907 unz64_s* s;
1908 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1909 if (file==NULL)
1910 return UNZ_PARAMERROR;
1911 s=(unz64_s*)file;
1912 pfile_in_zip_read_info=s->pfile_in_zip_read;
1913
1914 if (pfile_in_zip_read_info==NULL)
1915 return UNZ_PARAMERROR;
1916
1917 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1918}
1919
1920extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
1921{
1922
1923 unz64_s* s;
1924 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1925 if (file==NULL)
1926 return (ZPOS64_T)-1;
1927 s=(unz64_s*)file;
1928 pfile_in_zip_read_info=s->pfile_in_zip_read;
1929
1930 if (pfile_in_zip_read_info==NULL)
1931 return (ZPOS64_T)-1;
1932
1933 return pfile_in_zip_read_info->total_out_64;
1934}
1935
1936
1937/*
1938 return 1 if the end of file was reached, 0 elsewhere
1939*/
1940extern int ZEXPORT unzeof (unzFile file)
1941{
1942 unz64_s* s;
1943 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1944 if (file==NULL)
1945 return UNZ_PARAMERROR;
1946 s=(unz64_s*)file;
1947 pfile_in_zip_read_info=s->pfile_in_zip_read;
1948
1949 if (pfile_in_zip_read_info==NULL)
1950 return UNZ_PARAMERROR;
1951
1952 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1953 return 1;
1954 else
1955 return 0;
1956}
1957
1958
1959
1960/*
1961Read extra field from the current file (opened by unzOpenCurrentFile)
1962This is the local-header version of the extra field (sometimes, there is
1963more info in the local-header version than in the central-header)
1964
1965 if buf==NULL, it return the size of the local extra field that can be read
1966
1967 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1968 buf.
1969 the return value is the number of bytes copied in buf, or (if <0)
1970 the error code
1971*/
1972extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
1973{
1974 unz64_s* s;
1975 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1976 uInt read_now;
1977 ZPOS64_T size_to_read;
1978
1979 if (file==NULL)
1980 return UNZ_PARAMERROR;
1981 s=(unz64_s*)file;
1982 pfile_in_zip_read_info=s->pfile_in_zip_read;
1983
1984 if (pfile_in_zip_read_info==NULL)
1985 return UNZ_PARAMERROR;
1986
1987 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1988 pfile_in_zip_read_info->pos_local_extrafield);
1989
1990 if (buf==NULL)
1991 return (int)size_to_read;
1992
1993 if (len>size_to_read)
1994 read_now = (uInt)size_to_read;
1995 else
1996 read_now = (uInt)len ;
1997
1998 if (read_now==0)
1999 return 0;
2000
2001 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
2002 pfile_in_zip_read_info->filestream,
2003 pfile_in_zip_read_info->offset_local_extrafield +
2004 pfile_in_zip_read_info->pos_local_extrafield,
2005 ZLIB_FILEFUNC_SEEK_SET)!=0)
2006 return UNZ_ERRNO;
2007
2008 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
2009 pfile_in_zip_read_info->filestream,
2010 buf,read_now)!=read_now)
2011 return UNZ_ERRNO;
2012
2013 return (int)read_now;
2014}
2015
2016/*
2017 Close the file in zip opened with unzipOpenCurrentFile
2018 Return UNZ_CRCERROR if all the file was read but the CRC is not good
2019*/
2020extern int ZEXPORT unzCloseCurrentFile (unzFile file)
2021{
2022 int err=UNZ_OK;
2023
2024 unz64_s* s;
2025 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2026 if (file==NULL)
2027 return UNZ_PARAMERROR;
2028 s=(unz64_s*)file;
2029 pfile_in_zip_read_info=s->pfile_in_zip_read;
2030
2031 if (pfile_in_zip_read_info==NULL)
2032 return UNZ_PARAMERROR;
2033
2034
2035 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
2036 (!pfile_in_zip_read_info->raw))
2037 {
2038 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2039 err=UNZ_CRCERROR;
2040 }
2041
2042
2043 TRYFREE(pfile_in_zip_read_info->read_buffer);
2044 pfile_in_zip_read_info->read_buffer = NULL;
2045 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
2046 inflateEnd(&pfile_in_zip_read_info->stream);
2047#ifdef HAVE_BZIP2
2048 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2049 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
2050#endif
2051
2052
2053 pfile_in_zip_read_info->stream_initialised = 0;
2054 TRYFREE(pfile_in_zip_read_info);
2055
2056 s->pfile_in_zip_read=NULL;
2057
2058 return err;
2059}
2060
2061
2062/*
2063 Get the global comment string of the ZipFile, in the szComment buffer.
2064 uSizeBuf is the size of the szComment buffer.
2065 return the number of byte copied or an error code <0
2066*/
2067extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
2068{
2069 unz64_s* s;
2070 uLong uReadThis ;
2071 if (file==NULL)
2072 return (int)UNZ_PARAMERROR;
2073 s=(unz64_s*)file;
2074
2075 uReadThis = uSizeBuf;
2076 if (uReadThis>s->gi.size_comment)
2077 uReadThis = s->gi.size_comment;
2078
2079 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
2080 return UNZ_ERRNO;
2081
2082 if (uReadThis>0)
2083 {
2084 *szComment='\0';
2085 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
2086 return UNZ_ERRNO;
2087 }
2088
2089 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
2090 *(szComment+s->gi.size_comment)='\0';
2091 return (int)uReadThis;
2092}
2093
2094/* Additions by RX '2004 */
2095extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
2096{
2097 unz64_s* s;
2098
2099 if (file==NULL)
2100 return 0; /*UNZ_PARAMERROR; */
2101 s=(unz64_s*)file;
2102 if (!s->current_file_ok)
2103 return 0;
2104 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
2105 if (s->num_file==s->gi.number_entry)
2106 return 0;
2107 return s->pos_in_central_dir;
2108}
2109
2110extern uLong ZEXPORT unzGetOffset (unzFile file)
2111{
2112 ZPOS64_T offset64;
2113
2114 if (file==NULL)
2115 return 0; /*UNZ_PARAMERROR; */
2116 offset64 = unzGetOffset64(file);
2117 return (uLong)offset64;
2118}
2119
2120extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
2121{
2122 unz64_s* s;
2123 int err;
2124
2125 if (file==NULL)
2126 return UNZ_PARAMERROR;
2127 s=(unz64_s*)file;
2128
2129 s->pos_in_central_dir = pos;
2130 s->num_file = s->gi.number_entry; /* hack */
2131 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
2132 &s->cur_file_info_internal,
2133 NULL,0,NULL,0,NULL,0);
2134 s->current_file_ok = (err == UNZ_OK);
2135 return err;
2136}
2137
2138extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
2139{
2140 return unzSetOffset64(file,pos);
2141}
2142
2143
2144int ZEXPORT unzSetFlags(unzFile file, unsigned flags)
2145{
2146 unz64_s* s;
2147 if (file == NULL)
2148 return UNZ_PARAMERROR;
2149 s = (unz64_s*)file;
2150 s->flags |= flags;
2151 return UNZ_OK;
2152}
2153
2154
2155int ZEXPORT unzClearFlags(unzFile file, unsigned flags)
2156{
2157 unz64_s* s;
2158 if (file == NULL)
2159 return UNZ_PARAMERROR;
2160 s = (unz64_s*)file;
2161 s->flags &= ~flags;
2162 return UNZ_OK;
2163}
diff --git a/utils/rbutilqt/quazip/unzip.h b/utils/rbutilqt/quazip/unzip.h
new file mode 100644
index 0000000000..fdefa2217a
--- /dev/null
+++ b/utils/rbutilqt/quazip/unzip.h
@@ -0,0 +1,461 @@
1/* unzip.h -- IO for uncompress .zip files using zlib
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
4
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
6
7 Modifications of Unzip for Zip64
8 Copyright (C) 2007-2008 Even Rouault
9
10 Modifications for Zip64 support on both zip and unzip
11 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
12
13 For more info read MiniZip_info.txt
14
15 ---------------------------------------------------------------------------------
16
17 Condition of use and distribution are the same than zlib :
18
19 This software is provided 'as-is', without any express or implied
20 warranty. In no event will the authors be held liable for any damages
21 arising from the use of this software.
22
23 Permission is granted to anyone to use this software for any purpose,
24 including commercial applications, and to alter it and redistribute it
25 freely, subject to the following restrictions:
26
27 1. The origin of this software must not be misrepresented; you must not
28 claim that you wrote the original software. If you use this software
29 in a product, an acknowledgment in the product documentation would be
30 appreciated but is not required.
31 2. Altered source versions must be plainly marked as such, and must not be
32 misrepresented as being the original software.
33 3. This notice may not be removed or altered from any source distribution.
34
35 ---------------------------------------------------------------------------------
36
37 Changes
38
39 See header of unzip64.c
40
41 ---------------------------------------------------------------------------
42
43 As per the requirement above, this file is plainly marked as modified
44 by Sergey A. Tachenov. Most modifications include the I/O API redesign
45 to support QIODevice interface. Some improvements and small fixes were also made.
46*/
47
48#ifndef _unz64_H
49#define _unz64_H
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55#ifndef _ZLIB_H
56#include <zlib.h>
57#endif
58
59#ifndef _ZLIBIOAPI_H
60#include "ioapi.h"
61#endif
62
63#ifdef HAVE_BZIP2
64#include "bzlib.h"
65#endif
66
67#define Z_BZIP2ED 12
68
69#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
70/* like the STRICT of WIN32, we define a pointer that cannot be converted
71 from (void*) without cast */
72typedef struct TagunzFile__ { int unused; } unzFile__;
73typedef unzFile__ *unzFile;
74#else
75typedef voidp unzFile;
76#endif
77
78
79#define UNZ_OK (0)
80#define UNZ_END_OF_LIST_OF_FILE (-100)
81#define UNZ_ERRNO (Z_ERRNO)
82#define UNZ_EOF (0)
83#define UNZ_PARAMERROR (-102)
84#define UNZ_BADZIPFILE (-103)
85#define UNZ_INTERNALERROR (-104)
86#define UNZ_CRCERROR (-105)
87
88#define UNZ_AUTO_CLOSE 0x01u
89#define UNZ_DEFAULT_FLAGS UNZ_AUTO_CLOSE
90#define UNZ_ENCODING_UTF8 0x0800u
91
92/* tm_unz contain date/time info */
93typedef struct tm_unz_s
94{
95 uInt tm_sec; /* seconds after the minute - [0,59] */
96 uInt tm_min; /* minutes after the hour - [0,59] */
97 uInt tm_hour; /* hours since midnight - [0,23] */
98 uInt tm_mday; /* day of the month - [1,31] */
99 uInt tm_mon; /* months since January - [0,11] */
100 uInt tm_year; /* years - [1980..2044] */
101} tm_unz;
102
103/* unz_global_info structure contain global data about the ZIPfile
104 These data comes from the end of central dir */
105typedef struct unz_global_info64_s
106{
107 ZPOS64_T number_entry; /* total number of entries in
108 the central dir on this disk */
109 uLong size_comment; /* size of the global comment of the zipfile */
110} unz_global_info64;
111
112typedef struct unz_global_info_s
113{
114 uLong number_entry; /* total number of entries in
115 the central dir on this disk */
116 uLong size_comment; /* size of the global comment of the zipfile */
117} unz_global_info;
118
119/* unz_file_info contain information about a file in the zipfile */
120typedef struct unz_file_info64_s
121{
122 uLong version; /* version made by 2 bytes */
123 uLong version_needed; /* version needed to extract 2 bytes */
124 uLong flag; /* general purpose bit flag 2 bytes */
125 uLong compression_method; /* compression method 2 bytes */
126 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
127 uLong crc; /* crc-32 4 bytes */
128 ZPOS64_T compressed_size; /* compressed size 8 bytes */
129 ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */
130 uLong size_filename; /* filename length 2 bytes */
131 uLong size_file_extra; /* extra field length 2 bytes */
132 uLong size_file_comment; /* file comment length 2 bytes */
133
134 uLong disk_num_start; /* disk number start 2 bytes */
135 uLong internal_fa; /* internal file attributes 2 bytes */
136 uLong external_fa; /* external file attributes 4 bytes */
137
138 tm_unz tmu_date;
139} unz_file_info64;
140
141typedef struct unz_file_info_s
142{
143 uLong version; /* version made by 2 bytes */
144 uLong version_needed; /* version needed to extract 2 bytes */
145 uLong flag; /* general purpose bit flag 2 bytes */
146 uLong compression_method; /* compression method 2 bytes */
147 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
148 uLong crc; /* crc-32 4 bytes */
149 uLong compressed_size; /* compressed size 4 bytes */
150 uLong uncompressed_size; /* uncompressed size 4 bytes */
151 uLong size_filename; /* filename length 2 bytes */
152 uLong size_file_extra; /* extra field length 2 bytes */
153 uLong size_file_comment; /* file comment length 2 bytes */
154
155 uLong disk_num_start; /* disk number start 2 bytes */
156 uLong internal_fa; /* internal file attributes 2 bytes */
157 uLong external_fa; /* external file attributes 4 bytes */
158
159 tm_unz tmu_date;
160} unz_file_info;
161
162extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
163 const char* fileName2,
164 int iCaseSensitivity));
165/*
166 Compare two filename (fileName1,fileName2).
167 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
168 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
169 or strcasecmp)
170 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
171 (like 1 on Unix, 2 on Windows)
172*/
173
174
175extern unzFile ZEXPORT unzOpen OF((voidpf file));
176extern unzFile ZEXPORT unzOpen64 OF((voidpf file));
177/*
178 Open a Zip file. path contain the full pathname (by example,
179 on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
180 "zlib/zlib113.zip".
181 If the zipfile cannot be opened (file don't exist or in not valid), the
182 return value is NULL.
183 Else, the return value is a unzFile Handle, usable with other function
184 of this unzip package.
185 the "64" function take a const void* pointer, because the path is just the
186 value passed to the open64_file_func callback.
187 Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
188 is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
189 does not describe the reality
190*/
191
192
193extern unzFile ZEXPORT unzOpen2 OF((voidpf file,
194 zlib_filefunc_def* pzlib_filefunc_def));
195/*
196 Open a Zip file, like unzOpen, but provide a set of file low level API
197 for read/write the zip file (see ioapi.h)
198*/
199
200extern unzFile ZEXPORT unzOpen2_64 OF((voidpf file,
201 zlib_filefunc64_def* pzlib_filefunc_def));
202/*
203 Open a Zip file, like unz64Open, but provide a set of file low level API
204 for read/write the zip file (see ioapi.h)
205*/
206
207
208/*
209 * Exported by Sergey A. Tachenov to implement some QuaZIP features. This
210 * function MAY change signature in order to implement even more features.
211 * You have been warned!
212 * */
213extern unzFile unzOpenInternal (voidpf file,
214 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
215 int is64bitOpenFunction, unsigned flags);
216
217
218
219extern int ZEXPORT unzClose OF((unzFile file));
220/*
221 Close a ZipFile opened with unzipOpen.
222 If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
223 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
224 return UNZ_OK if there is no problem. */
225
226extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
227 unz_global_info *pglobal_info));
228
229extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
230 unz_global_info64 *pglobal_info));
231
232extern int ZEXPORT unzGetFileFlags OF((unzFile file, unsigned* pflags));
233/*
234 Write info about the ZipFile in the *pglobal_info structure.
235 No preparation of the structure is needed
236 return UNZ_OK if there is no problem. */
237
238
239extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
240 char *szComment,
241 uLong uSizeBuf));
242/*
243 Get the global comment string of the ZipFile, in the szComment buffer.
244 uSizeBuf is the size of the szComment buffer.
245 return the number of byte copied or an error code <0
246*/
247
248
249/***************************************************************************/
250/* Unzip package allow you browse the directory of the zipfile */
251
252extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
253/*
254 Set the current file of the zipfile to the first file.
255 return UNZ_OK if there is no problem
256*/
257
258extern int ZEXPORT unzGoToNextFile OF((unzFile file));
259/*
260 Set the current file of the zipfile to the next file.
261 return UNZ_OK if there is no problem
262 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
263*/
264
265extern int ZEXPORT unzLocateFile OF((unzFile file,
266 const char *szFileName,
267 int iCaseSensitivity));
268/*
269 Try locate the file szFileName in the zipfile.
270 For the iCaseSensitivity signification, see unzStringFileNameCompare
271
272 return value :
273 UNZ_OK if the file is found. It becomes the current file.
274 UNZ_END_OF_LIST_OF_FILE if the file is not found
275*/
276
277
278/* ****************************************** */
279/* Ryan supplied functions */
280/* unz_file_info contain information about a file in the zipfile */
281typedef struct unz_file_pos_s
282{
283 uLong pos_in_zip_directory; /* offset in zip file directory */
284 uLong num_of_file; /* # of file */
285} unz_file_pos;
286
287extern int ZEXPORT unzGetFilePos(
288 unzFile file,
289 unz_file_pos* file_pos);
290
291extern int ZEXPORT unzGoToFilePos(
292 unzFile file,
293 unz_file_pos* file_pos);
294
295typedef struct unz64_file_pos_s
296{
297 ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */
298 ZPOS64_T num_of_file; /* # of file */
299} unz64_file_pos;
300
301extern int ZEXPORT unzGetFilePos64(
302 unzFile file,
303 unz64_file_pos* file_pos);
304
305extern int ZEXPORT unzGoToFilePos64(
306 unzFile file,
307 const unz64_file_pos* file_pos);
308
309/* ****************************************** */
310
311extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
312 unz_file_info64 *pfile_info,
313 char *szFileName,
314 uLong fileNameBufferSize,
315 void *extraField,
316 uLong extraFieldBufferSize,
317 char *szComment,
318 uLong commentBufferSize));
319
320extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
321 unz_file_info *pfile_info,
322 char *szFileName,
323 uLong fileNameBufferSize,
324 void *extraField,
325 uLong extraFieldBufferSize,
326 char *szComment,
327 uLong commentBufferSize));
328/*
329 Get Info about the current file
330 if pfile_info!=NULL, the *pfile_info structure will contain somes info about
331 the current file
332 if szFileName!=NULL, the filemane string will be copied in szFileName
333 (fileNameBufferSize is the size of the buffer)
334 if extraField!=NULL, the extra field information will be copied in extraField
335 (extraFieldBufferSize is the size of the buffer).
336 This is the Central-header version of the extra field
337 if szComment!=NULL, the comment string of the file will be copied in szComment
338 (commentBufferSize is the size of the buffer)
339*/
340
341
342/** Addition for GDAL : START */
343
344extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
345
346/** Addition for GDAL : END */
347
348
349/***************************************************************************/
350/* for reading the content of the current zipfile, you can open it, read data
351 from it, and close it (you can close it before reading all the file)
352 */
353
354extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
355/*
356 Open for reading data the current file in the zipfile.
357 If there is no error, the return value is UNZ_OK.
358*/
359
360extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
361 const char* password));
362/*
363 Open for reading data the current file in the zipfile.
364 password is a crypting password
365 If there is no error, the return value is UNZ_OK.
366*/
367
368extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
369 int* method,
370 int* level,
371 int raw));
372/*
373 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
374 if raw==1
375 *method will receive method of compression, *level will receive level of
376 compression
377 note : you can set level parameter as NULL (if you did not want known level,
378 but you CANNOT set method parameter as NULL
379*/
380
381extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
382 int* method,
383 int* level,
384 int raw,
385 const char* password));
386/*
387 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
388 if raw==1
389 *method will receive method of compression, *level will receive level of
390 compression
391 note : you can set level parameter as NULL (if you did not want known level,
392 but you CANNOT set method parameter as NULL
393*/
394
395
396extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
397/*
398 Close the file in zip opened with unzOpenCurrentFile
399 Return UNZ_CRCERROR if all the file was read but the CRC is not good
400*/
401
402extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
403 voidp buf,
404 unsigned len));
405/*
406 Read bytes from the current file (opened by unzOpenCurrentFile)
407 buf contain buffer where data must be copied
408 len the size of buf.
409
410 return the number of byte copied if somes bytes are copied
411 return 0 if the end of file was reached
412 return <0 with error code if there is an error
413 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
414*/
415
416extern z_off_t ZEXPORT unztell OF((unzFile file));
417
418extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
419/*
420 Give the current position in uncompressed data
421*/
422
423extern int ZEXPORT unzeof OF((unzFile file));
424/*
425 return 1 if the end of file was reached, 0 elsewhere
426*/
427
428extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
429 voidp buf,
430 unsigned len));
431/*
432 Read extra field from the current file (opened by unzOpenCurrentFile)
433 This is the local-header version of the extra field (sometimes, there is
434 more info in the local-header version than in the central-header)
435
436 if buf==NULL, it return the size of the local extra field
437
438 if buf!=NULL, len is the size of the buffer, the extra header is copied in
439 buf.
440 the return value is the number of bytes copied in buf, or (if <0)
441 the error code
442*/
443
444/***************************************************************************/
445
446/* Get the current file offset */
447extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
448extern uLong ZEXPORT unzGetOffset (unzFile file);
449
450/* Set the current file offset */
451extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
452extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
453
454extern int ZEXPORT unzSetFlags(unzFile file, unsigned flags);
455extern int ZEXPORT unzClearFlags(unzFile file, unsigned flags);
456
457#ifdef __cplusplus
458}
459#endif
460
461#endif /* _unz64_H */
diff --git a/utils/rbutilqt/quazip/zip.c b/utils/rbutilqt/quazip/zip.c
new file mode 100644
index 0000000000..0f3deb04c1
--- /dev/null
+++ b/utils/rbutilqt/quazip/zip.c
@@ -0,0 +1,2111 @@
1/* zip.c -- IO on .zip files using zlib
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
4
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
6
7 Modifications for Zip64 support
8 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
9
10 For more info read MiniZip_info.txt
11
12 Modifications for QIODevice support and other QuaZIP fixes
13 Copyright (C) 2005-2014 Sergey A. Tachenov
14
15 Fixing static code analysis issues
16 Copyright (C) 2016 Intel Deutschland GmbH
17
18 Changes
19 Oct-2009 - Mathias Svensson - Remove old C style function prototypes
20 Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
21 Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
22 Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
23 It is used when recreting zip archive with RAW when deleting items from a zip.
24 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
25 Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
26 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
27
28*/
29
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <time.h>
35
36#include <zlib.h>
37#if (ZLIB_VERNUM < 0x1270)
38typedef uLongf z_crc_t;
39#endif
40#include "zip.h"
41
42#ifdef STDC
43# include <stddef.h>
44# include <string.h>
45# include <stdlib.h>
46#endif
47#ifdef NO_ERRNO_H
48 extern int errno;
49#else
50# include <errno.h>
51#endif
52
53
54#ifndef local
55# define local static
56#endif
57/* compile with -Dlocal if your debugger can't find static symbols */
58
59#ifndef VERSIONMADEBY
60# define VERSIONMADEBY (0x031e) /* best for standard pkware crypt */
61#endif
62
63#ifndef Z_BUFSIZE
64#define Z_BUFSIZE (64*1024) /* (16384) */
65#endif
66
67#ifndef Z_MAXFILENAMEINZIP
68#define Z_MAXFILENAMEINZIP (256)
69#endif
70
71#ifndef ALLOC
72# define ALLOC(size) (malloc(size))
73#endif
74#ifndef TRYFREE
75# define TRYFREE(p) {if (p) free(p);}
76#endif
77
78/*
79#define SIZECENTRALDIRITEM (0x2e)
80#define SIZEZIPLOCALHEADER (0x1e)
81*/
82
83/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
84
85
86/* NOT sure that this work on ALL platform */
87#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
88
89#ifndef SEEK_CUR
90#define SEEK_CUR 1
91#endif
92
93#ifndef SEEK_END
94#define SEEK_END 2
95#endif
96
97#ifndef SEEK_SET
98#define SEEK_SET 0
99#endif
100
101#ifndef DEF_MEM_LEVEL
102#if MAX_MEM_LEVEL >= 8
103# define DEF_MEM_LEVEL 8
104#else
105# define DEF_MEM_LEVEL MAX_MEM_LEVEL
106#endif
107#endif
108const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
109
110
111#define SIZEDATA_INDATABLOCK (4096-(4*4))
112
113#define LOCALHEADERMAGIC (0x04034b50)
114#define DESCRIPTORHEADERMAGIC (0x08074b50)
115#define CENTRALHEADERMAGIC (0x02014b50)
116#define ENDHEADERMAGIC (0x06054b50)
117#define ZIP64ENDHEADERMAGIC (0x6064b50)
118#define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
119
120#define FLAG_LOCALHEADER_OFFSET (0x06)
121#define CRC_LOCALHEADER_OFFSET (0x0e)
122
123#define SIZECENTRALHEADER (0x2e) /* 46 */
124
125typedef struct linkedlist_datablock_internal_s
126{
127 struct linkedlist_datablock_internal_s* next_datablock;
128 uLong avail_in_this_block;
129 uLong filled_in_this_block;
130 uLong unused; /* for future use and alignement */
131 unsigned char data[SIZEDATA_INDATABLOCK];
132} linkedlist_datablock_internal;
133
134typedef struct linkedlist_data_s
135{
136 linkedlist_datablock_internal* first_block;
137 linkedlist_datablock_internal* last_block;
138} linkedlist_data;
139
140
141typedef struct
142{
143 z_stream stream; /* zLib stream structure for inflate */
144#ifdef HAVE_BZIP2
145 bz_stream bstream; /* bzLib stream structure for bziped */
146#endif
147
148 int stream_initialised; /* 1 is stream is initialised */
149 uInt pos_in_buffered_data; /* last written byte in buffered_data */
150
151 ZPOS64_T pos_local_header; /* offset of the local header of the file
152 currenty writing */
153 char* central_header; /* central header data for the current file */
154 uLong size_centralExtra;
155 uLong size_centralheader; /* size of the central header for cur file */
156 uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
157 uLong flag; /* flag of the file currently writing */
158
159 int method; /* compression method of file currenty wr.*/
160 int raw; /* 1 for directly writing raw data */
161 Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
162 uLong dosDate;
163 uLong crc32;
164 int encrypt;
165 int zip64; /* Add ZIP64 extened information in the extra field */
166 ZPOS64_T pos_zip64extrainfo;
167 ZPOS64_T totalCompressedData;
168 ZPOS64_T totalUncompressedData;
169#ifndef NOCRYPT
170 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
171 const z_crc_t FAR * pcrc_32_tab;
172 int crypt_header_size;
173#endif
174} curfile64_info;
175
176typedef struct
177{
178 zlib_filefunc64_32_def z_filefunc;
179 voidpf filestream; /* io structore of the zipfile */
180 linkedlist_data central_dir;/* datablock with central dir in construction*/
181 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
182 curfile64_info ci; /* info on the file curretly writing */
183
184 ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
185 ZPOS64_T add_position_when_writting_offset;
186 ZPOS64_T number_entry;
187
188#ifndef NO_ADDFILEINEXISTINGZIP
189 char *globalcomment;
190#endif
191
192 unsigned flags;
193
194} zip64_internal;
195
196
197#ifndef NOCRYPT
198#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
199#include "minizip_crypt.h"
200#endif
201
202local linkedlist_datablock_internal* allocate_new_datablock()
203{
204 linkedlist_datablock_internal* ldi;
205 ldi = (linkedlist_datablock_internal*)
206 ALLOC(sizeof(linkedlist_datablock_internal));
207 if (ldi!=NULL)
208 {
209 ldi->next_datablock = NULL ;
210 ldi->filled_in_this_block = 0 ;
211 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
212 }
213 return ldi;
214}
215
216local void free_datablock(linkedlist_datablock_internal* ldi)
217{
218 while (ldi!=NULL)
219 {
220 linkedlist_datablock_internal* ldinext = ldi->next_datablock;
221 TRYFREE(ldi);
222 ldi = ldinext;
223 }
224}
225
226local void init_linkedlist(linkedlist_data* ll)
227{
228 ll->first_block = ll->last_block = NULL;
229}
230
231local void free_linkedlist(linkedlist_data* ll)
232{
233 free_datablock(ll->first_block);
234 ll->first_block = ll->last_block = NULL;
235}
236
237
238local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
239{
240 linkedlist_datablock_internal* ldi;
241 const unsigned char* from_copy;
242
243 if (ll==NULL)
244 return ZIP_INTERNALERROR;
245
246 if (ll->last_block == NULL)
247 {
248 ll->first_block = ll->last_block = allocate_new_datablock();
249 if (ll->first_block == NULL)
250 return ZIP_INTERNALERROR;
251 }
252
253 ldi = ll->last_block;
254 from_copy = (unsigned char*)buf;
255
256 while (len>0)
257 {
258 uInt copy_this;
259 uInt i;
260 unsigned char* to_copy;
261
262 if (ldi->avail_in_this_block==0)
263 {
264 ldi->next_datablock = allocate_new_datablock();
265 if (ldi->next_datablock == NULL)
266 return ZIP_INTERNALERROR;
267 ldi = ldi->next_datablock ;
268 ll->last_block = ldi;
269 }
270
271 if (ldi->avail_in_this_block < len)
272 copy_this = (uInt)ldi->avail_in_this_block;
273 else
274 copy_this = (uInt)len;
275
276 to_copy = &(ldi->data[ldi->filled_in_this_block]);
277
278 for (i=0;i<copy_this;i++)
279 *(to_copy+i)=*(from_copy+i);
280
281 ldi->filled_in_this_block += copy_this;
282 ldi->avail_in_this_block -= copy_this;
283 from_copy += copy_this ;
284 len -= copy_this;
285 }
286 return ZIP_OK;
287}
288
289
290
291/****************************************************************************/
292
293#ifndef NO_ADDFILEINEXISTINGZIP
294/* ===========================================================================
295 Inputs a long in LSB order to the given file
296 nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
297*/
298
299local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
300local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
301{
302 unsigned char buf[8];
303 int n;
304 for (n = 0; n < nbByte; n++)
305 {
306 buf[n] = (unsigned char)(x & 0xff);
307 x >>= 8;
308 }
309 if (x != 0)
310 { /* data overflow - hack for ZIP64 (X Roche) */
311 for (n = 0; n < nbByte; n++)
312 {
313 buf[n] = 0xff;
314 }
315 }
316
317 if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
318 return ZIP_ERRNO;
319 else
320 return ZIP_OK;
321}
322
323local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
324local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
325{
326 unsigned char* buf=(unsigned char*)dest;
327 int n;
328 for (n = 0; n < nbByte; n++) {
329 buf[n] = (unsigned char)(x & 0xff);
330 x >>= 8;
331 }
332
333 if (x != 0)
334 { /* data overflow - hack for ZIP64 */
335 for (n = 0; n < nbByte; n++)
336 {
337 buf[n] = 0xff;
338 }
339 }
340}
341
342/****************************************************************************/
343
344
345local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
346{
347 uLong year = (uLong)ptm->tm_year;
348 if (year>=1980)
349 year-=1980;
350 else if (year>=80)
351 year-=80;
352 return
353 (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
354 ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
355}
356
357
358/****************************************************************************/
359
360local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
361
362local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
363{
364 unsigned char c;
365 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
366 if (err==1)
367 {
368 *pi = (int)c;
369 return ZIP_OK;
370 }
371 else
372 {
373 if (ZERROR64(*pzlib_filefunc_def,filestream))
374 return ZIP_ERRNO;
375 else
376 return ZIP_EOF;
377 }
378}
379
380
381/* ===========================================================================
382 Reads a long in LSB order from the given gz_stream. Sets
383*/
384local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
385
386local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
387{
388 uLong x ;
389 int i = 0;
390 int err;
391
392 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
393 x = (uLong)i;
394
395 if (err==ZIP_OK)
396 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
397 x += ((uLong)i)<<8;
398
399 if (err==ZIP_OK)
400 *pX = x;
401 else
402 *pX = 0;
403 return err;
404}
405
406local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
407
408local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
409{
410 uLong x ;
411 int i = 0;
412 int err;
413
414 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
415 x = (uLong)i;
416
417 if (err==ZIP_OK)
418 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
419 x += ((uLong)i)<<8;
420
421 if (err==ZIP_OK)
422 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
423 x += ((uLong)i)<<16;
424
425 if (err==ZIP_OK)
426 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
427 x += ((uLong)i)<<24;
428
429 if (err==ZIP_OK)
430 *pX = x;
431 else
432 *pX = 0;
433 return err;
434}
435
436local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
437
438
439local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
440{
441 ZPOS64_T x;
442 int i = 0;
443 int err;
444
445 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
446 x = (ZPOS64_T)i;
447
448 if (err==ZIP_OK)
449 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
450 x += ((ZPOS64_T)i)<<8;
451
452 if (err==ZIP_OK)
453 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
454 x += ((ZPOS64_T)i)<<16;
455
456 if (err==ZIP_OK)
457 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
458 x += ((ZPOS64_T)i)<<24;
459
460 if (err==ZIP_OK)
461 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
462 x += ((ZPOS64_T)i)<<32;
463
464 if (err==ZIP_OK)
465 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
466 x += ((ZPOS64_T)i)<<40;
467
468 if (err==ZIP_OK)
469 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
470 x += ((ZPOS64_T)i)<<48;
471
472 if (err==ZIP_OK)
473 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
474 x += ((ZPOS64_T)i)<<56;
475
476 if (err==ZIP_OK)
477 *pX = x;
478 else
479 *pX = 0;
480
481 return err;
482}
483
484#ifndef BUFREADCOMMENT
485#define BUFREADCOMMENT (0x400)
486#endif
487/*
488 Locate the Central directory of a zipfile (at the end, just before
489 the global comment)
490*/
491local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
492
493local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
494{
495 unsigned char* buf;
496 ZPOS64_T uSizeFile;
497 ZPOS64_T uBackRead;
498 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
499 ZPOS64_T uPosFound=0;
500
501 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
502 return 0;
503
504
505 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
506
507 if (uMaxBack>uSizeFile)
508 uMaxBack = uSizeFile;
509
510 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
511 if (buf==NULL)
512 return 0;
513
514 uBackRead = 4;
515 while (uBackRead<uMaxBack)
516 {
517 uLong uReadSize;
518 ZPOS64_T uReadPos ;
519 int i;
520 if (uBackRead+BUFREADCOMMENT>uMaxBack)
521 uBackRead = uMaxBack;
522 else
523 uBackRead+=BUFREADCOMMENT;
524 uReadPos = uSizeFile-uBackRead ;
525
526 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
527 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
528 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
529 break;
530
531 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
532 break;
533
534 for (i=(int)uReadSize-3; (i--)>0;){
535 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
536 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
537 {
538 uPosFound = uReadPos+i;
539 break;
540 }
541 }
542
543 if (uPosFound!=0)
544 break;
545 }
546 TRYFREE(buf);
547 return uPosFound;
548}
549
550/*
551Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
552the global comment)
553*/
554local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
555
556local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
557{
558 unsigned char* buf;
559 ZPOS64_T uSizeFile;
560 ZPOS64_T uBackRead;
561 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
562 ZPOS64_T uPosFound=0;
563 uLong uL;
564 ZPOS64_T relativeOffset;
565
566 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
567 return 0;
568
569 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
570
571 if (uMaxBack>uSizeFile)
572 uMaxBack = uSizeFile;
573
574 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
575 if (buf==NULL)
576 return 0;
577
578 uBackRead = 4;
579 while (uBackRead<uMaxBack)
580 {
581 uLong uReadSize;
582 ZPOS64_T uReadPos;
583 int i;
584 if (uBackRead+BUFREADCOMMENT>uMaxBack)
585 uBackRead = uMaxBack;
586 else
587 uBackRead+=BUFREADCOMMENT;
588 uReadPos = uSizeFile-uBackRead ;
589
590 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
591 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
592 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
593 break;
594
595 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
596 break;
597
598 for (i=(int)uReadSize-3; (i--)>0;)
599 {
600 /* Signature "0x07064b50" Zip64 end of central directory locater */
601 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
602 {
603 uPosFound = uReadPos+i;
604 break;
605 }
606 }
607
608 if (uPosFound!=0)
609 break;
610 }
611
612 TRYFREE(buf);
613 if (uPosFound == 0)
614 return 0;
615
616 /* Zip64 end of central directory locator */
617 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
618 return 0;
619
620 /* the signature, already checked */
621 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
622 return 0;
623
624 /* number of the disk with the start of the zip64 end of central directory */
625 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
626 return 0;
627 if (uL != 0)
628 return 0;
629
630 /* relative offset of the zip64 end of central directory record */
631 if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
632 return 0;
633
634 /* total number of disks */
635 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
636 return 0;
637 if (uL != 1)
638 return 0;
639
640 /* Goto Zip64 end of central directory record */
641 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
642 return 0;
643
644 /* the signature */
645 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
646 return 0;
647
648 if (uL != 0x06064b50) /* signature of 'Zip64 end of central directory' */
649 return 0;
650
651 return relativeOffset;
652}
653
654int LoadCentralDirectoryRecord(zip64_internal* pziinit)
655{
656 int err=ZIP_OK;
657 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
658
659 ZPOS64_T size_central_dir; /* size of the central directory */
660 ZPOS64_T offset_central_dir; /* offset of start of central directory */
661 ZPOS64_T central_pos;
662 uLong uL;
663
664 uLong number_disk; /* number of the current dist, used for
665 spaning ZIP, unsupported, always 0*/
666 uLong number_disk_with_CD; /* number the the disk with central dir, used
667 for spaning ZIP, unsupported, always 0*/
668 ZPOS64_T number_entry;
669 ZPOS64_T number_entry_CD; /* total number of entries in
670 the central dir
671 (same than number_entry on nospan) */
672 uLong VersionMadeBy;
673 uLong VersionNeeded;
674 uLong size_comment;
675
676 int hasZIP64Record = 0;
677
678 /* check first if we find a ZIP64 record */
679 central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
680 if(central_pos > 0)
681 {
682 hasZIP64Record = 1;
683 }
684 else if(central_pos == 0)
685 {
686 central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
687 }
688
689/* disable to allow appending to empty ZIP archive
690 if (central_pos==0)
691 err=ZIP_ERRNO;
692*/
693
694 if(hasZIP64Record)
695 {
696 ZPOS64_T sizeEndOfCentralDirectory;
697 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
698 err=ZIP_ERRNO;
699
700 /* the signature, already checked */
701 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
702 err=ZIP_ERRNO;
703
704 /* size of zip64 end of central directory record */
705 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
706 err=ZIP_ERRNO;
707
708 /* version made by */
709 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
710 err=ZIP_ERRNO;
711
712 /* version needed to extract */
713 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
714 err=ZIP_ERRNO;
715
716 /* number of this disk */
717 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
718 err=ZIP_ERRNO;
719
720 /* number of the disk with the start of the central directory */
721 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
722 err=ZIP_ERRNO;
723
724 /* total number of entries in the central directory on this disk */
725 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
726 err=ZIP_ERRNO;
727
728 /* total number of entries in the central directory */
729 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
730 err=ZIP_ERRNO;
731
732 if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
733 err=ZIP_BADZIPFILE;
734
735 /* size of the central directory */
736 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
737 err=ZIP_ERRNO;
738
739 /* offset of start of central directory with respect to the
740 starting disk number */
741 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
742 err=ZIP_ERRNO;
743
744 /* TODO.. */
745 /* read the comment from the standard central header. */
746 size_comment = 0;
747 }
748 else
749 {
750 /* Read End of central Directory info */
751 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
752 err=ZIP_ERRNO;
753
754 /* the signature, already checked */
755 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
756 err=ZIP_ERRNO;
757
758 /* number of this disk */
759 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
760 err=ZIP_ERRNO;
761
762 /* number of the disk with the start of the central directory */
763 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
764 err=ZIP_ERRNO;
765
766 /* total number of entries in the central dir on this disk */
767 number_entry = 0;
768 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
769 err=ZIP_ERRNO;
770 else
771 number_entry = uL;
772
773 /* total number of entries in the central dir */
774 number_entry_CD = 0;
775 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
776 err=ZIP_ERRNO;
777 else
778 number_entry_CD = uL;
779
780 if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
781 err=ZIP_BADZIPFILE;
782
783 /* size of the central directory */
784 size_central_dir = 0;
785 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
786 err=ZIP_ERRNO;
787 else
788 size_central_dir = uL;
789
790 /* offset of start of central directory with respect to the starting disk number */
791 offset_central_dir = 0;
792 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
793 err=ZIP_ERRNO;
794 else
795 offset_central_dir = uL;
796
797
798 /* zipfile global comment length */
799 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
800 err=ZIP_ERRNO;
801 }
802
803 if ((central_pos<offset_central_dir+size_central_dir) &&
804 (err==ZIP_OK))
805 err=ZIP_BADZIPFILE;
806
807 if (err!=ZIP_OK)
808 {
809 if ((pziinit->flags & ZIP_AUTO_CLOSE) != 0) {
810 ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
811 } else {
812 ZFAKECLOSE64(pziinit->z_filefunc, pziinit->filestream);
813 }
814 return ZIP_ERRNO;
815 }
816
817 if (size_comment>0)
818 {
819 pziinit->globalcomment = (char*)ALLOC(size_comment+1);
820 if (pziinit->globalcomment)
821 {
822 size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
823 pziinit->globalcomment[size_comment]=0;
824 }
825 }
826
827 byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
828 pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
829
830 {
831 ZPOS64_T size_central_dir_to_read = size_central_dir;
832 size_t buf_size = SIZEDATA_INDATABLOCK;
833 void* buf_read = (void*)ALLOC(buf_size);
834 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
835 err=ZIP_ERRNO;
836
837 while ((size_central_dir_to_read>0) && (err==ZIP_OK))
838 {
839 ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
840 if (read_this > size_central_dir_to_read)
841 read_this = size_central_dir_to_read;
842
843 if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
844 err=ZIP_ERRNO;
845
846 if (err==ZIP_OK)
847 err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
848
849 size_central_dir_to_read-=read_this;
850 }
851 TRYFREE(buf_read);
852 }
853 pziinit->begin_pos = byte_before_the_zipfile;
854 pziinit->number_entry = number_entry_CD;
855
856 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
857 err=ZIP_ERRNO;
858
859 return err;
860}
861
862
863#endif /* !NO_ADDFILEINEXISTINGZIP*/
864
865
866/************************************************************/
867extern zipFile ZEXPORT zipOpen3 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
868 unsigned flags)
869{
870 zip64_internal ziinit;
871 zip64_internal* zi;
872 int err=ZIP_OK;
873
874 ziinit.flags = flags;
875 ziinit.z_filefunc.zseek32_file = NULL;
876 ziinit.z_filefunc.ztell32_file = NULL;
877 if (pzlib_filefunc64_32_def==NULL)
878 fill_qiodevice64_filefunc(&ziinit.z_filefunc.zfile_func64);
879 else
880 ziinit.z_filefunc = *pzlib_filefunc64_32_def;
881
882 ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
883 file,
884 (append == APPEND_STATUS_CREATE) ?
885 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
886 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
887
888 if (ziinit.filestream == NULL)
889 return NULL;
890
891 if (append == APPEND_STATUS_CREATEAFTER)
892 ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
893
894 ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
895 ziinit.in_opened_file_inzip = 0;
896 ziinit.ci.stream_initialised = 0;
897 ziinit.number_entry = 0;
898 ziinit.add_position_when_writting_offset = 0;
899 init_linkedlist(&(ziinit.central_dir));
900
901
902
903 zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
904 if (zi==NULL)
905 {
906 if ((ziinit.flags & ZIP_AUTO_CLOSE) != 0) {
907 ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
908 } else {
909 ZFAKECLOSE64(ziinit.z_filefunc,ziinit.filestream);
910 }
911 return NULL;
912 }
913
914 /* now we add file in a zipfile */
915# ifndef NO_ADDFILEINEXISTINGZIP
916 ziinit.globalcomment = NULL;
917 if (append == APPEND_STATUS_ADDINZIP)
918 {
919 /* Read and Cache Central Directory Records */
920 err = LoadCentralDirectoryRecord(&ziinit);
921 }
922
923 if (globalcomment)
924 {
925 *globalcomment = ziinit.globalcomment;
926 }
927# endif /* !NO_ADDFILEINEXISTINGZIP*/
928
929 if (err != ZIP_OK)
930 {
931# ifndef NO_ADDFILEINEXISTINGZIP
932 TRYFREE(ziinit.globalcomment);
933# endif /* !NO_ADDFILEINEXISTINGZIP*/
934 TRYFREE(zi);
935 return NULL;
936 }
937 else
938 {
939 *zi = ziinit;
940 return (zipFile)zi;
941 }
942}
943
944extern zipFile ZEXPORT zipOpen2 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
945{
946 if (pzlib_filefunc32_def != NULL)
947 {
948 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
949 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
950 return zipOpen3(file, append, globalcomment, &zlib_filefunc64_32_def_fill, ZIP_DEFAULT_FLAGS);
951 }
952 else
953 return zipOpen3(file, append, globalcomment, NULL, ZIP_DEFAULT_FLAGS);
954}
955
956extern zipFile ZEXPORT zipOpen2_64 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
957{
958 if (pzlib_filefunc_def != NULL)
959 {
960 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
961 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
962 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
963 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
964 return zipOpen3(file, append, globalcomment, &zlib_filefunc64_32_def_fill, ZIP_DEFAULT_FLAGS);
965 }
966 else
967 return zipOpen3(file, append, globalcomment, NULL, ZIP_DEFAULT_FLAGS);
968}
969
970
971
972extern zipFile ZEXPORT zipOpen (voidpf file, int append)
973{
974 return zipOpen3(file,append,NULL,NULL, ZIP_DEFAULT_FLAGS);
975}
976
977extern zipFile ZEXPORT zipOpen64 (voidpf file, int append)
978{
979 return zipOpen3(file,append,NULL,NULL, ZIP_DEFAULT_FLAGS);
980}
981
982int Write_LocalFileHeader(zip64_internal* zi, const char* filename,
983 uInt size_extrafield_local,
984 const void* extrafield_local,
985 uLong version_to_extract)
986{
987 /* write the local header */
988 int err;
989 uInt size_filename = (uInt)strlen(filename);
990 uInt size_extrafield = size_extrafield_local;
991
992 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
993
994 if (err==ZIP_OK)
995 {
996 if(zi->ci.flag & ZIP_ENCODING_UTF8)
997 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)63,2);/* Version 6.3 is required for Unicode support */
998 else if(zi->ci.zip64)
999 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
1000 else
1001 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)version_to_extract,2);
1002 }
1003
1004 if (err==ZIP_OK)
1005 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
1006
1007 if (err==ZIP_OK)
1008 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
1009
1010 if (err==ZIP_OK)
1011 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
1012
1013 /* CRC / Compressed size / Uncompressed size will be filled in later and rewritten later */
1014 if (err==ZIP_OK)
1015 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
1016 if (err==ZIP_OK)
1017 {
1018 if(zi->ci.zip64)
1019 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
1020 else
1021 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
1022 }
1023 if (err==ZIP_OK)
1024 {
1025 if(zi->ci.zip64)
1026 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
1027 else
1028 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
1029 }
1030
1031 if (err==ZIP_OK)
1032 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
1033
1034 if(zi->ci.zip64)
1035 {
1036 size_extrafield += 20;
1037 }
1038
1039 if (err==ZIP_OK)
1040 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
1041
1042 if ((err==ZIP_OK) && (size_filename > 0))
1043 {
1044 if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
1045 err = ZIP_ERRNO;
1046 }
1047
1048 if ((err==ZIP_OK) && (size_extrafield_local > 0))
1049 {
1050 if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
1051 err = ZIP_ERRNO;
1052 }
1053
1054
1055 if ((err==ZIP_OK) && (zi->ci.zip64))
1056 {
1057 /* write the Zip64 extended info */
1058 short HeaderID = 1;
1059 short DataSize = 16;
1060 ZPOS64_T CompressedSize = 0;
1061 ZPOS64_T UncompressedSize = 0;
1062
1063 /* Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) */
1064 zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
1065
1066 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
1067 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
1068
1069 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
1070 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
1071 }
1072
1073 return err;
1074}
1075
1076/*
1077 NOTE.
1078 When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
1079 before calling this function it can be done with zipRemoveExtraInfoBlock
1080
1081 It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
1082 unnecessary allocations.
1083 */
1084extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1085 const void* extrafield_local, uInt size_extrafield_local,
1086 const void* extrafield_global, uInt size_extrafield_global,
1087 const char* comment, int method, int level, int raw,
1088 int windowBits,int memLevel, int strategy,
1089 const char* password, uLong crcForCrypting,
1090 uLong versionMadeBy, uLong flagBase, int zip64)
1091{
1092 zip64_internal* zi;
1093 uInt size_filename;
1094 uInt size_comment;
1095 uInt i;
1096 int err = ZIP_OK;
1097 uLong version_to_extract;
1098
1099# ifdef NOCRYPT
1100 if (password != NULL)
1101 return ZIP_PARAMERROR;
1102# endif
1103
1104 if (file == NULL)
1105 return ZIP_PARAMERROR;
1106
1107#ifdef HAVE_BZIP2
1108 if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
1109 return ZIP_PARAMERROR;
1110#else
1111 if ((method!=0) && (method!=Z_DEFLATED))
1112 return ZIP_PARAMERROR;
1113#endif
1114
1115 zi = (zip64_internal*)file;
1116
1117 if (zi->in_opened_file_inzip == 1)
1118 {
1119 err = zipCloseFileInZip (file);
1120 if (err != ZIP_OK)
1121 return err;
1122 }
1123
1124 if (method == 0
1125 && (level == 0 || (zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0)
1126 && (zi->flags & ZIP_SEQUENTIAL) == 0)
1127 {
1128 version_to_extract = 10;
1129 }
1130 else
1131 {
1132 version_to_extract = 20;
1133 }
1134
1135 if (filename==NULL)
1136 filename="-";
1137
1138 if (comment==NULL)
1139 size_comment = 0;
1140 else
1141 size_comment = (uInt)strlen(comment);
1142
1143 size_filename = (uInt)strlen(filename);
1144
1145 if (zipfi == NULL)
1146 zi->ci.dosDate = 0;
1147 else
1148 {
1149 if (zipfi->dosDate != 0)
1150 zi->ci.dosDate = zipfi->dosDate;
1151 else
1152 zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
1153 }
1154
1155 zi->ci.flag = flagBase;
1156 if (zi->flags & ZIP_ENCODING_UTF8)
1157 zi->ci.flag |= ZIP_ENCODING_UTF8;
1158 if ((level==8) || (level==9))
1159 zi->ci.flag |= 2;
1160 if (level==2)
1161 zi->ci.flag |= 4;
1162 if (level==1)
1163 zi->ci.flag |= 6;
1164 if (password != NULL)
1165 zi->ci.flag |= 1;
1166 if (version_to_extract >= 20
1167 && ((zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) != 0
1168 || (zi->flags & ZIP_SEQUENTIAL) != 0))
1169 zi->ci.flag |= 8;
1170
1171 zi->ci.crc32 = 0;
1172 zi->ci.method = method;
1173 zi->ci.encrypt = 0;
1174 zi->ci.stream_initialised = 0;
1175 zi->ci.pos_in_buffered_data = 0;
1176 zi->ci.raw = raw;
1177 zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
1178
1179 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
1180 zi->ci.size_centralExtraFree = 32; /* Extra space we have reserved in case we need to add ZIP64 extra info data */
1181
1182 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
1183 if(!zi->ci.central_header) {
1184 return (Z_MEM_ERROR);
1185 }
1186
1187 zi->ci.size_centralExtra = size_extrafield_global;
1188 zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
1189 /* version info */
1190 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
1191 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)version_to_extract,2);
1192 zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
1193 zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
1194 zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
1195 zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
1196 zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
1197 zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
1198 zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
1199 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
1200 zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
1201 zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
1202
1203 if (zipfi==NULL)
1204 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
1205 else
1206 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
1207
1208 if (zipfi==NULL)
1209 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
1210 else
1211 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
1212
1213 if(zi->ci.pos_local_header >= 0xffffffff)
1214 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
1215 else
1216 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
1217
1218 for (i=0;i<size_filename;i++)
1219 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
1220
1221 for (i=0;i<size_extrafield_global;i++)
1222 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
1223 *(((const char*)extrafield_global)+i);
1224
1225 for (i=0;i<size_comment;i++)
1226 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
1227 size_extrafield_global+i) = *(comment+i);
1228 if (zi->ci.central_header == NULL)
1229 return ZIP_INTERNALERROR;
1230
1231 zi->ci.zip64 = zip64;
1232 zi->ci.totalCompressedData = 0;
1233 zi->ci.totalUncompressedData = 0;
1234 zi->ci.pos_zip64extrainfo = 0;
1235
1236 err = Write_LocalFileHeader(zi, filename, size_extrafield_local,
1237 extrafield_local, version_to_extract);
1238
1239#ifdef HAVE_BZIP2
1240 zi->ci.bstream.avail_in = (uInt)0;
1241 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1242 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1243 zi->ci.bstream.total_in_hi32 = 0;
1244 zi->ci.bstream.total_in_lo32 = 0;
1245 zi->ci.bstream.total_out_hi32 = 0;
1246 zi->ci.bstream.total_out_lo32 = 0;
1247#endif
1248
1249 zi->ci.stream.avail_in = (uInt)0;
1250 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1251 zi->ci.stream.next_out = zi->ci.buffered_data;
1252 zi->ci.stream.total_in = 0;
1253 zi->ci.stream.total_out = 0;
1254 zi->ci.stream.data_type = Z_BINARY;
1255
1256#ifdef HAVE_BZIP2
1257 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1258#else
1259 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1260#endif
1261 {
1262 if(zi->ci.method == Z_DEFLATED)
1263 {
1264 zi->ci.stream.zalloc = (alloc_func)0;
1265 zi->ci.stream.zfree = (free_func)0;
1266 zi->ci.stream.opaque = (voidpf)0;
1267
1268 if (windowBits>0)
1269 windowBits = -windowBits;
1270
1271 err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
1272
1273 if (err==Z_OK)
1274 zi->ci.stream_initialised = Z_DEFLATED;
1275 }
1276 else if(zi->ci.method == Z_BZIP2ED)
1277 {
1278#ifdef HAVE_BZIP2
1279 /* Init BZip stuff here */
1280 zi->ci.bstream.bzalloc = 0;
1281 zi->ci.bstream.bzfree = 0;
1282 zi->ci.bstream.opaque = (voidpf)0;
1283
1284 err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
1285 if(err == BZ_OK)
1286 zi->ci.stream_initialised = Z_BZIP2ED;
1287#endif
1288 }
1289
1290 }
1291
1292# ifndef NOCRYPT
1293 zi->ci.crypt_header_size = 0;
1294 if ((err==Z_OK) && (password != NULL))
1295 {
1296 unsigned char bufHead[RAND_HEAD_LEN];
1297 unsigned int sizeHead;
1298 zi->ci.encrypt = 1;
1299 zi->ci.pcrc_32_tab = get_crc_table();
1300 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
1301 if (crcForCrypting == 0) {
1302 crcForCrypting = (uLong)zi->ci.dosDate << 16; /* ATTANTION! Without this row, you don't unpack your password protected archive in other app. */
1303 }
1304 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
1305 zi->ci.crypt_header_size = sizeHead;
1306
1307 if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
1308 err = ZIP_ERRNO;
1309 }
1310# endif
1311
1312 if (err==Z_OK)
1313 zi->in_opened_file_inzip = 1;
1314 return err;
1315}
1316
1317extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1318 const void* extrafield_local, uInt size_extrafield_local,
1319 const void* extrafield_global, uInt size_extrafield_global,
1320 const char* comment, int method, int level, int raw,
1321 int windowBits,int memLevel, int strategy,
1322 const char* password, uLong crcForCrypting,
1323 uLong versionMadeBy, uLong flagBase)
1324{
1325 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1326 extrafield_local, size_extrafield_local,
1327 extrafield_global, size_extrafield_global,
1328 comment, method, level, raw,
1329 windowBits, memLevel, strategy,
1330 password, crcForCrypting, versionMadeBy, flagBase, 0);
1331}
1332
1333extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1334 const void* extrafield_local, uInt size_extrafield_local,
1335 const void* extrafield_global, uInt size_extrafield_global,
1336 const char* comment, int method, int level, int raw,
1337 int windowBits,int memLevel, int strategy,
1338 const char* password, uLong crcForCrypting)
1339{
1340 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1341 extrafield_local, size_extrafield_local,
1342 extrafield_global, size_extrafield_global,
1343 comment, method, level, raw,
1344 windowBits, memLevel, strategy,
1345 password, crcForCrypting, VERSIONMADEBY, 0, 0);
1346}
1347
1348extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
1349 const void* extrafield_local, uInt size_extrafield_local,
1350 const void* extrafield_global, uInt size_extrafield_global,
1351 const char* comment, int method, int level, int raw,
1352 int windowBits,int memLevel, int strategy,
1353 const char* password, uLong crcForCrypting, int zip64)
1354{
1355 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1356 extrafield_local, size_extrafield_local,
1357 extrafield_global, size_extrafield_global,
1358 comment, method, level, raw,
1359 windowBits, memLevel, strategy,
1360 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
1361}
1362
1363extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
1364 const void* extrafield_local, uInt size_extrafield_local,
1365 const void* extrafield_global, uInt size_extrafield_global,
1366 const char* comment, int method, int level, int raw)
1367{
1368 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1369 extrafield_local, size_extrafield_local,
1370 extrafield_global, size_extrafield_global,
1371 comment, method, level, raw,
1372 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1373 NULL, 0, VERSIONMADEBY, 0, 0);
1374}
1375
1376extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
1377 const void* extrafield_local, uInt size_extrafield_local,
1378 const void* extrafield_global, uInt size_extrafield_global,
1379 const char* comment, int method, int level, int raw, int zip64)
1380{
1381 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1382 extrafield_local, size_extrafield_local,
1383 extrafield_global, size_extrafield_global,
1384 comment, method, level, raw,
1385 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1386 NULL, 0, VERSIONMADEBY, 0, zip64);
1387}
1388
1389extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1390 const void* extrafield_local, uInt size_extrafield_local,
1391 const void*extrafield_global, uInt size_extrafield_global,
1392 const char* comment, int method, int level, int zip64)
1393{
1394 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1395 extrafield_local, size_extrafield_local,
1396 extrafield_global, size_extrafield_global,
1397 comment, method, level, 0,
1398 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1399 NULL, 0, VERSIONMADEBY, 0, zip64);
1400}
1401
1402extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1403 const void* extrafield_local, uInt size_extrafield_local,
1404 const void*extrafield_global, uInt size_extrafield_global,
1405 const char* comment, int method, int level)
1406{
1407 return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1408 extrafield_local, size_extrafield_local,
1409 extrafield_global, size_extrafield_global,
1410 comment, method, level, 0,
1411 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1412 NULL, 0, VERSIONMADEBY, 0, 0);
1413}
1414
1415local int zip64FlushWriteBuffer(zip64_internal* zi)
1416{
1417 int err=ZIP_OK;
1418
1419 if (zi->ci.encrypt != 0)
1420 {
1421#ifndef NOCRYPT
1422 uInt i;
1423 int t;
1424 for (i=0;i<zi->ci.pos_in_buffered_data;i++)
1425 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
1426#endif
1427 }
1428
1429 if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
1430 err = ZIP_ERRNO;
1431
1432 zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
1433
1434#ifdef HAVE_BZIP2
1435 if(zi->ci.method == Z_BZIP2ED)
1436 {
1437 zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
1438 zi->ci.bstream.total_in_lo32 = 0;
1439 zi->ci.bstream.total_in_hi32 = 0;
1440 }
1441 else
1442#endif
1443 {
1444 zi->ci.totalUncompressedData += zi->ci.stream.total_in;
1445 zi->ci.stream.total_in = 0;
1446 }
1447
1448
1449 zi->ci.pos_in_buffered_data = 0;
1450
1451 return err;
1452}
1453
1454extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
1455{
1456 zip64_internal* zi;
1457 int err=ZIP_OK;
1458
1459 if (file == NULL)
1460 return ZIP_PARAMERROR;
1461 zi = (zip64_internal*)file;
1462
1463 if (zi->in_opened_file_inzip == 0)
1464 return ZIP_PARAMERROR;
1465
1466 zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
1467
1468#ifdef HAVE_BZIP2
1469 if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
1470 {
1471 zi->ci.bstream.next_in = (void*)buf;
1472 zi->ci.bstream.avail_in = len;
1473 err = BZ_RUN_OK;
1474
1475 while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
1476 {
1477 if (zi->ci.bstream.avail_out == 0)
1478 {
1479 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1480 err = ZIP_ERRNO;
1481 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1482 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1483 }
1484
1485
1486 if(err != BZ_RUN_OK)
1487 break;
1488
1489 if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1490 {
1491 uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
1492/* uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; */
1493 err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
1494
1495 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
1496 }
1497 }
1498
1499 if(err == BZ_RUN_OK)
1500 err = ZIP_OK;
1501 }
1502 else
1503#endif
1504 {
1505 zi->ci.stream.next_in = (Bytef*)buf;
1506 zi->ci.stream.avail_in = len;
1507
1508 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
1509 {
1510 if (zi->ci.stream.avail_out == 0)
1511 {
1512 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1513 err = ZIP_ERRNO;
1514 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1515 zi->ci.stream.next_out = zi->ci.buffered_data;
1516 }
1517
1518
1519 if(err != ZIP_OK)
1520 break;
1521
1522 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1523 {
1524 uInt uAvailOutBefore = zi->ci.stream.avail_out;
1525 err=deflate(&zi->ci.stream, Z_NO_FLUSH);
1526 zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out;
1527 }
1528 else
1529 {
1530 uInt copy_this,i;
1531 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
1532 copy_this = zi->ci.stream.avail_in;
1533 else
1534 copy_this = zi->ci.stream.avail_out;
1535
1536 for (i = 0; i < copy_this; i++)
1537 *(((char*)zi->ci.stream.next_out)+i) =
1538 *(((const char*)zi->ci.stream.next_in)+i);
1539 {
1540 zi->ci.stream.avail_in -= copy_this;
1541 zi->ci.stream.avail_out-= copy_this;
1542 zi->ci.stream.next_in+= copy_this;
1543 zi->ci.stream.next_out+= copy_this;
1544 zi->ci.stream.total_in+= copy_this;
1545 zi->ci.stream.total_out+= copy_this;
1546 zi->ci.pos_in_buffered_data += copy_this;
1547 }
1548 }
1549 }/* while(...) */
1550 }
1551
1552 return err;
1553}
1554
1555extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
1556{
1557 return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
1558}
1559
1560extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
1561{
1562 zip64_internal* zi;
1563 ZPOS64_T compressed_size;
1564 uLong invalidValue = 0xffffffff;
1565 short datasize = 0;
1566 int err=ZIP_OK;
1567
1568 if (file == NULL)
1569 return ZIP_PARAMERROR;
1570 zi = (zip64_internal*)file;
1571
1572 if (zi->in_opened_file_inzip == 0)
1573 return ZIP_PARAMERROR;
1574 zi->ci.stream.avail_in = 0;
1575
1576 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1577 {
1578 while (err==ZIP_OK)
1579 {
1580 uLong uAvailOutBefore;
1581 if (zi->ci.stream.avail_out == 0)
1582 {
1583 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1584 err = ZIP_ERRNO;
1585 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1586 zi->ci.stream.next_out = zi->ci.buffered_data;
1587 }
1588 uAvailOutBefore = zi->ci.stream.avail_out;
1589 err=deflate(&zi->ci.stream, Z_FINISH);
1590 zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out;
1591 }
1592 }
1593 else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1594 {
1595#ifdef HAVE_BZIP2
1596 err = BZ_FINISH_OK;
1597 while (err==BZ_FINISH_OK)
1598 {
1599 uLong uTotalOutBefore;
1600 if (zi->ci.bstream.avail_out == 0)
1601 {
1602 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1603 err = ZIP_ERRNO;
1604 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1605 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1606 }
1607 uTotalOutBefore = zi->ci.bstream.total_out_lo32;
1608 err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
1609 if(err == BZ_STREAM_END)
1610 err = Z_STREAM_END;
1611
1612 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
1613 }
1614
1615 if(err == BZ_FINISH_OK)
1616 err = ZIP_OK;
1617#endif
1618 }
1619
1620 if (err==Z_STREAM_END)
1621 err=ZIP_OK; /* this is normal */
1622
1623 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1624 {
1625 if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
1626 err = ZIP_ERRNO;
1627 }
1628
1629 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1630 {
1631 int tmp_err = deflateEnd(&zi->ci.stream);
1632 if (err == ZIP_OK)
1633 err = tmp_err;
1634 zi->ci.stream_initialised = 0;
1635 }
1636#ifdef HAVE_BZIP2
1637 else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1638 {
1639 int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
1640 if (err==ZIP_OK)
1641 err = tmperr;
1642 zi->ci.stream_initialised = 0;
1643 }
1644#endif
1645
1646 if (!zi->ci.raw)
1647 {
1648 crc32 = (uLong)zi->ci.crc32;
1649 uncompressed_size = zi->ci.totalUncompressedData;
1650 }
1651 compressed_size = zi->ci.totalCompressedData;
1652
1653# ifndef NOCRYPT
1654 compressed_size += zi->ci.crypt_header_size;
1655# endif
1656
1657 /* update Current Item crc and sizes, */
1658 if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
1659 {
1660 /*version Made by*/
1661 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
1662 /*version needed*/
1663 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)((zi->ci.flag & ZIP_ENCODING_UTF8) ? 63 : 45),2);
1664 }
1665
1666 zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
1667
1668
1669 if(compressed_size >= 0xffffffff)
1670 zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
1671 else
1672 zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
1673
1674 /* set internal file attributes field */
1675 if (zi->ci.stream.data_type == Z_ASCII)
1676 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1677
1678 if(uncompressed_size >= 0xffffffff)
1679 zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
1680 else
1681 zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
1682
1683 /* Add ZIP64 extra info field for uncompressed size */
1684 if(uncompressed_size >= 0xffffffff)
1685 datasize += 8;
1686
1687 /* Add ZIP64 extra info field for compressed size */
1688 if(compressed_size >= 0xffffffff)
1689 datasize += 8;
1690
1691 /* Add ZIP64 extra info field for relative offset to local file header of current file */
1692 if(zi->ci.pos_local_header >= 0xffffffff)
1693 datasize += 8;
1694
1695 if(datasize > 0)
1696 {
1697 char* p = NULL;
1698
1699 if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
1700 {
1701 /* we can not write more data to the buffer that we have room for. */
1702 return ZIP_BADZIPFILE;
1703 }
1704
1705 p = zi->ci.central_header + zi->ci.size_centralheader;
1706
1707 /* Add Extra Information Header for 'ZIP64 information' */
1708 zip64local_putValue_inmemory(p, 0x0001, 2); /* HeaderID */
1709 p += 2;
1710 zip64local_putValue_inmemory(p, datasize, 2); /* DataSize */
1711 p += 2;
1712
1713 if(uncompressed_size >= 0xffffffff)
1714 {
1715 zip64local_putValue_inmemory(p, uncompressed_size, 8);
1716 p += 8;
1717 }
1718
1719 if(compressed_size >= 0xffffffff)
1720 {
1721 zip64local_putValue_inmemory(p, compressed_size, 8);
1722 p += 8;
1723 }
1724
1725 if(zi->ci.pos_local_header >= 0xffffffff)
1726 {
1727 zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
1728 p += 8;
1729 }
1730
1731 /* Update how much extra free space we got in the memory buffer */
1732 /* and increase the centralheader size so the new ZIP64 fields are included */
1733 /* ( 4 below is the size of HeaderID and DataSize field ) */
1734 zi->ci.size_centralExtraFree -= datasize + 4;
1735 zi->ci.size_centralheader += datasize + 4;
1736
1737 /* Update the extra info size field */
1738 zi->ci.size_centralExtra += datasize + 4;
1739 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
1740 }
1741
1742 if (err==ZIP_OK)
1743 err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
1744
1745 TRYFREE(zi->ci.central_header);
1746
1747 if (err==ZIP_OK)
1748 {
1749 if ((zi->flags & ZIP_SEQUENTIAL) == 0) {
1750 /* Update the LocalFileHeader with the new values. */
1751
1752 ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
1753
1754 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
1755 err = ZIP_ERRNO;
1756
1757 if (err==ZIP_OK)
1758 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1759
1760 if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff)
1761 {
1762 if(zi->ci.pos_zip64extrainfo > 0)
1763 {
1764 /* Update the size in the ZIP64 extended field. */
1765 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
1766 err = ZIP_ERRNO;
1767
1768 if (err==ZIP_OK) /* compressed size, unknown */
1769 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
1770
1771 if (err==ZIP_OK) /* uncompressed size, unknown */
1772 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
1773 }
1774 }
1775 else
1776 {
1777 if (err==ZIP_OK) /* compressed size, unknown */
1778 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1779
1780 if (err==ZIP_OK) /* uncompressed size, unknown */
1781 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1782 }
1783
1784 if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
1785 err = ZIP_ERRNO;
1786 }
1787
1788 if ((zi->ci.flag & 8) != 0) {
1789 /* Write local Descriptor after file data */
1790 if (err==ZIP_OK)
1791 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)DESCRIPTORHEADERMAGIC,4);
1792 if (err==ZIP_OK)
1793 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1794 if (zi->ci.zip64) {
1795 if (err==ZIP_OK) /* compressed size, unknown */
1796 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,8);
1797
1798 if (err==ZIP_OK) /* uncompressed size, unknown */
1799 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,8);
1800 } else {
1801 if (err==ZIP_OK) /* compressed size, unknown */
1802 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1803 if (err==ZIP_OK) /* uncompressed size, unknown */
1804 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1805 }
1806 }
1807 }
1808
1809 zi->number_entry ++;
1810 zi->in_opened_file_inzip = 0;
1811
1812 return err;
1813}
1814
1815extern int ZEXPORT zipCloseFileInZip (zipFile file)
1816{
1817 return zipCloseFileInZipRaw (file,0,0);
1818}
1819
1820int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
1821{
1822 int err = ZIP_OK;
1823 ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
1824
1825 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
1826
1827 /*num disks*/
1828 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1829 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
1830
1831 /*relative offset*/
1832 if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
1833 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
1834
1835 /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
1836 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1837 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
1838
1839 return err;
1840}
1841
1842int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
1843{
1844 int err = ZIP_OK;
1845
1846 uLong Zip64DataSize = 44;
1847
1848 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
1849
1850 if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
1851 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); /* why ZPOS64_T of this ? */
1852
1853 if (err==ZIP_OK) /* version made by */
1854 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
1855
1856 if (err==ZIP_OK) /* version needed */
1857 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)((zi->ci.flag & ZIP_ENCODING_UTF8) ? 63 : 45),2);
1858
1859 if (err==ZIP_OK) /* number of this disk */
1860 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
1861
1862 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1863 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
1864
1865 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1866 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
1867
1868 if (err==ZIP_OK) /* total number of entries in the central dir */
1869 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
1870
1871 if (err==ZIP_OK) /* size of the central directory */
1872 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
1873
1874 if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
1875 {
1876 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1877 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
1878 }
1879 return err;
1880}
1881int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
1882{
1883 int err = ZIP_OK;
1884
1885 /*signature*/
1886 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
1887
1888 if (err==ZIP_OK) /* number of this disk */
1889 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1890
1891 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1892 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1893
1894 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1895 {
1896 {
1897 if(zi->number_entry >= 0xFFFF)
1898 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */
1899 else
1900 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1901 }
1902 }
1903
1904 if (err==ZIP_OK) /* total number of entries in the central dir */
1905 {
1906 if(zi->number_entry >= 0xFFFF)
1907 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */
1908 else
1909 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1910 }
1911
1912 if (err==ZIP_OK) /* size of the central directory */
1913 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
1914
1915 if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
1916 {
1917 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1918 if(pos >= 0xffffffff)
1919 {
1920 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
1921 }
1922 else
1923 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
1924 }
1925
1926 return err;
1927}
1928
1929int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
1930{
1931 int err = ZIP_OK;
1932 uInt size_global_comment = 0;
1933
1934 if(global_comment != NULL)
1935 size_global_comment = (uInt)strlen(global_comment);
1936
1937 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
1938
1939 if (err == ZIP_OK && size_global_comment > 0)
1940 {
1941 if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
1942 err = ZIP_ERRNO;
1943 }
1944 return err;
1945}
1946
1947extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
1948{
1949 zip64_internal* zi;
1950 int err = 0;
1951 uLong size_centraldir = 0;
1952 ZPOS64_T centraldir_pos_inzip;
1953 ZPOS64_T pos;
1954
1955 if (file == NULL)
1956 return ZIP_PARAMERROR;
1957
1958 zi = (zip64_internal*)file;
1959
1960 if (zi->in_opened_file_inzip == 1)
1961 {
1962 err = zipCloseFileInZip (file);
1963 }
1964
1965#ifndef NO_ADDFILEINEXISTINGZIP
1966 if (global_comment==NULL)
1967 global_comment = zi->globalcomment;
1968#endif
1969
1970 centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
1971
1972 if (err==ZIP_OK)
1973 {
1974 linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
1975 while (ldi!=NULL)
1976 {
1977 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1978 {
1979 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
1980 err = ZIP_ERRNO;
1981 }
1982
1983 size_centraldir += ldi->filled_in_this_block;
1984 ldi = ldi->next_datablock;
1985 }
1986 }
1987 free_linkedlist(&(zi->central_dir));
1988
1989 pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1990 if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
1991 {
1992 ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
1993 Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
1994
1995 Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
1996 }
1997
1998 if (err==ZIP_OK)
1999 err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
2000
2001 if(err == ZIP_OK)
2002 err = Write_GlobalComment(zi, global_comment);
2003
2004 if ((zi->flags & ZIP_AUTO_CLOSE) != 0) {
2005 if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) {
2006 if (err == ZIP_OK)
2007 err = ZIP_ERRNO;
2008 }
2009 } else {
2010 if (ZFAKECLOSE64(zi->z_filefunc,zi->filestream) != 0) {
2011 if (err == ZIP_OK)
2012 err = ZIP_ERRNO;
2013 }
2014 }
2015
2016#ifndef NO_ADDFILEINEXISTINGZIP
2017 TRYFREE(zi->globalcomment);
2018#endif
2019 TRYFREE(zi);
2020
2021 return err;
2022}
2023
2024extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
2025{
2026 char* p = pData;
2027 int size = 0;
2028 char* pNewHeader;
2029 char* pTmp;
2030 short header;
2031 short dataSize;
2032
2033 int retVal = ZIP_OK;
2034
2035 if(pData == NULL || *dataLen < 4)
2036 return ZIP_PARAMERROR;
2037
2038 pNewHeader = (char*)ALLOC(*dataLen);
2039 if(!pNewHeader) {
2040 return Z_MEM_ERROR;
2041 }
2042 pTmp = pNewHeader;
2043
2044 while(p < (pData + *dataLen))
2045 {
2046 header = *(short*)p;
2047 dataSize = *(((short*)p)+1);
2048
2049 if( header == sHeader ) /* Header found. */
2050 {
2051 p += dataSize + 4; /* skip it. do not copy to temp buffer */
2052 }
2053 else
2054 {
2055 /* Extra Info block should not be removed, So copy it to the temp buffer. */
2056 memcpy(pTmp, p, dataSize + 4);
2057 p += dataSize + 4;
2058 size += dataSize + 4;
2059 }
2060
2061 }
2062
2063 if(size < *dataLen)
2064 {
2065 /* clean old extra info block. */
2066 memset(pData,0, *dataLen);
2067
2068 /* copy the new extra info block over the old */
2069 if(size > 0)
2070 memcpy(pData, pNewHeader, size);
2071
2072 /* set the new extra info size */
2073 *dataLen = size;
2074
2075 retVal = ZIP_OK;
2076 }
2077 else
2078 retVal = ZIP_ERRNO;
2079
2080 TRYFREE(pNewHeader);
2081
2082 return retVal;
2083}
2084
2085int ZEXPORT zipSetFlags(zipFile file, unsigned flags)
2086{
2087 zip64_internal* zi;
2088 if (file == NULL)
2089 return ZIP_PARAMERROR;
2090 zi = (zip64_internal*)file;
2091 zi->flags |= flags;
2092 // If the output is non-seekable, the data descriptor is needed.
2093 if ((zi->flags & ZIP_SEQUENTIAL) != 0) {
2094 zi->flags |= ZIP_WRITE_DATA_DESCRIPTOR;
2095 }
2096 return ZIP_OK;
2097}
2098
2099int ZEXPORT zipClearFlags(zipFile file, unsigned flags)
2100{
2101 zip64_internal* zi;
2102 if (file == NULL)
2103 return ZIP_PARAMERROR;
2104 zi = (zip64_internal*)file;
2105 zi->flags &= ~flags;
2106 // If the data descriptor is not written, we can't use a non-seekable output.
2107 if ((zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0) {
2108 zi->flags &= ~ZIP_SEQUENTIAL;
2109 }
2110 return ZIP_OK;
2111}
diff --git a/utils/rbutilqt/quazip/zip.h b/utils/rbutilqt/quazip/zip.h
new file mode 100644
index 0000000000..114a1bf6e7
--- /dev/null
+++ b/utils/rbutilqt/quazip/zip.h
@@ -0,0 +1,391 @@
1/* zip.h -- IO on .zip files using zlib
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
4
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
6
7 Modifications for Zip64 support
8 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
9
10 For more info read MiniZip_info.txt
11
12 ---------------------------------------------------------------------------
13
14 Condition of use and distribution are the same than zlib :
15
16 This software is provided 'as-is', without any express or implied
17 warranty. In no event will the authors be held liable for any damages
18 arising from the use of this software.
19
20 Permission is granted to anyone to use this software for any purpose,
21 including commercial applications, and to alter it and redistribute it
22 freely, subject to the following restrictions:
23
24 1. The origin of this software must not be misrepresented; you must not
25 claim that you wrote the original software. If you use this software
26 in a product, an acknowledgment in the product documentation would be
27 appreciated but is not required.
28 2. Altered source versions must be plainly marked as such, and must not be
29 misrepresented as being the original software.
30 3. This notice may not be removed or altered from any source distribution.
31
32 ---------------------------------------------------------------------------
33
34 Changes
35
36 See header of zip.h
37
38 ---------------------------------------------------------------------------
39
40 As per the requirement above, this file is plainly marked as modified
41 by Sergey A. Tachenov. Most modifications include the I/O API redesign
42 to support QIODevice interface. Some improvements and small fixes were also made.
43
44*/
45
46#ifndef _zip12_H
47#define _zip12_H
48
49#ifdef __cplusplus
50extern "C" {
51#endif
52
53//#define HAVE_BZIP2
54
55#ifndef _ZLIB_H
56#include <zlib.h>
57#endif
58
59#ifndef _ZLIBIOAPI_H
60#include "ioapi.h"
61#endif
62
63#ifdef HAVE_BZIP2
64#include "bzlib.h"
65#endif
66
67#define Z_BZIP2ED 12
68
69#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
70/* like the STRICT of WIN32, we define a pointer that cannot be converted
71 from (void*) without cast */
72typedef struct TagzipFile__ { int unused; } zipFile__;
73typedef zipFile__ *zipFile;
74#else
75typedef voidp zipFile;
76#endif
77
78#define ZIP_OK (0)
79#define ZIP_EOF (0)
80#define ZIP_ERRNO (Z_ERRNO)
81#define ZIP_PARAMERROR (-102)
82#define ZIP_BADZIPFILE (-103)
83#define ZIP_INTERNALERROR (-104)
84
85#define ZIP_WRITE_DATA_DESCRIPTOR 0x8u
86#define ZIP_AUTO_CLOSE 0x1u
87#define ZIP_SEQUENTIAL 0x2u
88#define ZIP_ENCODING_UTF8 0x0800u
89#define ZIP_DEFAULT_FLAGS (ZIP_AUTO_CLOSE | ZIP_WRITE_DATA_DESCRIPTOR)
90
91#ifndef DEF_MEM_LEVEL
92# if MAX_MEM_LEVEL >= 8
93# define DEF_MEM_LEVEL 8
94# else
95# define DEF_MEM_LEVEL MAX_MEM_LEVEL
96# endif
97#endif
98/* default memLevel */
99
100/* tm_zip contain date/time info */
101typedef struct tm_zip_s
102{
103 uInt tm_sec; /* seconds after the minute - [0,59] */
104 uInt tm_min; /* minutes after the hour - [0,59] */
105 uInt tm_hour; /* hours since midnight - [0,23] */
106 uInt tm_mday; /* day of the month - [1,31] */
107 uInt tm_mon; /* months since January - [0,11] */
108 uInt tm_year; /* years - [1980..2044] */
109} tm_zip;
110
111typedef struct
112{
113 tm_zip tmz_date; /* date in understandable format */
114 uLong dosDate; /* if dos_date == 0, tmu_date is used */
115/* uLong flag; */ /* general purpose bit flag 2 bytes */
116
117 uLong internal_fa; /* internal file attributes 2 bytes */
118 uLong external_fa; /* external file attributes 4 bytes */
119} zip_fileinfo;
120
121typedef const char* zipcharpc;
122
123
124#define APPEND_STATUS_CREATE (0)
125#define APPEND_STATUS_CREATEAFTER (1)
126#define APPEND_STATUS_ADDINZIP (2)
127
128extern zipFile ZEXPORT zipOpen OF((voidpf file, int append));
129extern zipFile ZEXPORT zipOpen64 OF((voidpf file, int append));
130/*
131 Create a zipfile.
132 the file argument depends on the API used, for QuaZIP it's a QIODevice
133 pointer.
134 if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
135 will be created at the end of the file.
136 (useful if the file contain a self extractor code)
137 if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
138 add files in existing zip (be sure you don't add file that doesn't exist)
139 If the zipfile cannot be opened, the return value is NULL.
140 Else, the return value is a zipFile Handle, usable with other function
141 of this zip package.
142*/
143
144/* Note : there is no delete function into a zipfile.
145 If you want delete file into a zipfile, you must open a zipfile, and create another
146 Of couse, you can use RAW reading and writing to copy the file you did not want delte
147*/
148
149extern zipFile ZEXPORT zipOpen2 OF((voidpf file,
150 int append,
151 zipcharpc* globalcomment,
152 zlib_filefunc_def* pzlib_filefunc_def));
153
154extern zipFile ZEXPORT zipOpen2_64 OF((voidpf file,
155 int append,
156 zipcharpc* globalcomment,
157 zlib_filefunc64_def* pzlib_filefunc_def));
158
159/*
160 * Exported by Sergey A. Tachenov to suit the needs of QuaZIP.
161 * Note that this function MAY change signature in order to
162 * provide new QuaZIP features. You have been warned!
163 * */
164extern zipFile ZEXPORT zipOpen3 (voidpf file,
165 int append,
166 zipcharpc* globalcomment,
167 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
168 unsigned flags);
169
170extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
171 const char* filename,
172 const zip_fileinfo* zipfi,
173 const void* extrafield_local,
174 uInt size_extrafield_local,
175 const void* extrafield_global,
176 uInt size_extrafield_global,
177 const char* comment,
178 int method,
179 int level));
180
181extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
182 const char* filename,
183 const zip_fileinfo* zipfi,
184 const void* extrafield_local,
185 uInt size_extrafield_local,
186 const void* extrafield_global,
187 uInt size_extrafield_global,
188 const char* comment,
189 int method,
190 int level,
191 int zip64));
192
193/*
194 Open a file in the ZIP for writing.
195 filename : the filename in zip (if NULL, '-' without quote will be used
196 *zipfi contain supplemental information
197 if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
198 contains the extrafield data the the local header
199 if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
200 contains the extrafield data the the local header
201 if comment != NULL, comment contain the comment string
202 method contain the compression method (0 for store, Z_DEFLATED for deflate)
203 level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
204 zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
205 this MUST be '1' if the uncompressed size is >= 0xffffffff.
206
207*/
208
209
210extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
211 const char* filename,
212 const zip_fileinfo* zipfi,
213 const void* extrafield_local,
214 uInt size_extrafield_local,
215 const void* extrafield_global,
216 uInt size_extrafield_global,
217 const char* comment,
218 int method,
219 int level,
220 int raw));
221
222
223extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
224 const char* filename,
225 const zip_fileinfo* zipfi,
226 const void* extrafield_local,
227 uInt size_extrafield_local,
228 const void* extrafield_global,
229 uInt size_extrafield_global,
230 const char* comment,
231 int method,
232 int level,
233 int raw,
234 int zip64));
235/*
236 Same than zipOpenNewFileInZip, except if raw=1, we write raw file
237 */
238
239extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
240 const char* filename,
241 const zip_fileinfo* zipfi,
242 const void* extrafield_local,
243 uInt size_extrafield_local,
244 const void* extrafield_global,
245 uInt size_extrafield_global,
246 const char* comment,
247 int method,
248 int level,
249 int raw,
250 int windowBits,
251 int memLevel,
252 int strategy,
253 const char* password,
254 uLong crcForCrypting));
255
256extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
257 const char* filename,
258 const zip_fileinfo* zipfi,
259 const void* extrafield_local,
260 uInt size_extrafield_local,
261 const void* extrafield_global,
262 uInt size_extrafield_global,
263 const char* comment,
264 int method,
265 int level,
266 int raw,
267 int windowBits,
268 int memLevel,
269 int strategy,
270 const char* password,
271 uLong crcForCrypting,
272 int zip64
273 ));
274
275/*
276 Same than zipOpenNewFileInZip2, except
277 windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
278 password : crypting password (NULL for no crypting)
279 crcForCrypting : crc of file to compress (needed for crypting)
280 */
281
282extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
283 const char* filename,
284 const zip_fileinfo* zipfi,
285 const void* extrafield_local,
286 uInt size_extrafield_local,
287 const void* extrafield_global,
288 uInt size_extrafield_global,
289 const char* comment,
290 int method,
291 int level,
292 int raw,
293 int windowBits,
294 int memLevel,
295 int strategy,
296 const char* password,
297 uLong crcForCrypting,
298 uLong versionMadeBy,
299 uLong flagBase
300 ));
301
302
303extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
304 const char* filename,
305 const zip_fileinfo* zipfi,
306 const void* extrafield_local,
307 uInt size_extrafield_local,
308 const void* extrafield_global,
309 uInt size_extrafield_global,
310 const char* comment,
311 int method,
312 int level,
313 int raw,
314 int windowBits,
315 int memLevel,
316 int strategy,
317 const char* password,
318 uLong crcForCrypting,
319 uLong versionMadeBy,
320 uLong flagBase,
321 int zip64
322 ));
323/*
324 Same than zipOpenNewFileInZip4, except
325 versionMadeBy : value for Version made by field
326 flag : value for flag field (compression level info will be added)
327 */
328
329
330extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
331 const void* buf,
332 unsigned len));
333/*
334 Write data in the zipfile
335*/
336
337extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
338/*
339 Close the current file in the zipfile
340*/
341
342extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
343 uLong uncompressed_size,
344 uLong crc32));
345
346extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
347 ZPOS64_T uncompressed_size,
348 uLong crc32));
349
350/*
351 Close the current file in the zipfile, for file opened with
352 parameter raw=1 in zipOpenNewFileInZip2
353 uncompressed_size and crc32 are value for the uncompressed size
354*/
355
356extern int ZEXPORT zipClose OF((zipFile file,
357 const char* global_comment));
358/*
359 Close the zipfile
360*/
361
362
363extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
364/*
365 zipRemoveExtraInfoBlock - Added by Mathias Svensson
366
367 Remove extra information block from a extra information data for the local file header or central directory header
368
369 It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
370
371 0x0001 is the signature header for the ZIP64 extra information blocks
372
373 usage.
374 Remove ZIP64 Extra information from a central director extra field data
375 zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
376
377 Remove ZIP64 Extra information from a Local File Header extra field data
378 zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
379*/
380
381/*
382 Added by Sergey A. Tachenov to tweak zipping behaviour.
383*/
384extern int ZEXPORT zipSetFlags(zipFile file, unsigned flags);
385extern int ZEXPORT zipClearFlags(zipFile file, unsigned flags);
386
387#ifdef __cplusplus
388}
389#endif
390
391#endif /* _zip64_H */