Added zziplib

This commit is contained in:
pelya
2010-11-29 12:44:44 +02:00
parent 6a8b3039ce
commit 45393e1e16
42 changed files with 11020 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := zzip
APP_SUBDIRS := $(patsubst $(LOCAL_PATH)/%, %, $(shell find $(LOCAL_PATH)/zzip -type d))
LOCAL_CFLAGS := -O3 $(foreach D, $(APP_SUBDIRS), -I$(LOCAL_PATH)/$(D)) \
-I$(LOCAL_PATH)/include -I$(LOCAL_PATH)/../sdl-$(SDL_VERSION)/include
LOCAL_CPP_EXTENSION := .cpp
LOCAL_SRC_FILES := $(foreach F, $(APP_SUBDIRS), $(addprefix $(F)/,$(notdir $(wildcard $(LOCAL_PATH)/$(F)/*.cpp))))
LOCAL_SRC_FILES += $(foreach F, $(APP_SUBDIRS), $(addprefix $(F)/,$(notdir $(wildcard $(LOCAL_PATH)/$(F)/*.c))))
LOCAL_SHARED_LIBRARIES := sdl-$(SDL_VERSION)
LOCAL_STATIC_LIBRARIES :=
LOCAL_LDLIBS := -llog -lz
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,481 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

1497
project/jni/zzip/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

47
project/jni/zzip/README Normal file
View File

@@ -0,0 +1,47 @@
PROJECT
The zziplib provides read access to zipped files in a zip-archive,
using compression based solely on free algorithms provided by zlib.
It also provides a functionality to overlay the archive filesystem
with the filesystem of the operating system environment.
AUTHOR
The project was originally written by Tomi Ollila, later largely
rewritten by Guido Draheim, and extended with contributions in
the years to follow. Guido Draheim <guidod@gmx.de> holds the full
copyright to the zziplib sources.
COPYING
The zziplib may be used freely under the restrictions of the
GNU Lesser General Public License version 2 or later. Alternativly
the Mozilla Public license can be chosen. The sources are under
a dual license, as long as the MPL hint is not removed, the modified
files will be again under a dual license for the final recipient.
LICENSING
If you can not use a dynalinked library according to LGPL rules,
then look at docs/copying.htm for a few hints. Generally the LGPL
has a way for staticlinking as well as the MPL has a way. Anyway,
special (paid) licenses can be negotiated with the copyright holder.
HOMEPAGE
The zziplib project is hosted at SourceForge, the complete
documentation can be found at http://zziplib.sf.net - the
SourceForge servers are also used to distribute the sources
of the zziplib project. Releases are announced via the
freshmeat services on http://freshmeat.net/projects/zziplib
INSTALLATION
The zziplib sources are built with gnu autotools and they should
be easy to install on unixish systems via the usual sequence of
`configure && make && make check && make install`. Many distributors
ship prebuilt packages e.g. in rpm format. Additionally there are
MSVC project files shipped along for usage with the Microsoft
VisualC series of compilers. There should be no problem either
when crosscompiling the zziplib for a third host platform.
MAINTAINANCE
The zziplib library is intentionally a lightweight interface to
zip files. The author take patches but please consider to put
complex extensions into separate modules rather than implanting them
right into the core of the library engine. All Patches and Bug Reports
should be sent to Guido Draheim <guidod@gmx.de>.

107
project/jni/zzip/TODO Normal file
View File

@@ -0,0 +1,107 @@
SHORTTERM
- handle international filenames more gracefully (unicode API?)
- most is multithreaded ... but zzip_dir_open (Thorsten Schöning)
- rboerdijk@ does also report errors on overlapping reads, another
one pointed to the usage of seek_set that may cause the problems
WISHLIST
- Check the CRC value at the end of read... and add more error codes.
- Do more test. Currently use only with tested "friendly" archives.
This is also related to usages of zziplib in virus detection
code which should better have a hardened library code. That does
also include inflate interface code to need the most testing.
- the buffer reusage code was not strictly multithreading. It should
be fixed by now but it would be better to have an automatic test
routine to check reentrancy/multithreaded functionality.
- Sligthly More documentation. With the generation of man pages and
multiple pages for the website, it does already look acceptable.
It should still get better of course - kinda newbie friendly *g*
- Boris Schäling likes to open a zzip archive in memory.
KNOWN PROBLEMS
The win32 compilers need each a different config.h derivate that
matches both the headers shipped with the compiler and installed
with updates of the SDK. There is no autoconfigure on win32 as
that - unless you install some unix tools along.
The sparc-sun-solaris2.* will utter warnings for "char subscript"
which is caused by isdigit() from ctype.h - this will NOT FIX as
it is only in the example source code and we want to keep those
lean and mean to make them easy to adopt by developers.
The hppa1.1-hp-hpux10.20 did show spurious problems of making
shared libraries - this may well fix with an update of the
libtool package, the libtool 1.4 is dated 2001/04/24
There are reports of misaligned access to some zip fields that
I would guess to be on little-endian non-x86 platforms. The current
bytewise access of multibyte fields is targetted towards the
bigendian unix machines. The fix would need to go to fetch.h but
so far no response came about as that one could test a solution.
There are spurious reports of users on win32 platforms that tell
of some problems with a specific zip file they have but it was
not possible so far to recreate an environment abroad to show
the problem too. One can not say if that is due some general
instability out of DLL hell, or if there is a bug hiding somewhere.
Please send all those zip files to the maintainer, perhaps it
can help to find the real cause (I doubt it is in zziplib, but..)
Since lately the xml docbook tools have hardened the checks on the
input xml that is used for manpage generation. Interestingly the
resulting manpages are still okay but one should try to fixaway the
warnings as may be later the result would lead to garbage output
due more changes in the tools. Needs to change the xml generator
used in zzip (a python script).
TESTED PLATFORMS
sparc-sun-solaris2.6/gcc2.95.3
sparc-sun-solaris2.8/gcc2.95.3
hppa1.1-hp-hpux10.20
i686-mandrake-linux-9.0/gcc3.2
i686-mandrake-linux-9.1/gcc3.2.2
i686-debian-linux-2.2/gcc2.95.2
i386-unknown-freebsd4.7/gcc2.95.4 (formerly with wrapwrap)
powerpc-apple-darwin5.5 (formerly with wrapwrap)
alphaev67-unknown-linux-gnu/gcc2.95.4 (that's a 64bit platform)
i386-ms-win32/msvc6
i386-ms-win32/msvc7
i386-ms-win32/mingw+msys
... and probably a lot of others not known to the maintainer.
Additionally, note that Sourceforge has discontinued their compilefarm
server laboratory. That makes it unlikely that proper support for
crossplatform functionality can be provided. Expect a compile problem
here or there - the code however should be prepared to get around any
problems easily. Send patches! (especially Linux distributions makers
are usually not sending their patches to upstream maintainers).
Note: the latest cross platform tests are done indirectly by using
the build.opensuse.org rpm packaging where one can run "make check"
just before doing the "make install" of the compiled library.
SUSE BUILDSERVER INFO
I: A function overflows or underflows an array access. This could be a real error,
but occasionaly this condition is also misdetected due to loop unrolling or strange pointer
handling. So this is warning only, please review.
W: zziplib arraysubscript ../../zzip/memdisk.c:114
I: File is compiled without RPM_OPT_FLAGS
W: zziplib no-rpm-opt-flags <cmdline>:../../SDL/SDL_rwops_zzcat.c, ../../SDL/SDL_rwops_zzip.c
I: Program is likely to break with new gcc. Try -fno-strict-aliasing.
W: zziplib strict-aliasing-punning ../../zzip/file.c:275
W: zziplib strict-aliasing-punning ../../zzip/fseeko.c:99, 126, 147, 158, 182, 281, 288, 301, 360, 539, 543, 546, 563
W: zziplib strict-aliasing-punning ../../zzip/memdisk.c:181, 182, 183, 185, 186, 187, 188, 189, 192, 193, 194, 195, 247, 455, 456
W: zziplib strict-aliasing-punning ../../zzip/mmapped.c:277, 289, 311, 314, 339, 340, 393, 397, 410, 438, 440, 443, 444, 549, 551, 552, 558, 559, 561
W: zziplib strict-aliasing-punning ../../zzip/zip.c:318, 320, 321, 322, 339, 341, 342, 343, 484, 485, 486, 497, 498, 499, 500, 501
E: zziplib 64bit-portability-issue ../../zzip/memdisk.c:112
System halted.

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2001 Guido Draheim <guidod@gmx.de>
* Use freely under the restrictions of the ZLIB License
*
* You should be able to drop it in the place of a SDL_RWFromFile. Then
* go to X/share/myapp and do `cd graphics && zip -9r ../graphics.zip .`
* and rename the graphics/ subfolder - and still all your files
* are found: a filepath like X/shared/graphics/game/greetings.bmp
* will open X/shared/graphics.zip and return the zipped file
* game/greetings.bmp in the zip-archive (for reading that is).
*
*/
#ifndef _SDL_RWops_ZZIP_h
#define _SDL_RWops_ZZIP_h
#include <SDL_rwops.h>
#ifndef ZZIP_NO_DECLSPEC
#define ZZIP_DECLSPEC
#else /* use DECLSPEC from SDL/begin_code.h */
#define ZZIP_DECLSPEC DECLSPEC
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern ZZIP_DECLSPEC
SDL_RWops *SDL_RWFromZZIP(const char* file, const char* mode);
#ifdef __cplusplus
} /* extern C */
#endif
#endif

View File

@@ -0,0 +1,89 @@
#ifndef __ZZIP_INTERNAL_DEBUG_H
#define __ZZIP_INTERNAL_DEBUG_H
#include <zzip/conf.h>
#include <zzip/__hints.h>
/* perhaps want to show on syslog(3) ?? */
#ifdef DEBUG
#include <stdio.h>
#define DBG1(X1) ZZIP_FOR1 { \
fprintf(stderr,"\n%s:%i:"X1"\n", ZZIP_FUNC,__LINE__ \
); } ZZIP_END1
#define DBG2(X1,X2) ZZIP_FOR1 { \
fprintf(stderr,"\n%s:%i:"X1"\n", ZZIP_FUNC,__LINE__ \
,X2);} ZZIP_END1
#define DBG3(X1,X2,X3) ZZIP_FOR1 { \
fprintf(stderr,"\n%s:%i:"X1"\n", ZZIP_FUNC,__LINE__ \
,X2,X3); } ZZIP_END1
#define DBG4(X1,X2,X3,X4) ZZIP_FOR1 { \
fprintf(stderr,"\n%s:%i:"X1"\n", ZZIP_FUNC,__LINE__ \
,X2,X3,X4); } ZZIP_END1
#define DBG5(X1,X2,X3,X4,X5) ZZIP_FOR1 { \
fprintf(stderr,"\n%s:%i:"X1"\n", ZZIP_FUNC,__LINE__ \
,X2,X3,X4,X5); } ZZIP_END1
#define DBG6(X1,X2,X3,X4,X5,X6) ZZIP_FOR1 { \
fprintf(stderr,"\n%s:%i:"X1"\n", ZZIP_FUNC,__LINE__ \
,X2,X3,X4,X5,X6); } ZZIP_END1
#else
#define DBG1(X1) {}
#define DBG2(X1,X2) {}
#define DBG3(X1,X2,X3) {}
#define DBG4(X1,X2,X3,X4) {}
#define DBG5(X1,X2,X3,X4,X5) {}
#define DBG6(X1,X2,X3,X4,X5,X6) {}
#endif
#define HINT1(X1) DBG1("HINT: " X1)
#define HINT2(X1,X2) DBG2("HINT: " X1,X2)
#define HINT3(X1,X2,X3) DBG3("HINT: " X1,X2,X3)
#define HINT4(X1,X2,X3,X4) DBG4("HINT: " X1,X2,X3,X4)
#define HINT5(X1,X2,X3,X4,X5) DBG5("HINT: " X1,X2,X3,X4,X5)
#define HINT6(X1,X2,X3,X4,X5,X6) DBG6("HINT: " X1,X2,X3,X4,X5,X6)
#define NOTE1(X1) DBG1("NOTE: " X1)
#define NOTE2(X1,X2) DBG2("NOTE: " X1,X2)
#define NOTE3(X1,X2,X3) DBG3("NOTE: " X1,X2,X3)
#define NOTE4(X1,X2,X3,X4) DBG4("NOTE: " X1,X2,X3,X4)
#define NOTE5(X1,X2,X3,X4,X5) DBG5("NOTE: " X1,X2,X3,X4,X5)
#define NOTE6(X1,X2,X3,X4,X5,X6) DBG6("NOTE: " X1,X2,X3,X4,X5,X6)
#define WARN1(X1) DBG1("WARN: " X1)
#define WARN2(X1,X2) DBG2("WARN: " X1,X2)
#define WARN3(X1,X2,X3) DBG3("WARN: " X1,X2,X3)
#define WARN4(X1,X2,X3,X4) DBG4("WARN: " X1,X2,X3,X4)
#define WARN5(X1,X2,X3,X4,X5) DBG5("WARN: " X1,X2,X3,X4,X5)
#define WARN6(X1,X2,X3,X4,X5,X6) DBG6("WARN: " X1,X2,X3,X4,X5,X6)
#define FAIL1(X1) DBG1("FAIL: " X1)
#define FAIL2(X1,X2) DBG2("FAIL: " X1,X2)
#define FAIL3(X1,X2,X3) DBG3("FAIL: " X1,X2,X3)
#define FAIL4(X1,X2,X3,X4) DBG4("FAIL: " X1,X2,X3,X4)
#define FAIL5(X1,X2,X3,X4,X5) DBG5("FAIL: " X1,X2,X3,X4,X5)
#define FAIL6(X1,X2,X3,X4,X5,X6) DBG6("FAIL: " X1,X2,X3,X4,X5,X6)
#ifdef DEBUG
_zzip_inline static void zzip_debug_xbuf (unsigned char* p, int l)
/* ZZIP_GNUC_UNUSED */
{
# define q(a) ((a&0x7F)<32?32:(a&0x7F))
while (l > 0)
{
fprintf (stderr,
"%02x %02x %02x %02x "
"%02x %02x %02x %02x "
"%c%c%c%c %c%c%c%c\n",
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
q(p[0]), q(p[1]), q(p[2]), q(p[3]),
q(p[4]), q(p[5]), q(p[6]), q(p[7]));
p += 8; l -= 8;
}
# undef q
}
#endif
#endif

View File

@@ -0,0 +1,395 @@
#ifndef ZZIP_INTERNAL_DIRENT_H
#define ZZIP_INTERNAL_DIRENT_H
#include <zzip/conf.h>
/*
* DO NOT USE THIS CODE.
*
* It is an internal header file for zziplib that carries some inline
* functions (or just static members) and a few defines, simply to be
* able to reuse these across - and have everything in a specific place.
*
* Copyright (c) 2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#ifdef ZZIP_HAVE_DIRENT_H
#define USE_DIRENT 1
#define _zzip_opendir opendir
#define _zzip_readdir readdir
#define _zzip_closedir closedir
#define _zzip_rewinddir rewinddir
#ifndef ANDROID
#define _zzip_telldir telldir
#define _zzip_seekdir seekdir
#endif
#define _zzip_DIR DIR
#include <dirent.h>
#elif defined ZZIP_HAVE_WINBASE_H
#define USE_DIRENT 2
#define _zzip_opendir win32_opendir
#define _zzip_readdir win32_readdir
#define _zzip_closedir win32_closedir
#define _zzip_rewinddir win32_rewinddir
#define _zzip_telldir win32_telldir
#define _zzip_seekdir win32_seekdir
#define _zzip_DIR DIR
/*
* DIRENT.H (formerly DIRLIB.H)
*
* by M. J. Weinstein Released to public domain 1-Jan-89
*
* Because I have heard that this feature (opendir, readdir, closedir)
* it so useful for programmers coming from UNIX or attempting to port
* UNIX code, and because it is reasonably light weight, I have included
* it in the Mingw32 package. I have also added an implementation of
* rewinddir, seekdir and telldir.
* - Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
*
* This code is distributed in the hope that is will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAMED. This includeds but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <io.h>
struct dirent
{
long d_ino; /* Always zero. */
unsigned short d_reclen; /* Always zero. */
unsigned short d_namlen; /* Length of name in d_name. */
char* d_name; /* File name. */
/* NOTE: The name in the dirent structure points to the name in the
* finddata_t structure in the DIR. */
};
/*
* This is an internal data structure. Good programmers will not use it
* except as an argument to one of the functions below.
*/
typedef struct
{
/* disk transfer area for this dir */
struct _finddata_t dd_dta;
/* dirent struct to return from dir (NOTE: this makes this thread
* safe as long as only one thread uses a particular DIR struct at
* a time) */
struct dirent dd_dir;
/* _findnext handle */
long dd_handle;
/*
* Status of search:
* 0 = not started yet (next entry to read is first entry)
* -1 = off the end
* positive = 0 based index of next entry
*/
short dd_stat;
/* given path for dir with search pattern (struct is extended) */
char dd_name[1];
} DIR;
/*
* dirent.c
*
* Derived from DIRLIB.C by Matt J. Weinstein
* This note appears in the DIRLIB.H
* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
*
* Updated by Jeremy Bettis <jeremy@hksys.com>
* Significantly revised and rewinddir, seekdir and telldir added by Colin
* Peters <colin@fu.is.saga-u.ac.jp>
*/
#include <direct.h>
#include <errno.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#define win32_SUFFIX "*"
#define win32_SLASH "\\"
#ifndef S_ISDIR
#define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) /* is a directory */
#endif S_ISDIR
/*
opendir
Returns a pointer to a DIR structure appropriately filled in to begin
searching a directory.
*/
static DIR*
win32_opendir (const char *szPath)
{
DIR *nd;
struct _stat statDir;
errno = 0;
if (!szPath) {
errno = EFAULT;
return (DIR *) 0;
}
if (szPath[0] == '\0') {
errno = ENOTDIR;
return (DIR *) 0;
}
/* Attempt to determine if the given path really is a directory. */
if (_stat (szPath, &statDir)) {
/* Error, stat should have set an error value. */
return (DIR *) 0;
}
if (!S_ISDIR (statDir.st_mode)) {
/* Error, stat reports not a directory. */
errno = ENOTDIR;
return (DIR *) 0;
}
/* Allocate enough space to store DIR structure and the complete *
directory path given. */
nd = (DIR *) calloc (1, sizeof (DIR) + strlen (szPath)
+ strlen (win32_SLASH) + strlen (win32_SUFFIX));
if (!nd) {
/* Error, out of memory. */
errno = ENOMEM;
return (DIR *) 0;
}
/* Create the search expression. */
strcpy (nd->dd_name, szPath);
/* Add on a slash if the path does not end with one. */
if (nd->dd_name[0] != '\0' &&
nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
nd->dd_name[strlen (nd->dd_name) - 1] != '\\') {
strcat (nd->dd_name, win32_SLASH);
}
/* Add on the search pattern */
strcat (nd->dd_name, win32_SUFFIX);
/* Initialize handle to -1 so that a premature closedir doesn't try * to
call _findclose on it. */
nd->dd_handle = -1;
/* Initialize the status. */
nd->dd_stat = 0;
/* Initialize the dirent structure. ino and reclen are invalid under *
Win32, and name simply points at the appropriate part of the *
findfirst_t structure. */
nd->dd_dir.d_ino = 0;
nd->dd_dir.d_reclen = 0;
nd->dd_dir.d_namlen = 0;
nd->dd_dir.d_name = nd->dd_dta.name;
return nd;
}
/*
readdir
Return a pointer to a dirent structure filled with the information on the
next entry in the directory.
*/
static struct dirent *
win32_readdir (DIR * dirp)
{
errno = 0;
/* Check for valid DIR struct. */
if (!dirp) {
errno = EFAULT;
return (struct dirent *) 0;
}
if (dirp->dd_dir.d_name != dirp->dd_dta.name) {
/* The structure does not seem to be set up correctly. */
errno = EINVAL;
return (struct dirent *) 0;
}
if (dirp->dd_stat < 0) {
/* We have already returned all files in the directory * (or the
structure has an invalid dd_stat). */
return (struct dirent *) 0;
} else if (dirp->dd_stat == 0) {
/* We haven't started the search yet. */
/* Start the search */
dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));
if (dirp->dd_handle == -1) {
/* Whoops! Seems there are no files in that * directory. */
dirp->dd_stat = -1;
} else {
dirp->dd_stat = 1;
}
} else {
/* Get the next search entry. */
if (_findnext (dirp->dd_handle, &(dirp->dd_dta))) {
/* We are off the end or otherwise error. */
_findclose (dirp->dd_handle);
dirp->dd_handle = -1;
dirp->dd_stat = -1;
} else {
/* Update the status to indicate the correct * number. */
dirp->dd_stat++;
}
}
if (dirp->dd_stat > 0) {
/* Successfully got an entry. Everything about the file is * already
appropriately filled in except the length of the * file name. */
dirp->dd_dir.d_namlen = (unsigned short) strlen (dirp->dd_dir.d_name);
return &dirp->dd_dir;
}
return (struct dirent *) 0;
}
/*
closedir
Frees up resources allocated by opendir.
*/
static int
win32_closedir (DIR * dirp)
{
int rc;
errno = 0;
rc = 0;
if (!dirp) {
errno = EFAULT;
return -1;
}
if (dirp->dd_handle != -1) {
rc = _findclose (dirp->dd_handle);
}
/* Delete the dir structure. */
free (dirp);
return rc;
}
/*
rewinddir
Return to the beginning of the directory "stream". We simply call findclose
and then reset things like an opendir.
*/
static void
win32_rewinddir (DIR * dirp)
{
errno = 0;
if (!dirp) {
errno = EFAULT;
return;
}
if (dirp->dd_handle != -1) {
_findclose (dirp->dd_handle);
}
dirp->dd_handle = -1;
dirp->dd_stat = 0;
}
/*
telldir
Returns the "position" in the "directory stream" which can be used with
seekdir to go back to an old entry. We simply return the value in stat.
*/
static long
win32_telldir (DIR * dirp)
{
errno = 0;
if (!dirp) {
errno = EFAULT;
return -1;
}
return dirp->dd_stat;
}
/*
seekdir
Seek to an entry previously returned by telldir. We rewind the directory
and call readdir repeatedly until either dd_stat is the position number
or -1 (off the end). This is not perfect, in that the directory may
have changed while we weren't looking. But that is probably the case with
any such system.
*/
static void
win32_seekdir (DIR * dirp, long lPos)
{
errno = 0;
if (!dirp) {
errno = EFAULT;
return;
}
if (lPos < -1) {
/* Seeking to an invalid position. */
errno = EINVAL;
return;
} else if (lPos == -1) {
/* Seek past end. */
if (dirp->dd_handle != -1) {
_findclose (dirp->dd_handle);
}
dirp->dd_handle = -1;
dirp->dd_stat = -1;
} else {
/* Rewind and read forward to the appropriate index. */
win32_rewinddir (dirp);
while ((dirp->dd_stat < lPos) && win32_readdir (dirp));
}
}
#else
#define USE_DIRENT 0
#define _zzip_opendir(_N_) 0
#define _zzip_readdir(_D_) 0
#define _zzip_closedir(_D_) /* omit return code */
#define _zzip_rewinddir(_D_)
#define _zzip_telldir(_D_) 0
#define _zzip_seekdir(_D_,_V_) /* omit return code */
#define _zzip_DIR void*
/* end of DIRENT implementation */
#endif
/* once */
#endif

View File

@@ -0,0 +1,29 @@
#ifndef __ZZIP_INTERNAL_FNMATCH_H
#define __ZZIP_INTERNAL_FNMATCH_H
/** included by fseeko.c, mmapped.c, memdisk.c */
#include <zzip/conf.h>
#include <stdio.h>
#ifdef ZZIP_HAVE_FNMATCH_H
#include <fnmatch.h>
#endif
#ifdef ZZIP_HAVE_FNMATCH_H
#define _zzip_fnmatch fnmatch
# ifdef FNM_CASEFOLD
# define _zzip_fnmatch_CASEFOLD FNM_CASEFOLD
# else
# define _zzip_fnmatch_CASEFOLD 0
# endif
#else
# define _zzip_fnmatch_CASEFOLD 0
/* if your system does not have fnmatch, we fall back to strcmp: */
static int _zzip_fnmatch(char* pattern, char* string, int flags)
{
fprintf (stderr, "<zzip:mmapped:strcmp>");
return strcmp (pattern, string);
}
#endif
#endif

View File

@@ -0,0 +1,195 @@
#ifndef __ZZIP_INTERNAL_HINTS_H
#define __ZZIP_INTERNAL_HINTS_H
#include <zzip/conf.h>
#ifndef ZZIP_GNUC_ATLEAST
# if defined __GNUC__ && defined __GNUC_MINOR__
# define ZZIP_GNUC_ATLEAST(_M_,_N_) \
((__GNUC__ << 10) + __GNUC_MINOR__ >= ((_M_) << 10) + (_N_))
# elif defined __GNUC__
# define ZZIP_GNUC_ATLEAST(_M_,_N_) \
((__GNUC__ << 10) >= ((_M_) << 10))
# else
# define ZZIP_GNUC_ATLEAST(_M_, _N_) 0
# endif
#endif
#ifndef ZZIP_GNUC_EXTENSION
# if ZZIP_GNUC_ATLEAST(2,8)
# define ZZIP_GNUC_EXTENSION __extension__
# else
# define ZZIP_GNUC_EXTENSION
# endif
#endif
/* func has no side effects, return value depends only on params and globals */
#ifndef ZZIP_GNUC_PURE
# if ZZIP_GNUC_ATLEAST(2,8)
# define ZZIP_GNUC_PURE __attribute__((__pure__))
# else
# define ZZIP_GNUC_PURE
# endif
#endif
/* func has no side effects, return value depends only on params */
#ifndef ZZIP_GNUC_CONST
# if ZZIP_GNUC_ATLEAST(2,4)
# define ZZIP_GNUC_CONST __attribute__((__const__))
# else
# define ZZIP_GNUC_CONST
# endif
#endif
/* typename / variable / function possibly unused */
#ifndef ZZIP_GNUC_UNUSED
# if ZZIP_GNUC_ATLEAST(2,4)
# define ZZIP_GNUC_UNUSED __attribute__((__unused__))
# else
# define ZZIP_GNUC_UNUSED
# endif
#endif
/* obvious. btw, a noreturn-func should return void */
#ifndef ZZIP_GNUC_NORETURN
# if ZZIP_GNUC_ATLEAST(2,5)
# define ZZIP_GNUC_NORETURN __attribute__((__noreturn__))
# else
# define ZZIP_GNUC_NORETURN
# endif
#endif
/* omit function from profiling with -finstrument-functions */
#ifndef ZZIP_GNUC_NO_INSTRUMENT
# if ZZIP_GNUC_ATLEAST(2,4)
# define ZZIP_GNUC_NO_INSTRUMENT __attribute__((__no_instrument_function__))
# else
# define ZZIP_GNUC_NO_INSTRUMENT
# endif
#endif
/* all pointer args must not be null, and allow optimiztons based on the fact*/
#ifndef ZZIP_GNUC_NONNULL
# if ZZIP_GNUC_ATLEAST(3,1)
# define ZZIP_GNUC_NONNULL __attribute__((nonnull))
# else
# define ZZIP_GNUC_NONNULL
# endif
#endif
/* the function can not throw - the libc function are usually nothrow */
#ifndef ZZIP_GNUC_NOTHROW
# if ZZIP_GNUC_ATLEAST(3,2)
# define ZZIP_GNUC_NOTHROW __attribute__((nothrow))
# else
# define ZZIP_GNUC_NOTHROW
# endif
#endif
/* typename / function / variable is obsolete but still listed in headers */
#ifndef ZZIP_GNUC_DEPRECATED
# if ZZIP_GNUC_ATLEAST(3,1)
# define ZZIP_GNUC_DEPRECATED __attribute__((deprecated))
# else
# define ZZIP_GNUC_DEPRECATED
# endif
#endif
/* resolve references to this function during pre-linking the libary */
#ifndef ZZIP_GNUC_LIB_PROTECTED
# if ZZIP_GNUC_ATLEAST(3,1)
# define ZZIP_GNUC_LIB_PROTECTED __attribute__((visiblity("protected")))
# else
# define ZZIP_GNUC_LIB_PROTECTED
# endif
#endif
/* func shall only be usable within the same lib (so, no entry in lib symtab)*/
#ifndef ZZIP_GNUC_LIB_PRIVATE
# if ZZIP_GNUC_ATLEAST(3,1)
# define ZZIP_GNUC_LIB_PRIVATE __attribute__((visiblity("hidden")))
# else
# define ZZIP_GNUC_LIB_PRIVATE
# endif
#endif
/* ... and not even passed as a function pointer reference to outside the lib*/
#ifndef ZZIP_GNUC_LIB_INTERNAL
# if ZZIP_GNUC_ATLEAST(3,1)
# define ZZIP_GNUC_LIB_INTERNAL __attribute__((visiblity("internal")))
# else
# define ZZIP_GNUC_LIB_INTERNAL
# endif
#endif
#ifndef ZZIP_GNUC_FORMAT
# if ZZIP_GNUC_ATLEAST(2,4)
# define ZZIP_GNUC_FORMAT(_X_) __attribute__((__format_arg__(_X_)))
# else
# define ZZIP_GNUC_FORMAT(_X_)
# endif
#endif
#ifndef ZZIP_GNUC_SCANF
# if ZZIP_GNUC_ATLEAST(2,4)
# define ZZIP_GNUC_SCANF(_S_,_X_) __attribute__((__scanf__(_S_,_X_)))
# else
# define ZZIP_GNUC_SCANF(_S_,_X_)
# endif
#endif
#ifndef ZZIP_GNUC_PRINTF
# if ZZIP_GNUC_ATLEAST(2,4)
# define ZZIP_GNUC_PRINTF(_S_,_X_) __attribute__((__printf__(_S_,_X_)))
# else
# define ZZIP_GNUC_PRINTF(_S_,_X_)
# endif
#endif
#ifdef __GNUC__
#define ZZIP_GNUC_PACKED __attribute__((packed))
#else
#define ZZIP_GNUC_PACKED
#endif
#ifndef ZZIP_FUNCTION
# if ZZIP_GNUC_ATLEAST(2,6)
# define ZZIP_FUNC __FUNCTION__
# define ZZIP_FUNCTION __FUNCTION__
# elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
# define ZZIP_FUNC __func__
# define ZZIP_FUNCTION ""
# else
# define ZZIP_FUNC 0
# define ZZIP_FUNCTION ""
# endif
#endif
#ifndef ZZIP_STRING
#define ZZIP_STRING(_X_) ZZIP_STRING_(_X_)
#define ZZIP_STRING_(_Y_) #_Y_
#endif
#ifndef ZZIP_DIM
#define ZZIP_DIM(_A_) (sizeof(_A_) / sizeof ((_A_)[0]))
#endif
#if !(defined ZZIP_FOR1 && defined ZZIP_END1)
# if defined sun || defined __sun__
# define ZZIP_FOR1 if (1)
# define ZZIP_END1 else (void)0
# else
# define ZZIP_FOR1 do
# define ZZIP_END1 while (0)
# endif
#endif
#ifndef ZZIP_BRANCH_OVER
# if ZZIP_GNUC_ATLEAST(2,96)
# define ZZIP_BRANCH_OVER(_X_) __builtin_expect((_X_),0)
# else
# define ZZIP_BRANCH_OVER(_X_) (_X_)
# endif
#endif
#endif

View File

@@ -0,0 +1,107 @@
#ifndef __ZZIP_INTERNAL_MMAP_H
#define __ZZIP_INTERNAL_MMAP_H
#include <zzip/types.h>
/*
* DO NOT USE THIS CODE.
*
* It is an internal header file for zziplib that carries some inline
* functions (or just static members) and a few defines, simply to be
* able to reuse these across - and have everything in a specific place.
*
* Copyright (c) 2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#ifdef _USE_MMAP
#if defined ZZIP_HAVE_SYS_MMAN_H
#include <sys/mman.h>
#define USE_POSIX_MMAP 1
#elif defined ZZIP_HAVE_WINBASE_H || defined WIN32
#include <windows.h>
#define USE_WIN32_MMAP 1
#else
#undef _USE_MMAP
#endif
#endif
/* -------------- specify MMAP function imports --------------------------- */
#if defined USE_POSIX_MMAP
#define USE_MMAP 1
#define _zzip_mmap(user, fd, offs, len) \
mmap (0, len, PROT_READ, MAP_SHARED, fd, offs)
#define _zzip_munmap(user, ptr, len) \
munmap (ptr, len)
#define _zzip_getpagesize(user) getpagesize()
#ifndef MAP_FAILED /* hpux10.20 does not have it */
#define MAP_FAILED ((void*)(-1))
#endif
#elif defined USE_WIN32_MMAP
#define USE_MMAP 1
#ifndef MAP_FAILED
#define MAP_FAILED 0
#endif
/* we (ab)use the "*user" variable to store the FileMapping handle */
/* which assumes (sizeof(long) == sizeof(HANDLE)) */
static size_t win32_getpagesize (void)
{
SYSTEM_INFO si; GetSystemInfo (&si);
return si.dwAllocationGranularity;
}
static void* win32_mmap (long* user, int fd, zzip_off_t offs, size_t len)
{
if (! user || *user != 1) /* || offs % getpagesize() */
return 0;
{
HANDLE hFile = (HANDLE)_get_osfhandle(fd);
if (hFile)
*user = (int) CreateFileMapping (hFile, 0, PAGE_READONLY, 0, 0, NULL);
if (*user)
{
char* p = 0;
p = MapViewOfFile(*(HANDLE*)user, FILE_MAP_READ, 0, offs, len);
if (p) return p + offs;
CloseHandle (*(HANDLE*)user); *user = 1;
}
return MAP_FAILED;
}
}
static void win32_munmap (long* user, char* fd_map, size_t len)
{
UnmapViewOfFile (fd_map);
CloseHandle (*(HANDLE*)user); *user = 1;
}
#define _zzip_mmap(user, fd, offs, len) \
win32_mmap ((long*) &(user), fd, offs, len)
#define _zzip_munmap(user, ptr, len) \
win32_munmap ((long*) &(user), ptr, len)
#define _zzip_getpagesize(user) win32_getpagesize()
#else /* disable */
#define USE_MMAP 0
/* USE_MAP is intentional: we expect the compiler to do some "code removal"
* on any source code enclosed in if (USE_MMAP) {...} i.e. the unreachable
* branch of an if (0) {....} is not emitted to the final object binary. */
#ifndef MAP_FAILED
#define MAP_FAILED 0
#endif
#define _zzip_mmap(user, fd, offs, len) (MAP_FAILED)
#define _zzip_munmap(user, ptr, len) {}
#define _zzip_getpagesize(user) 1
#endif /* USE_MMAP defines */
#endif

View File

@@ -0,0 +1,252 @@
#ifndef _ZZIP__CONFIG_H
#define _ZZIP__CONFIG_H 1
/* zzip/_config.h. Generated automatically at end of configure. */
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define if pointers to integers require aligned access */
#define HAVE_ALIGNED_ACCESS_REQUIRED 1
/* Define to 1 if you have the <byteswap.h> header file. */
#ifndef ZZIP_HAVE_BYTESWAP_H
#define ZZIP_HAVE_BYTESWAP_H 1
#endif
/* Define to 1 if you have the <direct.h> header file. */
/* #undef HAVE_DIRECT_H */
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#ifndef ZZIP_HAVE_DIRENT_H
#define ZZIP_HAVE_DIRENT_H 1
#endif
/* Define to 1 if you have the <dlfcn.h> header file. */
#ifndef ZZIP_HAVE_DLFCN_H
#define ZZIP_HAVE_DLFCN_H 1
#endif
/* Define to 1 if you have the <fnmatch.h> header file. */
#ifndef ZZIP_HAVE_FNMATCH_H
#define ZZIP_HAVE_FNMATCH_H 1
#endif
/* Define to 1 if you have the <inttypes.h> header file. */
#ifndef ZZIP_HAVE_INTTYPES_H
#define ZZIP_HAVE_INTTYPES_H 1
#endif
/* Define to 1 if you have the <io.h> header file. */
/* #undef HAVE_IO_H */
/* Define to 1 if you have the <memory.h> header file. */
#ifndef ZZIP_HAVE_MEMORY_H
#define ZZIP_HAVE_MEMORY_H 1
#endif
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the <stdint.h> header file. */
#ifndef ZZIP_HAVE_STDINT_H
#define ZZIP_HAVE_STDINT_H 1
#endif
/* Define to 1 if you have the <stdlib.h> header file. */
#ifndef ZZIP_HAVE_STDLIB_H
#define ZZIP_HAVE_STDLIB_H 1
#endif
/* Define to 1 if you have the `strcasecmp' function. */
#ifndef ZZIP_HAVE_STRCASECMP
#define ZZIP_HAVE_STRCASECMP 1
#endif
/* Define to 1 if you have the <strings.h> header file. */
#ifndef ZZIP_HAVE_STRINGS_H
#define ZZIP_HAVE_STRINGS_H 1
#endif
/* Define to 1 if you have the <string.h> header file. */
#ifndef ZZIP_HAVE_STRING_H
#define ZZIP_HAVE_STRING_H 1
#endif
/* Define to 1 if you have the `strndup' function. */
#ifndef ZZIP_HAVE_STRNDUP
#define ZZIP_HAVE_STRNDUP 1
#endif
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_DIR_H */
/* Define to 1 if you have the <sys/int_types.h> header file. */
/* #undef HAVE_SYS_INT_TYPES_H */
/* Define to 1 if you have the <sys/mman.h> header file. */
#ifndef ZZIP_HAVE_SYS_MMAN_H
#define ZZIP_HAVE_SYS_MMAN_H 1
#endif
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
/* Define to 1 if you have the <sys/param.h> header file. */
#ifndef ZZIP_HAVE_SYS_PARAM_H
#define ZZIP_HAVE_SYS_PARAM_H 1
#endif
/* Define to 1 if you have the <sys/stat.h> header file. */
#ifndef ZZIP_HAVE_SYS_STAT_H
#define ZZIP_HAVE_SYS_STAT_H 1
#endif
/* Define to 1 if you have the <sys/types.h> header file. */
#ifndef ZZIP_HAVE_SYS_TYPES_H
#define ZZIP_HAVE_SYS_TYPES_H 1
#endif
/* Define to 1 if you have the <unistd.h> header file. */
#ifndef ZZIP_HAVE_UNISTD_H
#define ZZIP_HAVE_UNISTD_H 1
#endif
/* Define to 1 if you have the <winbase.h> header file. */
/* #undef HAVE_WINBASE_H */
/* Define to 1 if you have the <windows.h> header file. */
/* #undef HAVE_WINDOWS_H */
/* Define to 1 if you have the <winnt.h> header file. */
/* #undef HAVE_WINNT_H */
/* Define to 1 if you have the <zlib.h> header file. */
#ifndef ZZIP_HAVE_ZLIB_H
#define ZZIP_HAVE_ZLIB_H 1
#endif
/* whether the system defaults to 32bit off_t but can do 64bit when requested
*/
/* #undef LARGEFILE_SENSITIVE */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#ifndef ZZIP_LT_OBJDIR
#define ZZIP_LT_OBJDIR ".libs/"
#endif
/* Name of package */
#ifndef ZZIP_PACKAGE
#define ZZIP_PACKAGE "zziplib"
#endif
/* Define to the address where bug reports for this package should be sent. */
#ifndef ZZIP_PACKAGE_BUGREPORT
#define ZZIP_PACKAGE_BUGREPORT ""
#endif
/* Define to the full name of this package. */
#ifndef ZZIP_PACKAGE_NAME
#define ZZIP_PACKAGE_NAME ""
#endif
/* Define to the full name and version of this package. */
#ifndef ZZIP_PACKAGE_STRING
#define ZZIP_PACKAGE_STRING ""
#endif
/* Define to the one symbol short name of this package. */
#ifndef ZZIP_PACKAGE_TARNAME
#define ZZIP_PACKAGE_TARNAME ""
#endif
/* Define to the version of this package. */
#ifndef ZZIP_PACKAGE_VERSION
#define ZZIP_PACKAGE_VERSION ""
#endif
/* The number of bytes in type int */
#ifndef ZZIP_SIZEOF_INT
#define ZZIP_SIZEOF_INT 4
#endif
/* The number of bytes in type long */
#ifndef ZZIP_SIZEOF_LONG
#define ZZIP_SIZEOF_LONG 8
#endif
/* The number of bytes in type short */
#ifndef ZZIP_SIZEOF_SHORT
#define ZZIP_SIZEOF_SHORT 2
#endif
/* Define to 1 if you have the ANSI C header files. */
#ifndef ZZIP_STDC_HEADERS
#define ZZIP_STDC_HEADERS 1
#endif
/* Version number of package */
#ifndef ZZIP_VERSION
#define ZZIP_VERSION "0.13.59"
#endif
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* Define to `long long' if <sys/types.h> does not define. */
#ifndef ZZIP___int64
#define ZZIP___int64 long long
#endif
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to `_zzip_off_t' if <sys/types.h> does not define. */
#ifndef _zzip_off64_t
#define _zzip_off64_t _zzip_off_t
#endif
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
supported. Do not define if restrict is supported directly. */
#ifndef _zzip_restrict
#define _zzip_restrict __restrict__
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
/* once: _ZZIP__CONFIG_H */
#endif

View File

@@ -0,0 +1,229 @@
#ifndef _ZZIP__MSVC_H
#define _ZZIP__MSVC_H 1
/* zzip/_msvc.h. Generated automatically at end of configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define if pointers to integers require aligned access */
/* #undef HAVE_ALIGNED_ACCESS_REQUIRED */
/* Define to 1 if you have the <byteswap.h> header file. */
/* #undef HAVE_BYTESWAP_H */
/* Define to 1 if you have the <direct.h> header file. */
#ifndef ZZIP_HAVE_DIRECT_H
#define ZZIP_HAVE_DIRECT_H 1
#endif
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_DIRENT_H */
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the <fnmatch.h> header file. */
/* #undef HAVE_FNMATCH_H */
/* Define to 1 if you have the <inttypes.h> header file. */
/* #undef HAVE_INTTYPES_H */
/* Define to 1 if you have the <io.h> header file. */
#ifndef ZZIP_HAVE_IO_H
#define ZZIP_HAVE_IO_H 1
#endif
/* Define to 1 if you have the <memory.h> header file. */
#ifndef ZZIP_HAVE_MEMORY_H
#define ZZIP_HAVE_MEMORY_H 1
#endif
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the <stdint.h> header file. */
/* #undef HAVE_STDINT_H */
/* Define to 1 if you have the <stdlib.h> header file. */
#ifndef ZZIP_HAVE_STDLIB_H
#define ZZIP_HAVE_STDLIB_H 1
#endif
/* Define to 1 if you have the `strcasecmp' function. */
/* #undef HAVE_STRCASECMP */
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#ifndef ZZIP_HAVE_STRING_H
#define ZZIP_HAVE_STRING_H 1
#endif
/* Define to 1 if you have the `strndup' function. */
/* #undef HAVE_STRNDUP */
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_DIR_H */
/* Define to 1 if you have the <sys/int_types.h> header file. */
/* #undef HAVE_SYS_INT_TYPES_H */
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H */
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
/* Define to 1 if you have the <sys/param.h> header file. */
/* #undef HAVE_SYS_PARAM_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#ifndef ZZIP_HAVE_SYS_STAT_H
#define ZZIP_HAVE_SYS_STAT_H 1
#endif
/* Define to 1 if you have the <sys/types.h> header file. */
#ifndef ZZIP_HAVE_SYS_TYPES_H
#define ZZIP_HAVE_SYS_TYPES_H 1
#endif
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define to 1 if you have the <winbase.h> header file. */
#ifndef ZZIP_HAVE_WINBASE_H
#define ZZIP_HAVE_WINBASE_H 1 /* hmm, is that win32 ? */
#endif
/* Define to 1 if you have the <windows.h> header file. */
#ifndef ZZIP_HAVE_WINDOWS_H
#define ZZIP_HAVE_WINDOWS_H 1 /* yes, this is windows */
#endif
/* Define to 1 if you have the <winnt.h> header file. */
#ifndef ZZIP_HAVE_WINNT_H
#define ZZIP_HAVE_WINNT_H 1 /* is that always true? */
#endif
/* Define to 1 if you have the <zlib.h> header file. */
#ifndef ZZIP_HAVE_ZLIB_H
#define ZZIP_HAVE_ZLIB_H 1 /* you do have it, right? */
#endif
/* whether the system defaults to 32bit off_t but can do 64bit when requested
*/
/* #undef LARGEFILE_SENSITIVE */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/* #undef LT_OBJDIR */
/* Name of package */
#ifndef ZZIP_PACKAGE
#define ZZIP_PACKAGE "zziplib-msvc" /* yes, make it known */
#endif
/* Define to the address where bug reports for this package should be sent. */
/* #undef PACKAGE_BUGREPORT */
/* Define to the full name of this package. */
/* #undef PACKAGE_NAME */
/* Define to the full name and version of this package. */
/* #undef PACKAGE_STRING */
/* Define to the one symbol short name of this package. */
/* #undef PACKAGE_TARNAME */
/* Define to the version of this package. */
/* #undef PACKAGE_VERSION */
/* The number of bytes in type int */
#ifndef ZZIP_SIZEOF_INT
#define ZZIP_SIZEOF_INT 4
#endif
/* The number of bytes in type long */
#ifndef ZZIP_SIZEOF_LONG
#define ZZIP_SIZEOF_LONG 4
#endif
/* The number of bytes in type short */
#ifndef ZZIP_SIZEOF_SHORT
#define ZZIP_SIZEOF_SHORT 2
#endif
/* Define to 1 if you have the ANSI C header files. */
#ifndef ZZIP_STDC_HEADERS
#define ZZIP_STDC_HEADERS 1
#endif
/* Version number of package */
#ifndef ZZIP_VERSION
#define ZZIP_VERSION "0.13.x"
#endif
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* Define to `long long' if <sys/types.h> does not define. */
/* #undef __int64 */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#ifndef _zzip_inline
#define _zzip_inline __inline
#endif
#endif
/* Define to `_zzip_off_t' if <sys/types.h> does not define. */
#ifndef _zzip_off64_t
#define _zzip_off64_t __int64
#endif
/* Define to `long int' if <sys/types.h> does not define. */
#ifndef _zzip_off_t
#define _zzip_off_t long
#endif
/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
supported. Do not define if restrict is supported directly. */
#ifndef _zzip_restrict
#define _zzip_restrict
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
#ifndef _zzip_ssize_t
#define _zzip_ssize_t int
#endif
/* once: _ZZIP__MSVC_H */
#endif

View File

@@ -0,0 +1,45 @@
#ifndef _ZZIP_AUTOCONF_H_
#define _ZZIP_AUTOCONF_H_ 1
/*
* This file is trying to override configure time checks of zzip with
* definitions at compile time. This is not used by zzip sources themselves
* but it may be really helpful with thirdparty software that happens to
* include zzip headers from a central place but running on a different host.
*/
#include "conf.h" /* <zzip/conf.h> : <zzip/_config.h> */
#if defined HAVE_ENDIAN_H || defined ZZIP_HAVE_ENDIAN_H
#include <endian.h> /* glibc */
#elif defined HAVE_SYS_PARAM_H || defined ZZIP_HAVE_SYS_PARAM_H
#include <sys/param.h> /* solaris */
#endif
#if defined __BYTE_ORDER
#define ZZIP_BYTE_ORDER __BYTE_ORDER
#elif defined BYTE_ORDER
#define ZZIP_BYTE_ORDER BYTE_ORDER
#elif defined _LITTLE_ENDIAN
#define ZZIP_BYTE_ORDER 1234
#elif defined _BIG_ENDIAN
#define ZZIP_BYTE_ORDER 4321
#elif defined __i386__
#define ZZIP_BYTE_ORDER 1234
#elif defined WORDS_BIGENDIAN || defined ZZIP_WORDS_BIGENDIAN
#define ZZIP_BYTE_ORDER 4321
#else
#define ZZIP_BYTE_ORDER 1234
#endif
/* override ZZIP_WORDS_BIGENDIAN : macros ZZIP_GET16 / ZZIP_GET32 */
#ifdef ZZIP_BYTE_ORDER+0 == 1234
#undef ZZIP_WORDS_BIGENDIAN
#endif
#ifdef ZZIP_BYTE_ORDER+0 == 4321
#ifndef ZZIP_WORDS_BIGENDIAN
#define ZZIP_WORDS_BIGENDIAN 1
#endif
#endif
#endif

View File

@@ -0,0 +1,264 @@
/*
* Here we postprocess autoconf generated prefix-config.h entries.
* This is generally for things like "off_t" which is left undefined
* in plain config.h if the host system does already have it but we do
* need the prefix variant - so we add here a #define _zzip_off_t off_t
*
* This file is supposed to only carry '#define's.
* See <zzip/types.h> for definitions that might be seen by the compiler.
*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2001,2002,2003,2004 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#ifndef _ZZIP_CONF_H
#define _ZZIP_CONF_H 1
#if !defined ZZIP_OMIT_CONFIG_H
# if defined _MSC_VER || defined __BORLANDC__ || defined __WATCOMC__
# include <zzip/_msvc.h>
# elif defined ZZIP_1_H
# include "zzip-1.h"
# elif defined ZZIP_2_H
# include "zzip-2.h"
# elif defined ZZIP_3_H
# include "zzip-3.h"
# elif defined ZZIP_4_H
# include "zzip-4.h"
# elif defined ZZIP_5_H
# include "zzip-5.h"
# else /* autoconf generated */
# include <zzip/_config.h>
# endif
#endif
/* especially win32 platforms do not declare off_t so far - see zzip-msvc.h */
#ifndef _zzip_off_t
#ifdef ZZIP_off_t
#define _zzip_off_t ZZIP_off_t
#else
#define _zzip_off_t off_t
#endif
#endif
#ifndef _zzip_off64_t
#ifdef ZZIP_off64_t
#define _zzip_off64_t ZZIP_off64_t
#else
#define _zzip_off64_t off64_t
#endif
#endif
/* currently unused, all current zziplib-users do have ansi-C94 compilers. */
#ifndef _zzip_const
#ifdef ZZIP_const
#define _zzip_const ZZIP_const
#else
#define _zzip_const const
#endif
#endif
#ifndef _zzip_inline
#ifdef ZZIP_inline
#define _zzip_inline ZZIP_inline
#else
#define _zzip_inline inline
#endif
#endif
#ifndef _zzip_restrict
#ifdef ZZIP_restrict
#define _zzip_restrict ZZIP_restrict
#else
#define _zzip_restrict restrict
#endif
#endif
#if defined __linux__ && __GNUC__+0 >= 4
#define zzip__new__ __attribute__((malloc))
#elif defined __linux__ && __GNUC__+0 >= 3 && __GNUC_MINOR_+0 >= 3
#define zzip__new__ __attribute__((malloc))
#else
#define zzip__new__
#endif
#ifndef _zzip_size_t
#ifdef ZZIP_size_t
#define _zzip_size_t ZZIP_size_t
#else
#define _zzip_size_t size_t
#endif
#endif
#ifndef _zzip_ssize_t
#ifdef ZZIP_ssize_t
#define _zzip_ssize_t ZZIP_ssize_t
#else
#define _zzip_ssize_t ssize_t
#endif
#endif
#ifndef _zzip___int64
#ifdef ZZIP___int64
#define _zzip___int64 ZZIP___int64
#else
#define _zzip___int64 long long
#endif
#endif
/* whether this library shall use a 64bit off_t largefile variant in 64on32: */
/* (some exported names must be renamed to avoid bad calls after linking) */
#if defined ZZIP_LARGEFILE_SENSITIVE
# if _FILE_OFFSET_BITS+0 == 64
# define ZZIP_LARGEFILE_RENAME
# elif defined _LARGE_FILES /* used on older AIX to get at 64bit off_t */
# define ZZIP_LARGEFILE_RENAME
# elif defined _ZZIP_LARGEFILE /* or simply use this one for zzip64 runs */
# define ZZIP_LARGEFILE_RENAME
# endif
#endif
/* if the environment did not setup these for 64bit off_t largefile... */
#ifdef ZZIP_LARGEFILE_RENAME
# ifndef _FILE_OFFSET_BITS
# ifdef ZZIP__FILE_OFFSET_BITS /* == 64 */
# define _FILE_OFFSET_BITS ZZIP__FILE_OFFSET_BITS
# endif
# endif
# ifndef _LARGE_FILES
# ifdef ZZIP__LARGE_FILES /* == 1 */
# define _LARGE_FILES ZZIP__LARGE_FILES
# endif
# endif
# ifndef _LARGEFILE_SOURCE
# ifdef ZZIP__LARGEFILE_SOURCE /* == 1 */
# define _LARGEFILE_SOURCE ZZIP__LARGEFILE_SOURCE
# endif
# endif
#endif
#include <errno.h>
/* mingw32msvc errno : would be in winsock.h */
#ifndef EREMOTE
#define EREMOTE ESPIPE
#endif
#ifndef ELOOP
#if defined EILSEQ
#define ELOOP EILSEQ
#else
#define ELOOP ENOEXEC
#endif
#endif
#if defined __WATCOMC__
#undef _zzip_inline
#define _zzip_inline static
#endif
#if defined _MSC_VER || defined __WATCOMC__
#include <io.h>
#endif
#ifdef _MSC_VER
# if !__STDC__
# ifndef _zzip_lseek
# define _zzip_lseek _lseek
# endif
# ifndef _zzip_read
# define _zzip_read _read
# endif
# ifndef _zzip_write
# define _zzip_write _write
# endif
# if 0
# ifndef _zzip_stat
# define _zzip_stat _stat
# endif
# endif
# endif /* !__STDC__ */
#endif
/*MSVC*/
#if defined _MSC_VER || defined __WATCOMC__
# ifndef strcasecmp
# define strcasecmp _stricmp
# endif
#endif
# ifndef _zzip_lseek
# define _zzip_lseek lseek
# endif
# ifndef _zzip_read
# define _zzip_read read
# endif
# ifndef _zzip_write
# define _zzip_write write
# endif
# if 0
# ifndef _zzip_stat
# define _zzip_stat stat
# endif
# endif
#if defined ZZIP_EXPORTS || defined ZZIPLIB_EXPORTS
# undef ZZIP_DLL
#define ZZIP_DLL 1
#endif
/* based on zconf.h : */
/* compile with -DZZIP_DLL for Windows DLL support */
#if defined ZZIP_DLL
# if defined _WINDOWS || defined WINDOWS || defined _WIN32
/*# include <windows.h>*/
# endif
# if !defined _zzip_export && defined _MSC_VER && (defined WIN32 || defined _WIN32)
# define _zzip_export __declspec(dllexport) /*WINAPI*/
# endif
# if !defined _zzip_export && defined __BORLANDC__
# if __BORLANDC__ >= 0x0500 && defined WIN32
# include <windows.h>
# define _zzip_export __declspec(dllexport) /*WINAPI*/
# else
# if defined _Windows && defined __DLL__
# define _zzip_export _export
# endif
# endif
# endif
# if !defined _zzip_export && defined __GNUC__
# if defined __declspec
# define _zzip_export extern __declspec(dllexport)
# else
# define _zzip_export extern
# endif
# endif
# if !defined _zzip_export && defined __BEOS__
# define _zzip_export extern __declspec(export)
# endif
# if !defined _zzip_export && defined __WATCOMC__
# define _zzip_export extern __declspec(dllexport)
# define ZEXPORT __syscall
# define ZEXTERN extern
# endif
#endif
#if !defined _zzip_export
# if defined __GNUC__ /* || !defined HAVE_LIBZZIP */
# define _zzip_export extern
# elif defined __declspec || (defined _MSC_VER && defined ZZIP_DLL)
# define _zzip_export extern __declspec(dllimport)
# else
# define _zzip_export extern
# endif
#endif
#endif

View File

@@ -0,0 +1,374 @@
#ifndef _ZZIP_FORMATS_H
#define _ZZIP_FORMATS_H
#include <zzip/types.h>
#include <zzip/format.h>
#include <zzip/stdint.h>
#include <zzip/__hints.h>
/* linux knows "byteswap.h" giving us an optimized variant */
#ifdef ZZIP_HAVE_BYTESWAP_H
#include <byteswap.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* get 16/32 bits from little-endian zip-file to host byteorder */
extern uint32_t __zzip_get32(zzip_byte_t * s) ZZIP_GNUC_CONST;
extern uint16_t __zzip_get16(zzip_byte_t * s) ZZIP_GNUC_CONST;
extern void __zzip_set32(zzip_byte_t * s, uint32_t v);
extern void __zzip_set16(zzip_byte_t * s, uint16_t v);
extern uint64_t __zzip_get64(zzip_byte_t * s) ZZIP_GNUC_CONST;
extern void __zzip_set64(zzip_byte_t * s, uint64_t v);
/* just in case that you use a non-configure-d setup (e.g. MSVC) */
#ifndef ZZIP_HAVE_ALIGNED_ACCESS_REQUIRED
# if defined __mips__ || defined __sparc__ || defined __powerpc__ || defined __arm__ || defined __ia64__
# define ZZIP_HAVE_ALIGNED_ACCESS_REQUIRED 11
# endif
#endif
/* on linux with a cisc processor we can use the bswap for some extra speed */
#ifdef ZZIP_WORDS_BIGENDIAN
# ifndef ZZIP_HAVE_ALIGNED_ACCESS_REQUIRED
# if defined bswap_16 && defined bswap_32 && defined bswap_64 /* i.e. linux */
# define _ZZIP_USE_BSWAP
# endif
# endif
#endif
/* little endian on intel cisc processors is the original zip format byteorder */
#ifndef ZZIP_WORDS_BIGENDIAN
# ifndef ZZIP_HAVE_ALIGNED_ACCESS_REQUIRED
# if defined __i386__ || defined __x86_64__ || defined _M_X86 || defined _M_X64
# define _ZZIP_USE_DEREF
# endif
#endif
#ifdef _ZZIP_USE_BSWAP
#define ZZIP_GET16(__p) bswap_16(*(uint16_t*)(__p))
#define ZZIP_GET32(__p) bswap_32(*(uint32_t*)(__p))
#define ZZIP_GET64(__p) bswap_64(*(uint64_t*)(__p))
#define ZZIP_SET16(__p,__x) (*(uint16_t*)(__p) = bswap_16((uint16_t)(__x)))
#define ZZIP_SET32(__p,__x) (*(uint32_t*)(__p) = bswap_32((uint32_t)(__x)))
#define ZZIP_SET64(__p,__x) (*(uint64_t*)(__p) = bswap_64((uint64_t)(__x)))
#elif defined _ZZIP_USE_DEREF
#define ZZIP_GET16(__p) (*(uint16_t*)(__p))
#define ZZIP_GET32(__p) (*(uint32_t*)(__p))
#define ZZIP_GET64(__p) (*(uint64_t*)(__p))
#define ZZIP_SET16(__p,__x) (*(uint16_t*)(__p) = (uint16_t)(__x))
#define ZZIP_SET32(__p,__x) (*(uint32_t*)(__p) = (uint32_t)(__x))
#define ZZIP_SET64(__p,__x) (*(uint64_t*)(__p) = (uint64_t)(__x))
#else
#define ZZIP_GET64(__p) (__zzip_get64((__p)))
#define ZZIP_GET32(__p) (__zzip_get32((__p)))
#define ZZIP_GET16(__p) (__zzip_get16((__p)))
#define ZZIP_SET64(__p,__x) (__zzip_set64((__p),(__x)))
#define ZZIP_SET32(__p,__x) (__zzip_set32((__p),(__x)))
#define ZZIP_SET16(__p,__x) (__zzip_set16((__p),(__x)))
#endif
#endif
/* ..................... bitcorrect physical access .................... */
/* zzip_file_header - the local file header */
#define zzip_file_header_get_magic(__p) ZZIP_GET32((__p)->z_magic)
#define zzip_file_header_set_magic(__p,__x) ZZIP_SET32((__p)->z_magic,(__x))
#define zzip_file_header_get_flags(__p) ZZIP_GET16((__p)->z_flags)
#define zzip_file_header_set_flags(__p,__x) ZZIP_SET16((__p)->z_flags,(__x))
#define zzip_file_header_get_compr(__p) ZZIP_GET16((__p)->z_compr)
#define zzip_file_header_set_compr(__p,__x) ZZIP_SET16((__p)->z_compr,(__x))
#define zzip_file_header_get_crc32(__p) ZZIP_GET32((__p)->z_crc32)
#define zzip_file_header_set_crc32(__p,__x) ZZIP_SET32((__p)->z_crc32,(__x))
#define zzip_file_header_get_csize(__p) ZZIP_GET32((__p)->z_csize)
#define zzip_file_header_set_csize(__p,__x) ZZIP_SET32((__p)->z_csize,(__x))
#define zzip_file_header_get_usize(__p) ZZIP_GET32((__p)->z_usize)
#define zzip_file_header_set_usize(__p,__x) ZZIP_SET32((__p)->z_usize,(__x))
#define zzip_file_header_get_namlen(__p) ZZIP_GET16((__p)->z_namlen)
#define zzip_file_header_set_namlen(__p,__x) ZZIP_SET16((__p)->z_namlen,(__x))
#define zzip_file_header_get_extras(__p) ZZIP_GET16((__p)->z_extras)
#define zzip_file_header_set_extras(__p,__x) ZZIP_SET16((__p)->z_extras,(__x))
#define zzip_file_header_sizeof_tails(__p) (zzip_file_header_get_namlen(__p)+\
zzip_file_header_get_extras(__p) )
#define zzip_file_header_check_magic(__p) ZZIP_FILE_HEADER_CHECKMAGIC((__p))
/* zzip_file_trailer - data descriptor per file block */
#define zzip_file_trailer_get_magic(__p) ZZIP_GET32((__p)->z_magic)
#define zzip_file_trailer_set_magic(__p,__x) ZZIP_SET32((__p)->z_magic,(__x))
#define zzip_file_header_get_crc32(__p) ZZIP_GET32((__p)->z_crc32)
#define zzip_file_trailer_set_crc32(__p,__x) ZZIP_SET32((__p)->z_crc32,(__x))
#define zzip_file_trailer_get_csize(__p) ZZIP_GET32((__p)->z_csize)
#define zzip_file_trailer_set_csize(__p,__x) ZZIP_SET32((__p)->z_csize,(__x))
#define zzip_file_trailer_get_usize(__p) ZZIP_GET32((__p)->z_usize)
#define zzip_file_trailer_set_usize(__p,__x) ZZIP_SET32((__p)->z_usize,(__x))
#define zzip_file_trailer_sizeof_tails(__p) 0
#define zzip_file_trailer_check_magic(__p) ZZIP_FILE_TRAILER_CHECKMAGIC((__p))
/* zzip_disk_entry (currently named zzip_root_dirent) */
#define zzip_disk_entry_get_magic(__p) ZZIP_GET32((__p)->z_magic)
#define zzip_disk_entry_set_magic(__p,__x) ZZIP_SET32((__p)->z_magic,(__x))
#define zzip_disk_entry_get_flags(__p) ZZIP_GET16((__p)->z_flags)
#define zzip_disk_entry_set_flags(__p,__x) ZZIP_SET16((__p)->z_flags,(__x))
#define zzip_disk_entry_get_compr(__p) ZZIP_GET16((__p)->z_compr)
#define zzip_disk_entry_set_compr(__p,__x) ZZIP_SET16((__p)->z_compr,(__x))
#define zzip_disk_entry_get_crc32(__p) ZZIP_GET32((__p)->z_crc32)
#define zzip_disk_entry_set_crc32(__p,__x) ZZIP_SET32((__p)->z_crc32,(__x))
#define zzip_disk_entry_get_csize(__p) ZZIP_GET32((__p)->z_csize)
#define zzip_disk_entry_set_csize(__p,__x) ZZIP_SET32((__p)->z_csize,(__x))
#define zzip_disk_entry_get_usize(__p) ZZIP_GET32((__p)->z_usize)
#define zzip_disk_entry_set_usize(__p,__x) ZZIP_SET32((__p)->z_usize,(__x))
#define zzip_disk_entry_get_namlen(__p) ZZIP_GET16((__p)->z_namlen)
#define zzip_disk_entry_set_namlen(__p,__x) ZZIP_SET16((__p)->z_namlen,(__x))
#define zzip_disk_entry_get_extras(__p) ZZIP_GET16((__p)->z_extras)
#define zzip_disk_entry_set_extras(__p,__x) ZZIP_SET16((__p)->z_extras,(__x))
#define zzip_disk_entry_get_comment(__p) ZZIP_GET16((__p)->z_comment)
#define zzip_disk_entry_set_comment(__p,__x) ZZIP_SET16((__p)->z_comment,(__x))
#define zzip_disk_entry_get_diskstart(__p) ZZIP_GET16((__p)->z_diskstart)
#define zzip_disk_entry_set_diskstart(__p,__x) ZZIP_SET16((__p)->z_diskstart,(__x))
#define zzip_disk_entry_get_filetype(__p) ZZIP_GET16((__p)->z_filetype)
#define zzip_disk_entry_set_filetype(__p,__x) ZZIP_SET16((__p)->z_filetype,(__x))
#define zzip_disk_entry_get_filemode(__p) ZZIP_GET32((__p)->z_filemode)
#define zzip_disk_entry_set_filemode(__p,__x) ZZIP_SET32((__p)->z_filemode,(__x))
#define zzip_disk_entry_get_offset(__p) ZZIP_GET32((__p)->z_offset)
#define zzip_disk_entry_set_offset(__p,__x) ZZIP_SET32((__p)->z_offset,(__x))
#define zzip_disk_entry_sizeof_tails(__p) (zzip_disk_entry_get_namlen(__p) +\
zzip_disk_entry_get_extras(__p) +\
zzip_disk_entry_get_comment(__p) )
#define zzip_disk_entry_check_magic(__p) ZZIP_DISK_ENTRY_CHECKMAGIC((__p))
/* zzip_disk_trailer - the zip archive entry point */
#define zzip_disk_trailer_get_magic(__p) ZZIP_GET32((__p)->z_magic)
#define zzip_disk_trailer_set_magic(__p,__x) ZZIP_SET32((__p)->z_magic,(__x))
#define zzip_disk_trailer_get_disk(__p) ZZIP_GET16((__p)->z_disk)
#define zzip_disk_trailer_set_disk(__p,__x) ZZIP_SET16((__p)->z_disk,(__x))
#define zzip_disk_trailer_get_finaldisk(__p) ZZIP_GET16((__p)->z_finaldisk)
#define zzip_disk_trailer_set_finaldisk(__p,__x) ZZIP_SET16((__p)->z_finaldisk,(__x))
#define zzip_disk_trailer_get_entries(__p) ZZIP_GET16((__p)->z_entries)
#define zzip_disk_trailer_set_entries(__p,__x) ZZIP_SET16((__p)->z_entries,(__x))
#define zzip_disk_trailer_get_finalentries(__p) ZZIP_GET16((__p)->z_finalentries)
#define zzip_disk_trailer_set_finalentries(__p,__x) ZZIP_SET16((__p)->z_finalentries,(__x))
#define zzip_disk_trailer_get_rootsize(__p) ZZIP_GET32((__p)->z_rootsize)
#define zzip_disk_trailer_set_rootsize(__p,__x) ZZIP_SET32((__p)->z_rootsize,(__x))
#define zzip_disk_trailer_get_rootseek(__p) ZZIP_GET32((__p)->z_rootseek)
#define zzip_disk_trailer_set_rootseek(__p,__x) ZZIP_SET32((__p)->z_rootseek,(__x))
#define zzip_disk_trailer_get_comment(__p) ZZIP_GET16((__p)->z_comment)
#define zzip_disk_trailer_set_comment(__p,__x) ZZIP_SET16((__p)->z_comment,(__x))
#define zzip_disk_trailer_sizeof_tails(__p) ( zzip_disk_entry_get_comment(__p))
#define zzip_disk_trailer_check_magic(__p) ZZIP_DISK_TRAILER_CHECKMAGIC((__p))
/* extra field should be type + size + data + type + size + data ... */
#define zzip_extra_block_get_datatype(__p) ZZIP_GET16((zzip_byte_t*)(__p))
#define zzip_extra_block_set_datatype(__p,__x) ZZIP_SET16((zzip_byte_t*)(__p),__x)
#define zzip_extra_block_get_datasize(__p) ZZIP_GET16((zzip_byte_t*)(__p)+2)
#define zzip_extra_block_set_datasize(__p,__x) ZZIP_SET16((zzip_byte_t*)(__p)+2,__x)
/* zzip64_disk_trailer - the zip64 archive entry point */
#define zzip_disk64_trailer_get_magic(__p) ZZIP_GET32((__p)->z_magic)
#define zzip_disk64_trailer_set_magic(__p,__x) ZZIP_SET32((__p)->z_magic,(__x))
#define zzip_disk64_trailer_get_size(__p) ZZIP_GET64((__p)->z_size)
#define zzip_disk64_trailer_set_size(__p,__x) ZZIP_SET64((__p)->z_size,(__x))
#define zzip_disk64_trailer_get_disk(__p) ZZIP_GET32((__p)->z_disk)
#define zzip_disk64_trailer_set_disk(__p,__x) ZZIP_SET32((__p)->z_disk,(__x))
#define zzip_disk64_trailer_get_finaldisk(__p) ZZIP_GET32((__p)->z_finaldisk)
#define zzip_disk64_trailer_set_finaldisk(__p,__x) ZZIP_SET32((__p)->z_finaldisk,(__x))
#define zzip_disk64_trailer_get_entries(__p) ZZIP_GET64((__p)->z_entries)
#define zzip_disk64_trailer_set_entries(__p,__x) ZZIP_SET64((__p)->z_entries,(__x))
#define zzip_disk64_trailer_get_finalentries(__p) ZZIP_GET64((__p)->z_finalentries)
#define zzip_disk64_trailer_set_finalentries(__p,__x) ZZIP_SET64((__p)->z_finalentries,(__x))
#define zzip_disk64_trailer_get_rootsize(__p) ZZIP_GET64((__p)->z_rootsize)
#define zzip_disk64_trailer_set_rootsize(__p,__x) ZZIP_SET64((__p)->z_rootsize,(__x))
#define zzip_disk64_trailer_get_rootseek(__p) ZZIP_GET64((__p)->z_rootseek)
#define zzip_disk64_trailer_set_rootseek(__p,__x) ZZIP_SET64((__p)->z_rootseek,(__x))
#define zzip_disk64_trailer_check_magic(__p) ZZIP_DISK64_TRAILER_CHECKMAGIC((__p))
/* .............. some logical typed access wrappers ....................... */
/* zzip_file_header - the local file header */
#define zzip_file_header_csize(__p) ((zzip_size_t) \
zzip_file_header_get_csize(__p))
#define zzip_file_header_usize(__p) ((zzip_size_t) \
zzip_file_header_get_usize(__p))
#define zzip_file_header_namlen(__p) ((zzip_size_t) \
zzip_file_header_get_namlen(__p))
#define zzip_file_header_extras(__p) ((zzip_size_t) \
zzip_file_header_get_extras(__p))
#define zzip_file_header_sizeof_tail(__p) ((zzip_size_t) \
zzip_file_header_sizeof_tails(__p))
#define zzip_file_header_sizeto_end(__p) ((zzip_size_t) \
(zzip_file_header_sizeof_tail(__p) + zzip_file_header_headerlength))
#define zzip_file_header_skipto_end(__p) ((void*) (__p) + \
(zzip_file_header_sizeof_tail(__p) + zzip_file_header_headerlength))
#define zzip_file_header_to_filename(__p) ((char*) \
((char*)(__p) + zzip_file_header_headerlength))
#define zzip_file_header_to_extras(__p) ((char*) \
(zzip_file_header_to_filename(__p) + zzip_file_header_namlen(__p)))
#define zzip_file_header_to_data(__p) ((zzip_byte_t*) \
(zzip_file_header_to_extras(__p) + zzip_file_header_extras(__p)))
#define zzip_file_header_to_trailer(__p) ((struct zzip_file_trailer*) \
(zzip_file_header_to_data(__p) + zzip_file_header_csize(__p)))
/* zzip_file_trailer - data descriptor per file block */
#define zzip_file_trailer_csize(__p) ((zzip_size_t) \
zzip_file_trailer_get_csize(__p))
#define zzip_file_trailer_usize(__p) ((zzip_size_t) \
zzip_file_trailer_get_usize(__p))
#define zzip_file_trailer_sizeof_tail(__p) ((zzip_size_t) \
zzip_file_trailer_sizeof_tails(__p))
#define zzip_file_trailer_sizeto_end(__p) ((zzip_size_t) \
(zzip_file_trailer_sizeof_tail(__p) + zzip_file_trailer_headerlength))
#define zzip_file_trailer_skipto_end(__p) ((void*) (__p) + \
(zzip_file_trailer_sizeof_tail(__p) + zzip_file_trailer_headerlength))
/* zzip_disk_entry (currently named zzip_root_dirent) */
#define zzip_disk_entry_csize(__p) ((zzip_size_t) \
zzip_disk_entry_get_csize(__p))
#define zzip_disk_entry_usize(__p) ((zzip_size_t) \
zzip_disk_entry_get_usize(__p))
#define zzip_disk_entry_namlen(__p) ((zzip_size_t) \
zzip_disk_entry_get_namlen(__p))
#define zzip_disk_entry_extras(__p) ((zzip_size_t) \
zzip_disk_entry_get_extras(__p))
#define zzip_disk_entry_comment(__p) ((zzip_size_t) \
zzip_disk_entry_get_comment(__p))
#define zzip_disk_entry_diskstart(__p) ((int) \
zzip_disk_entry_get_diskstart(__p))
#define zzip_disk_entry_filetype(__p) ((int) \
zzip_disk_entry_get_filetype(__p))
#define zzip_disk_entry_filemode(__p) ((int) \
zzip_disk_entry_get_filemode(__p))
#define zzip_disk_entry_fileoffset(__p) ((zzip_off_t) \
zzip_disk_entry_get_offset(__p))
#define zzip_disk_entry_sizeof_tail(__p) ((zzip_size_t) \
zzip_disk_entry_sizeof_tails(__p))
#define zzip_disk_entry_sizeto_end(__p) ((zzip_size_t) \
(zzip_disk_entry_sizeof_tail(__p) + zzip_disk_entry_headerlength))
#define zzip_disk_entry_skipto_end(__p) ((zzip_byte_t*) (__p) + \
(zzip_disk_entry_sizeof_tail(__p) + zzip_disk_entry_headerlength))
#define zzip_disk_entry_to_filename(__p) ((char*) \
((char*)(__p) + zzip_disk_entry_headerlength))
#define zzip_disk_entry_to_extras(__p) ((char*) \
(zzip_disk_entry_to_filename(__p) + zzip_disk_entry_namlen(__p)))
#define zzip_disk_entry_to_comment(__p) ((char*) \
(zzip_disk_entry_to_extras(__p) + zzip_disk_entry_extras(__p)))
#define zzip_disk_entry_to_next_entry(__p) ((struct zzip_disk_entry*) \
(zzip_disk_entry_to_comment(__p) + zzip_disk_entry_comment(__p)))
/* zzip_disk_trailer - the zip archive entry point */
#define zzip_disk_trailer_localdisk(__p) ((int) \
zzip_disk_trailer_get_disk(__p))
#define zzip_disk_trailer_finaldisk(__p) ((int) \
zzip_disk_trailer_get_finaldisk(__p))
#define zzip_disk_trailer_localentries(__p) ((int) \
zzip_disk_trailer_get_entries(__p))
#define zzip_disk_trailer_finalentries(__p) ((int) \
zzip_disk_trailer_get_finalentries(__p))
#define zzip_disk_trailer_rootsize(__p) ((zzip_off_t) \
zzip_disk_trailer_get_rootsize(__p))
#define zzip_disk_trailer_rootseek(__p) ((zzip_off_t) \
zzip_disk_trailer_get_rootseek(__p))
#define zzip_disk_trailer_comment(__p) ((zzip_size_t) \
zzip_disk_trailer_get_comment(__p))
#define zzip_disk_trailer_sizeof_tail(__p) ((zzip_size_t) \
zzip_disk_trailer_sizeof_tails(__p))
#define zzip_disk_trailer_sizeto_end(__p) ((zzip_size_t) \
(zzip_disk_trailer_sizeof_tail(__p) + zzip_disk_trailer_headerlength))
#define zzip_disk_trailer_skipto_end(__p) ((void*) (__p) \
(zzip_disk_trailer_sizeof_tail(__p) + zzip_disk_trailer_headerlength))
#define zzip_disk_trailer_to_comment(__p) ((char*) \
((char*)(__p) + zzip_disk_trailer_headerlength))
#define zzip_disk_trailer_to_endoffile(__p) ((void*) \
(zzip_disk_trailer_to_comment(__p) + zzip_disk_trailer_comment(__p)))
/* zzip_disk64_trailer - the zip archive entry point */
#define zzip_disk64_trailer_localdisk(__p) ((int) \
zzip_disk64_trailer_get_disk(__p))
#define zzip_disk64_trailer_finaldisk(__p) ((int) \
zzip_disk64_trailer_get_finaldisk(__p))
#define zzip_disk64_trailer_localentries(__p) ((int) \
zzip_disk64_trailer_get_entries(__p))
#define zzip_disk64_trailer_finalentries(__p) ((int) \
zzip_disk64_trailer_get_finalentries(__p))
#define zzip_disk64_trailer_rootsize(__p) ((zzip_off64_t) \
zzip_disk64_trailer_get_rootsize(__p))
#define zzip_disk64_trailer_rootseek(__p) ((zzip_off64_t) \
zzip_disk64_trailer_get_rootseek(__p))
#define zzip_disk64_trailer_sizeof_tail(__p) ((zzip_size_t) \
zzip_disk64_trailer_get_size(__p) - zzip_disk64_trailer_headerlength)
#define zzip_disk64_trailer_sizeto_end(__p) ((zzip_size_t) \
zzip_disk64_trailer_get_size(__p))
#define zzip_disk64_trailer_skipto_end(__p) ((void*) \
((char*)(__p) + zzip_disk64_sizeto_end(__p)))
/* extra field should be type + size + data + type + size + data ... */
#define zzip_extra_block_sizeof_tail(__p) ((zzip_size_t) \
(zzip_extra_block_get_datasize(__p)))
#define zzip_extra_block_sizeto_end(__p) ((zzip_size_t) \
(zzip_extra_block_sizeof_tail(__p) + zzip_extra_block_headerlength))
#define zzip_extra_block_skipto_end(__p) ((void*) (__p) \
(zzip_extra_block_sizeof_tail(__p) + zzip_extra_block_headerlength))
/* ................... and put these to the next level ................ */
#define zzip_file_header_data_encrypted(__p) \
ZZIP_IS_ENCRYPTED( zzip_file_header_get_flags(__p) )
#define zzip_file_header_data_comprlevel(__p) \
ZZIP_IS_COMPRLEVEL( zzip_file_header_get_flags(__p) )
#define zzip_file_header_data_streamed(__p) \
ZZIP_IS_STREAMED( zzip_file_header_get_flags(__p) )
#define zzip_file_header_data_stored(__p) \
( ZZIP_IS_STORED == zzip_file_header_get_compr(__p) )
#define zzip_file_header_data_deflated(__p) \
( ZZIP_IS_DEFLATED == zzip_file_header_get_compr(__p) )
#define zzip_disk_entry_data_encrypted(__p) \
ZZIP_IS_ENCRYPTED( zzip_disk_entry_get_flags(__p) )
#define zzip_disk_entry_data_comprlevel(__p) \
ZZIP_IS_COMPRLEVEL( zzip_disk_entry_get_flags(__p) )
#define zzip_disk_entry_data_streamed(__p) \
ZZIP_IS_STREAMED( zzip_disk_entry_get_flags(__p) )
#define zzip_disk_entry_data_stored(__p) \
( ZZIP_IS_STORED == zzip_disk_entry_get_compr(__p) )
#define zzip_disk_entry_data_deflated(__p) \
( ZZIP_IS_DEFLATED == zzip_disk_entry_get_compr(__p) )
#define zzip_disk_entry_data_ascii(__p) \
( zzip_disk_entry_get_filetype(__p) & 1)
#define zzip_file_header_data_not_deflated(__p) \
(zzip_file_header_data_stored(__p))
#define zzip_file_header_data_std_deflated(__p) \
(zzip_file_header_data_deflated(__p) && \
zzip_file_header_data_comprlevel(__p) == ZZIP_DEFLATED_STD_COMPR)
#define zzip_file_header_data_max_deflated(__p) \
(zzip_file_header_data_deflated(__p) && \
zzip_file_header_data_comprlevel(__p) == ZZIP_DEFLATED_MAX_COMPR)
#define zzip_file_header_data_low_deflated(__p) \
(zzip_file_header_data_deflated(__p) && \
zzip_file_header_data_comprlevel(__p) == ZZIP_DEFLATED_LOW_COMPR)
#define zzip_file_header_data_min_deflated(__p) \
(zzip_file_header_data_deflated(__p) && \
zzip_file_header_data_comprlevel(__p) == ZZIP_DEFLATED_MIN_COMPR)
#define zzip_disk_entry_data_not_deflated(__p) \
(zzip_disk_entry_data_stored(__p))
#define zzip_disk_entry_data_std_deflated(__p) \
(zzip_disk_entry_data_deflated(__p) && \
zzip_disk_entry_data_comprlevel(__p) == ZZIP_DEFLATED_STD_COMPR)
#define zzip_disk_entry_data_max_deflated(__p) \
(zzip_disk_entry_data_deflated(__p) && \
zzip_disk_entry_data_comprlevel(__p) == ZZIP_DEFLATED_MAX_COMPR)
#define zzip_disk_entry_data_low_deflated(__p) \
(zzip_disk_entry_data_deflated(__p) && \
zzip_disk_entry_data_comprlevel(__p) == ZZIP_DEFLATED_LOW_COMPR)
#define zzip_disk_entry_data_min_deflated(__p) \
(zzip_disk_entry_data_deflated(__p) && \
zzip_disk_entry_data_comprlevel(__p) == ZZIP_DEFLATED_MIN_COMPR)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,81 @@
/*
* this is an internal header file - the structure contains two off_t
* atleast making it LARGEFILE_SENSITIVE on linux2 and solaris systems
* whereas about all functions just return a ZZIP_FILE* in zzip/zzip.h
*
* and so, this structure should be handled version-specific and
* subject to change - it had been kept binary-compatible for quite
* a while now so perhaps some program sources have errnously taken
* advantage of this file.
*
* Author:
* Guido Draheim <guidod@gmx.de>
* Tomi Ollila <Tomi.Ollila@tfi.net>
*
* Copyright (c) 1999,2000,2001,2002 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#ifndef _ZZIP_FILE_H /* zzip-file.h */
#define _ZZIP_FILE_H 1
#ifndef ZZIP_32K
#ifdef __GNUC__
/* include zzip/lib.h beforehand in order to suppress the following warning */
#warning zzip/file.h is an internal header, do not use it freely
#endif
#endif
#include <zzip/lib.h>
#include <zlib.h>
#ifdef ZZIP_HAVE_UNISTD_H
#include <unistd.h>
#else
#include <stdio.h>
# ifdef ZZIP_HAVE_SYS_TYPES_H
# include <sys/types.h>
# endif
#endif
#ifdef ZZIP_HAVE_SYS_PARAM_H
#include <sys/param.h> /* PATH_MAX */
#endif
#ifndef PATH_MAX
# ifdef MAX_PATH /* windows */
# define PATH_MAX MAX_PATH
# else
# define PATH_MAX 512
# endif
#endif
/*
* ZZIP_FILE structure... currently no need to unionize, since structure needed
* for inflate is superset of structure needed for unstore.
*
* Don't make this public. Instead, create methods for needed operations.
*/
struct zzip_file
{
struct zzip_dir* dir;
int fd;
int method;
zzip_size_t restlen;
zzip_size_t crestlen;
zzip_size_t usize;
zzip_size_t csize;
/* added dataoffset member - data offset from start of zipfile*/
zzip_off_t dataoffset;
char* buf32k;
zzip_off_t offset; /* offset from the start of zipfile... */
z_stream d_stream;
zzip_plugin_io_t io;
};
#endif /* _ZZIP_FILE_H */

View File

@@ -0,0 +1,234 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2000,2001,2002,2003 Guido Draheim
* All rights reserved
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*
* The information was taken from appnote-981119-iz.zip
* at http://www.freesoftware.com/pub/infozip/doc/
* which in turn is based on PKWARE's appnote.txt
* (newer link: ftp://ftp.info-zip.org/pub/infozip/doc/)
*/
#ifndef _ZZIP_FORMAT_H /* zzipformat.h */
#define _ZZIP_FORMAT_H
#include <zzip/types.h>
#include <zzip/__hints.h>
/* we have ICO C 9X types defined */
/*
* Overall zipfile format
* [local file header + file data stream + checksum descriptor] ...
* ... [disk central directory] [disk trailer record]
*/
# ifdef _MSC_VER
# pragma pack(push, 1)
# endif
struct zzip_version
{
zzip_byte_t version[1];
zzip_byte_t ostype[1];
} ZZIP_GNUC_PACKED;
struct zzip_dostime
{
zzip_byte_t time[2];
zzip_byte_t date[2];
} ZZIP_GNUC_PACKED;
#ifdef ZZIP_NEED_PACKED
/* if your compiler does interesting things about struct packing... */
typedef zzip_byte_t zzip_version_t[2];
typedef zzip_byte_t zzip_dostime_t[4];
#else
typedef struct zzip_version zzip_version_t;
typedef struct zzip_dostime zzip_dostime_t;
#endif
#define ZZIP_CHECKMAGIC(__p,__A,__B,__C,__D) \
( (((zzip_byte_t*)(__p))[0]==(__A)) && \
(((zzip_byte_t*)(__p))[1]==(__B)) && \
(((zzip_byte_t*)(__p))[2]==(__C)) && \
(((zzip_byte_t*)(__p))[3]==(__D)) )
/* A. Local file header */
struct zzip_file_header
{
# define ZZIP_FILE_HEADER_MAGIC 0x04034b50
# define ZZIP_FILE_HEADER_CHECKMAGIC(__p) ZZIP_CHECKMAGIC(__p,'P','K','\3','\4')
zzip_byte_t z_magic[4]; /* local file header signature (0x04034b50) */
zzip_version_t z_extract; /* version needed to extract */
zzip_byte_t z_flags[2]; /* general purpose bit flag */
zzip_byte_t z_compr[2]; /* compression method */
zzip_dostime_t z_dostime; /* last mod file time (dos format) */
zzip_byte_t z_crc32[4]; /* crc-32 */
zzip_byte_t z_csize[4]; /* compressed size */
zzip_byte_t z_usize[4]; /* uncompressed size */
zzip_byte_t z_namlen[2]; /* filename length (null if stdin) */
zzip_byte_t z_extras[2]; /* extra field length */
/* followed by filename (of variable size) */
/* followed by extra field (of variable size) */
} ZZIP_GNUC_PACKED;
#define zzip_file_header_headerlength (4+2+2+2+4+4+4+4+2+2)
/* B. data descriptor
* the data descriptor exists only if bit 3 of z_flags is set. It is byte aligned
* and immediately follows the last byte of compressed data. It is only used if
* the output media of the compressor was not seekable, eg. standard output.
*/
struct zzip_file_trailer
{
# define ZZIP_FILE_TRAILER_MAGIC 0x08074B50
# define ZZIP_FILE_TRAILER_CHECKMAGIC(__p) ZZIP_CHECKMAGIC(__p,'P','K','\7','\8')
zzip_byte_t z_magic[4]; /* data descriptor signature (0x08074b50) */
zzip_byte_t z_crc32[4]; /* crc-32 */
zzip_byte_t z_csize[4]; /* compressed size */
zzip_byte_t z_usize[4]; /* uncompressed size */
} ZZIP_GNUC_PACKED;
#define zzip_file_trailer_headerlength (4+4+4+4)
/* C. central directory structure:
[file header] . . . end of central dir record
*/
/* directory file header
* - a single entry including filename, extras and comment may not exceed 64k.
*/
struct zzip_disk_entry
{
# define ZZIP_DISK_ENTRY_MAGIC 0x02014b50
# define ZZIP_DISK_ENTRY_CHECKMAGIC(__p) ZZIP_CHECKMAGIC(__p,'P','K','\1','\2')
zzip_byte_t z_magic[4]; /* central file header signature (0x02014b50) */
zzip_version_t z_encoder; /* version made by */
zzip_version_t z_extract; /* version need to extract */
zzip_byte_t z_flags[2]; /* general purpose bit flag */
zzip_byte_t z_compr[2]; /* compression method */
zzip_dostime_t z_dostime; /* last mod file time&date (dos format) */
zzip_byte_t z_crc32[4]; /* crc-32 */
zzip_byte_t z_csize[4]; /* compressed size */
zzip_byte_t z_usize[4]; /* uncompressed size */
zzip_byte_t z_namlen[2]; /* filename length (null if stdin) */
zzip_byte_t z_extras[2]; /* extra field length */
zzip_byte_t z_comment[2]; /* file comment length */
zzip_byte_t z_diskstart[2]; /* disk number of start (if spanning zip over multiple disks) */
zzip_byte_t z_filetype[2]; /* internal file attributes, bit0 = ascii */
zzip_byte_t z_filemode[4]; /* extrnal file attributes, eg. msdos attrib byte */
zzip_byte_t z_offset[4]; /* relative offset of local file header, seekval if singledisk */
/* followed by filename (of variable size) */
/* followed by extra field (of variable size) */
/* followed by file comment (of variable size) */
} ZZIP_GNUC_PACKED;
#define zzip_disk_entry_headerlength (4+2+2+2+2+4+4+4+4+2+2+2+2+2+4+4)
struct zzip_root_dirent
{ /* the old name of the structure above */
# define ZZIP_ROOT_DIRENT_MAGIC 0x02014b50
# define ZZIP_ROOT_DIRENT_CHECKMAGIC(__p) ZZIP_DISK_ENTRY_CHECKMAGIC(__p)
zzip_byte_t z_magic[4];
zzip_version_t z_encoder;
zzip_version_t z_extract;
zzip_byte_t z_flags[2];
zzip_byte_t z_compr[2];
zzip_dostime_t z_dostime;
zzip_byte_t z_crc32[4];
zzip_byte_t z_csize[4];
zzip_byte_t z_usize[4];
zzip_byte_t z_namlen[2];
zzip_byte_t z_extras[2];
zzip_byte_t z_comment[2];
zzip_byte_t z_diskstart[2];
zzip_byte_t z_filetype[2];
zzip_byte_t z_filemode[4];
zzip_byte_t z_off[4];
} ZZIP_GNUC_PACKED;
/* end of central dir record */
struct zzip_disk_trailer
{
# define ZZIP_DISK_TRAILER_MAGIC 0x06054b50
# define ZZIP_DISK_TRAILER_CHECKMAGIC(__p) ZZIP_CHECKMAGIC(__p,'P','K','\5','\6')
zzip_byte_t z_magic[4]; /* end of central dir signature (0x06054b50) */
zzip_byte_t z_disk[2]; /* number of this disk */
zzip_byte_t z_finaldisk[2]; /* number of the disk with the start of the central dir */
zzip_byte_t z_entries[2]; /* total number of entries in the central dir on this disk */
zzip_byte_t z_finalentries[2]; /* total number of entries in the central dir */
zzip_byte_t z_rootsize[4]; /* size of the central directory */
zzip_byte_t z_rootseek[4]; /* offset of start of central directory with respect to *
* the starting disk number */
zzip_byte_t z_comment[2]; /* zipfile comment length */
/* followed by zipfile comment (of variable size) */
} ZZIP_GNUC_PACKED;
#define zzip_disk_trailer_headerlength (4+2+2+2+2+4+4+2)
/* extra field should be type + size + data + type + size + data ... */
struct zzip_extra_block
{ /* fetch.h macros do not need this struct */
zzip_byte_t z_datatype[2]; /* as input type - a mere <char*> is okay */
zzip_byte_t z_datasize[2]; /* being returned by xx_to_extras usually */
} ZZIP_GNUC_PACKED;
#define zzip_extra_block_headerlength (2+2)
/* Zip64 end of central dir record */
struct zzip_disk64_trailer
{
# define ZZIP_DISK64_TRAILER_MAGIC 0x06064b50
# define ZZIP_DISK64_TRAILER_CHECKMAGIC(__p) ZZIP_CHECKMAGIC(__p,'P','K','\6','\6')
zzip_byte_t z_magic[4]; /* end of central dir signature (0x06054b50) */
zzip_byte_t z_size[8]; /* size of this central directory record */
zzip_version_t z_encoder; /* version made by */
zzip_version_t z_extract; /* version need to extract */
zzip_byte_t z_disk[4]; /* number of this disk */
zzip_byte_t z_finaldisk[4]; /* number of the disk with the start of the central dir */
zzip_byte_t z_entries[8]; /* total number of entries in the central dir on this disk */
zzip_byte_t z_finalentries[8]; /* total number of entries in the central dir */
zzip_byte_t z_rootsize[8]; /* size of the central directory */
zzip_byte_t z_rootseek[8]; /* offset of start of central directory with respect to *
* the starting disk number */
/* followed by zip64 extensible data sector (of variable size) */
} ZZIP_GNUC_PACKED;
#define zzip_disk64_trailer_headerlength (4+8+2+2+4+4+8+8+8+8)
/* z_flags */
#define ZZIP_IS_ENCRYPTED(p) ((*(zzip_byte_t*)p)&1)
#define ZZIP_IS_COMPRLEVEL(p) (((*(zzip_byte_t*)p)>>1)&3)
#define ZZIP_IS_STREAMED(p) (((*(zzip_byte_t*)p)>>3)&1)
#define ZZIP_IS_PATCHED(p) (((*(zzip_byte_t*)p)>>5)&1)
/* z_compr */
#define ZZIP_IS_STORED 0
#define ZZIP_IS_SHRUNK 1
#define ZZIP_IS_REDUCEDx1 2
#define ZZIP_IS_REDUCEDx2 3
#define ZZIP_IS_REDUCEDx3 4
#define ZZIP_IS_REDUCEDx4 5
#define ZZIP_IS_IMPLODED 6
#define ZZIP_IS_TOKENIZED 7
#define ZZIP_IS_DEFLATED 8
#define ZZIP_IS_DEFLATED_BETTER 9
#define ZZIP_IS_IMPLODED_BETTER 10
/* deflated comprlevel */
#define ZZIP_DEFLATED_STD_COMPR 0
#define ZZIP_DEFLATED_MAX_COMPR 1
#define ZZIP_DEFLATED_LOW_COMPR 2
#define ZZIP_DEFLATED_MIN_COMPR 3
# ifdef _MSC_VER
# pragma pack(pop)
# endif
#endif /* _ZZIPFORMAT_H */

View File

@@ -0,0 +1,129 @@
#ifndef _ZZIP_FSEEKO_H_
#define _ZZIP_FSEEKO_H_
/*
* NOTE: this is part of libzzipfseeko (i.e. it is not libzzip).
*
* simplified zip disk access using fseeko on a stdio FILE handle
*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2003,2004 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#include <zzip/types.h>
#include <stdio.h>
#ifdef _ZZIP_ENTRY_STRUCT
#include <zlib.h>
#include <zzip/format.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct zzip_entry ZZIP_ENTRY;
typedef struct zzip_entry_file ZZIP_ENTRY_FILE;
typedef int (*zzip_strcmp_fn_t)(char*, char*);
typedef int (*zzip_fnmatch_fn_t)(char*, char*, int);
#ifndef zzip_entry_extern
#define zzip_entry_extern extern
#endif
zzip_entry_extern zzip_off_t
zzip_entry_data_offset(ZZIP_ENTRY* entry);
zzip__new__
zzip_entry_extern ZZIP_ENTRY*
zzip_entry_findfirst(FILE* file);
zzip__new__
zzip_entry_extern ZZIP_ENTRY*
zzip_entry_findnext(ZZIP_ENTRY* _zzip_restrict entry);
#define zzip_entry_findlast zzip_entry_free
#define zzip_entry_findlastfile zzip_entry_free
#define zzip_entry_findlastmatch zzip_entry_free
zzip_entry_extern int
zzip_entry_free(ZZIP_ENTRY* entry);
zzip__new__
zzip_entry_extern char*
zzip_entry_strdup_name(ZZIP_ENTRY* entry);
zzip_entry_extern char*
zzip_entry_to_data(ZZIP_ENTRY* entry);
zzip__new__
zzip_entry_extern ZZIP_ENTRY*
zzip_entry_findfile(FILE* disk, char* filename,
ZZIP_ENTRY* _zzip_restrict old,
zzip_strcmp_fn_t compare);
zzip__new__
zzip_entry_extern ZZIP_ENTRY*
zzip_entry_findmatch(FILE* disk, char* filespec,
ZZIP_ENTRY* _zzip_restrict old,
zzip_fnmatch_fn_t compare, int flags);
zzip__new__
zzip_entry_extern ZZIP_ENTRY_FILE*
zzip_entry_fopen (ZZIP_ENTRY* entry, int takeover);
zzip__new__
zzip_entry_extern ZZIP_ENTRY_FILE*
zzip_entry_ffile (FILE* disk, char* filename);
zzip_entry_extern _zzip_size_t
zzip_entry_fread (void* ptr, _zzip_size_t size, _zzip_size_t nmemb,
ZZIP_ENTRY_FILE* file);
zzip_entry_extern int
zzip_entry_fclose (ZZIP_ENTRY_FILE* file);
int
zzip_entry_feof (ZZIP_ENTRY_FILE* file);
# ifdef _ZZIP_ENTRY_STRUCT
# ifdef __cplusplus
# define __zzip_entry_extends_zzip_disk_entry
struct zzip_entry : public struct zzip_disk_entry
{
char* _zzip_restrict tail;
zzip_off_t tailalloc; /* the allocated size of tail */
FILE* diskfile; /* a file reference */
zzip_off_t disksize; /* the size of the file */
zzip_off_t headseek; /* the offset within the file */
zzip_off_t zz_usize;
zzip_off_t zz_csize; /* items scanned from header */
zzip_off_t zz_offset; /* or zip64 extension block */
int zz_diskstart;
};
# else
struct zzip_entry /* : struct zzip_disk_entry */
{
struct zzip_disk_entry head;
char* _zzip_restrict tail;
zzip_off_t tailalloc; /* the allocated size of tail */
FILE* diskfile; /* a file reference */
zzip_off_t disksize; /* the size of the file */
zzip_off_t headseek; /* the offset within the file */
zzip_off_t zz_usize;
zzip_off_t zz_csize; /* items scanned from header */
zzip_off_t zz_offset; /* or zip64 extension block */
int zz_diskstart;
};
# endif /* __cplusplus */
# endif /* _ZZIP_MEM_ENTRY_PRIVATE */
#ifdef __cplusplus
extern "C" {
}
#endif
#endif

View File

@@ -0,0 +1,25 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2000,2001,2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#ifdef ZZIP_USE_INTERNAL
/* do not make these public, they are for internal use only */
#define ZZIP_error(__dir) __dir->errcode
#define ZZIP_seterror(__dir, __code) __dir->errcode = __code
#define ZZIP_dirhandle(__fp) __fp->dir
#define ZZIP_dirfd(__dir) __dir->fd
#define ZZIP_dir_real(__dir) __dir->realdir != 0
#define ZZIP_file_real(__fp) __fp->dir == 0
#define ZZIP_realdir(__dir) __dir->realdir
#define ZZIP_reafd(__fp) __fp->fd
#endif

View File

@@ -0,0 +1,91 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
* Tomi Ollila <Tomi.Ollila@iki.fi>
*
* Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
* All rights reserved
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*
* This is the private header containing definitions that are not
* use by a libzzip user application. Writing an extension lib that
* uses libzzip will still want to include this. The extension
* write should make way to have the ISO C9X integer types defined.
*/
#ifndef _ZZIP_LIB_H /* zzip.h */
#define _ZZIP_LIB_H
#include <zzip/zzip.h>
#include <zzip/plugin.h>
#include <zzip/stdint.h>
#include <zzip/zzip32.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* this structure cannot be wildly enlarged... (see zzip-zip.c)
*/
struct zzip_dir_hdr
{
uint32_t d_usize; /* uncompressed size */
uint32_t d_csize; /* compressed size */
uint32_t d_crc32; /* the adler32-checksum */
uint32_t d_off; /* offset of file in zipfile */
uint16_t d_reclen; /* next dir_hdr structure offset */
uint16_t d_namlen; /* explicit namelen of d_name */
uint8_t d_compr; /* the compression type, 0 = store, 8 = inflate */
char d_name[1]; /* the actual name of the entry, may contain DIRSEPs */
};
#define _ZZIP_DIRENT_HAVE_D_NAMLEN
#define _ZZIP_DIRENT_HAVE_D_OFF
#define _ZZIP_DIRENT_HAVE_D_RECLEN
/*
* you shall not use this struct anywhere else than in zziplib sources.
*/
struct zzip_dir
{
int fd;
int errcode; /* zzip_error_t */
long refcount;
struct { /* reduce a lot of alloc/deallocations by caching these: */
int * volatile locked;
struct zzip_file * volatile fp;
char * volatile buf32k;
} cache;
struct zzip_dir_hdr * hdr0; /* zfi; */
struct zzip_dir_hdr * hdr; /* zdp; directory pointer, for dirent stuff */
struct zzip_file * currentfp; /* last fp used... */
struct zzip_dirent dirent;
void* realdir; /* e.g. DIR* from posix dirent.h */
char* realname;
zzip_strings_t* fileext; /* list of fileext to test for */
zzip_plugin_io_t io; /* vtable for io routines */
};
#define ZZIP_32K 32768
/* try to open a zip-basename with default_fileext */
int __zzip_try_open (zzip_char_t* filename, int filemode,
zzip_strings_t* ext, zzip_plugin_io_t io);
ZZIP_DIR *
zzip_dir_fdopen(int fd, zzip_error_t * errcode_p);
ZZIP_DIR*
zzip_dir_fdopen_ext_io(int fd, zzip_error_t * errorcode_p,
zzip_strings_t* ext, const zzip_plugin_io_t io);
ZZIP_DIR* /*depracated*/
zzip_dir_alloc_ext_io (zzip_strings_t* ext, const zzip_plugin_io_t io);
#ifdef __cplusplus
}
#endif
#endif /* _ZZIP_H */

View File

@@ -0,0 +1,171 @@
#ifndef __ZZIP_MEMDISK_H
#define __ZZIP_MEMDISK_H
/* NOTE: this is part of libzzipmmapped (i.e. it is not libzzip). */
#include <zzip/types.h>
#include <zzip/mmapped.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _zzip_mem_disk ZZIP_MEM_DISK;
typedef struct _zzip_mem_entry ZZIP_MEM_ENTRY;
struct _zzip_mem_disk {
ZZIP_DISK* disk;
ZZIP_MEM_ENTRY* list;
ZZIP_MEM_ENTRY* last;
};
#ifndef zzip_mem_disk_extern
#define zzip_mem_disk_extern
#endif
zzip_mem_disk_extern zzip__new__ ZZIP_MEM_DISK*
zzip_mem_disk_new (void);
zzip_mem_disk_extern zzip__new__ ZZIP_MEM_DISK*
zzip_mem_disk_open (char* filename);
zzip_mem_disk_extern zzip__new__ ZZIP_MEM_DISK*
zzip_mem_disk_fdopen (int fd);
zzip_mem_disk_extern zzip__new__ ZZIP_MEM_DISK *
zzip_mem_disk_buffer(char *buffer, size_t buflen);
zzip_mem_disk_extern void
zzip_mem_disk_close (ZZIP_MEM_DISK* _zzip_restrict dir);
zzip_mem_disk_extern long
zzip_mem_disk_load (ZZIP_MEM_DISK* dir, ZZIP_DISK* disk);
zzip_mem_disk_extern void
zzip_mem_disk_unload (ZZIP_MEM_DISK* dir);
ZZIP_EXTRA_BLOCK*
zzip_mem_entry_extra_block (ZZIP_MEM_ENTRY* entry, short datatype);
#ifdef USE_INLINE
_zzip_inline ZZIP_DISK* zzip_disk (ZZIP_MEM_DISK* dir) { return dir->disk; }
#else
#define zzip_disk(_X_) ((_X_)->disk)
#endif
/* these functions are much faster than the orgiinal zzip_disk_ functions */
/* zzip_mem_entry <is similar to> zzip_disk_entry */
struct _zzip_mem_entry {
struct _zzip_mem_entry* zz_next;
char* zz_name; /* zero-terminated (from "filename") */
zzip_byte_t* zz_data; /* compressed content start (mmap addr) */
int zz_flags; /* (from "z_flags") */
int zz_compr; /* (from "z_compr") */
long zz_mktime; /* (from "z_dostime") */
long zz_crc32; /* (from "z_crc32") */
zzip_off_t zz_csize; /* (from "z_csize") overridden by zip64 */
zzip_off_t zz_usize; /* (from "z_usize") overridden by zip64 */
zzip_off_t zz_offset; /* (from "z_offset") overridden by zip64 */
int zz_diskstart; /* (from "z_diskstart") rridden by zip64 */
int zz_filetype; /* (from "z_filetype") */
char* zz_comment; /* zero-terminated (from "comment") */
ZZIP_EXTRA_BLOCK* zz_ext[3]; /* terminated by null in z_datatype */
}; /* the extra blocks are NOT converted */
#define _zzip_mem_disk_findfirst(_d_) ((_d_)->list)
#define _zzip_mem_disk_findnext(_d_,_e_) (!(_e_)?(_d_)->list:(_e_)->zz_next)
#define _zzip_mem_entry_findnext(_e_) ((_e_)->zz_next)
#ifndef USE_INLINE
#define zzip_mem_disk_findfirst _zzip_mem_disk_findfirst
#define zzip_mem_disk_findnext _zzip_mem_disk_findnext
#define zzip_mem_entry_findnext _zzip_mem_entry_findnext
#else
_zzip_inline ZZIP_MEM_ENTRY*
zzip_mem_disk_findfirst(ZZIP_MEM_DISK* dir) {
if (! dir) return 0;
return _zzip_mem_disk_findfirst(dir); }
_zzip_inline ZZIP_MEM_ENTRY*
zzip_mem_disk_findnext(ZZIP_MEM_DISK* dir, ZZIP_MEM_ENTRY* entry) {
if (! dir) return 0;
return _zzip_mem_disk_findnext(dir, entry); }
_zzip_inline ZZIP_MEM_ENTRY*
zzip_mem_entry_findnext(ZZIP_MEM_ENTRY* entry) {
if (! entry) return 0;
return _zzip_mem_entry_findnext(entry); }
#endif
#define _zzip_mem_entry_to_name(_e_) ((_e_)->zz_name)
#define _zzip_mem_entry_to_comment(_e_) ((_e_)->zz_comment)
#define _zzip_mem_entry_strdup_name(_e_) (strdup((_e_)->zz_name))
#define _zzip_mem_entry_to_data(_e_) ((_e_)->zz_data)
#ifndef USE_INLINE
#define zzip_mem_entry_to_name _zzip_mem_entry_to_name
#define zzip_mem_entry_to_comment _zzip_mem_entry_to_comment
#define zzip_mem_entry_strdup_name _zzip_mem_entry_strdup_name
#define zzip_mem_entry_to_data _zzip_mem_entry_to_data
#else
_zzip_inline char*
zzip_mem_entry_to_name(ZZIP_MEM_ENTRY* entry) {
if (! entry) return 0;
return _zzip_mem_entry_to_name(entry); }
_zzip_inline char*
zzip_mem_entry_to_comment(ZZIP_MEM_ENTRY* entry) {
if (! entry) return 0;
return _zzip_mem_entry_to_comment(entry); }
zzip__new__
_zzip_inline char*
zzip_mem_entry_strdup_name(ZZIP_MEM_ENTRY* entry) {
if (! entry) return 0;
return _zzip_mem_entry_strdup_name(entry); }
_zzip_inline zzip_byte_t*
zzip_mem_entry_to_data(ZZIP_MEM_ENTRY* entry) {
if (! entry) return 0;
return _zzip_mem_entry_to_data(entry); }
#endif
ZZIP_MEM_ENTRY*
zzip_mem_disk_findfile(ZZIP_MEM_DISK* dir,
char* filename, ZZIP_MEM_ENTRY* after,
zzip_strcmp_fn_t compare);
ZZIP_MEM_ENTRY*
zzip_mem_disk_findmatch(ZZIP_MEM_DISK* dir,
char* filespec, ZZIP_MEM_ENTRY* after,
zzip_fnmatch_fn_t compare, int flags);
/* named access -------------------------------------------------------- */
#define zzip_mem_entry_usize(_e_) ((_e_)->zz_usize)
#define zzip_mem_entry_csize(_e_) ((_e_)->zz_csize)
#define zzip_mem_entry_data_encrypted(_e_) ZZIP_IS_ENCRYPTED((_e_)->zz_flags)
#define zzip_mem_entry_data_streamed(_e_) ZZIP_IS_STREAMED((_e_)->zz_flags)
#define zzip_mem_entry_data_comprlevel(_e_) ((_e_)->zz_compr)
#define zzip_mem_entry_data_stored(_e_) ((_e_)->zz_compr == ZZIP_IS_STORED)
#define zzip_mem_entry_data_deflated(_e_) ((_e_)->zz_compr == ZZIP_IS_DEFLATED)
/* zzip_mem_disk_file -------------------------------------------------- */
/* since only the header data is being cached, all the real data
* operations are actually the same as in mmapped.h - just fopen makes
* access to the header data in memory instead of the zip archive.
*/
typedef ZZIP_DISK_FILE ZZIP_MEM_DISK_FILE;
zzip__new__ ZZIP_MEM_DISK_FILE*
zzip_mem_entry_fopen (ZZIP_MEM_DISK* dir, ZZIP_MEM_ENTRY* entry);
zzip__new__ ZZIP_MEM_DISK_FILE*
zzip_mem_disk_fopen (ZZIP_MEM_DISK* dir, char* filename);
_zzip_size_t
zzip_mem_disk_fread (void* ptr, _zzip_size_t size, _zzip_size_t nmemb,
ZZIP_MEM_DISK_FILE* file);
int
zzip_mem_disk_fclose (ZZIP_MEM_DISK_FILE* file);
int
zzip_mem_disk_feof (ZZIP_MEM_DISK_FILE* file);
/* convert dostime of entry to unix time_t */
long zzip_disk_entry_get_mktime(ZZIP_DISK_ENTRY* entry);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,138 @@
#ifndef _ZZIP_MMAPPED_H_
#define _ZZIP_MMAPPED_H_
/*
* NOTE: this is part of libzzipmmapped (i.e. it is not libzzip).
*
* simplified zip disk access using a mmapping of the whole archive.
*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2003,2004 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#include <zzip/types.h>
#ifdef _ZZIP_DISK_FILE_STRUCT
#include <zlib.h> /* z_stream */
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct zzip_disk_file ZZIP_DISK_FILE;
typedef struct zzip_disk ZZIP_DISK;
/* def struct zzip_disk_entry ZZIP_DISK_ENTRY; */
/* we expose this structure so third party applications can augment
* on them. The mmapped zip access usually just needs the two pointers
* specifying the mmapped area, whereever you have that from.
*/
struct zzip_disk
{
zzip_byte_t* buffer; /* start of mmapped area, the base of all seekvals */
zzip_byte_t* endbuf; /* end of mmapped area, i.e. buffer + buflen */
void* reserved; /* - for later extensions (might be renamed) */
void* user; /* - free for applications (use this!) */
long flags; /* bit 0: findfile searches case-insensitive */
long mapped; /* used for mmap() wrappers of zzip/__mmap.h */
long unused; /* - for later extensions (might be renamed) */
long code; /* - free for applications (use this!) */
};
/* fnmatch search shall be case insensitive */
#define ZZIP_DISK_FLAGS_MATCH_NOCASE 1
#define ZZIP_DISK_FLAGS_OWNED_BUFFER 2
typedef int (*zzip_strcmp_fn_t)(char*, char*);
typedef int (*zzip_fnmatch_fn_t)(char*, char*, int);
#define zzip_disk_extern extern
zzip_disk_extern int
zzip_disk_init(ZZIP_DISK* disk, void* buffer, zzip_size_t buflen);
zzip_disk_extern zzip__new__ ZZIP_DISK*
zzip_disk_new(void);
zzip_disk_extern zzip__new__ ZZIP_DISK*
zzip_disk_mmap(int fd);
zzip_disk_extern int
zzip_disk_munmap(ZZIP_DISK* disk);
zzip_disk_extern zzip__new__ ZZIP_DISK*
zzip_disk_open(char* filename);
zzip_disk_extern zzip__new__ ZZIP_DISK *
zzip_disk_buffer(void *buffer, size_t buflen);
zzip_disk_extern int
zzip_disk_close(ZZIP_DISK* disk);
zzip_disk_extern ZZIP_DISK_ENTRY*
zzip_disk_findfirst(ZZIP_DISK* disk);
zzip_disk_extern ZZIP_DISK_ENTRY*
zzip_disk_findnext(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry);
zzip_disk_extern zzip__new__ char*
zzip_disk_entry_strdup_name(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry);
zzip_disk_extern zzip__new__ char*
zzip_disk_entry_strdup_comment(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry);
zzip_disk_extern struct zzip_file_header*
zzip_disk_entry_to_file_header(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry);
zzip_disk_extern zzip_byte_t*
zzip_disk_entry_to_data(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry);
zzip_disk_extern ZZIP_DISK_ENTRY*
zzip_disk_findfile(ZZIP_DISK* disk,
char* filename, ZZIP_DISK_ENTRY* after,
zzip_strcmp_fn_t compare);
zzip_disk_extern ZZIP_DISK_ENTRY*
zzip_disk_findmatch(ZZIP_DISK* disk,
char* filespec, ZZIP_DISK_ENTRY* after,
zzip_fnmatch_fn_t compare, int flags);
zzip_disk_extern zzip__new__ ZZIP_DISK_FILE*
zzip_disk_entry_fopen (ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry);
zzip_disk_extern zzip__new__ ZZIP_DISK_FILE*
zzip_disk_fopen (ZZIP_DISK* disk, char* filename);
zzip_disk_extern _zzip_size_t
zzip_disk_fread (void* ptr, _zzip_size_t size, _zzip_size_t nmemb,
ZZIP_DISK_FILE* file);
zzip_disk_extern int
zzip_disk_fclose (ZZIP_DISK_FILE* file);
int
zzip_disk_feof (ZZIP_DISK_FILE* file);
#ifdef _ZZIP_DISK_FILE_STRUCT
/**
* typedef struct zzip_disk_file ZZIP_DISK_FILE;
*/
struct zzip_disk_file
{
zzip_byte_t* buffer; /* fopen disk->buffer */
zzip_byte_t* endbuf; /* fopen disk->endbuf */
zzip_size_t avail; /* memorized for checks on EOF */
z_stream zlib; /* for inflated blocks */
zzip_byte_t* stored; /* for stored blocks */
};
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,96 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2002,2003 Guido Draheim
* All rights reserved
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*
* the interfaces for the plugin_io system
*
* Using the following you can provide your own file I/O functions to
* e.g. read data directly from memory, provide simple
* "encryption"/"decryption" of on-disk .zip-files...
* Note that this currently only provides a subset of the functionality
* in zziplib. It does not attempt to provide any directory functions,
* but if your program 1) only uses ordinary on-disk files and you
* just want this for file obfuscation, or 2) you only access your
* .zip archives using zzip_open & co., this is sufficient.
*
* Currently the default io are the POSIX functions, except
* for 'filesize' that is zziplibs own provided zzip_filesize function,
* using standard POSIX fd's. You are however free to replace this with
* whatever data type you need, so long as you provide implementations
* for all the functions, and the data type fits an int.
*
* all functions receiving ext_io are able to cope with both arguments
* set to zero which will let them default to a ZIP ext and posix io.
*/
#ifndef _ZZIP_PLUGIN_H /* zzip-io.h */
#define _ZZIP_PLUGIN_H 1
#include <zzip/zzip.h>
#ifdef __cplusplus
extern "C" {
#endif
/* we have renamed zzip_plugin_io.use_mmap to zzip_plugin_io.sys */
#define ZZIP_PLUGIN_IO_SYS 1
struct zzip_plugin_io { /* use "zzip_plugin_io_handlers" in applications !! */
int (*open)(zzip_char_t* name, int flags, ...);
int (*close)(int fd);
zzip_ssize_t (*read)(int fd, void* buf, zzip_size_t len);
zzip_off_t (*seeks)(int fd, zzip_off_t offset, int whence);
zzip_off_t (*filesize)(int fd);
long sys;
long type;
zzip_ssize_t (*write)(int fd, _zzip_const void* buf, zzip_size_t len);
};
typedef union _zzip_plugin_io
{
struct zzip_plugin_io fd;
struct { void* padding[8]; } ptr;
} zzip_plugin_io_handlers;
#define _zzip_plugin_io_handlers zzip_plugin_io_handlers
/* for backward compatibility, and the following to your application code:
* #ifndef _zzip_plugin_io_handlers
* #define _zzip_plugin_io_handlers struct zzip_plugin_io
*/
typedef zzip_plugin_io_handlers* zzip_plugin_io_handlers_t;
#ifdef ZZIP_LARGEFILE_RENAME
#define zzip_filesize zzip_filesize64
#define zzip_get_default_io zzip_get_default_io64
#define zzip_init_io zzip_init_io64
#endif
_zzip_export zzip_off_t
zzip_filesize(int fd);
/* get the default file I/O functions */
_zzip_export zzip_plugin_io_t zzip_get_default_io(void);
/*
* Initializes a zzip_plugin_io_t to the zziplib default io.
* This is useful if you only want to override e.g. the 'read' function.
* all zzip functions that can receive a zzip_plugin_io_t can
* handle a zero pointer in that place and default to posix io.
*/
_zzip_export
int zzip_init_io(zzip_plugin_io_handlers_t io, int flags);
/* zzip_init_io flags : */
# define ZZIP_IO_USE_MMAP 1
#ifdef __cplusplus
};
#endif
#endif

View File

@@ -0,0 +1,45 @@
#ifndef _ZZIP__STDINT_H /* zzip-stdint.h */
#define _ZZIP__STDINT_H 1
/* this file ensures that we have some kind of typedef declarations for
unsigned C9X typedefs. The ISO C 9X: 7.18 Integer types file is stdint.h
*/
#include <zzip/conf.h>
/* enforce use of ifdef'd C9X entries in system headers */
#define __USE_ANSI 1
#define __USE_ISOC9X 1
#ifdef ZZIP_HAVE_STDINT_H
/* ISO C 9X: 7.18 Integer types <stdint.h> */
#include <stdint.h>
#elif defined ZZIP_HAVE_SYS_INT_TYPES_H /*solaris*/
#include <sys/int_types.h>
#elif defined ZZIP_HAVE_INTTYPES_H /*freebsd*/
#include <inttypes.h>
#else
typedef unsigned char uint8_t; typedef signed char int8_t;
# if ZZIP_SIZEOF_INT && ZZIP_SIZEOF_INT == 2
typedef unsigned int uint16_t; typedef signed int int16_t;
# elif ZZIP_SIZEOF_SHORT && ZZIP_SIZEOF_SHORT == 2
typedef unsigned short uint16_t; typedef signed short int16_t;
# else
# error unable to typedef int16_t from either int or short
typedef unsigned short uint16_t; typedef signed short int16_t;
# endif
# if defined ZZIP_SIZEOF_INT && ZZIP_SIZEOF_INT == 4
typedef unsigned int uint32_t; typedef signed int int32_t;
# elif defined ZZIP_SIZEOF_LONG && ZZIP_SIZEOF_LONG == 4
typedef unsigned long uint32_t; typedef signed long int32_t;
# else
# error unable to typedef int32_t from either int or long
typedef unsigned long uint32_t; typedef signed long int32_t;
# endif
typedef unsigned _zzip___int64 uint64_t; typedef _zzip___int64 int64_t;
#endif
#endif /*_ZZIP_STDINT_H*/

View File

@@ -0,0 +1,57 @@
/*
* unlike in <zzip/conf.h> we are allowed to make up typedefs here,
* while over there only #defines are allowed
*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2003,2004 Guido Draheim
* All rights reserved,
* usage allowed under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*
* This file is usually the first to define some real symbols. If you do
* see some errors here then it is most likely the includepath is wrong
* or some includeheader is missing / unreadable on your system.
* (a) we include local headers with a "zzip/" prefix just to be sure
* to not actually get the wrong one. Consider to add `-I..` somewhere
* and especially VC/IDE users (who make up their own workspace files)
* should include the root source directory of this project.
* (b) size_t and ssize_t are sometimes found be `configure` but they are
* not in the usual places (ANSI C = stddef.h; UNIX = sys/types.h), so
* be sure to look for them and add the respective header as an #include.
*/
#ifndef _ZZIP_TYPES_H_
#define _ZZIP_TYPES_H_
#include <zzip/conf.h>
#include <fcntl.h>
#include <stddef.h> /* size_t and friends */
#ifdef ZZIP_HAVE_SYS_TYPES_H
#include <sys/types.h> /* bsd (mac) has size_t here */
#endif
/* msvc6 has neither ssize_t (we assume "int") nor off_t (assume "long") */
typedef unsigned char zzip_byte_t; // especially zlib decoding data
typedef _zzip_off64_t zzip_off64_t;
typedef _zzip_off_t zzip_off_t;
typedef _zzip_size_t zzip_size_t; /* Some error here? */
typedef _zzip_ssize_t zzip_ssize_t; /* See notes above! */
/* in <zzip/format.h> */
typedef struct zzip_disk64_trailer ZZIP_DISK64_TRAILER;
typedef struct zzip_disk_trailer ZZIP_DISK_TRAILER;
typedef struct zzip_file_trailer ZZIP_FILE_TRAILER;
typedef struct zzip_root_dirent ZZIP_ROOT_DIRENT;
typedef struct zzip_file_header ZZIP_FILE_HEADER;
typedef struct zzip_disk_entry ZZIP_DISK_ENTRY;
typedef struct zzip_extra_block ZZIP_EXTRA_BLOCK;
#endif

View File

@@ -0,0 +1,58 @@
#ifndef _ZZIP_WRITE_H
#define _ZZIP_WRITE_H
#include <zzip/lib.h>
/* ........................................................................
* write support is not yet implemented
* zzip/write.c
*/
#define ZZIP_NO_CREAT 1
ZZIP_DIR* zzip_dir_creat_ext_io(zzip_char_t* name, int o_mode,
zzip_strings_t* ext, zzip_plugin_io_t io);
ZZIP_DIR* zzip_dir_creat(zzip_char_t* name, int o_mode);
int zzip_file_mkdir(ZZIP_DIR* dir, zzip_char_t* name, int o_mode);
ZZIP_FILE* zzip_file_creat(ZZIP_DIR* dir, zzip_char_t* name, int o_mode);
zzip_ssize_t zzip_file_write(ZZIP_FILE* file,
const void* ptr, zzip_size_t len);
ZZIP_DIR* zzip_createdir(zzip_char_t* name, int o_mode);
zzip_ssize_t zzip_write(ZZIP_FILE* file, const void* ptr, zzip_size_t len);
zzip_size_t zzip_fwrite(const void* ptr, zzip_size_t len,
zzip_size_t multiply, ZZIP_FILE* file);
#ifndef zzip_savefile
#define zzip_savefile 0
#define zzip_savefile_is_null
#endif
#ifdef _ZZIP_NO_INLINE
#define zzip_mkdir(_name_,_mode_) \
zzip_file_mkdir((zzip_savefile),(_name_),(_mode_))
#define zzip_creat(_name_,_mode_) \
zzip_file_creat((zzip_savefile),(_name_),(_mode_))
#define zzip_sync() \
{ zzip_closedir((zzip_savefile)); (zzip_savefile) = 0; }
#define zzip_start(_name_,_mode_,_ext_) \
{ if ((zzip_savefile)) zzip_closedir((zzip_savefile));
zzip_savefile = zzip_dir_creat(_name_, _mode_,_ext_); }
#else
_zzip_inline static int zzip_mkdir(zzip_char_t* name, int o_mode)
{ return zzip_file_mkdir(zzip_savefile, name, o_mode); }
_zzip_inline static ZZIP_FILE* zzip_creat(zzip_char_t* name, int o_mode)
{ return zzip_file_creat(zzip_savefile, name, o_mode); }
#ifndef zzip_savefile_is_null
_zzip_inline static void zzip_sync(void)
{ zzip_closedir(zzip_savefile); zzip_savefile = 0; }
_zzip_inline static void zzip_mkfifo(zzip_char_t* name, int o_mode)
{ if ((zzip_savefile)) zzip_closedir (zzip_savefile);
zzip_savefile = zzip_createdir(_name_,_mode_); }
#else
_zzip_inline static void zzip_sync(void) {}
_zzip_inline static void zzip_mkfifo(zzip_char_t* name, int o_mode) {}
#endif
#endif /* _ZZIP_NO_INLINE */
#endif /* _ZZIP_WRITE_H */

View File

@@ -0,0 +1,270 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
* Tomi Ollila <Tomi.Ollila@iki.fi>
*
* Copyright (c) 1999,2000,2001,2002,2003,2004 Guido Draheim
* All rights reserved,
* usage allowed under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*
* if you see "unknown symbol" errors, check first that `-I ..` is part of
* your compiler options - a special hint to VC/IDE users who tend to make up
* their own workspace files. All includes look like #include <zzip|*.h>, so
* you need to add an include path to the dir containing (!!) the ./zzip/ dir
*/
#ifndef _ZZIP_ZZIP_H /* zziplib.h */
#define _ZZIP_ZZIP_H
#include <zzip/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/* the zzip_error_t is also used to pass back ZLIB errors... */
#define ZZIP_ERROR -4096
typedef enum
{
ZZIP_NO_ERROR = 0, /* no error, may be used if user sets it. */
ZZIP_OUTOFMEM = ZZIP_ERROR-20, /* out of memory */
ZZIP_DIR_OPEN = ZZIP_ERROR-21, /* failed to open zipfile, see errno for details */
ZZIP_DIR_STAT = ZZIP_ERROR-22, /* failed to fstat zipfile, see errno for details */
ZZIP_DIR_SEEK = ZZIP_ERROR-23, /* failed to lseek zipfile, see errno for details */
ZZIP_DIR_READ = ZZIP_ERROR-24, /* failed to read zipfile, see errno for details */
ZZIP_DIR_TOO_SHORT = ZZIP_ERROR-25,
ZZIP_DIR_EDH_MISSING = ZZIP_ERROR-26,
ZZIP_DIRSIZE = ZZIP_ERROR-27,
ZZIP_ENOENT = ZZIP_ERROR-28,
ZZIP_UNSUPP_COMPR = ZZIP_ERROR-29,
ZZIP_CORRUPTED = ZZIP_ERROR-31,
ZZIP_UNDEF = ZZIP_ERROR-32,
ZZIP_DIR_LARGEFILE = ZZIP_ERROR-33
} zzip_error_t;
/*
* zzip_open flags.
*/
#define ZZIP_CASEINSENSITIVE O_APPEND /* do not use anymore. use CASLESS */
#define ZZIP_IGNOREPATH O_TRUNC /* do not use anymore. use NOPATHS */
#define ZZIP_EXTRAFLAGS (ZZIP_CASEINSENSITIVE|ZZIP_IGNOREPATH)
/* zzip_open_ext_io o_modes flags : new style. use these from now on! */
#define ZZIP_CASELESS (1<<12) /* ignore filename case inside zips */
#define ZZIP_NOPATHS (1<<13) /* ignore subdir paths, just filename*/
#define ZZIP_PREFERZIP (1<<14) /* try first zipped file, then real*/
#define ZZIP_ONLYZIP (1<<16) /* try _only_ zipped file, skip real*/
#define ZZIP_FACTORY (1<<17) /* old file handle is not closed */
#define ZZIP_ALLOWREAL (1<<18) /* real files use default_io (magic) */
#define ZZIP_THREADED (1<<19) /* try to be safe for multithreading */
/*
* zzip largefile renames
*/
#ifdef ZZIP_LARGEFILE_RENAME
#define zzip_telldir zzip_telldir64
#define zzip_seekdir zzip_seekdir64
#endif
/*
* zzip typedefs
*/
/* zzip_strings_t ext[] = { ".zip", ".jar", ".pk3", 0 } */
typedef char _zzip_const * _zzip_const zzip_strings_t;
typedef char _zzip_const zzip_char_t;
typedef struct zzip_dir ZZIP_DIR;
typedef struct zzip_file ZZIP_FILE;
typedef struct zzip_dirent ZZIP_DIRENT;
typedef struct zzip_dirent ZZIP_STAT;
struct zzip_dirent
{
int d_compr; /* compression method */
int d_csize; /* compressed size */
int st_size; /* file size / decompressed size */
char * d_name; /* file name / strdupped name */
};
/*
* Getting error strings
* zzip/err.c
*/
_zzip_export /* error in _opendir : */
zzip_char_t* zzip_strerror(int errcode);
_zzip_export /* error in other functions : */
zzip_char_t* zzip_strerror_of(ZZIP_DIR * dir);
_zzip_export /* error mapped to errno.h defines : */
int zzip_errno(int errcode);
/*
* Functions to grab information from ZZIP_DIR/ZZIP_FILE structure
* (if ever needed)
* zzip/info.c
*/
_zzip_export
int zzip_error(ZZIP_DIR * dir);
_zzip_export
void zzip_seterror(ZZIP_DIR * dir, int errcode);
_zzip_export
zzip_char_t* zzip_compr_str(int compr);
_zzip_export
ZZIP_DIR * zzip_dirhandle(ZZIP_FILE * fp);
_zzip_export
int zzip_dirfd(ZZIP_DIR * dir);
_zzip_export
int zzip_dir_real(ZZIP_DIR * dir);
_zzip_export
int zzip_file_real(ZZIP_FILE * fp);
_zzip_export
void* zzip_realdir(ZZIP_DIR * dir);
_zzip_export
int zzip_realfd(ZZIP_FILE * fp);
/*
* zip handle management
* zzip/zip.c
*/
_zzip_export
ZZIP_DIR * zzip_dir_alloc(zzip_strings_t* fileext);
_zzip_export
int zzip_dir_free(ZZIP_DIR *);
/*
* Opening/closing a zip archive
* zzip-zip.c
*/
_zzip_export
ZZIP_DIR * zzip_dir_fdopen(int fd, zzip_error_t * errcode_p);
_zzip_export
ZZIP_DIR * zzip_dir_open(zzip_char_t* filename, zzip_error_t * errcode_p);
_zzip_export
int zzip_dir_close(ZZIP_DIR * dir);
_zzip_export
int zzip_dir_read(ZZIP_DIR * dir, ZZIP_DIRENT * dirent);
/*
* Scanning files in zip archive
* zzip/dir.c
* zzip/zip.c
*/
_zzip_export
ZZIP_DIR * zzip_opendir(zzip_char_t* filename);
_zzip_export
int zzip_closedir(ZZIP_DIR * dir);
_zzip_export
ZZIP_DIRENT * zzip_readdir(ZZIP_DIR * dir);
_zzip_export
void zzip_rewinddir(ZZIP_DIR * dir);
#ifndef ANDROID
_zzip_export
zzip_off_t zzip_telldir(ZZIP_DIR * dir);
_zzip_export
void zzip_seekdir(ZZIP_DIR * dir, zzip_off_t offset);
#endif
/*
* 'opening', 'closing' and reading invidual files in zip archive.
* zzip/file.c
*/
_zzip_export
ZZIP_FILE * zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int flags);
_zzip_export
int zzip_file_close(ZZIP_FILE * fp);
_zzip_export
zzip_ssize_t zzip_file_read(ZZIP_FILE * fp, void* buf, zzip_size_t len);
_zzip_export
ZZIP_FILE * zzip_open(zzip_char_t* name, int flags);
_zzip_export
int zzip_close(ZZIP_FILE * fp);
_zzip_export
zzip_ssize_t zzip_read(ZZIP_FILE * fp, void * buf, zzip_size_t len);
/*
* the stdc variant to open/read/close files. - Take note of the freopen()
* call as it may reuse an existing preparsed copy of a zip central directory
*/
_zzip_export
ZZIP_FILE* zzip_freopen(zzip_char_t* name, zzip_char_t* mode, ZZIP_FILE*);
_zzip_export
ZZIP_FILE* zzip_fopen(zzip_char_t* name, zzip_char_t* mode);
_zzip_export
zzip_size_t zzip_fread(void *ptr, zzip_size_t size, zzip_size_t nmemb,
ZZIP_FILE * file);
_zzip_export
int zzip_fclose(ZZIP_FILE * fp);
/*
* seek and tell functions
*/
_zzip_export
int zzip_rewind(ZZIP_FILE *fp);
_zzip_export
zzip_off_t zzip_seek(ZZIP_FILE * fp, zzip_off_t offset, int whence);
_zzip_export
zzip_off_t zzip_tell(ZZIP_FILE * fp);
/*
* reading info of a single file
* zzip/stat.c
*/
_zzip_export
int zzip_dir_stat(ZZIP_DIR * dir, zzip_char_t* name,
ZZIP_STAT * zs, int flags);
_zzip_export
int zzip_file_stat(ZZIP_FILE * fp, ZZIP_STAT * zs);
_zzip_export
int zzip_fstat(ZZIP_FILE * fp, ZZIP_STAT * zs);
#ifdef ZZIP_LARGEFILE_RENAME
#define zzip_open_shared_io zzip_open_shared_io64
#define zzip_open_ext_io zzip_open_ext_io64
#define zzip_opendir_ext_io zzip_opendir_ext_io64
#define zzip_dir_open_ext_io zzip_dir_open_ext_io64
#define zzip_plugin_io_t zzip_plugin_io64_t
#endif
/*
* all ext_io functions can be called with a default of ext/io == zero/zero
* which will default to a ".zip" extension and posix io of the system.
*/
typedef union _zzip_plugin_io _zzip_const * zzip_plugin_io_t;
_zzip_export
ZZIP_FILE * zzip_open_shared_io(ZZIP_FILE* stream,
zzip_char_t* name, int o_flags, int o_modes,
zzip_strings_t* ext, zzip_plugin_io_t io);
_zzip_export
ZZIP_FILE * zzip_open_ext_io(zzip_char_t* name, int o_flags, int o_modes,
zzip_strings_t* ext, zzip_plugin_io_t io);
_zzip_export
ZZIP_DIR * zzip_opendir_ext_io(zzip_char_t* name, int o_modes,
zzip_strings_t* ext, zzip_plugin_io_t io);
_zzip_export
ZZIP_DIR * zzip_dir_open_ext_io(zzip_char_t* filename,
zzip_error_t* errcode_p,
zzip_strings_t* ext, zzip_plugin_io_t io);
/* zzip_file_open_ext_io => zzip_dir_open_ext_io + zzip_file_open */
#ifdef __cplusplus
};
#endif
#endif /* _ZZIPLIB_H */
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/

View File

@@ -0,0 +1,53 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2010 Guido Draheim
* All rights reserved,
* usage allowed under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*
* The compat32 headers is targeted towards those poor souls who can
* not compile their application or library with _LARGEFILE_SOURCE but
* they may still need to access a libzzip compiled in largefile mode.
* In that case they can change back to calling these suffix32 functions
* which are ensured to use "long" as the parameter type - just as it used
* to be before off_t was defined as an alias for it.
*/
#ifndef _ZZIP_ZZIP32_H
#define _ZZIP_ZZIP32_H
#include <zzip/lib.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Scanning files in zip archive.
* Implemented in zzip/dir.c
*/
#ifndef ANDROID
_zzip_export
long zzip_telldir32(ZZIP_DIR * dir);
_zzip_export
void zzip_seekdir32(ZZIP_DIR * dir, long offset);
/*
* seek and tell functions.
* Implemented in zzip/file.c
*/
_zzip_export
long zzip_seek32(ZZIP_FILE * fp, long offset, int whence);
_zzip_export
long zzip_tell32(ZZIP_FILE * fp);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2001 Guido Draheim <guidod@gmx.de>
* Use freely under the restrictions of the ZLIB License
*
* (this example uses errno which might not be multithreaded everywhere)
*/
#include <zzip/SDL_rwops_zzip.h>
#include <zzip/zzip.h>
#include <string.h> /* strchr */
/* MSVC can not take a casted variable as an lvalue ! */
#define SDL_RWOPS_ZZIP_DATA(_context) \
((_context)->hidden.unknown.data1)
#define SDL_RWOPS_ZZIP_FILE(_context) (ZZIP_FILE*) \
((_context)->hidden.unknown.data1)
static int __zzip_seek(SDL_RWops *context, int offset, int whence)
{
return zzip_seek(SDL_RWOPS_ZZIP_FILE(context), offset, whence);
}
static int __zzip_read(SDL_RWops *context, void *ptr, int size, int maxnum)
{
return zzip_read(SDL_RWOPS_ZZIP_FILE(context), ptr, size*maxnum) / size;
}
static int __zzip_write(SDL_RWops *context, const void *ptr, int size, int num)
{
return 0; /* ignored */
}
static int __zzip_close(SDL_RWops *context)
{
if (! context) return 0; /* may be SDL_RWclose is called by atexit */
zzip_close (SDL_RWOPS_ZZIP_FILE(context));
SDL_FreeRW (context);
return 0;
}
SDL_RWops *SDL_RWFromZZIP(const char* file, const char* mode)
{
register SDL_RWops* rwops;
register ZZIP_FILE* zzip_file;
if (! strchr (mode, 'r'))
return SDL_RWFromFile(file, mode);
zzip_file = zzip_fopen (file, mode);
if (! zzip_file) return 0;
rwops = SDL_AllocRW ();
if (! rwops) { errno=ENOMEM; zzip_close (zzip_file); return 0; }
SDL_RWOPS_ZZIP_DATA(rwops) = zzip_file;
rwops->read = __zzip_read;
rwops->write = __zzip_write;
rwops->seek = __zzip_seek;
rwops->close = __zzip_close;
return rwops;
}

334
project/jni/zzip/zzip/dir.c Normal file
View File

@@ -0,0 +1,334 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#include <zzip/lib.h> /* exported... */
#include <zzip/file.h>
#include <stddef.h> /*offsetof */
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef ZZIP_HAVE_SYS_STAT_H
#include <sys/stat.h>
#else
#include <stdio.h>
#endif
#include <zzip/__dirent.h>
#ifndef offsetof
#pragma warning had to DEFINE offsetof as it was not in stddef.h
#define offsetof(T,M) ((unsigned)(& ((T*)0)->M))
#endif
#ifdef ZZIP_HAVE_SYS_STAT_H
/* MSVC does have IFbitmask but not the corresponding IStests */
# if ! defined S_ISDIR && defined S_IFDIR
# define S_ISDIR(_X_) ((_X_) & S_IFDIR)
# endif
# if ! defined S_ISREG && defined S_IFREG
# define S_ISREG(_X_) ((_X_) & S_IFREG)
# endif
#endif
/**
* This function is the equivalent of a => rewinddir(2) for a realdir or
* the zipfile in place of a directory. The ZZIP_DIR handle returned from
* => zzip_opendir has a flag saying realdir or zipfile. As for a zipfile,
* the filenames will include the filesubpath, so take care.
*/
void
zzip_rewinddir(ZZIP_DIR * dir)
{
if (! dir)
return;
if (USE_DIRENT && dir->realdir)
{
_zzip_rewinddir(dir->realdir);
return;
}
if (dir->hdr0)
dir->hdr = dir->hdr0;
else
dir->hdr = 0;
}
#if ! USE_DIRENT
#define real_readdir(_X_) 1
#else
static int
real_readdir(ZZIP_DIR * dir)
{
struct stat st = { 0 };
char filename[PATH_MAX];
struct dirent *dirent = _zzip_readdir(dir->realdir);
if (! dirent)
return 0;
dir->dirent.d_name = dirent->d_name;
strcpy(filename, dir->realname);
strcat(filename, "/");
strcat(filename, dirent->d_name);
if (stat(filename, &st) == -1)
return -1;
dir->dirent.d_csize = dir->dirent.st_size = st.st_size;
if (st.st_mode)
{
if (! S_ISREG(st.st_mode))
{
dir->dirent.d_compr = st.st_mode;
dir->dirent.d_compr |= 0x80000000;
/* makes it effectively negative,
* but can still be fed to S_ISXXX(x) */
} else
{
dir->dirent.d_compr = 0; /* stored */
}
} else
{
dir->dirent.d_compr = 0; /* stored */
}
return 1;
}
#endif
/**
* This function is the equivalent of a => readdir(2) for a realdir
* or a zipfile referenced by the ZZIP_DIR returned from => zzip_opendir.
*
* The ZZIP_DIR handle (as returned by => zzip_opendir) contains a few more
* entries than being copied into the ZZIP_DIRENT. The only valid fields in
* a ZZIP_DIRENT are d_name (the file name), d_compr (compression), d_csize
* (compressed size), st_size (uncompressed size).
*/
ZZIP_DIRENT *
zzip_readdir(ZZIP_DIR * dir)
{
if (! dir)
{ errno=EBADF; return 0; }
if (USE_DIRENT && dir->realdir)
{
if (! real_readdir(dir))
return 0;
} else
{
if (! dir->hdr)
return 0;
dir->dirent.d_name = dir->hdr->d_name;
dir->dirent.d_compr = dir->hdr->d_compr;
dir->dirent.d_csize = dir->hdr->d_csize;
dir->dirent.st_size = dir->hdr->d_usize;
if (! dir->hdr->d_reclen)
dir->hdr = 0;
else
dir->hdr = (struct zzip_dir_hdr *)
((char *) dir->hdr + dir->hdr->d_reclen);
}
return &dir->dirent;
}
/** => zzip_rewinddir
* This function is the equivalent of => telldir(2) for a realdir or zipfile.
*/
#ifndef ANDROID
zzip_off_t
zzip_telldir(ZZIP_DIR * dir)
{
if (! dir)
{ errno=EBADF; return -1; }
if (USE_DIRENT && dir->realdir)
{
return _zzip_telldir(dir->realdir);
} else
{
return ((zzip_off_t) ((char *) dir->hdr - (char *) dir->hdr0));
}
}
/** => zzip_rewinddir
* This function is the equivalent of => seekdir(2) for a realdir or zipfile.
*/
void
zzip_seekdir(ZZIP_DIR * dir, zzip_off_t offset)
{
if (! dir)
return;
if (USE_DIRENT && dir->realdir)
{
_zzip_seekdir(dir->realdir, offset);
} else
{
dir->hdr = (struct zzip_dir_hdr *)
(dir->hdr0 ? (char *) dir->hdr0 + (size_t) offset : 0);
}
}
#ifndef EOVERFLOW
#define EOVERFLOW EFBIG
#endif
/** => zzip_rewinddir
* This function is provided for users who can not use any largefile-mode.
*/
long
zzip_telldir32(ZZIP_DIR * dir)
{
if (sizeof(zzip_off_t) == sizeof(long))
{
return zzip_telldir(dir);
} else
{
off_t off = zzip_telldir(dir);
if (off >= 0) {
register long off32 = off;
if (off32 == off) return off32;
errno = EOVERFLOW;
}
return -1;
}
}
/** => zzip_rewinddir
* This function is provided for users who can not use any largefile-mode.
*/
void
zzip_seekdir32(ZZIP_DIR * dir, long offset)
{
zzip_seekdir(dir, offset);
}
#endif
#if defined ZZIP_LARGEFILE_RENAME && defined EOVERFLOW && defined PIC
#undef zzip_seekdir /* zzip_seekdir64 */
#undef zzip_telldir /* zzip_telldir64 */
/* DLL compatibility layer - so that 32bit code can link with a 64on32 too */
long zzip_telldir(ZZIP_DIR * dir) { return zzip_telldir32(dir); }
void zzip_seekdir(ZZIP_DIR * dir, long offset) { zzip_seekdir32(dir, offset); }
#endif
/**
* This function is the equivalent of => opendir(3) for a realdir or zipfile.
*
* This function has some magic - if the given argument-path
* is a directory, it will wrap a real => opendir(3) into the ZZIP_DIR
* structure. Otherwise it will divert to => zzip_dir_open which
* can also attach a ".zip" extension if needed to find the archive.
*
* the error-code is mapped to => errno(3).
*/
ZZIP_DIR *
zzip_opendir(zzip_char_t * filename)
{
return zzip_opendir_ext_io(filename, 0, 0, 0);
}
/** => zzip_opendir
* This function uses explicit ext and io instead of the internal
* defaults, setting them to zero is equivalent to => zzip_opendir
*/
ZZIP_DIR *
zzip_opendir_ext_io(zzip_char_t * filename, int o_modes,
zzip_strings_t * ext, zzip_plugin_io_t io)
{
zzip_error_t e;
ZZIP_DIR *dir;
# ifdef ZZIP_HAVE_SYS_STAT_H
struct stat st;
# endif
if (o_modes & (ZZIP_PREFERZIP | ZZIP_ONLYZIP))
goto try_zzip;
try_real:
# ifdef ZZIP_HAVE_SYS_STAT_H
if (stat(filename, &st) >= 0 && S_ISDIR(st.st_mode))
{
if (USE_DIRENT)
{
_zzip_DIR *realdir = _zzip_opendir(filename);
if (realdir)
{
if (! (dir = (ZZIP_DIR *) calloc(1, sizeof(*dir))))
{
_zzip_closedir(realdir);
return 0;
} else
{
dir->realdir = realdir;
dir->realname = strdup(filename);
return dir;
}
}
}
return 0;
}
# endif /* HAVE_SYS_STAT_H */
try_zzip:
dir = zzip_dir_open_ext_io(filename, &e, ext, io);
if (! dir && (o_modes & ZZIP_PREFERZIP))
goto try_real;
if (e)
errno = zzip_errno(e);
return dir;
}
/**
* This function is the equivalent of => closedir(3) for a realdir or zipfile.
*
* This function is magic - if the given arg-ZZIP_DIR
* is a real directory, it will call the real => closedir(3) and then
* free the wrapping ZZIP_DIR structure. Otherwise it will divert
* to => zzip_dir_close which will free the ZZIP_DIR structure.
*/
int
zzip_closedir(ZZIP_DIR * dir)
{
if (! dir)
{ errno = EBADF; return -1; }
if (USE_DIRENT && dir->realdir)
{
_zzip_closedir(dir->realdir);
free(dir->realname);
free(dir);
return 0;
} else
{
zzip_dir_close(dir);
return 0;
}
}
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/

168
project/jni/zzip/zzip/err.c Normal file
View File

@@ -0,0 +1,168 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
* Tomi Ollila <Tomi.Ollila@iki.fi>
*
* Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#include <zzip/lib.h> /* exported... */
#include <zlib.h>
#include <string.h>
#include <errno.h>
#include <zzip/file.h>
/* *INDENT-OFF* */
static struct errlistentry { int code; const char* mesg; }
errlist[] =
{
{ ZZIP_NO_ERROR, "No error" },
{ ZZIP_OUTOFMEM,
"could not get temporary memory for internal structures" },
{ ZZIP_DIR_OPEN, "Failed to open zip-file %s" },
{ ZZIP_DIR_STAT, "Failed to fstat zip-file %s" },
{ ZZIP_DIR_SEEK, "Failed to lseek zip-file %s" },
{ ZZIP_DIR_READ, "Failed to read zip-file %s"},
{ ZZIP_DIR_TOO_SHORT, "zip-file %s too short" },
{ ZZIP_DIR_EDH_MISSING, "zip-file central directory not found" },
{ ZZIP_DIRSIZE, "Directory size too big..." },
{ ZZIP_ENOENT, "No such file found in zip-file %s" },
{ ZZIP_UNSUPP_COMPR, "Unsupported compression format" },
{ ZZIP_CORRUPTED, "Zipfile corrupted" },
{ ZZIP_UNDEF, "Some undefined error occurred" },
{ ZZIP_DIR_LARGEFILE, "Directory is largefile variant" },
{ 0, 0 },
};
/* *INDENT-ON* */
#define errlistSIZE (sizeof(errlist)/sizeof(*errlist))
/**
* returns the static string for the given error code. The
* error code can be either a normal system error (a
* positive error code will flag this), it can be => libz
* error code (a small negative error code will flag this)
* or it can be an error code from => libzzip, which is an
* negative value lower than => ZZIP_ERROR
*/
zzip_char_t *
zzip_strerror(int errcode)
{
if (errcode < ZZIP_ERROR && errcode > ZZIP_ERROR - 32)
{
struct errlistentry *err = errlist;
for (; err->mesg; err++)
{
if (err->code == errcode)
return err->mesg;
}
errcode = EINVAL;
}
if (errcode < 0)
{
if (errcode == -1)
return strerror(errcode);
else
return zError(errcode);
}
return strerror(errcode);
}
/** => zzip_strerror
* This function fetches the errorcode from the => DIR-handle and
* runs it through => zzip_strerror to obtain the static string
* describing the error.
*/
zzip_char_t *
zzip_strerror_of(ZZIP_DIR * dir)
{
if (! dir)
return strerror(errno);
return zzip_strerror(dir->errcode);
}
/* *INDENT-OFF* */
static struct errnolistentry { int code; int e_no; }
errnolist[] =
{
{ Z_STREAM_ERROR, EPIPE },
{ Z_DATA_ERROR, ESPIPE },
{ Z_MEM_ERROR, ENOMEM },
{ Z_BUF_ERROR, EMFILE },
{ Z_VERSION_ERROR, ENOEXEC },
{ ZZIP_DIR_OPEN, ENOTDIR },
{ ZZIP_DIR_STAT, EREMOTE },
{ ZZIP_DIR_SEEK, ESPIPE },
# ifdef ESTRPIPE
{ ZZIP_DIR_READ, ESTRPIPE},
# else
{ ZZIP_DIR_READ, EPIPE},
# endif
{ ZZIP_DIR_TOO_SHORT, ENOEXEC },
# ifdef ENOMEDIUM
{ ZZIP_DIR_EDH_MISSING, ENOMEDIUM },
# else
{ ZZIP_DIR_EDH_MISSING, EIO },
# endif
{ ZZIP_DIRSIZE, EFBIG },
{ ZZIP_OUTOFMEM, ENOMEM },
{ ZZIP_ENOENT, ENOENT },
# ifdef EPFNOSUPPORT
{ ZZIP_UNSUPP_COMPR, EPFNOSUPPORT },
# else
{ ZZIP_UNSUPP_COMPR, EACCES },
# endif
# ifdef EILSEQ
{ ZZIP_CORRUPTED, EILSEQ },
# else
{ ZZIP_CORRUPTED, ELOOP },
# endif
{ ZZIP_UNDEF, EINVAL },
{ 0, 0 },
};
/* *INDENT-ON* */
/**
* map the error code to a system error code. This is used
* for the drop-in replacement functions to return a value
* that can be interpreted correctly by code sections that
* are unaware of the fact they their => open(2) call had been
* diverted to a file inside a zip-archive.
*/
int
zzip_errno(int errcode)
{
if (errcode >= -1)
{
return errno;
} else
{
struct errnolistentry *err = errnolist;
for (; err->code; err++)
{
if (err->code == errcode)
return err->e_no;
}
return EINVAL;
}
}
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/

View File

@@ -0,0 +1,126 @@
/*
* These routines are helpers - note that this file gets linked into all the
* zip-access variants that refer to <zzip/format.h>. On the x86 platform the
* actual definitions will be empty - fetching is done on native machine-level
*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2004,2005,2006 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#include <zzip/fetch.h>
/* ------------------------- fetch helpers --------------------------------- */
/**
* Make 32 bit value in host byteorder from little-endian mapped octet-data
* (works also on machines which SIGBUS on misaligned data access (eg. 68000))
*/
uint32_t
__zzip_get32(unsigned char *s)
{
#if defined __ZZIP_GET32
return __ZZIP_GET32(s);
#else
return ((uint32_t) s[3] << 24) | ((uint32_t) s[2] << 16)
| ((uint32_t) s[1] << 8) | ((uint32_t) s[0]);
#endif
}
/** => __zzip_get32
* This function does the same for a 16 bit value.
*/
uint16_t
__zzip_get16(unsigned char *s)
{
#if defined __ZZIP_GET16
return __ZZIP_GET16(s);
#else
return ((uint16_t) s[1] << 8) | ((uint16_t) s[0]);
#endif
}
/** => __zzip_get32
* This function does the same for an off64_t value.
*/
uint64_t
__zzip_get64(unsigned char *s)
{
#ifdef __GNUC__
/* *INDENT-OFF* */
register uint64_t v
= s[7]; v <<= 8;
v |= s[6]; v <<= 8;
v |= s[5]; v <<= 8;
v |= s[4]; v <<= 8;
v |= s[3]; v <<= 8;
v |= s[2]; v <<= 8;
v |= s[1]; v <<= 8;
v |= s[0]; return v;
/* *INDENT-ON* */
#else
return ((uint64_t) s[7] << 56) | ((uint64_t) s[6] << 48)
| ((uint64_t) s[5] << 40) | ((uint64_t) s[4] << 32)
| ((uint64_t) s[3] << 24) | ((uint64_t) s[2] << 16)
| ((uint64_t) s[1] << 8) | ((uint64_t) s[0]);
#endif
}
/** => __zzip_get32
* This function pushes a 32bit value at the specified address
*/
void
__zzip_set32(unsigned char *s, uint32_t v)
{
#if defined __ZZIP_SET32
return __ZZIP_SET32(s, v);
#else
/* *INDENT-OFF* */
s[0] = (unsigned char) (v); v >>= 8;
s[1] = (unsigned char) (v); v >>= 8;
s[2] = (unsigned char) (v); v >>= 8;
s[3] = (unsigned char) (v);
/* *INDENT-ON* */
#endif
}
/** => __zzip_get32
* This function does the same for a 16 bit value.
*/
void
__zzip_set16(unsigned char *s, uint16_t v)
{
#if defined __ZZIP_SET16
return __ZZIP_SET16(s, v);
#else
/* *INDENT-OFF* */
s[0] = (unsigned char) (v); v >>= 8;
s[1] = (unsigned char) (v);
/* *INDENT-ON* */
#endif
}
/** => __zzip_get32
* This function pushes a off64_t value at the specified address
*/
void
__zzip_set64(unsigned char *s, uint64_t v)
{
/* *INDENT-OFF* */
s[0] = (unsigned char) (v); v >>= 8;
s[1] = (unsigned char) (v); v >>= 8;
s[2] = (unsigned char) (v); v >>= 8;
s[3] = (unsigned char) (v); v >>= 8;
s[4] = (unsigned char) (v); v >>= 8;
s[5] = (unsigned char) (v); v >>= 8;
s[6] = (unsigned char) (v); v >>= 8;
s[7] = (unsigned char) (v);
/* *INDENT-ON* */
}

1177
project/jni/zzip/zzip/file.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,685 @@
/*
* NOTE: this is part of libzzipfseeko (i.e. it is not libzzip).
* ==================
*
* These routines are fully independent from the traditional zzip
* implementation. They assume a readonly seekable stdio handle
* representing a complete zip file. The functions show how to
* parse the structure, find files and return a decoded bytestream.
*
* These routines are a bit simple and really here for documenting
* the way to access a zip file. The complexity of zip access comes
* from staggered reading of bytes and reposition of a filepointer in
* a big archive with lots of files and long compressed datastreams.
* Plus varaints of drop-in stdio replacements, obfuscation routines,
* auto fileextensions, drop-in dirent replacements, and so on...
*
* btw, we can _not_ use fgetpos/fsetpos since an fpos_t has no asserted
* relation to a linear seek value as specified in zip info headers. In
* general it is not a problem if your system has no fseeko/ftello pair
* since we can fallback to fseek/ftell which limits the zip disk size
* to 2MiBs but the zip-storable seek values are 32bit limited anyway.
*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2003,2004 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#define _LARGEFILE_SOURCE 1
#define _ZZIP_ENTRY_STRUCT 1
#include <zzip/fseeko.h>
#include <zzip/fetch.h>
#include <zzip/__mmap.h>
#include <zzip/__fnmatch.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/stat.h>
#if defined ZZIP_HAVE_STRING_H
#include <string.h>
#elif defined ZZIP_HAVE_STRINGS_H
#include <strings.h>
#endif
#if defined ZZIP_HAVE_STDINT_H
#include <stdint.h>
#endif
#if __STDC_VERSION__+0 > 199900L
#define ___
#define ____
#else
#define ___ {
#define ____ }
#endif
#ifndef ZZIP_HAVE_FSEEKO
#define fseeko fseek
#define ftello ftell
#endif
/* note that the struct zzip_entry inherits the zzip_disk_entry values
* and usually carries a copy of its values (in disk format!). To make the
* following code more readable, we use a shorthand notation for the
* upcast needed in C (not needed in C++) as "disk_(entry)".
*/
#ifdef __zzip_entry_extends_zzip_disk_entry
#define disk_(_entry_) _entry_
#else
#define disk_(_entry_) (& (_entry_)->head)
#endif
/* we try to round all seeks to the pagesize - since we do not use
* the sys/mmap interface we have to guess a good value here: */
#define PAGESIZE 8192
/* ====================================================================== */
/* helper functions */
/** => zzip_entry_data_offset
* This functions read the correspoding struct zzip_file_header from
* the zip disk of the given "entry". The returned off_t points to the
* end of the file_header where the current fseek pointer has stopped.
* This is used to immediatly parse out any filename/extras block following
* the file_header. The return value is null on error.
*/
static zzip_off_t
zzip_entry_fread_file_header(ZZIP_ENTRY * entry,
struct zzip_file_header *file_header)
{
if (! entry || ! file_header)
return 0;
___ zzip_off_t offset = zzip_disk_entry_fileoffset(disk_(entry));
if (0 > offset || offset >= entry->disksize)
return 0;
if (fseeko(entry->diskfile, offset, SEEK_SET) == -1) return 0;
return (fread(file_header, sizeof(*file_header), 1, entry->diskfile)
? offset + sizeof(*file_header) : 0);
____;
}
/** helper functions for (fseeko) zip access api
*
* This functions returns the seekval offset of the data portion of the
* file referenced by the given zzip_entry. It requires an intermediate
* check of the file_header structure (i.e. it reads it from disk). After
* this call, the contained diskfile readposition is already set to the
* data_offset returned here. On error -1 is returned.
*/
zzip_off_t
zzip_entry_data_offset(ZZIP_ENTRY * entry)
{
struct zzip_file_header file_header;
if (! entry)
return -1;
___ zzip_off_t offset = zzip_entry_fread_file_header(entry, &file_header);
if (! offset)
return -1;
offset += zzip_file_header_sizeof_tails(&file_header);
if (fseeko(entry->diskfile, offset, SEEK_SET) == -1)
return -1;
return offset;
____;
}
/** => zzip_entry_data_offset
* This function is a big helper despite its little name: in a zip file the
* encoded filenames are usually NOT zero-terminated but for common usage
* with libc we need it that way. Secondly, the filename SHOULD be present
* in the zip central directory but if not then we fallback to the filename
* given in the file_header of each compressed data portion.
*/
zzip__new__ char *
zzip_entry_strdup_name(ZZIP_ENTRY * entry)
{
if (! entry)
return 0;
___ zzip_size_t len;
if ((len = zzip_disk_entry_namlen(disk_(entry))))
{
char *name = malloc(len + 1);
if (! name)
return 0;
memcpy(name, entry->tail, len);
name[len] = '\0';
return name;
}
___ auto struct zzip_file_header header;
if (zzip_entry_fread_file_header(entry, &header)
&& (len = zzip_file_header_namlen(&header)))
{
char *name = malloc(len + 1);
if (! name) {
return 0;
} else {
zzip_size_t n = fread(name, 1, len, entry->diskfile);
if (n != len) {
free (name);
return 0;
}
name[n] = '\0';
return name;
}
}
return 0;
____;
____;
}
static int
prescan_entry(ZZIP_ENTRY * entry)
{
assert(entry);
___ zzip_off_t tailsize = zzip_disk_entry_sizeof_tails(disk_(entry));
if (tailsize + 1 > entry->tailalloc)
{
char *newtail = realloc(entry->tail, tailsize + 1);
if (! newtail)
return ENOMEM;
entry->tail = newtail;
entry->tailalloc = tailsize + 1;
}
# ifdef SIZE_MAX /* from stdint.h */
if (tailsize > (zzip_off_t)(SIZE_MAX)) { return EFBIG; }
# endif
___ zzip_size_t readsize = fread(entry->tail, 1, tailsize, entry->diskfile);
/* name + comment + extras */
if ((zzip_off_t)readsize != tailsize) {
return errno;
} else {
return 0;
} ____; ____;
}
static void
prescan_clear(ZZIP_ENTRY * entry)
{
assert(entry);
if (entry->tail)
free(entry->tail);
entry->tail = 0;
entry->tailalloc = 0;
}
/* ====================================================================== */
/** => zzip_entry_findfile
*
* This function is the first call of all the zip access functions here.
* It contains the code to find the first entry of the zip central directory.
* Here we require the stdio handle to represent a real zip file where the
* disk_trailer is _last_ in the file area, so that its position would be at
* a fixed offset from the end of the file area if not for the comment field
* allowed to be of variable length (which needs us to do a little search
* for the disk_tailer). However, in this simple implementation we disregard
* any disk_trailer info telling about multidisk archives, so we just return
* a pointer to the first entry in the zip central directory of that file.
*
* For an actual means, we are going to search backwards from the end
* of the mmaped block looking for the PK-magic signature of a
* disk_trailer. If we see one then we check the rootseek value to
* find the first disk_entry of the root central directory. If we find
* the correct PK-magic signature of a disk_entry over there then we
* assume we are done and we are going to return a pointer to that label.
*
* The return value is a pointer to the first zzip_disk_entry being checked
* to be within the bounds of the file area specified by the arguments. If
* no disk_trailer was found then null is returned, and likewise we only
* accept a disk_trailer with a seekvalue that points to a disk_entry and
* both parts have valid PK-magic parts. Beyond some sanity check we try to
* catch a common brokeness with zip archives that still allows us to find
* the start of the zip central directory.
*/
zzip__new__ ZZIP_ENTRY *
zzip_entry_findfirst(FILE * disk)
{
if (! disk)
return 0;
if (fseeko(disk, 0, SEEK_END) == -1)
return 0;
___ zzip_off_t disksize = ftello(disk);
if (disksize < (zzip_off_t) sizeof(struct zzip_disk_trailer))
return 0;
/* we read out chunks of 8 KiB in the hope to match disk granularity */
___ zzip_off_t pagesize = PAGESIZE; /* getpagesize() */
___ ZZIP_ENTRY *entry = malloc(sizeof(*entry));
if (! entry)
return 0;
___ unsigned char *buffer = malloc(pagesize);
if (! buffer)
goto nomem;
assert(pagesize / 2 > (zzip_off_t) sizeof(struct zzip_disk_trailer));
/* at each step, we will fread a pagesize block which overlaps with the
* previous read by means of pagesize/2 step at the end of the while(1) */
___ zzip_off_t mapoffs = disksize & ~(pagesize - 1);
___ zzip_off_t mapsize = disksize - mapoffs;
if (mapoffs && mapsize < pagesize / 2)
{
mapoffs -= pagesize / 2;
mapsize += pagesize / 2;
}
assert(mapsize < 3*8192);
while (1)
{
if (fseeko(disk, mapoffs, SEEK_SET) == -1)
goto error;
if (fread(buffer, 1, mapsize, disk) != (zzip_size_t)mapsize)
goto error;
___ unsigned char *p =
buffer + mapsize - sizeof(struct zzip_disk_trailer);
for (; p >= buffer; p--)
{
zzip_off_t root; /* (struct zzip_disk_entry*) */
if (zzip_disk_trailer_check_magic(p))
{
root = zzip_disk_trailer_rootseek((struct zzip_disk_trailer *)
p);
if (root > disksize - (long) sizeof(struct zzip_disk_trailer))
{
/* first disk_entry is after the disk_trailer? can't be! */
struct zzip_disk_trailer *trailer =
(struct zzip_disk_trailer *) p;
zzip_off_t rootsize = zzip_disk_trailer_rootsize(trailer);
if (rootsize > mapoffs)
continue;
/* a common brokeness that can be fixed: we just assume the
* central directory was written directly before : */
root = mapoffs - rootsize;
}
} else if (zzip_disk64_trailer_check_magic(p))
{
struct zzip_disk64_trailer *trailer =
(struct zzip_disk64_trailer *) p;
if (sizeof(zzip_off_t) < 8)
return 0;
root = zzip_disk64_trailer_rootseek(trailer);
} else
continue;
assert(0 <= root && root < mapsize);
if (fseeko(disk, root, SEEK_SET) == -1)
goto error;
if (fread(disk_(entry), 1, sizeof(*disk_(entry)), disk)
!= sizeof(*disk_(entry))) goto error;
if (zzip_disk_entry_check_magic(entry))
{
free(buffer);
entry->headseek = root;
entry->diskfile = disk;
entry->disksize = disksize;
if (prescan_entry(entry))
goto nomem;
return entry;
}
}
____;
if (! mapoffs)
break;
assert(mapsize >= pagesize / 2);
mapoffs -= pagesize / 2; /* mapsize += pagesize/2; */
mapsize = pagesize; /* if (mapsize > pagesize) ... */
if (disksize - mapoffs > 64 * 1024)
break;
}
error:
free(buffer);
nomem:
free(entry);
____;
____;
____;
____;
____;
____;
return 0;
}
/** => zzip_entry_findfile
*
* This function takes an existing "entry" in the central root directory
* (e.g. from zzip_entry_findfirst) and moves it to point to the next entry.
* On error it returns 0, otherwise the old entry. If no further match is
* found then null is returned and the entry already free()d. If you want
* to stop searching for matches before that case then please call
* => zzip_entry_free on the cursor struct ZZIP_ENTRY.
*/
zzip__new__ ZZIP_ENTRY *
zzip_entry_findnext(ZZIP_ENTRY * _zzip_restrict entry)
{
if (! entry)
return entry;
if (! zzip_disk_entry_check_magic(entry))
goto err;
___ zzip_off_t seek =
entry->headseek + zzip_disk_entry_sizeto_end(disk_(entry));
if (seek + (zzip_off_t) sizeof(*disk_(entry)) > entry->disksize)
goto err;
if (fseeko(entry->diskfile, seek, SEEK_SET) == -1)
goto err;
if (fread(disk_(entry), 1, sizeof(*disk_(entry)), entry->diskfile)
!= sizeof(*disk_(entry))) goto err;
entry->headseek = seek;
if (! zzip_disk_entry_check_magic(entry))
goto err;
if (prescan_entry(entry))
goto err;
return entry;
err:
zzip_entry_free(entry);
return 0;
____;
}
/** => zzip_entry_findfile
* this function releases the malloc()ed areas needed for zzip_entry, the
* pointer is invalid afterwards. This function has #define synonyms of
* zzip_entry_findlast(), zzip_entry_findlastfile(), zzip_entry_findlastmatch()
*/
int
zzip_entry_free(ZZIP_ENTRY * entry)
{
if (! entry)
return 0;
prescan_clear(entry);
free(entry);
return 1;
}
/** search for files in the (fseeko) zip central directory
*
* This function is given a filename as an additional argument, to find the
* disk_entry matching a given filename. The compare-function is usually
* strcmp or strcasecmp or perhaps strcoll, if null then strcmp is used.
* - use null as argument for "old"-entry when searching the first
* matching entry, otherwise the last returned value if you look for other
* entries with a special "compare" function (if null then a doubled search
* is rather useless with this variant of _findfile). If no further entry is
* found then null is returned and any "old"-entry gets already free()d.
*/
zzip__new__ ZZIP_ENTRY *
zzip_entry_findfile(FILE * disk, char *filename,
ZZIP_ENTRY * _zzip_restrict entry, zzip_strcmp_fn_t compare)
{
if (! filename || ! disk)
return 0;
if (! entry)
entry = zzip_entry_findfirst(disk);
else
entry = zzip_entry_findnext(entry);
if (! compare)
compare = (zzip_strcmp_fn_t) (strcmp);
for (; entry; entry = zzip_entry_findnext(entry))
{
/* filenames within zip files are often not null-terminated! */
char *realname = zzip_entry_strdup_name(entry);
if (! realname)
continue;
if (! compare(filename, realname))
{
free(realname);
return entry;
} else
{
free(realname);
continue;
}
}
return 0;
}
/** => zzip_entry_findfile
*
* This function uses a compare-function with an additional argument
* and it is called just like fnmatch(3) from POSIX.2 AD:1993), i.e.
* the argument filespec first and the ziplocal filename second with
* the integer-flags put in as third to the indirect call. If the
* platform has fnmatch available then null-compare will use that one
* and otherwise we fall back to mere strcmp, so if you need fnmatch
* searching then please provide an implementation somewhere else.
* - use null as argument for "after"-entry when searching the first
* matching entry, or the last disk_entry return-value to find the
* next entry matching the given filespec. If no further entry is
* found then null is returned and any "old"-entry gets already free()d.
*/
zzip__new__ ZZIP_ENTRY *
zzip_entry_findmatch(FILE * disk, char *filespec,
ZZIP_ENTRY * _zzip_restrict entry,
zzip_fnmatch_fn_t compare, int flags)
{
if (! filespec || ! disk)
return 0;
if (! entry)
entry = zzip_entry_findfirst(disk);
else
entry = zzip_entry_findnext(entry);
if (! compare)
compare = (zzip_fnmatch_fn_t) _zzip_fnmatch;
for (; entry; entry = zzip_entry_findnext(entry))
{
/* filenames within zip files are often not null-terminated! */
char *realname = zzip_entry_strdup_name(entry);
if (! realname)
continue;
if (! compare(filespec, realname, flags))
{
free(realname);
return entry;
} else
{
free(realname);
continue;
}
}
return 0;
}
/* ====================================================================== */
/**
* typedef struct zzip_disk_file ZZIP_ENTRY_FILE;
*/
struct zzip_entry_file /* : zzip_file_header */
{
struct zzip_file_header header; /* fopen detected header */
ZZIP_ENTRY *entry; /* fopen entry */
zzip_off_t data; /* for stored blocks */
zzip_size_t avail; /* memorized for checks on EOF */
zzip_size_t compressed; /* compressed flag and datasize */
zzip_size_t dataoff; /* offset from data start */
z_stream zlib; /* for inflated blocks */
unsigned char buffer[PAGESIZE]; /* work buffer for inflate algorithm */
};
/** open a file within a zip disk for reading
*
* This function does take an "entry" argument and copies it (or just takes
* it over as owner) to a new ZZIP_ENTRY_FILE handle structure. That
* structure contains also a zlib buffer for decoding. This function does
* seek to the file_header of the given "entry" and validates it for the
* data buffer following it. We do also prefetch some data from the data
* buffer thereby trying to match the disk pagesize for faster access later.
* The => zzip_entry_fread will then read in chunks of pagesizes which is
* the size of the internal readahead buffer. If an error occurs then null
* is returned.
*/
zzip__new__ ZZIP_ENTRY_FILE *
zzip_entry_fopen(ZZIP_ENTRY * entry, int takeover)
{
if (! entry)
return 0;
if (! takeover)
{
ZZIP_ENTRY *found = malloc(sizeof(*entry));
if (! found)
return 0;
memcpy(found, entry, sizeof(*entry)); /* prescan_copy */
found->tail = malloc(found->tailalloc);
if (! found->tail)
{ free (found); return 0; }
memcpy(found->tail, entry->tail, entry->tailalloc);
entry = found;
}
___ ZZIP_ENTRY_FILE *file = malloc(sizeof(*file));
if (! file)
goto fail1;
file->entry = entry;
if (! zzip_entry_fread_file_header(entry, &file->header))
goto fail2;
file->avail = zzip_file_header_usize(&file->header);
file->data = zzip_entry_data_offset(entry);
file->dataoff = 0;
if (! file->avail || zzip_file_header_data_stored(&file->header))
{ file->compressed = 0; return file; }
file->compressed = zzip_file_header_csize(&file->header);
file->zlib.opaque = 0;
file->zlib.zalloc = Z_NULL;
file->zlib.zfree = Z_NULL;
___ zzip_off_t seek = file->data;
seek += sizeof(file->buffer);
seek -= seek & (sizeof(file->buffer) - 1);
assert(file->data < seek); /* pre-read to next PAGESIZE boundary... */
if (fseeko(file->entry->diskfile, file->data + file->dataoff, SEEK_SET) == -1)
goto fail2;
file->zlib.next_in = file->buffer;
file->zlib.avail_in = fread(file->buffer, 1, seek - file->data,
file->entry->diskfile);
file->dataoff += file->zlib.avail_in;
____;
if (! zzip_file_header_data_deflated(&file->header)
|| inflateInit2(&file->zlib, -MAX_WBITS) != Z_OK)
goto fail2;
return file;
fail2:
free(file);
fail1:
zzip_entry_free(entry);
return 0;
____;
}
/** => zzip_entry_fopen
*
* This function opens a file found by name, so it does a search into
* the zip central directory with => zzip_entry_findfile and whatever
* is found first is given to => zzip_entry_fopen
*/
zzip__new__ ZZIP_ENTRY_FILE *
zzip_entry_ffile(FILE * disk, char *filename)
{
ZZIP_ENTRY *entry = zzip_entry_findfile(disk, filename, 0, 0);
if (! entry)
return 0;
return zzip_entry_fopen(entry, 1);
}
/** => zzip_entry_fopen
*
* This function reads more bytes into the output buffer specified as
* arguments. The return value is null on eof or error, the stdio-like
* interface can not distinguish between these so you need to check
* with => zzip_entry_feof for the difference.
*/
zzip_size_t
zzip_entry_fread(void *ptr, zzip_size_t sized, zzip_size_t nmemb,
ZZIP_ENTRY_FILE * file)
{
if (! file)
return 0;
___ zzip_size_t size = sized * nmemb;
if (! file->compressed)
{
if (size > file->avail)
size = file->avail;
if (fread(ptr, 1, size, file->entry->diskfile) != size) return 0;
file->dataoff += size;
file->avail -= size;
return size;
}
file->zlib.avail_out = size;
file->zlib.next_out = ptr;
___ zzip_size_t total_old = file->zlib.total_out;
while (1)
{
if (! file->zlib.avail_in)
{
size = file->compressed - file->dataoff;
if (size > sizeof(file->buffer))
size = sizeof(file->buffer);
/* fseek (file->data + file->dataoff, file->entry->diskfile); */
file->zlib.avail_in = fread(file->buffer, 1, size,
file->entry->diskfile);
file->zlib.next_in = file->buffer;
file->dataoff += file->zlib.avail_in;
}
if (! file->zlib.avail_in)
return 0;
___ int err = inflate(&file->zlib, Z_NO_FLUSH);
if (err == Z_STREAM_END)
file->avail = 0;
else if (err == Z_OK)
file->avail -= file->zlib.total_out - total_old;
else
return 0;
____;
if (file->zlib.avail_out && ! file->zlib.avail_in)
continue;
return file->zlib.total_out - total_old;
}
____;
____;
}
/** => zzip_entry_fopen
* This function releases any zlib decoder info needed for decompression
* and dumps the ZZIP_ENTRY_FILE struct then.
*/
int
zzip_entry_fclose(ZZIP_ENTRY_FILE * file)
{
if (! file)
return 0;
if (file->compressed)
inflateEnd(&file->zlib);
zzip_entry_free(file->entry);
free(file);
return 0;
}
/** => zzip_entry_fopen
*
* This function allows to distinguish an error from an eof condition.
* Actually, if we found an error but we did already reach eof then we
* just keep on saying that it was an eof, so the app can just continue.
*/
int
zzip_entry_feof(ZZIP_ENTRY_FILE * file)
{
return ! file || ! file->avail;
}

View File

@@ -0,0 +1,163 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2000,2001,2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#include <zzip/lib.h> /* exported... */
#include <zzip/file.h>
#include <zzip/format.h>
#ifdef ZZIP_HAVE_SYS_STAT_H
#include <sys/stat.h>
#else
#include <stdlib.h>
#include <stdio.h>
#endif
/**
* just returns dir->errcode of the ZZIP_DIR handle
* see: => zzip_dir_open, => zzip_dir_open, => zzip_readdir, => zzip_dir_read
*/
int
zzip_error(ZZIP_DIR * dir)
{
return dir->errcode;
}
/** => zzip_error
* This function just does dir->errcode = errcode
*/
void
zzip_seterror(ZZIP_DIR * dir, int errcode) { dir->errcode = errcode; }
/**
* This function will just return fp->dir
*
* If a ZZIP_FILE is contained within a zip-file that one will be a valid
* pointer, otherwise a NULL is returned and the ZZIP_FILE wraps a real file.
*/
ZZIP_DIR *
zzip_dirhandle(ZZIP_FILE * fp)
{
return fp->dir;
}
/** => zzip_dirhandle
* This function will just return dir->fd
*
* If a ZZIP_DIR does point to a zipfile then the file-descriptor of that
* zipfile is returned, otherwise a NULL is returned and the ZZIP_DIR wraps
* a real directory DIR (if you have dirent on your system).
*/
int
zzip_dirfd(ZZIP_DIR * dir)
{
return dir->fd;
}
/**
* return static const string of the known compression methods,
* otherwise just "zipped" is returned
*/
zzip_char_t *
zzip_compr_str(int compr)
{
switch (compr)
{
/* *INDENT-OFF* */
case ZZIP_IS_STORED: return "stored";
case ZZIP_IS_SHRUNK: return "shrunk";
case ZZIP_IS_REDUCEDx1:
case ZZIP_IS_REDUCEDx2:
case ZZIP_IS_REDUCEDx3:
case ZZIP_IS_REDUCEDx4: return "reduced";
case ZZIP_IS_IMPLODED: return "imploded";
case ZZIP_IS_TOKENIZED: return "tokenized";
case ZZIP_IS_DEFLATED: return "deflated";
case ZZIP_IS_DEFLATED_BETTER: return "deflatedX";
case ZZIP_IS_IMPLODED_BETTER: return "implodedX";
default:
if (0 < compr && compr < 256) return "zipped";
else
{
# ifdef S_ISDIR
if (S_ISDIR(compr)) return "directory";
# endif
# ifdef S_ISCHR
if (S_ISCHR(compr)) return "is/chr";
# endif
# ifdef S_ISBLK
if (S_ISBLK(compr)) return "is/blk";
# endif
# ifdef S_ISFIFO
if (S_ISFIFO(compr)) return "is/fifo";
# endif
# ifdef S_ISSOCK
if (S_ISSOCK(compr)) return "is/sock";
# endif
# ifdef S_ISLNK
if (S_ISLNK(compr)) return "is/lnk";
# endif
return "special";
}
/* *INDENT-ON* */
} /*switch */
}
/** => zzip_file_real
* This function checks if the ZZIP_DIR-handle is wrapping
* a real directory or a zip-archive.
* Returns 1 for a stat'able directory, and 0 for a handle to zip-archive.
*/
int
zzip_dir_real(ZZIP_DIR * dir)
{
return dir->realdir != 0;
}
/**
* This function checks if the ZZIP_FILE-handle is wrapping
* a real file or a zip-contained file.
* Returns 1 for a stat'able file, and 0 for a file inside a zip-archive.
*/
int
zzip_file_real(ZZIP_FILE * fp)
{
return fp->dir == 0; /* ie. not dependent on a zip-arch-dir */
}
/** => zzip_file_real
* This function returns the posix DIR* handle (if one exists).
* Check before with => zzip_dir_real if the
* the ZZIP_DIR points to a real directory.
*/
void *
zzip_realdir(ZZIP_DIR * dir)
{
return dir->realdir;
}
/** => zzip_file_real
* This function returns the posix file descriptor (if one exists).
* Check before with => zzip_file_real if the
* the ZZIP_FILE points to a real file.
*/
int
zzip_realfd(ZZIP_FILE * fp)
{
return fp->fd;
}
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/

View File

@@ -0,0 +1,466 @@
/*
* NOTE: this is part of libzzipmmapped (i.e. it is not libzzip).
* ==================
*
* The mem_disk cache will parse the central information of a zip archive
* and store it internally. One the one hand it allows to find files
* faster - no disk access is required and endian conversion is not
* needed. If zzip is compiled with zip extensions then it is about
* the only way to build maintainable code around the zip format.
*
* Note that 64bit support is almost entirely living in extension
* blocks as well as different character encodings and file access
* control bits that are mostly platform specific.
*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#define _ZZIP_DISK_FILE_STRUCT 1
#include <zzip/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <zlib.h>
#include <zzip/format.h>
#include <zzip/fetch.h>
#include <zzip/mmapped.h>
#include <zzip/memdisk.h>
#include <zzip/__fnmatch.h>
#define ___ {
#define ____ }
static const char *error[] = {
"Ok",
# define _zzip_mem_disk_open_fail 1
"zzip_mem_disk_open: zzip_disk_open did fail",
# define _zzip_mem_disk_fdopen_fail 2
"zzip_mem_disk_fdopen: zzip_disk_mmap did fail"
# define _zzip_mem_disk_buffer_fail 3
"zzip_mem_disk_buffer: zzip_disk_buffer did fail",
0
};
#define ZZIP_EXTRA_zip64 0x0001
typedef struct _zzip_extra_zip64
{ /* ZIP64 extended information extra field */
zzip_byte_t z_datatype[2]; /* Tag for this "extra" block type */
zzip_byte_t z_datasize[2]; /* Size of this "extra" block */
zzip_byte_t z_usize[8]; /* Original uncompressed file size */
zzip_byte_t z_csize[8]; /* Size of compressed data */
zzip_byte_t z_offset[8]; /* Offset of local header record */
zzip_byte_t z_diskstart[4]; /* Number of the disk for file start */
} zzip_extra_zip64;
/*forward*/
static zzip__new__ ZZIP_MEM_ENTRY *
zzip_mem_entry_new(ZZIP_DISK * disk, ZZIP_DISK_ENTRY * entry);
static void
zzip_mem_entry_free(ZZIP_MEM_ENTRY * _zzip_restrict item);
zzip__new__ ZZIP_MEM_DISK *
zzip_mem_disk_new(void)
{
return calloc(1, sizeof(ZZIP_MEM_DISK));
}
/** create new diskdir handle.
* wraps underlying zzip_disk_open. */
zzip__new__ ZZIP_MEM_DISK *
zzip_mem_disk_open(char *filename)
{
ZZIP_DISK *disk = zzip_disk_open(filename);
if (! disk)
{ perror(error[_zzip_mem_disk_open_fail]); return 0; }
___ ZZIP_MEM_DISK *dir = zzip_mem_disk_new();
zzip_mem_disk_load(dir, disk);
return dir;
____;
}
/** create new diskdir handle.
* wraps underlying zzip_disk_open. */
zzip__new__ ZZIP_MEM_DISK *
zzip_mem_disk_fdopen(int fd)
{
ZZIP_DISK *disk = zzip_disk_mmap(fd);
if (! disk)
{ perror(error[_zzip_mem_disk_fdopen_fail]); return 0; }
___ ZZIP_MEM_DISK *dir = zzip_mem_disk_new();
zzip_mem_disk_load(dir, disk);
return dir;
____;
}
/** create new diskdir handle.
* wraps underlying zzip_disk_buffer. */
zzip__new__ ZZIP_MEM_DISK *
zzip_mem_disk_buffer(char *buffer, size_t buflen)
{
ZZIP_DISK *disk = zzip_disk_buffer(buffer, buflen);
if (! disk)
{ perror(error[_zzip_mem_disk_buffer_fail]); return 0; }
___ ZZIP_MEM_DISK *dir = zzip_mem_disk_new();
zzip_mem_disk_load(dir, disk);
return dir;
____;
}
/** parse central dir.
* creates an internal copy of each entry converted to the local platform.
* returns: number of entries, or -1 on error (setting errno)
*/
long
zzip_mem_disk_load(ZZIP_MEM_DISK * dir, ZZIP_DISK * disk)
{
if (! dir || ! disk)
{ errno=EINVAL; return -1; }
if (dir->list)
zzip_mem_disk_unload(dir);
___ long count = 0;
___ struct zzip_disk_entry *entry = zzip_disk_findfirst(disk);
for (; entry; entry = zzip_disk_findnext(disk, entry))
{
ZZIP_MEM_ENTRY *item = zzip_mem_entry_new(disk, entry);
if (! item)
goto error;
if (dir->last)
{
dir->last->zz_next = item; /* chain last */
} else
{
dir->list = item;
}
dir->last = item; /* to earlier */
count++;
}
____;
dir->disk = disk;
return count;
____;
error:
zzip_mem_disk_unload(dir);
return -1;
}
/** convert a zip disk entry to internal format.
* creates a new item parsing the information out of the various places
* in the zip archive. This is a good place to extend functionality if
* you have a project with extra requirements as you can push more bits
* right into the diskdir_entry for later usage in higher layers.
* returns: new item, or null on error (setting errno)
*/
zzip__new__ ZZIP_MEM_ENTRY *
zzip_mem_entry_new(ZZIP_DISK * disk, ZZIP_DISK_ENTRY * entry)
{
if (! disk || ! entry)
{ errno=EINVAL; return 0; }
___ ZZIP_MEM_ENTRY *item = calloc(1, sizeof(*item));
if (! item)
return 0; /* errno=ENOMEM; */
___ struct zzip_file_header *header =
zzip_disk_entry_to_file_header(disk, entry);
/* there is a number of duplicated information in the file header
* or the disk entry block. Theoretically some part may be missing
* that exists in the other, ... but we will prefer the disk entry.
*/
item->zz_comment = zzip_disk_entry_strdup_comment(disk, entry);
item->zz_name = zzip_disk_entry_strdup_name(disk, entry);
item->zz_data = zzip_file_header_to_data(header);
item->zz_flags = zzip_disk_entry_get_flags(entry);
item->zz_compr = zzip_disk_entry_get_compr(entry);
item->zz_mktime = zzip_disk_entry_get_mktime(entry);
item->zz_crc32 = zzip_disk_entry_get_crc32(entry);
item->zz_csize = zzip_disk_entry_get_csize(entry);
item->zz_usize = zzip_disk_entry_get_usize(entry);
item->zz_diskstart = zzip_disk_entry_get_diskstart(entry);
item->zz_filetype = zzip_disk_entry_get_filetype(entry);
{ /* copy the extra blocks to memory as well */
int /* */ ext1 = zzip_disk_entry_get_extras(entry);
char *_zzip_restrict ptr1 = zzip_disk_entry_to_extras(entry);
int /* */ ext2 = zzip_file_header_get_extras(header);
char *_zzip_restrict ptr2 = zzip_file_header_to_extras(header);
if (ext1)
{
void *mem = malloc(ext1 + 2);
item->zz_ext[1] = mem;
memcpy(mem, ptr1, ext1);
((char *) (mem))[ext1 + 0] = 0;
((char *) (mem))[ext1 + 1] = 0;
}
if (ext2)
{
void *mem = malloc(ext2 + 2);
item->zz_ext[2] = mem;
memcpy(mem, ptr2, ext2);
((char *) (mem))[ext2 + 0] = 0;
((char *) (mem))[ext2 + 1] = 0;
}
}
{
/* override sizes/offsets with zip64 values for largefile support */
zzip_extra_zip64 *block = (zzip_extra_zip64 *)
zzip_mem_entry_extra_block(item, ZZIP_EXTRA_zip64);
if (block)
{
item->zz_usize = __zzip_get64(block->z_usize);
item->zz_csize = __zzip_get64(block->z_csize);
item->zz_offset = __zzip_get64(block->z_offset);
item->zz_diskstart = __zzip_get32(block->z_diskstart);
}
}
/* NOTE:
* All information from the central directory entry is now in memory.
* Effectivly that allows us to modify it and write it back to disk.
*/
return item;
____;
____;
}
/* find an extra block for the given datatype code.
* We assume that the central directory has been preparsed to memory.
*/
ZZIP_EXTRA_BLOCK *
zzip_mem_entry_extra_block(ZZIP_MEM_ENTRY * entry, short datatype)
{
int i = 2;
while (1)
{
ZZIP_EXTRA_BLOCK *ext = entry->zz_ext[i];
if (ext)
{
while (*(short *) (ext->z_datatype))
{
if (datatype == zzip_extra_block_get_datatype(ext))
{
return ext;
}
___ char *e = (char *) ext;
e += zzip_extra_block_headerlength;
e += zzip_extra_block_get_datasize(ext);
ext = (void *) e;
____;
}
}
if (! i)
return 0;
i--;
}
}
void
zzip_mem_entry_free(ZZIP_MEM_ENTRY * _zzip_restrict item)
{
if (item)
{
/* *INDENT-OFF* */
if (item->zz_ext[0]) free (item->zz_ext[0]);
if (item->zz_ext[1]) free (item->zz_ext[1]);
if (item->zz_ext[2]) free (item->zz_ext[2]);
if (item->zz_comment) free (item->zz_comment);
if (item->zz_name) free (item->zz_name);
free (item);
/* *INDENT-ON* */
}
}
void
zzip_mem_disk_unload(ZZIP_MEM_DISK * dir)
{
ZZIP_MEM_ENTRY *item = dir->list;
while (item)
{
ZZIP_MEM_ENTRY *next = item->zz_next;
zzip_mem_entry_free(item);
item = next;
}
dir->list = dir->last = 0;
zzip_disk_close(dir->disk);
dir->disk = 0;
}
void
zzip_mem_disk_close(ZZIP_MEM_DISK * _zzip_restrict dir)
{
if (dir)
{
zzip_mem_disk_unload(dir);
zzip_disk_close(dir->disk);
free(dir);
}
}
#if 0
static void
foo(short zz_datatype)
{
switch (zz_datatype)
{
/* *INDENT-OFF* */
case 0x0001: /* ZIP64 extended information extra field */
case 0x0007: /* AV Info */
case 0x0008: /* Reserved for future Unicode file name data (PFS) */
case 0x0009: /* OS/2 */
case 0x000a: /* NTFS */
case 0x000c: /* OpenVMS */
case 0x000d: /* Unix */
case 0x000e: /* Reserved for file stream and fork descriptors */
case 0x000f: /* Patch Descriptor */
case 0x0014: /* PKCS#7 Store for X.509 Certificates */
case 0x0015: /* X.509 Certificate ID and Signature for file */
case 0x0016: /* X.509 Certificate ID for Central Directory */
case 0x0017: /* Strong Encryption Header */
case 0x0018: /* Record Management Controls */
case 0x0019: /* PKCS#7 Encryption Recipient Certificate List */
case 0x0065: /* IBM S/390, AS/400 attributes - uncompressed */
case 0x0066: /* Reserved for IBM S/390, AS/400 attr - compressed */
case 0x07c8: /* Macintosh */
case 0x2605: /* ZipIt Macintosh */
case 0x2705: /* ZipIt Macintosh 1.3.5+ */
case 0x2805: /* ZipIt Macintosh 1.3.5+ */
case 0x334d: /* Info-ZIP Macintosh */
case 0x4341: /* Acorn/SparkFS */
case 0x4453: /* Windows NT security descriptor (binary ACL) */
case 0x4704: /* VM/CMS */
case 0x470f: /* MVS */
case 0x4b46: /* FWKCS MD5 (see below) */
case 0x4c41: /* OS/2 access control list (text ACL) */
case 0x4d49: /* Info-ZIP OpenVMS */
case 0x4f4c: /* Xceed original location extra field */
case 0x5356: /* AOS/VS (ACL) */
case 0x5455: /* extended timestamp */
case 0x554e: /* Xceed unicode extra field */
case 0x5855: /* Info-ZIP Unix (original, also OS/2, NT, etc) */
case 0x6542: /* BeOS/BeBox */
case 0x756e: /* ASi Unix */
case 0x7855: /* Info-ZIP Unix (new) */
case 0xfd4a: /* SMS/QDOS */
/* *INDENT-ON* */
}
}
#endif
ZZIP_MEM_ENTRY *
zzip_mem_disk_findfile(ZZIP_MEM_DISK * dir,
char *filename, ZZIP_MEM_ENTRY * after,
zzip_strcmp_fn_t compare)
{
ZZIP_MEM_ENTRY *entry = (! after ? dir->list : after->zz_next);
if (! compare)
compare = (zzip_strcmp_fn_t) (strcmp);
for (; entry; entry = entry->zz_next)
{
if (! compare(filename, entry->zz_name))
{
return entry;
}
}
return 0;
}
ZZIP_MEM_ENTRY *
zzip_mem_disk_findmatch(ZZIP_MEM_DISK * dir,
char *filespec, ZZIP_MEM_ENTRY * after,
zzip_fnmatch_fn_t compare, int flags)
{
ZZIP_MEM_ENTRY *entry = (! after ? dir->list : after->zz_next);
if (! compare)
compare = (zzip_fnmatch_fn_t) _zzip_fnmatch;
for (; entry; entry = entry->zz_next)
{
if (! compare(filespec, entry->zz_name, flags))
{
return entry;
}
}
return 0;
}
zzip__new__ ZZIP_MEM_DISK_FILE *
zzip_mem_entry_fopen(ZZIP_MEM_DISK * dir, ZZIP_MEM_ENTRY * entry)
{
/* keep this in sync with zzip_disk_entry_fopen */
ZZIP_DISK_FILE *file = malloc(sizeof(ZZIP_MEM_DISK_FILE));
if (! file)
return file;
file->buffer = dir->disk->buffer;
file->endbuf = dir->disk->endbuf;
file->avail = zzip_mem_entry_usize(entry);
if (! file->avail || zzip_mem_entry_data_stored(entry))
{ file->stored = zzip_mem_entry_to_data (entry); return file; }
file->stored = 0;
file->zlib.opaque = 0;
file->zlib.zalloc = Z_NULL;
file->zlib.zfree = Z_NULL;
file->zlib.avail_in = zzip_mem_entry_csize(entry);
file->zlib.next_in = zzip_mem_entry_to_data(entry);
if (! zzip_mem_entry_data_deflated(entry) ||
inflateInit2(&file->zlib, -MAX_WBITS) != Z_OK)
{ free (file); return 0; }
return file;
}
zzip__new__ ZZIP_MEM_DISK_FILE *
zzip_mem_disk_fopen(ZZIP_MEM_DISK * dir, char *filename)
{
ZZIP_MEM_ENTRY *entry = zzip_mem_disk_findfile(dir, filename, 0, 0);
if (! entry)
return 0;
else
return zzip_mem_entry_fopen(dir, entry);
}
_zzip_size_t
zzip_mem_disk_fread(void *ptr, _zzip_size_t size, _zzip_size_t nmemb,
ZZIP_MEM_DISK_FILE * file)
{
return zzip_disk_fread(ptr, size, nmemb, file);
}
int
zzip_mem_disk_fclose(ZZIP_MEM_DISK_FILE * file)
{
return zzip_disk_fclose(file);
}
int
zzip_mem_disk_feof(ZZIP_MEM_DISK_FILE * file)
{
return zzip_disk_feof(file);
}
/* convert dostime of entry to unix time_t */
long
zzip_disk_entry_get_mktime(ZZIP_DISK_ENTRY * entry)
{
uint16_t dostime = ZZIP_GET16(entry->z_dostime.time);
uint16_t dosdate = ZZIP_GET16(entry->z_dostime.date);
struct tm date;
date.tm_sec = (dostime) & 0x1F; /* bits 0..4 */
date.tm_min = (dostime >> 5) & 0x3F; /* bits 5..10 */
date.tm_hour = (dostime >> 11); /* bits 11..15 */
date.tm_mday = (dosdate) & 0x1F; /* bits 16..20 */
date.tm_mon = (dosdate >> 5) & 0xF; /* bits 21..24 */
date.tm_year = (dosdate >> 9) + 80; /* bits 25..31 */
return mktime(&date); /* well, unix has that function... */
}

View File

@@ -0,0 +1,646 @@
/*
* NOTE: this is part of libzzipmmapped (i.e. it is not libzzip).
* ==================
*
* These routines are fully independent from the traditional zzip
* implementation. They assume a readonly mmapped sharedmem block
* representing a complete zip file. The functions show how to
* parse the structure, find files and return a decoded bytestream.
*
* These routines are a bit simple and really here for documenting
* the way to access a zip file. The complexity of zip access comes
* from staggered reading of bytes and reposition of a filepointer in
* a big archive with lots of files and long compressed datastreams.
* Plus varaints of drop-in stdio replacements, obfuscation routines,
* auto fileextensions, drop-in dirent replacements, and so on...
*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2003,2004,2006 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#define _ZZIP_DISK_FILE_STRUCT 1
#ifdef __linux__
#define _GNU_SOURCE _glibc_developers_are_idiots_to_call_strndup_gnu_specific_
#endif
#include <zzip/mmapped.h>
#include <zzip/format.h>
#include <zzip/fetch.h>
#include <zzip/__mmap.h>
#include <zzip/__fnmatch.h>
#include <stdlib.h>
#include <sys/stat.h>
#if defined ZZIP_HAVE_UNISTD_H
#include <unistd.h>
#elif defined ZZIP_HAVE_IO_H
#include <io.h>
#endif
#if defined ZZIP_HAVE_STRING_H
#include <string.h>
#elif defined ZZIP_HAVE_STRINGS_H
#include <strings.h>
#endif
#if __STDC_VERSION__+0 > 199900L
#define ___
#define ____
#else
#define ___ {
#define ____ }
#endif
/** => zzip_disk_mmap
* This function does primary initialization of a disk-buffer struct.
*/
int
zzip_disk_init(ZZIP_DISK * disk, void *buffer, zzip_size_t buflen)
{
disk->buffer = (zzip_byte_t *) buffer;
disk->endbuf = (zzip_byte_t *) buffer + buflen;
disk->reserved = 0;
disk->flags = 0;
disk->mapped = 0;
/* do not touch disk->user */
/* do not touch disk->code */
return 0;
}
/** => zzip_disk_mmap
* This function allocates a new disk-buffer with => malloc(3)
*/
zzip__new__ ZZIP_DISK *
zzip_disk_new(void)
{
ZZIP_DISK *disk = malloc(sizeof(ZZIP_DISK));
if (! disk)
return disk;
zzip_disk_init(disk, 0, 0);
return disk;
}
/** turn a filehandle into a mmapped zip disk archive handle
*
* This function uses the given file-descriptor to detect the length of the
* file and calls the system => mmap(2) to put it in main memory. If it is
* successful then a newly allocated ZZIP_DISK* is returned with
* disk->buffer pointing to the mapview of the zipdisk content.
*/
zzip__new__ ZZIP_DISK *
zzip_disk_mmap(int fd)
{
struct stat st;
if (fstat(fd, &st) || ! st.st_size)
return 0;
___ ZZIP_DISK *disk = zzip_disk_new();
if (! disk)
return 0;
disk->buffer = _zzip_mmap(disk->mapped, fd, 0, st.st_size);
if (disk->buffer == MAP_FAILED)
{ free (disk); return 0; }
disk->endbuf = disk->buffer + st.st_size;
return disk;
____;
}
/** => zzip_disk_mmap
* This function is the inverse of => zzip_disk_mmap and using the system
* munmap(2) on the buffer area and => free(3) on the ZZIP_DISK structure.
*/
int
zzip_disk_munmap(ZZIP_DISK * disk)
{
if (! disk)
return 0;
_zzip_munmap(disk->mapped, disk->buffer, disk->endbuf - disk->buffer);
free(disk);
return 0;
}
/** => zzip_disk_mmap
*
* This function opens the given archive by name and turn the filehandle
* to => zzip_disk_mmap for bringing it to main memory. If it can not
* be => mmap(2)'ed then we slurp the whole file into a newly => malloc(2)'ed
* memory block. Only if that fails too then we return null. Since handling
* of disk->buffer is ambigous it should not be snatched away please.
*/
zzip__new__ ZZIP_DISK *
zzip_disk_open(char *filename)
{
# ifndef O_BINARY
# define O_BINARY 0
# endif
struct stat st;
if (stat(filename, &st) || ! st.st_size)
return 0;
___ int fd = open(filename, O_RDONLY | O_BINARY);
if (fd <= 0)
return 0;
___ ZZIP_DISK *disk = zzip_disk_mmap(fd);
if (disk)
return disk;
___ zzip_byte_t *buffer = malloc(st.st_size);
if (! buffer)
return 0;
if ((st.st_size == read(fd, buffer, st.st_size)) &&
(disk = zzip_disk_new()))
{
disk->buffer = buffer;
disk->endbuf = buffer + st.st_size;
disk->mapped = -1;
disk->flags |= ZZIP_DISK_FLAGS_OWNED_BUFFER;
} else {
free(buffer);
}
return disk;
____;
____;
____;
}
/** => zzip_disk_mmap
* This function will attach a buffer with a zip image
* that was acquired from another source than a file.
* Note that if zzip_disk_mmap fails then zzip_disk_open
* will fall back and try to read the full file to memory
* wrapping a ZZIP_DISK around the memory buffer just as
* this function will do. Note that this function will not
* own the buffer, it will neither be written nor free()d.
*/
zzip__new__ ZZIP_DISK *
zzip_disk_buffer(void *buffer, size_t buflen) {
ZZIP_DISK *disk = zzip_disk_new();
if (disk)
{
disk->buffer = (zzip_byte_t *) buffer;
disk->endbuf = (zzip_byte_t *) buffer + buflen;
disk->mapped = -1;
}
return disk;
}
/** => zzip_disk_mmap
*
* This function will release all data needed to access a (mmapped)
* zip archive, including any malloc()ed blocks, sharedmem mappings
* and it dumps the handle struct as well.
*/
int
zzip_disk_close(ZZIP_DISK * disk)
{
if (! disk)
return 0;
if (disk->mapped != -1)
return zzip_disk_munmap(disk);
if (disk->flags & ZZIP_DISK_FLAGS_OWNED_BUFFER)
free(disk->buffer);
free(disk);
return 0;
}
/* ====================================================================== */
/* helper functions */
#ifdef ZZIP_HAVE_STRNDUP
#define _zzip_strndup strndup
#else
/* if your system does not have strndup: */
zzip__new__ static char *
_zzip_strndup(char *p, size_t maxlen)
{
if (! p)
return 0;
___ zzip_byte_t *r = malloc(maxlen + 1);
if (! r)
return r;
strncpy(r, p, maxlen);
r[maxlen] = '\0';
return r;
____;
}
#endif
#if defined ZZIP_HAVE_STRCASECMP || defined strcasecmp
#define _zzip_strcasecmp strcasecmp
#else
/* if your system does not have strcasecmp: */
static int
_zzip_strcasecmp(char *__zzip_restrict a, char *_zzip_restrict b)
{
if (! a)
return (b) ? 1 : 0;
if (! b)
return -1;
while (1)
{
int v = tolower(*a) - tolower(*b);
if (v)
return v;
if (! *a)
return 1;
if (! *b)
return -1;
a++;
b++;
}
}
#endif
/** helper functions for (mmapped) zip access api
*
* This function augments the other zzip_disk_entry_* helpers: here we move
* a disk_entry pointer (as returned by _find* functions) into a pointer to
* the data block right after the file_header. Only disk->buffer would be
* needed to perform the seek but we check the mmapped range end as well.
*/
zzip_byte_t *
zzip_disk_entry_to_data(ZZIP_DISK * disk, struct zzip_disk_entry * entry)
{
struct zzip_file_header *file = zzip_disk_entry_to_file_header(disk, entry);
if (file)
return zzip_file_header_to_data(file);
return 0;
}
/** => zzip_disk_entry_to_data
* This function does half the job of => zzip_disk_entry_to_data where it
* can augment with => zzip_file_header_to_data helper from format/fetch.h
*/
struct zzip_file_header *
zzip_disk_entry_to_file_header(ZZIP_DISK * disk, struct zzip_disk_entry *entry)
{
zzip_byte_t *file_header = /* (struct zzip_file_header*) */
(disk->buffer + zzip_disk_entry_fileoffset(entry));
if (disk->buffer > file_header || file_header >= disk->endbuf)
return 0;
return (struct zzip_file_header *) file_header;
}
/** => zzip_disk_entry_to_data
* This function is a big helper despite its little name: in a zip file the
* encoded filenames are usually NOT zero-terminated but for common usage
* with libc we need it that way. Secondly, the filename SHOULD be present
* in the zip central directory but if not then we fallback to the filename
* given in the file_header of each compressed data portion.
*/
zzip__new__ char *
zzip_disk_entry_strdup_name(ZZIP_DISK * disk, struct zzip_disk_entry *entry)
{
if (! disk || ! entry)
return 0;
___ char *name;
zzip_size_t len;
struct zzip_file_header *file;
if ((len = zzip_disk_entry_namlen(entry)))
name = zzip_disk_entry_to_filename(entry);
else if ((file = zzip_disk_entry_to_file_header(disk, entry)) &&
(len = zzip_file_header_namlen(file)))
name = zzip_file_header_to_filename(file);
else
return 0;
if ((zzip_byte_t *) name < disk->buffer ||
(zzip_byte_t *) name + len > disk->endbuf)
return 0;
return _zzip_strndup(name, len);
____;
}
/** => zzip_disk_entry_to_data
* This function is similar creating a reference to a zero terminated
* string but it can only exist in the zip central directory entry.
*/
zzip__new__ char *
zzip_disk_entry_strdup_comment(ZZIP_DISK * disk, struct zzip_disk_entry *entry)
{
if (! disk || ! entry)
return 0;
___ char *text;
zzip_size_t len;
if ((len = zzip_disk_entry_comment(entry)))
text = zzip_disk_entry_to_comment(entry);
else
return 0;
if ((zzip_byte_t *) text < disk->buffer ||
(zzip_byte_t *) text + len > disk->endbuf)
return 0;
return _zzip_strndup(text, len);
____;
}
/* ====================================================================== */
/** => zzip_disk_findfile
*
* This function is the first call of all the zip access functions here.
* It contains the code to find the first entry of the zip central directory.
* Here we require the mmapped block to represent a real zip file where the
* disk_trailer is _last_ in the file area, so that its position would be at
* a fixed offset from the end of the file area if not for the comment field
* allowed to be of variable length (which needs us to do a little search
* for the disk_tailer). However, in this simple implementation we disregard
* any disk_trailer info telling about multidisk archives, so we just return
* a pointer to the zip central directory.
*
* For an actual means, we are going to search backwards from the end
* of the mmaped block looking for the PK-magic signature of a
* disk_trailer. If we see one then we check the rootseek value to
* find the first disk_entry of the root central directory. If we find
* the correct PK-magic signature of a disk_entry over there then we
* assume we are done and we are going to return a pointer to that label.
*
* The return value is a pointer to the first zzip_disk_entry being checked
* to be within the bounds of the file area specified by the arguments. If
* no disk_trailer was found then null is returned, and likewise we only
* accept a disk_trailer with a seekvalue that points to a disk_entry and
* both parts have valid PK-magic parts. Beyond some sanity check we try to
* catch a common brokeness with zip archives that still allows us to find
* the start of the zip central directory.
*/
struct zzip_disk_entry *
zzip_disk_findfirst(ZZIP_DISK * disk)
{
if (disk->buffer > disk->endbuf - sizeof(struct zzip_disk_trailer))
return 0;
___ zzip_byte_t *p = disk->endbuf - sizeof(struct zzip_disk_trailer);
for (; p >= disk->buffer; p--)
{
zzip_byte_t *root; /* (struct zzip_disk_entry*) */
if (zzip_disk_trailer_check_magic(p))
{
struct zzip_disk_trailer *trailer = (struct zzip_disk_trailer *) p;
root = disk->buffer + zzip_disk_trailer_get_rootseek(trailer);
if (root > p)
{
/* the first disk_entry is after the disk_trailer? can't be! */
zzip_size_t rootsize = zzip_disk_trailer_get_rootsize(trailer);
if (disk->buffer + rootsize > p)
continue;
/* a common brokeness that can be fixed: we just assume the
* central directory was written directly before the trailer:*/
root = p - rootsize;
}
} else if (zzip_disk64_trailer_check_magic(p))
{
struct zzip_disk64_trailer *trailer =
(struct zzip_disk64_trailer *) p;
if (sizeof(void *) < 8)
return 0; /* EOVERFLOW */
root = disk->buffer + zzip_disk64_trailer_get_rootseek(trailer);
if (root > p)
continue;
} else
{
continue;
}
if (root < disk->buffer)
continue;
if (zzip_disk_entry_check_magic(root))
return (struct zzip_disk_entry *) root;
} ____;
return 0;
}
/** => zzip_disk_findfile
*
* This function takes an existing disk_entry in the central root directory
* (e.g. from zzip_disk_findfirst) and returns the next entry within in
* the given bounds of the mmapped file area.
*/
struct zzip_disk_entry *
zzip_disk_findnext(ZZIP_DISK * disk, struct zzip_disk_entry *entry)
{
if ((zzip_byte_t *) entry < disk->buffer ||
(zzip_byte_t *) entry > disk->endbuf - sizeof(entry) ||
! zzip_disk_entry_check_magic(entry) ||
zzip_disk_entry_sizeto_end(entry) > 64 * 1024)
return 0;
entry = zzip_disk_entry_to_next_entry(entry);
if ((zzip_byte_t *) entry > disk->endbuf - sizeof(entry) ||
! zzip_disk_entry_check_magic(entry) ||
zzip_disk_entry_sizeto_end(entry) > 64 * 1024 ||
zzip_disk_entry_skipto_end(entry) + sizeof(entry) > disk->endbuf)
return 0;
else
return entry;
}
/** search for files in the (mmapped) zip central directory
*
* This function is given a filename as an additional argument, to find the
* disk_entry matching a given filename. The compare-function is usually
* strcmp or strcasecmp or perhaps strcoll, if null then strcmp is used.
* - use null as argument for "after"-entry when searching the first
* matching entry, otherwise the last returned value if you look for other
* entries with a special "compare" function (if null then a doubled search
* is rather useless with this variant of _findfile).
*/
struct zzip_disk_entry *
zzip_disk_findfile(ZZIP_DISK * disk, char *filename,
struct zzip_disk_entry *after, zzip_strcmp_fn_t compare)
{
struct zzip_disk_entry *entry = (! after ? zzip_disk_findfirst(disk)
: zzip_disk_findnext(disk, after));
if (! compare)
compare = (zzip_strcmp_fn_t) ((disk->flags & ZZIP_DISK_FLAGS_MATCH_NOCASE) ?
(_zzip_strcasecmp) : (strcmp));
for (; entry; entry = zzip_disk_findnext(disk, entry))
{
/* filenames within zip files are often not null-terminated! */
char *realname = zzip_disk_entry_strdup_name(disk, entry);
if (realname && ! compare(filename, realname))
{
free(realname);
return entry;
}
free(realname);
}
return 0;
}
/** => zzip_disk_findfile
*
* This function uses a compare-function with an additional argument
* and it is called just like fnmatch(3) from POSIX.2 AD:1993), i.e.
* the argument filespec first and the ziplocal filename second with
* the integer-flags put in as third to the indirect call. If the
* platform has fnmatch available then null-compare will use that one
* and otherwise we fall back to mere strcmp, so if you need fnmatch
* searching then please provide an implementation somewhere else.
* - use null as argument for "after"-entry when searching the first
* matching entry, or the last disk_entry return-value to find the
* next entry matching the given filespec.
*/
struct zzip_disk_entry *
zzip_disk_findmatch(ZZIP_DISK * disk, char *filespec,
struct zzip_disk_entry *after,
zzip_fnmatch_fn_t compare, int flags)
{
struct zzip_disk_entry *entry = (! after ? zzip_disk_findfirst(disk)
: zzip_disk_findnext(disk, after));
if (! compare)
{
compare = (zzip_fnmatch_fn_t) _zzip_fnmatch;
if (disk->flags & ZZIP_DISK_FLAGS_MATCH_NOCASE)
flags |= _zzip_fnmatch_CASEFOLD;
}
for (; entry; entry = zzip_disk_findnext(disk, entry))
{
/* filenames within zip files are often not null-terminated! */
char *realname = zzip_disk_entry_strdup_name(disk, entry);
if (realname && ! compare(filespec, realname, flags))
{
free(realname);
return entry;
}
free(realname);
}
return 0;
}
/* ====================================================================== */
/** => zzip_disk_fopen
*
* the ZZIP_DISK_FILE* is rather simple in just encapsulating the
* arguments given to this function plus a zlib deflate buffer.
* Note that the ZZIP_DISK pointer does already contain the full
* mmapped file area of a zip disk, so open()ing a file part within
* that area happens to be a lookup of its bounds and encoding. That
* information is memorized on the ZZIP_DISK_FILE so that subsequent
* _read() operations will be able to get the next data portion or
* return an eof condition for that file part wrapped in the zip archive.
*/
zzip__new__ ZZIP_DISK_FILE *
zzip_disk_entry_fopen(ZZIP_DISK * disk, ZZIP_DISK_ENTRY * entry)
{
/* keep this in sync with zzip_mem_entry_fopen */
struct zzip_file_header *header =
zzip_disk_entry_to_file_header(disk, entry);
if (! header)
return 0;
___ ZZIP_DISK_FILE *file = malloc(sizeof(ZZIP_DISK_FILE));
if (! file)
return file;
file->buffer = disk->buffer;
file->endbuf = disk->endbuf;
file->avail = zzip_file_header_usize(header);
if (! file->avail || zzip_file_header_data_stored(header))
{ file->stored = zzip_file_header_to_data (header); return file; }
file->stored = 0;
file->zlib.opaque = 0;
file->zlib.zalloc = Z_NULL;
file->zlib.zfree = Z_NULL;
file->zlib.avail_in = zzip_file_header_csize(header);
file->zlib.next_in = zzip_file_header_to_data(header);
if (! zzip_file_header_data_deflated(header) ||
inflateInit2(&file->zlib, -MAX_WBITS) != Z_OK)
{ free (file); return 0; }
return file;
____;
}
/** openening a file part wrapped within a (mmapped) zip archive
*
* This function opens a file found by name, so it does a search into
* the zip central directory with => zzip_disk_findfile and whatever
* is found first is given to => zzip_disk_entry_fopen
*/
zzip__new__ ZZIP_DISK_FILE *
zzip_disk_fopen(ZZIP_DISK * disk, char *filename)
{
ZZIP_DISK_ENTRY *entry = zzip_disk_findfile(disk, filename, 0, 0);
if (! entry)
return 0;
else
return zzip_disk_entry_fopen(disk, entry);
}
/** => zzip_disk_fopen
*
* This function reads more bytes into the output buffer specified as
* arguments. The return value is null on eof or error, the stdio-like
* interface can not distinguish between these so you need to check
* with => zzip_disk_feof for the difference.
*/
zzip_size_t
zzip_disk_fread(void *ptr, zzip_size_t sized, zzip_size_t nmemb,
ZZIP_DISK_FILE * file)
{
zzip_size_t size = sized * nmemb;
if (size > file->avail)
size = file->avail;
if (file->stored)
{
memcpy(ptr, file->stored, size);
file->stored += size;
file->avail -= size;
return size;
}
file->zlib.avail_out = sized * nmemb;
file->zlib.next_out = ptr;
___ zzip_size_t total_old = file->zlib.total_out;
___ int err = inflate(&file->zlib, Z_NO_FLUSH);
if (err == Z_STREAM_END)
file->avail = 0;
else if (err == Z_OK)
file->avail -= file->zlib.total_out - total_old;
else
return 0;
return file->zlib.total_out - total_old;
____;
____;
}
/** => zzip_disk_fopen
* This function releases any zlib decoder info needed for decompression
* and dumps the ZZIP_DISK_FILE* then.
*/
int
zzip_disk_fclose(ZZIP_DISK_FILE * file)
{
if (! file->stored)
inflateEnd(&file->zlib);
free(file);
return 0;
}
/** => zzip_disk_fopen
*
* This function allows to distinguish an error from an eof condition.
* Actually, if we found an error but we did already reach eof then we
* just keep on saying that it was an eof, so the app can just continue.
*/
int
zzip_disk_feof(ZZIP_DISK_FILE * file)
{
return ! file || ! file->avail;
}

View File

@@ -0,0 +1,86 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
* Mike Nordell <tamlin-@-algonet-se>
*
* Copyright (c) 2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#include <zzip/lib.h>
#include <zzip/plugin.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#ifdef DEBUG
#include <stdio.h>
#endif
#include <zzip/file.h>
#include <zzip/format.h>
zzip_off_t
zzip_filesize(int fd)
{
struct stat st;
if (fstat(fd, &st) < 0)
return -1;
# if defined DEBUG && ! defined _WIN32
if (! st.st_size && st.st_blocks > 1) /* seen on some darwin 10.1 machines */
fprintf(stderr, "broken fstat(2) ?? st_size=%ld st_blocks=%ld\n",
(long) st.st_size, (long) st.st_blocks);
# endif
return st.st_size;
}
static const struct zzip_plugin_io default_io = {
&open,
&close,
&_zzip_read,
&_zzip_lseek,
&zzip_filesize,
1, 1,
&_zzip_write
};
/** => zzip_init_io
* This function returns a zzip_plugin_io_t handle to static defaults
* wrapping the posix io file functions for actual file access.
*/
zzip_plugin_io_t
zzip_get_default_io(void)
{
return (zzip_plugin_io_t) & default_io;
}
/**
* This function initializes the users handler struct to default values
* being the posix io functions in default configured environments.
*/
int
zzip_init_io(zzip_plugin_io_handlers_t io, int flags)
{
if (! io)
{
return ZZIP_ERROR;
}
memcpy(io, &default_io, sizeof(default_io));
io->fd.sys = flags;
return 0;
}
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/

View File

@@ -0,0 +1,132 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
* Tomi Ollila <Tomi.Ollila@iki.fi>
*
* Copyright (c) 1999,2000,2001,2002 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*
* Description:
* although this file is defining a function called zzip_stat it
* will not need a real stat(2) exported by the Operating System.
* It will just try to fill the fields of the ZZIP_STAT structure
* of
*/
#include <zzip/lib.h> /* exported... */
#include <zzip/file.h>
#include <string.h>
#include <sys/stat.h>
#define ZZIP_USE_INTERNAL
#include <zzip/info.h>
/**
* obtain information about a filename in an opened zip-archive without
* opening that file first. Mostly used to obtain the uncompressed
* size of a file inside a zip-archive. see => zzip_dir_open.
*/
int
zzip_dir_stat(ZZIP_DIR * dir, zzip_char_t * name, ZZIP_STAT * zs, int flags)
{
struct zzip_dir_hdr *hdr = dir->hdr0;
int (*cmp) (zzip_char_t *, zzip_char_t *);
cmp = (flags & ZZIP_CASEINSENSITIVE) ? strcasecmp : strcmp;
if (! hdr)
{
dir->errcode = ZZIP_ENOENT;
return -1;
}
if (flags & ZZIP_IGNOREPATH)
{
char *n = strrchr(name, '/');
if (n)
name = n + 1;
}
while (1)
{
register char *hdr_name = hdr->d_name;
if (flags & ZZIP_IGNOREPATH)
{
register char *n = strrchr(hdr_name, '/');
if (n)
hdr_name = n + 1;
}
if (! cmp(hdr_name, name))
break;
if (! hdr->d_reclen)
{
dir->errcode = ZZIP_ENOENT;
return -1;
}
hdr = (struct zzip_dir_hdr *) ((char *) hdr + hdr->d_reclen);
}
zs->d_compr = hdr->d_compr;
zs->d_csize = hdr->d_csize;
zs->st_size = hdr->d_usize;
zs->d_name = hdr->d_name;
return 0;
}
/** => zzip_dir_stat
* This function will obtain information about a opened file _within_ a
* zip-archive. The file is supposed to be open (otherwise -1 is returned).
* The st_size stat-member contains the uncompressed size. The optional
* d_name is never set here.
*/
int
zzip_file_stat(ZZIP_FILE * file, ZZIP_STAT * zs)
{
if (! file)
return -1;
zs->d_compr = file->method;
zs->d_csize = file->csize;
zs->st_size = file->usize;
zs->d_name = 0;
return 0;
}
/** => zzip_dir_stat
* This function will obtain information about a opened file which may be
* either real/zipped. The file is supposed to be open (otherwise -1 is
* returned). The st_size stat-member contains the uncompressed size.
* The optional d_name is never set here. For a real file, we do set the
* d_csize := st_size and d_compr := 0 for meaningful defaults.
*/
int
zzip_fstat(ZZIP_FILE * file, ZZIP_STAT * zs)
{
if (ZZIP_file_real(file))
{
struct stat st;
if (fstat(file->fd, &st) < 0)
return -1;
zs->st_size = st.st_size;
zs->d_csize = st.st_size;
zs->d_compr = 0;
return 0;
} else
{
return zzip_file_stat(file, zs);
}
}
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/

View File

@@ -0,0 +1,493 @@
/*
* The write-support in zziplib is not a full-flegded interface to the
* internals that zip file-header or zip archive an contain. It's
* primary use goes for savegames or transfer `pack-n-go` archives
* where time-stamps are rather unimportant. Here we can create an
* archive with filenames and their data portions, possibly obfuscated.
*
* DONT USE THIS
*
* The write support is supposed to be added directly into the main
* zziplib but it has not been implemented so far. It does however
* export the relevant call entries which will return EROFS (read-only
* filesystem) in case they are being called. That allows later programs
* to start up with earlier versions of zziplib that can only read ZIPs.
*
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#define _ZZIP_WRITE_SOURCE
#if defined DDDD || defined DDDDD || defined DDDDDD || defined DDDDDDD
#define _ZZIP_ENABLE_WRITE
#else /* per default, we add support for passthrough to posix write */
#define _ZZIP_POSIX_WRITE
#endif
#include <zzip/write.h> /* #includes <zzip/lib.h> */
#include <zzip/file.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef ZZIP_HAVE_DIRECT_H
#include <direct.h>
#endif
#include <zzip/format.h>
#include <zzip/plugin.h>
#include <zzip/__debug.h>
#define ___ {
#define ____ }
#ifndef EROFS
# ifdef ENOSYS
#define EROFS ENOSYS
# else
#define EROFS EPERM
#endif
#endif
/* try real zlib routines for writing ? very experimental, very very ex... */
#ifndef _ZZIP_ENABLE_WRITE
#define _ZZIP_TRY 0
#else
#define _ZZIP_TRY 1
#endif
/* btw, is there any system that did define those different ? get away.. */
# ifndef S_IWGRP
# define S_IWGRP 00020
# endif
# ifndef S_IRWXO
# define S_IRWXO 00007
# endif
# ifdef ZZIP_HAVE_DIRECT_H
# define _mkdir(a,b) mkdir(a)
# else
# define _mkdir mkdir
# endif
/** create a new zip archive for writing
*
* This function will create a new zip archive. The returned parameter
* is a new "zzip dir" handle that should be saved to a variable so it
* can be used a base argument for => zzip_mkdir and => zzip_creat calls.
* The returned handle represents a zip central directory that must be
* saved to disk using => zzip_closedir.
*
* Returns null on error and sets errno. Remember, according to posix
* the => creat(2) call is equivalent to
open (path, O_WRONLY | O_CREAT | O_TRUNC, o_mode)
* so any previous zip-archive will be overwritten unconditionally and
* EEXIST errors from => mkdir(2) are suppressed. (fixme: delete the
* given subtree? like suggested by O_TRUNC? not done so far!)
*/
ZZIP_DIR *
zzip_dir_creat(zzip_char_t * name, int o_mode)
{
return zzip_dir_creat_ext_io(name, o_mode, 0, 0);
}
/** => zzip_dir_creat
*
* If the third argument "ext" has another special meaning here, as it
* is used to ensure that a given zip-file is created with the first entry
* of the ext-list appended as an extension unless the file-path already
* ends with a file-extension registered in the list. Therefore {"",0}
* matches all files and creates them as zip-archives under the given
* nonmodified name. (Some magic here? If the path ends in the path
* separator then make a real directory even in the presence of ext-list?)
*
* This function is not yet implemented, check for #def ZZIP_NO_CREAT
* Write-support will extend => zzip_closedir with semantics to finalize the
* zip-archive by writing the zip-trailer and closing the archive file.
*/
ZZIP_DIR *
zzip_dir_creat_ext_io(zzip_char_t * name, int o_mode,
zzip_strings_t * ext, zzip_plugin_io_t io)
{
if (! io)
io = zzip_get_default_io();
if (io != zzip_get_default_io())
{
/* the current io-structure does not contain a "write" entry,
* and therefore this parameter is useless. Anyone to expect
* some behavior should be warned, so here we let the function
* fail bluntly - and leaving the recovery to the application
*/
errno = EINVAL;
return 0;
}
if (! _ZZIP_TRY)
{
/* not implemented - however, we respect that a null argument to
* zzip_mkdir and zzip_creat works, so we silently still do the mkdir
*/
if (! _mkdir(name, o_mode) || errno == EEXIST)
errno = EROFS;
return 0;
} else
{
# define MAX_EXT_LEN 10
ZZIP_DIR *dir = zzip_dir_alloc(ext);
int name_len = strlen(name);
dir->realname = malloc(name_len + MAX_EXT_LEN);
if (! dir->realname)
goto error;
memcpy(dir->realname, name, name_len + 1);
___ int fd =
__zzip_try_open(dir->realname, O_EXCL | O_TRUNC | O_WRONLY, ext,
io);
if (fd != -1)
{ dir->fd = fd; return dir; }
___ zzip_strings_t *exx = ext;
int exx_len;
for (; *exx; exx++)
{
if ((exx_len = strlen(*exx) + 1) <= name_len &&
! memcmp(dir->realname + (name_len - exx_len), *exx, exx_len))
break; /* keep unmodified */
exx++;
if (*exx)
continue;
if (! (exx_len = strlen(*exx)) || exx_len >= MAX_EXT_LEN)
break;
memcpy(dir->realname + name_len, exx, exx_len); /* append! */
}
____;
fd = io->fd.open(dir->realname, O_CREAT | O_TRUNC | O_WRONLY, o_mode);
dir->realname[name_len] = '\0'; /* keep ummodified */
if (fd != -1)
{ dir->fd = fd; return dir; }
error:
zzip_dir_free(dir);
return 0;
____;
}
}
/** create a new archive area for writing
*
* This function will create a new archive area. This may either be a
* a new zip archive or a new directory in the filesystem. The returned
* parameter is a new "zzip dir" handle that should be saved to a variable
* so it can be used a base argument for => zzip_file_mkdir and
* => zzip_file_creat calls. The returned handle wraps both possibilities,
* it can be representing a zip central directory that must be
* saved to disk using => zzip_closedir or it is just a handle for the
* name of the real directory that still must be run through
* => zzip_closedir to release the wrapper around the directory name.
*
* The magic is pushed through the o_mode argument. Using a mode that
* has no group-write bit set (S_IWGRP = 0040) then the file is
* created as a zip directory. Note that this is unabridged of any
* umask value in the system where the argument to this function could
* be 0775 but with an umask of 0755 it turns out as 0755 for a real
* directory. Using 0755 directly would not create it as a real directory
* but as a zip archive handle.
*
* This function is not yet implemented, check for #def ZZIP_NO_CREAT
* Write-support will extend => zzip_closedir with semantics to finalize the
* zip-archive by writing the zip-trailer and closing the archive file.
*
* Returns null on error and sets errno. Remember, according to posix
* the => creat(2) call is equivalent to
open (path, O_WRONLY | O_CREAT | O_TRUNC, o_mode)
* so any previous zip-archive will be overwritten unconditionally and
* EEXIST errors from => mkdir(2) are suppressed. (fixme: delete the
* given subtree? like suggested by O_TRUNC? not done so far!)
*/
ZZIP_DIR *
zzip_createdir(zzip_char_t * name, int o_mode)
{
if (o_mode & S_IWGRP)
{
if (-1 == _mkdir(name, o_mode) && errno != EEXIST) /* fail */
return 0;
return zzip_opendir(name);
} else
return zzip_dir_creat(name, o_mode);
}
/** => zzip_file_creat also: mkdir(2), creat(2), zzip_dir_creat
*
* This function has an additional primary argument over the posix
* mkdir(2) - if it is null then this function behaves just like
* posix mkdir(2). The zzip_dir argument can be set to the result
* of a => zzip_createdir which allows for some magic that the
* given directory name is created as an entry in the zip archive.
*
* If the given dir name argument is not within the basepath of
* the zip central directory then a real directory is created.
* Any EEXIST errors are not suppressed unlike with => zzip_createdir
*
* Standard usage accepts a global/threaded/modular ZZIP_DIR pointer
* for all zip archive operations like in:
ZZIP_DIR* zip = zzip_createdir (sysconfpath, 0755, zip);
zzip_file_mkdir (zip, filepath[i], 0755);
ZZIP_FILE* file = zzip_file_creat (zip, filename[i], 0644);
zzip_write (file, buf, len);
zzip_close (file); file = 0;
zzip_closedir (zip); zip = 0;
*
* compare with => zzip_mkdir inline macro which allows to
* collapse the examples script to
#define zzip_savefile myproject_saveconfig
#include <zzip/zzip.h>
ZZIP_DIR* zzip_savefile = zzip_createdir (sysconfpath, 0755);
zzip_mkdir (filepath[i], 0755);
ZZIP_FILE* file = zzip_creat(filepath[i], 0644);
zzip_write (file, buf, len);
zzip_close (file); file = 0;
zzip_closedir (zip_savefile);
*/
int
zzip_file_mkdir(ZZIP_DIR * dir, zzip_char_t * name, int o_mode)
{
if (! dir)
return _mkdir(name, o_mode);
if (! _ZZIP_TRY)
{ /* not implemented */
errno = EROFS;
return -1;
} else
{
errno = EROFS;
return -1;
}
}
/** start next file entry in a zip archive
*
* This function will create a new file within a zzip archive, the
* one given as the primary argument and additionally to the posix
* creat(2) - just like zzip_mkdir has an additional argument over
* the posix mkdir(2) spec. For this function the primary parameter
* can be null as well thereby creating a real file instead of a new
* one inside the zip-archive otherwise given. If the primary parameter is
* not null but wraps a real directory then all new files are also real.
*
* This function is not yet implemented, check for #def ZZIP_NO_CREAT
*
* Returns NULL on an error setting errno, and opening a file _within_
* a zip archive using O_RDONLY (and similar stuff) will surely lead to
* an error.
*/
ZZIP_FILE *
zzip_file_creat(ZZIP_DIR * dir, zzip_char_t * name, int o_mode)
{
if (! dir)
return zzip_open(name, o_mode);
if (! _ZZIP_TRY)
{ /* not implemented */
errno = EROFS;
return 0;
} else
{
errno = EROFS;
return 0;
}
}
/** write to zzip storage also: write(2), zlib(3)
*
* This function will write data to a file descriptor. If the file
* descriptor represents a real file then it will be forwarded to
* call posix => write(2) directly. If it is a descriptor for a
* file within a zip directory then the data will be "deflated"
* using => zlib(3) and appended to the zip archive file.
*/
zzip_ssize_t
zzip_write(ZZIP_FILE * file, const void *ptr, zzip_size_t len)
{
if (zzip_file_real(file))
return write(zzip_realfd(file), ptr, len);
else
return zzip_file_write(file, ptr, len);
}
/** => zzip_write also: zzip_file_creat
*
* This function will write data to a file descriptor inside a zip
* archive. The data will be "deflated" using => zlib(3) compression
* and appended to the end of the zip archive file. Only one file
* descriptor may be open per zzip_dir archive handle (fifo-like).
*
* This function is not yet implemented, check for #def ZZIP_NO_CREAT
* It returns immediately -1 and sets errno=EROFS for indication.
*/
zzip_ssize_t
zzip_file_write(ZZIP_FILE * file, const void *ptr, zzip_size_t len)
{
if (! _ZZIP_TRY)
{ /* not implemented */
errno = EROFS;
return -1;
} else
{
/* add calls to zlib here... */
errno = EROFS;
return -1;
}
}
/** => zzip_write
* This function is the stdc variant for writing and the arguments
* are forwarded to => zzip_write - the return value is floored to
* null as for STDC spec but there is no zzip_ferror call so far
* for the zziplib (later? is it actually needed?).
*
* This function is not yet implemented, check for #def ZZIP_NO_CREAT
* Write-support extends => zzip_close with semantics to write out a
* file-trailer to the zip-archive leaving a name/offset marker in
* the (still-open) ZZIP_DIR handle.
*/
zzip_size_t
zzip_fwrite(const void *ptr, zzip_size_t len, zzip_size_t multiply,
ZZIP_FILE * file)
{
zzip_ssize_t value = zzip_write(file, ptr, len * multiply);
if (value == -1)
value = 0;
return (zzip_size_t) value;
}
#if 0 /* pure documentation */
/** create a zipped file/directory also: zzip_dir_creat, mkdir(2)
*
* This function creates a directory entry in the default zip-archive.
* If you did not specify a "#define zzip_savefile somevar"
* then the default zip-archive is null and all directories are
* created as real directories in the filesystem. This function is
* really a preprocessor macro or preferably an inline function
* around => zzip_file_mkdir, there is no such symbol generated
* into the library. The prototype is modelled after the posix
* => mkdir(2) call.
#ifndef zzip_savefile
#define zzip_savefile 0
#endif
#define zzip_mkdir(name,mode) \ -
zzip_file_mkdir(zzip_savefile,name,mode)
*
*/
int inline
zzip_mkdir(zzip_char_t * name, int o_mode)
{
return zzip_file_creat(zzip_savefile, name, mode);
}
#endif
#if 0 /* pure documentation */
/** => zzip_mkdir also: creat(2), zzip_start
*
* This function creates a file in the default zip-archive.
* If you did not specify a "#define zzip_savefile somevar"
* then the default zip-archive is null and all files are created
* as real files. This function is really a preprocessor macro
* or preferably an inline function around => zzip_file_creat,
* there is no such symbol generated into the library. The prototype
* is modelled after the posix => creat(2) call.
#ifndef zzip_savefile
#define zzip_savefile 0
#endif
#define zzip_creat(name,mode) \ -
zzip_file_creat(zzip_savefile,name,mode)
*/
ZZIP_FILE *inline
zzip_creat(zzip_char_t * name, int o_mode)
{
return zzip_file_creat(zzip_savefile, name, mode);
}
#endif
#if 0 /* pure documentation */
/** start writing to the magic zzip_savefile also: zzip_creat, zzip_write
*
* open a zip archive for writing via the magic zzip_savefile macro
* variable. The name and mode are given to => zzip_createdir and
* the result is stored into => zzip_savefile - if the => zzip_savefile
* did already have a zzip_dir handle then it is automatically
* finalized with => zzip_sync and the handle closed and the
* zzip_savefile variable reused for the new zip archive just started
* with this call. - This function is really a preprocessor macro
* or preferably an inline function around => zzip_dir_create, there
* is no such symbol generated into the library.
#ifndef zzip_savefile
#define zzip_savefile 0
#endif
#define zzip_start(name,mode,ext) \ -
{ if (zzip_savefile) zzip_closedir(zzip_savefile); \ -
zzip_savefile = zzip_createdir(name,mode,ext); }
* This function returns null on error or a zzip_dir handle on
* success. It is perfectly okay to continue with a null in the
* zzip_savefile variable since it makes subsequent calls to
* => zzip_creat and => zzip_mkdir to run as => creat(2) / => mkdir(2)
* on the real filesystem.
*/
void inline
zzip_mkfifo(zzip_char_t * name, int o_mode)
{
if (zzip_savefile)
zzip_closedir(zzip_savefile);
zzip_savefile = zzip_createdir(name, o_mode);
}
#endif
#if 0 /* pure documentation */
/** => zzip_mkfifo also: zzip_closedir, sync(2)
*
* finalize a zip archive thereby writing the central directory to
* the end of the file. If it was a real directory then we do just
* nothing - even that the prototype of the call itself is modelled
* to be similar to the posix => sync(2) call. This function is
* really a preprocessor macro or preferably an inline function
* around => zzip_closedir, there is no such symbol generated
* into the library.
#ifndef zzip_savefile
#define zzip_savefile 0
#endif
#define zzip_sync(name,mode) \ -
{ zzip_closedir(zzip_savefile); zzip_savefile = 0; }
*
*/
void inline
zzip_sync(void)
{
zzip_closedir(zzip_savefile);
zzip_savefile = 0;
}
#endif
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/

863
project/jni/zzip/zzip/zip.c Normal file
View File

@@ -0,0 +1,863 @@
/*
* Author:
* Guido Draheim <guidod@gmx.de>
* Tomi Ollila <too@iki.fi>
*
* Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
* or alternatively the restrictions
* of the Mozilla Public License 1.1
*/
#include <zzip/lib.h> /* archive handling */
#include <zzip/file.h>
#include <zzip/format.h>
#include <zzip/fetch.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#ifdef ZZIP_HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <zzip/__mmap.h>
#include <zzip/__debug.h>
#define __sizeof(X) ((zzip_ssize_t)(sizeof(X)))
#ifndef ZZIP_EASY
/* per default, we use a little hack to correct bad z_rootseek parts */
#define ZZIP_CORRECT_ROOTSEEK 1
#endif
#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ >= 4)
# ifdef DEBUG
# warning suppress a warning where the compiler should have optimized instead.
# endif
#define _255 254
#else
#define _255 255
#endif
#define ZZIP_DISK64_TRAILER 1
#ifdef ZZIP_DISK64_TRAILER
struct _disk_trailer
{
void *zz_tail;
void *zz_for_correct_rootseek; // ZZIP_CORRECT_ROOTSEEK
zzip_off64_t zz_entries;
zzip_off64_t zz_finalentries;
zzip_off64_t zz_rootseek;
zzip_off64_t zz_rootsize;
};
#define _disk_trailer_entries(__p) ((__p)->zz_entries)
#define _disk_trailer_localentries(__p) ((__p)->zz_entries)
#define _disk_trailer_finalentries(__p) ((__p)->zz_entries)
#define _disk_trailer_rootseek(__p) ((__p)->zz_rootseek)
#define _disk_trailer_rootsize(__p) ((__p)->zz_rootsize)
#define _disk_trailer_set_rootseek(__p,__v) ((__p)->rootseek = (__v))
#else
#define _disk_trailer zzip_disk_trailer
#define _disk_trailer_entries zzip_disk_trailer_entries
#define _disk_trailer_localentries zzip_disk_trailer_localentries
#define _disk_trailer_finalentries zzip_disk_trailer_finalentries
#define _disk_trailer_rootseek zzip_disk_trailer_rootseek
#define _disk_trailer_rootsize zzip_disk_trailer_rootsize
#define _disk_trailer_set_rootseek zzip_disk_trailer_set_rootseek
#define __zzip_fetch_disk_trailer __zzip_find_disk_trailer
#endif
/* --------------------------- internals -------------------------------- */
/* internal functions of zziplib, avoid at all cost, changes w/o warning.
* we do export them for debugging purpose and special external tools
* which know what they do and which can adapt from version to version
*/
int __zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
struct _disk_trailer *_zzip_restrict trailer,
zzip_plugin_io_t io);
int __zzip_parse_root_directory(int fd,
struct _disk_trailer *trailer,
struct zzip_dir_hdr **hdr_return,
zzip_plugin_io_t io);
_zzip_inline char *__zzip_aligned4(char *p);
/* ------------------------ harden routines ------------------------------ */
#ifdef ZZIP_HARDEN
/*
* check for inconsistent values in trailer and prefer lower seek value
* - we fix values assuming the root directory was written at the end
* and it is just before the zip trailer. Therefore, ...
*/
_zzip_inline static void
__fixup_rootseek(zzip_off_t offset_of_trailer, struct _disk_trailer *trailer)
{
if (_disk_trailer_rootseek(trailer) >
offset_of_trailer - _disk_trailer_rootsize(trailer) &&
offset_of_trailer > _disk_trailer_rootsize(trailer))
{
register zzip_off_t offset;
offset = offset_of_trailer - _disk_trailer_rootsize(trailer);
_disk_trailer_set_rootseek(trailer, offset);
HINT2("new rootseek=%li", (long) _disk_trailer_rootseek(trailer));
}
}
#define __correct_rootseek(A,B,C)
#elif defined ZZIP_CORRECT_ROOTSEEK
/* store the seekvalue of the trailer into the "z_magic" field and with
* a 64bit off_t we overwrite z_disk/z_finaldisk as well. If you change
* anything in zziplib or dump the trailer structure then watch out that
* these are still unused, so that this code may still (ab)use those. */
#define __fixup_rootseek(_offset_of_trailer, _trailer) \
*(zzip_off_t*)_trailer = _offset_of_trailer;
#define __correct_rootseek( _u_rootseek, _u_rootsize, _trailer) \
if (_u_rootseek > *(zzip_off_t*)_trailer - _u_rootsize) \
_u_rootseek = *(zzip_off_t*)_trailer - _u_rootsize;
#else
#define __fixup_rootseek(A,B)
#define __correct_rootseek(A,B,C)
#endif
#ifdef DEBUG
_zzip_inline static void
__debug_dir_hdr(struct zzip_dir_hdr *hdr)
{
if (sizeof(struct zzip_dir_hdr) > sizeof(struct zzip_disk_entry))
{ WARN1("internal sizeof-mismatch may break wreakage"); }
/* the internal directory structure is never bigger than the
* external zip central directory space had been beforehand
* (as long as the following assertion holds...)
*/
if (((zzip_off_t) hdr) & 3)
{
NOTE1("this machine's malloc(3) returns sth. not u32-aligned");
}
/* we assume that if this machine's malloc has returned a non-aligned
* memory block, then it is actually safe to access misaligned data, and
* since it does only affect the first hdr it should not even bring about
* too much of that cpu's speed penalty
*/
}
#else
#define __debug_dir_hdr(X)
#endif
/* -------------------------- low-level interface -------------------------- */
#if defined BUFSIZ
#if BUFSIZ == 1024 || BUFSIZ == 512 || BUFSIZ == 256
#define ZZIP_BUFSIZ BUFSIZ
#endif
#endif
#ifndef ZZIP_BUFSIZ
#define ZZIP_BUFSIZ 512
/* #define ZZIP_BUFSIZ 64 / * for testing */
#endif
/**
* This function is used by => zzip_file_open. It tries to find
* the zip's central directory info that is usually a few
* bytes off the end of the file.
*/
int
__zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
struct _disk_trailer *_zzip_restrict trailer,
zzip_plugin_io_t io)
{
#ifdef DEBUG
#define return(val) { e=val; HINT2("%s", zzip_strerror(e)); goto cleanup; }
#else
#define return(val) { e=val; goto cleanup; }
#endif
register int e;
#ifndef _LOWSTK
auto char buffer[2 * ZZIP_BUFSIZ];
char *buf = buffer;
#else
char *buf = malloc(2 * ZZIP_BUFSIZ);
#endif
zzip_off_t offset = 0;
zzip_ssize_t maplen = 0; /* mmap(),read(),getpagesize() use size_t !! */
char *fd_map = 0;
if (! trailer)
{ return(EINVAL); }
if (filesize < __sizeof(struct zzip_disk_trailer))
{ return(ZZIP_DIR_TOO_SHORT); }
if (! buf)
{ return(ZZIP_OUTOFMEM); }
offset = filesize; /* a.k.a. old offset */
while (1) /* outer loop */
{
register unsigned char *mapped;
if (offset <= 0)
{ return(ZZIP_DIR_EDH_MISSING); }
/* trailer cannot be farther away than 64K from fileend */
if (filesize - offset > 64 * 1024)
{ return(ZZIP_DIR_EDH_MISSING); }
/* the new offset shall overlap with the area after the old offset! */
if (USE_MMAP && io->fd.sys)
{
zzip_off_t mapoff = offset;
{
zzip_ssize_t pagesize = _zzip_getpagesize(io->fd.sys);
if (pagesize < ZZIP_BUFSIZ)
goto non_mmap; /* an error? */
if (mapoff == filesize && filesize > pagesize)
mapoff -= pagesize;
if (mapoff < pagesize)
{
maplen = (zzip_ssize_t) mapoff + pagesize;
mapoff = 0;
} else
{
mapoff -= pagesize;
maplen = 2 * pagesize;
if ((zzip_ssize_t) mapoff & (pagesize - 1))
{ /*only 1. run */
pagesize -= (zzip_ssize_t) mapoff & (pagesize - 1);
mapoff += pagesize;
maplen -= pagesize;
}
}
if (mapoff + maplen > filesize)
maplen = filesize - mapoff;
}
fd_map = _zzip_mmap(io->fd.sys, fd, mapoff, (zzip_size_t) maplen);
if (fd_map == MAP_FAILED)
goto non_mmap;
mapped = (unsigned char *) fd_map;
offset = mapoff; /* success */
HINT3("mapped *%p len=%li", fd_map, (long) maplen);
} else
{
non_mmap:
fd_map = 0; /* have no mmap */
{
zzip_off_t pagesize = ZZIP_BUFSIZ;
if (offset == filesize && filesize > pagesize)
offset -= pagesize;
if (offset < pagesize)
{
maplen = (zzip_ssize_t) offset + pagesize;
offset = 0;
} else
{
offset -= pagesize;
maplen = 2 * pagesize;
if ((zzip_ssize_t) offset & (pagesize - 1))
{ /*on 1st run */
pagesize -= (zzip_ssize_t) offset & (pagesize - 1);
offset += pagesize;
maplen -= pagesize;
}
}
if (offset + maplen > filesize)
maplen = filesize - offset;
}
if (io->fd.seeks(fd, offset, SEEK_SET) < 0)
{ return(ZZIP_DIR_SEEK); }
if (io->fd.read(fd, buf, (zzip_size_t) maplen) < maplen)
{ return(ZZIP_DIR_READ); }
mapped = (unsigned char *) buf; /* success */
HINT5("offs=$%lx len=%li filesize=%li pagesize=%i",
(long) offset, (long) maplen, (long) filesize, ZZIP_BUFSIZ);
}
{ /* now, check for the trailer-magic, hopefully near the end of file */
register unsigned char *end = mapped + maplen;
register unsigned char *tail;
for (tail = end - 1; (tail >= mapped); tail--)
{
if ((*tail == 'P') && /* quick pre-check for trailer magic */
end - tail >= __sizeof(struct zzip_disk_trailer) - 2 &&
zzip_disk_trailer_check_magic(tail))
{
# ifndef ZZIP_DISK64_TRAILER
/* if the file-comment is not present, it happens
that the z_comment field often isn't either */
if (end - tail >= __sizeof(*trailer))
{
memcpy(trailer, tail, sizeof(*trailer));
} else
{
memcpy(trailer, tail, sizeof(*trailer) - 2);
trailer->z_comment[0] = 0;
trailer->z_comment[1] = 0;
}
# else
struct zzip_disk_trailer *orig =
(struct zzip_disk_trailer *) tail;
trailer->zz_tail = tail;
trailer->zz_entries = zzip_disk_trailer_localentries(orig);
trailer->zz_finalentries =
zzip_disk_trailer_finalentries(orig);
trailer->zz_rootseek = zzip_disk_trailer_rootseek(orig);
trailer->zz_rootsize = zzip_disk_trailer_rootsize(orig);
# endif
__fixup_rootseek(offset + tail - mapped, trailer);
{ return(0); }
} else if ((*tail == 'P') &&
end - tail >=
__sizeof(struct zzip_disk64_trailer) - 2
&& zzip_disk64_trailer_check_magic(tail))
{
# ifndef ZZIP_DISK64_TRAILER
return (ZZIP_DIR_LARGEFILE);
# else
struct zzip_disk64_trailer *orig =
(struct zzip_disk64_trailer *) tail;
trailer->zz_tail = tail;
trailer->zz_entries =
zzip_disk64_trailer_localentries(orig);
trailer->zz_finalentries =
zzip_disk64_trailer_finalentries(orig);
trailer->zz_rootseek = zzip_disk64_trailer_rootseek(orig);
trailer->zz_rootsize = zzip_disk64_trailer_rootsize(orig);
{ return(0); }
# endif
}
}
}
if (USE_MMAP && fd_map)
{
HINT3("unmap *%p len=%li", fd_map, (long) maplen);
_zzip_munmap(io->fd.sys, fd_map, (zzip_size_t) maplen);
fd_map = 0;
}
} /*outer loop */
cleanup:
if (USE_MMAP && fd_map)
{
HINT3("unmap *%p len=%li", fd_map, (long) maplen);
_zzip_munmap(io->fd.sys, fd_map, (zzip_size_t) maplen);
}
# ifdef _LOWSTK
free(buf);
# endif
# undef return
return e;
}
/*
* making pointer alignments to values that can be handled as structures
* is tricky. We assume here that an align(4) is sufficient even for
* 64 bit machines. Note that binary operations are not usually allowed
* to pointer types but we do need only the lower bits in this implementation,
* so we can just cast the value to a long value.
*/
_zzip_inline char *
__zzip_aligned4(char *p)
{
#define aligned4 __zzip_aligned4
p += ((long) p) & 1; /* warnings about truncation of a "pointer" */
p += ((long) p) & 2; /* to a "long int" may be safely ignored :) */
return p;
}
/**
* This function is used by => zzip_file_open, it is usually called after
* => __zzip_find_disk_trailer. It will parse the zip's central directory
* information and create a zziplib private directory table in
* memory.
*/
int
__zzip_parse_root_directory(int fd,
struct _disk_trailer *trailer,
struct zzip_dir_hdr **hdr_return,
zzip_plugin_io_t io)
{
auto struct zzip_disk_entry dirent;
struct zzip_dir_hdr *hdr;
struct zzip_dir_hdr *hdr0;
uint16_t *p_reclen = 0;
zzip_off64_t entries;
zzip_off64_t zz_offset; /* offset from start of root directory */
char *fd_map = 0;
zzip_off64_t zz_fd_gap = 0;
zzip_off64_t zz_entries = _disk_trailer_localentries(trailer);
zzip_off64_t zz_rootsize = _disk_trailer_rootsize(trailer);
zzip_off64_t zz_rootseek = _disk_trailer_rootseek(trailer);
__correct_rootseek(zz_rootseek, zz_rootsize, trailer);
hdr0 = (struct zzip_dir_hdr *) malloc(zz_rootsize);
if (! hdr0)
return ZZIP_DIRSIZE;
hdr = hdr0;
__debug_dir_hdr(hdr);
if (USE_MMAP && io->fd.sys)
{
zz_fd_gap = zz_rootseek & (_zzip_getpagesize(io->fd.sys) - 1);
HINT4(" fd_gap=%ld, mapseek=0x%lx, maplen=%ld", (long) (zz_fd_gap),
(long) (zz_rootseek - zz_fd_gap),
(long) (zz_rootsize + zz_fd_gap));
fd_map =
_zzip_mmap(io->fd.sys, fd, zz_rootseek - zz_fd_gap,
zz_rootsize + zz_fd_gap);
/* if mmap failed we will fallback to seek/read mode */
if (fd_map == MAP_FAILED)
{
NOTE2("map failed: %s", strerror(errno));
fd_map = 0;
} else
{
HINT3("mapped *%p len=%li", fd_map,
(long) (zz_rootsize + zz_fd_gap));
}
}
for (entries=0, zz_offset=0; ; entries++)
{
register struct zzip_disk_entry *d;
uint16_t u_extras, u_comment, u_namlen;
# ifndef ZZIP_ALLOW_MODULO_ENTRIES
if (entries >= zz_entries) {
if (zz_offset + 256 < zz_rootsize) {
FAIL4("%li's entry is long before the end of directory - enable modulo_entries? (O:%li R:%li)",
(long) entries, (long) (zz_offset), (long) zz_rootsize);
}
break;
}
# endif
if (fd_map)
{ d = (void*)(fd_map+zz_fd_gap+zz_offset); } /* fd_map+fd_gap==u_rootseek */
else
{
if (io->fd.seeks(fd, zz_rootseek + zz_offset, SEEK_SET) < 0)
return ZZIP_DIR_SEEK;
if (io->fd.read(fd, &dirent, sizeof(dirent)) < __sizeof(dirent))
return ZZIP_DIR_READ;
d = &dirent;
}
if (! zzip_disk_entry_check_magic(d)) {
# ifndef ZZIP_ALLOW_MODULO_ENTRIES
FAIL4("%li's entry has no disk_entry magic indicator (O:%li R:%li)",
(long) entries, (long) (zz_offset), (long) zz_rootsize);
# endif
break;
}
if ((zzip_off64_t) (zz_offset + sizeof(*d)) > zz_rootsize ||
(zzip_off64_t) (zz_offset + sizeof(*d)) < 0)
{
FAIL4("%li's entry stretches beyond root directory (O:%li R:%li)",
(long) entries, (long) (zz_offset), (long) zz_rootsize);
break;
}
# if 0 && defined DEBUG
zzip_debug_xbuf((unsigned char *) d, sizeof(*d) + 8);
# endif
u_extras = zzip_disk_entry_get_extras(d);
u_comment = zzip_disk_entry_get_comment(d);
u_namlen = zzip_disk_entry_get_namlen(d);
HINT5("offset=0x%lx, size %ld, dirent *%p, hdr %p\n",
(long) (zz_offset + zz_rootseek), (long) zz_rootsize, d, hdr);
/* writes over the read buffer, Since the structure where data is
copied is smaller than the data in buffer this can be done.
It is important that the order of setting the fields is considered
when filling the structure, so that some data is not trashed in
first structure read.
at the end the whole copied list of structures is copied into
newly allocated buffer */
hdr->d_crc32 = zzip_disk_entry_get_crc32(d);
hdr->d_csize = zzip_disk_entry_get_csize(d);
hdr->d_usize = zzip_disk_entry_get_usize(d);
hdr->d_off = zzip_disk_entry_get_offset(d);
hdr->d_compr = zzip_disk_entry_get_compr(d);
if (hdr->d_compr > _255)
hdr->d_compr = 255;
if ((zzip_off64_t) (zz_offset + sizeof(*d) + u_namlen) > zz_rootsize ||
(zzip_off64_t) (zz_offset + sizeof(*d) + u_namlen) < 0)
{
FAIL4("%li's name stretches beyond root directory (O:%li N:%li)",
(long) entries, (long) (zz_offset), (long) (u_namlen));
break;
}
if (fd_map)
{ memcpy(hdr->d_name, fd_map+zz_fd_gap + zz_offset+sizeof(*d), u_namlen); }
else
{ io->fd.read(fd, hdr->d_name, u_namlen); }
hdr->d_name[u_namlen] = '\0';
hdr->d_namlen = u_namlen;
/* update offset by the total length of this entry -> next entry */
zz_offset += sizeof(*d) + u_namlen + u_extras + u_comment;
if (zz_offset > zz_rootsize)
{
FAIL3("%li's entry stretches beyond root directory (O:%li)",
(long) entries, (long) (zz_offset));
entries ++;
break;
}
HINT5("file %ld { compr=%d crc32=$%x offset=%d",
(long) entries, hdr->d_compr, hdr->d_crc32, hdr->d_off);
HINT5("csize=%d usize=%d namlen=%d extras=%d",
hdr->d_csize, hdr->d_usize, u_namlen, u_extras);
HINT5("comment=%d name='%s' %s <sizeof %d> } ",
u_comment, hdr->d_name, "", (int) sizeof(*d));
p_reclen = &hdr->d_reclen;
{
register char *p = (char *) hdr;
register char *q = aligned4(p + sizeof(*hdr) + u_namlen + 1);
*p_reclen = (uint16_t) (q - p);
hdr = (struct zzip_dir_hdr *) q;
}
} /*for */
if (USE_MMAP && fd_map)
{
HINT3("unmap *%p len=%li", fd_map, (long) (zz_rootsize + zz_fd_gap));
_zzip_munmap(io->fd.sys, fd_map, zz_rootsize + zz_fd_gap);
}
if (p_reclen)
{
*p_reclen = 0; /* mark end of list */
if (hdr_return)
*hdr_return = hdr0;
} /* else zero (sane) entries */
# ifndef ZZIP_ALLOW_MODULO_ENTRIES
return (entries != zz_entries ? ZZIP_CORRUPTED : 0);
# else
return ((entries & (unsigned)0xFFFF) != zz_entries ? ZZIP_CORRUPTED : 0);
# endif
}
/* ------------------------- high-level interface ------------------------- */
#ifndef O_BINARY
#define O_BINARY 0
#endif
static zzip_strings_t *
zzip_get_default_ext(void)
{
static zzip_strings_t ext[] = {
/* *INDENT-OFF* */
".zip", ".ZIP", /* common extension */
# ifdef ZZIP_USE_ZIPLIKES
".pk3", ".PK3", /* ID Software's Quake3 zipfiles */
".jar", ".JAR", /* Java zipfiles */
# endif
/* *INDENT-ON* */
0
};
return ext;
}
/**
* allocate a new ZZIP_DIR handle and do basic
* initializations before usage by => zzip_dir_fdopen
* => zzip_dir_open => zzip_file_open or through
* => zzip_open
* (ext==null flags uses { ".zip" , ".ZIP" } )
* (io ==null flags use of posix io defaults)
*/
ZZIP_DIR *
zzip_dir_alloc_ext_io(zzip_strings_t * ext, const zzip_plugin_io_t io)
{
ZZIP_DIR *dir;
if ((dir = (ZZIP_DIR *) calloc(1, sizeof(*dir))) == NULL)
return 0;
/* dir->fileext is currently unused - so what, still initialize it */
dir->fileext = ext ? ext : zzip_get_default_ext();
dir->io = io ? io : zzip_get_default_io();
return dir;
}
/** => zzip_dir_alloc_ext_io
* this function is obsolete - it was generally used for implementation
* and exported to let other code build on it. It is now advised to
* use => zzip_dir_alloc_ext_io now on explicitly, just set that second
* argument to zero to achieve the same functionality as the old style.
*/
ZZIP_DIR *
zzip_dir_alloc(zzip_strings_t * fileext)
{
return zzip_dir_alloc_ext_io(fileext, 0);
}
/**
* will free the zzip_dir handle unless there are still
* zzip_files attached (that may use its cache buffer).
* This is the inverse of => zzip_dir_alloc , and both
* are helper functions used implicitly in other zzipcalls
* e.g. => zzip_dir_close = zzip_close
*
* returns zero on sucess
* returns the refcount when files are attached.
*/
int
zzip_dir_free(ZZIP_DIR * dir)
{
if (dir->refcount)
return (dir->refcount); /* still open files attached */
if (dir->fd >= 0)
dir->io->fd.close(dir->fd);
if (dir->hdr0)
free(dir->hdr0);
if (dir->cache.fp)
free(dir->cache.fp);
if (dir->cache.buf32k)
free(dir->cache.buf32k);
if (dir->realname)
free(dir->realname);
free(dir);
return 0;
}
/** => zzip_dir_free
* It will also => free(2) the => ZZIP_DIR-handle given.
* the counterpart for => zzip_dir_open
* see also => zzip_dir_free
*/
int
zzip_dir_close(ZZIP_DIR * dir)
{
dir->refcount &= ~0x10000000; /* explicit dir close */
return zzip_dir_free(dir);
}
/**
* used by the => zzip_dir_open and zzip_opendir(2) call. Opens the
* zip-archive as specified with the fd which points to an
* already openend file. This function then search and parse
* the zip's central directory.
*
* NOTE: refcount is zero, so an _open/_close pair will also delete
* this _dirhandle
*/
ZZIP_DIR *
zzip_dir_fdopen(int fd, zzip_error_t * errcode_p)
{
return zzip_dir_fdopen_ext_io(fd, errcode_p, 0, 0);
}
static zzip_error_t __zzip_dir_parse(ZZIP_DIR * dir); /* forward */
/** => zzip_dir_fdopen
* this function uses explicit ext and io instead of the internal
* defaults, setting these to zero is equivalent to => zzip_dir_fdopen
*/
ZZIP_DIR *
zzip_dir_fdopen_ext_io(int fd, zzip_error_t * errcode_p,
zzip_strings_t * ext, const zzip_plugin_io_t io)
{
zzip_error_t rv;
ZZIP_DIR *dir;
if ((dir = zzip_dir_alloc_ext_io(ext, io)) == NULL)
{ rv = ZZIP_OUTOFMEM; goto error; }
dir->fd = fd;
if ((rv = __zzip_dir_parse(dir)))
goto error;
dir->hdr = dir->hdr0;
dir->refcount |= 0x10000000;
if (errcode_p)
*errcode_p = rv;
return dir;
error:
if (dir)
zzip_dir_free(dir);
if (errcode_p)
*errcode_p = rv;
return NULL;
}
static zzip_error_t
__zzip_dir_parse(ZZIP_DIR * dir)
{
zzip_error_t rv;
zzip_off_t filesize;
struct _disk_trailer trailer;
/* if (! dir || dir->fd < 0)
* { rv = EINVAL; goto error; }
*/
HINT2("------------------ fd=%i", (int) dir->fd);
if ((filesize = dir->io->fd.filesize(dir->fd)) < 0)
{ rv = ZZIP_DIR_STAT; goto error; }
HINT2("------------------ filesize=%ld", (long) filesize);
if ((rv = __zzip_fetch_disk_trailer(dir->fd, filesize, &trailer,
dir->io)) != 0)
{ goto error; }
HINT5("directory = { entries= %ld/%ld, size= %ld, seek= %ld } ",
(long) _disk_trailer_localentries(&trailer),
(long) _disk_trailer_finalentries(&trailer),
(long) _disk_trailer_rootsize(&trailer),
(long) _disk_trailer_rootseek(&trailer));
if ((rv = __zzip_parse_root_directory(dir->fd, &trailer, &dir->hdr0,
dir->io)) != 0)
{ goto error; }
error:
return rv;
}
/**
* This function will attach any of the .zip extensions then
* trying to open it the with => open(2). This is a helper
* function for => zzip_dir_open, => zzip_opendir and => zzip_open.
*
* This function returns a new system file handle or -1 on error.
* On error this function leaves the errno(3) of the underlying
* open(2) call on the last file.
*/
int
__zzip_try_open(zzip_char_t * filename, int filemode,
zzip_strings_t * ext, zzip_plugin_io_t io)
{
auto char file[PATH_MAX];
int fd;
zzip_size_t len = strlen(filename);
if (len + 4 >= PATH_MAX)
{ errno = ENAMETOOLONG; return -1; }
memcpy(file, filename, len + 1);
if (! io)
io = zzip_get_default_io();
if (! ext)
ext = zzip_get_default_ext();
for (; *ext; ++ext)
{
strcpy(file + len, *ext);
fd = io->fd.open(file, filemode);
if (fd != -1)
return fd;
}
return -1;
}
/**
* Opens the zip-archive (if available).
* the two ext_io arguments will default to use posix io and
* a set of default fileext that can atleast add .zip ext itself.
*/
ZZIP_DIR *
zzip_dir_open(zzip_char_t * filename, zzip_error_t * e)
{
return zzip_dir_open_ext_io(filename, e, 0, 0);
}
/** => zzip_dir_open
* this function uses explicit ext and io instead of the internal
* defaults. Setting these to zero is equivalent to => zzip_dir_open
*/
ZZIP_DIR *
zzip_dir_open_ext_io(zzip_char_t * filename, zzip_error_t * e,
zzip_strings_t * ext, zzip_plugin_io_t io)
{
int fd;
if (! io)
io = zzip_get_default_io();
if (! ext)
ext = zzip_get_default_ext();
fd = io->fd.open(filename, O_RDONLY | O_BINARY);
if (fd != -1)
{
return zzip_dir_fdopen_ext_io(fd, e, ext, io);
} else
{
fd = __zzip_try_open(filename, O_RDONLY | O_BINARY, ext, io);
if (fd != -1)
{
return zzip_dir_fdopen_ext_io(fd, e, ext, io);
} else
{
if (e)
{ *e = ZZIP_DIR_OPEN; }
return 0;
}
}
}
/** => zzip_dir_open
* fills the dirent-argument with the values and
* increments the read-pointer of the dir-argument.
*
* returns 0 if there no entry (anymore).
*/
int
zzip_dir_read(ZZIP_DIR * dir, ZZIP_DIRENT * d)
{
if (! dir || ! dir->hdr || ! d)
return 0;
d->d_compr = dir->hdr->d_compr;
d->d_csize = dir->hdr->d_csize;
d->st_size = dir->hdr->d_usize;
d->d_name = dir->hdr->d_name;
if (! dir->hdr->d_reclen)
{
dir->hdr = 0;
} else
{
dir->hdr = (struct zzip_dir_hdr *)
((char *) dir->hdr + dir->hdr->d_reclen);
}
return 1;
}
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/